| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | 
							- // Copyright (C) 2020 The Syncthing Authors.
 
- //
 
- // This Source Code Form is subject to the terms of the Mozilla Public
 
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
 
- // You can obtain one at https://mozilla.org/MPL/2.0/.
 
- package db
 
- import (
 
- 	"time"
 
- 	"github.com/syncthing/syncthing/lib/protocol"
 
- )
 
- func (db *Lowlevel) AddOrUpdatePendingDevice(device protocol.DeviceID, name, address string) error {
 
- 	key := db.keyer.GeneratePendingDeviceKey(nil, device[:])
 
- 	od := ObservedDevice{
 
- 		Time:    time.Now().Round(time.Second),
 
- 		Name:    name,
 
- 		Address: address,
 
- 	}
 
- 	bs, err := od.Marshal()
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	return db.Put(key, bs)
 
- }
 
- func (db *Lowlevel) RemovePendingDevice(device protocol.DeviceID) {
 
- 	key := db.keyer.GeneratePendingDeviceKey(nil, device[:])
 
- 	if err := db.Delete(key); err != nil {
 
- 		l.Warnf("Failed to remove pending device entry: %v", err)
 
- 	}
 
- }
 
- // PendingDevices enumerates all entries.  Invalid ones are dropped from the database
 
- // after a warning log message, as a side-effect.
 
- func (db *Lowlevel) PendingDevices() (map[protocol.DeviceID]ObservedDevice, error) {
 
- 	iter, err := db.NewPrefixIterator([]byte{KeyTypePendingDevice})
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	defer iter.Release()
 
- 	res := make(map[protocol.DeviceID]ObservedDevice)
 
- 	for iter.Next() {
 
- 		keyDev := db.keyer.DeviceFromPendingDeviceKey(iter.Key())
 
- 		deviceID, err := protocol.DeviceIDFromBytes(keyDev)
 
- 		var od ObservedDevice
 
- 		if err != nil {
 
- 			goto deleteKey
 
- 		}
 
- 		if err = od.Unmarshal(iter.Value()); err != nil {
 
- 			goto deleteKey
 
- 		}
 
- 		res[deviceID] = od
 
- 		continue
 
- 	deleteKey:
 
- 		// Deleting invalid entries is the only possible "repair" measure and
 
- 		// appropriate for the importance of pending entries.  They will come back
 
- 		// soon if still relevant.
 
- 		l.Infof("Invalid pending device entry, deleting from database: %x", iter.Key())
 
- 		if err := db.Delete(iter.Key()); err != nil {
 
- 			return nil, err
 
- 		}
 
- 	}
 
- 	return res, nil
 
- }
 
- func (db *Lowlevel) AddOrUpdatePendingFolder(id, label string, device protocol.DeviceID) error {
 
- 	key, err := db.keyer.GeneratePendingFolderKey(nil, device[:], []byte(id))
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	of := ObservedFolder{
 
- 		Time:  time.Now().Round(time.Second),
 
- 		Label: label,
 
- 	}
 
- 	bs, err := of.Marshal()
 
- 	if err != nil {
 
- 		return err
 
- 	}
 
- 	return db.Put(key, bs)
 
- }
 
- // RemovePendingFolderForDevice removes entries for specific folder / device combinations.
 
- func (db *Lowlevel) RemovePendingFolderForDevice(id string, device protocol.DeviceID) {
 
- 	key, err := db.keyer.GeneratePendingFolderKey(nil, device[:], []byte(id))
 
- 	if err != nil {
 
- 		return
 
- 	}
 
- 	if err := db.Delete(key); err != nil {
 
- 		l.Warnf("Failed to remove pending folder entry: %v", err)
 
- 	}
 
- }
 
- // RemovePendingFolder removes all entries matching a specific folder ID.
 
- func (db *Lowlevel) RemovePendingFolder(id string) {
 
- 	iter, err := db.NewPrefixIterator([]byte{KeyTypePendingFolder})
 
- 	if err != nil {
 
- 		l.Infof("Could not iterate through pending folder entries: %v", err)
 
- 		return
 
- 	}
 
- 	defer iter.Release()
 
- 	for iter.Next() {
 
- 		if id != string(db.keyer.FolderFromPendingFolderKey(iter.Key())) {
 
- 			continue
 
- 		}
 
- 		if err := db.Delete(iter.Key()); err != nil {
 
- 			l.Warnf("Failed to remove pending folder entry: %v", err)
 
- 		}
 
- 	}
 
- }
 
- // Consolidated information about a pending folder
 
- type PendingFolder struct {
 
- 	OfferedBy map[protocol.DeviceID]ObservedFolder `json:"offeredBy"`
 
- }
 
- func (db *Lowlevel) PendingFolders() (map[string]PendingFolder, error) {
 
- 	return db.PendingFoldersForDevice(protocol.EmptyDeviceID)
 
- }
 
- // PendingFoldersForDevice enumerates only entries matching the given device ID, unless it
 
- // is EmptyDeviceID.  Invalid ones are dropped from the database after a warning log
 
- // message, as a side-effect.
 
- func (db *Lowlevel) PendingFoldersForDevice(device protocol.DeviceID) (map[string]PendingFolder, error) {
 
- 	var err error
 
- 	prefixKey := []byte{KeyTypePendingFolder}
 
- 	if device != protocol.EmptyDeviceID {
 
- 		prefixKey, err = db.keyer.GeneratePendingFolderKey(nil, device[:], nil)
 
- 		if err != nil {
 
- 			return nil, err
 
- 		}
 
- 	}
 
- 	iter, err := db.NewPrefixIterator(prefixKey)
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	defer iter.Release()
 
- 	res := make(map[string]PendingFolder)
 
- 	for iter.Next() {
 
- 		keyDev, ok := db.keyer.DeviceFromPendingFolderKey(iter.Key())
 
- 		deviceID, err := protocol.DeviceIDFromBytes(keyDev)
 
- 		var of ObservedFolder
 
- 		var folderID string
 
- 		if !ok || err != nil {
 
- 			goto deleteKey
 
- 		}
 
- 		if folderID = string(db.keyer.FolderFromPendingFolderKey(iter.Key())); len(folderID) < 1 {
 
- 			goto deleteKey
 
- 		}
 
- 		if err = of.Unmarshal(iter.Value()); err != nil {
 
- 			goto deleteKey
 
- 		}
 
- 		if _, ok := res[folderID]; !ok {
 
- 			res[folderID] = PendingFolder{
 
- 				OfferedBy: map[protocol.DeviceID]ObservedFolder{},
 
- 			}
 
- 		}
 
- 		res[folderID].OfferedBy[deviceID] = of
 
- 		continue
 
- 	deleteKey:
 
- 		// Deleting invalid entries is the only possible "repair" measure and
 
- 		// appropriate for the importance of pending entries.  They will come back
 
- 		// soon if still relevant.
 
- 		l.Infof("Invalid pending folder entry, deleting from database: %x", iter.Key())
 
- 		if err := db.Delete(iter.Key()); err != nil {
 
- 			return nil, err
 
- 		}
 
- 	}
 
- 	return res, nil
 
- }
 
 
  |