package localserver import ( "encoding/json" "os" "path/filepath" "github.com/dgraph-io/badger/v3" ) type ZoneFilesDBHandler struct { CurrentLocation string ZoneID string rootPath string db func(string, func(*badger.DB) (err error)) (err error) } func NewZoneFilesDBHandler(zoneId string) (zoneFilesDBHandler *ZoneFilesDBHandler, err error) { zoneFilesDBHandler = &ZoneFilesDBHandler{ db: func(path string, f func(*badger.DB) (err error)) (err error) { root := filepath.Join(dataPath, "data", "zones", zoneId, "fs", path) db, err := badger.Open(badger.DefaultOptions(root).WithLogger(dbLogger)) if err != nil { return } defer db.Close() err = f(db) return }, ZoneID: zoneId, } zoneFilesDBHandler.rootPath = filepath.Join(dataPath, "data", "zones", zoneId, "fs") return } func (zcdbh *ZoneFilesDBHandler) AddNewFSEntity(path string, fsEntity *ZoneFSEntity) (err error) { bs, err := json.Marshal(fsEntity) if err != nil { return } err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { if updateErr := txn.Set([]byte(fsEntity.Name), bs); updateErr != nil { return updateErr } if fsEntity.Folder { err = os.Mkdir(filepath.Join(dataPath, "data", "zones", zcdbh.ZoneID, "fs", path, fsEntity.Name), 0700) } return }) return }) return } func (zcdbh *ZoneFilesDBHandler) DeleteFolder(path, name string) (err error) { if err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { err = txn.Delete([]byte(name)) return }) return }); err != nil { return } err = os.RemoveAll(filepath.Join(zcdbh.rootPath, path, name)) return } func (zcdbh *ZoneFilesDBHandler) DeleteFile(path, name string) (err error) { if err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { err = txn.Delete([]byte(name)) return }) return }); err != nil { return } err = os.Remove(filepath.Join(zcdbh.rootPath, path, "__files__", name)) return } func (zcdbh *ZoneFilesDBHandler) ListZoneFSEntity(path string, userId string, lastIndex int, limit int) (fsEntities []*ZoneFSEntity, l int, err error) { err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { opt := badger.DefaultIteratorOptions opt.Reverse = true it := txn.NewIterator(opt) defer it.Close() fsEntities = make([]*ZoneFSEntity, 0) splittedPath := filepath.SplitList(path) var parent *ZoneFSEntity if len(splittedPath) >= 2 { parent, err = zcdbh.GetFSEntity(filepath.Dir(path), filepath.Base(path)) } else if len(splittedPath) > 0 { parent = nil } if err != nil { return } for it.Rewind(); it.Valid(); it.Next() { item := it.Item() if err = item.Value(func(val []byte) (err error) { var fsEntity *ZoneFSEntity if err = json.Unmarshal(val, &fsEntity); err != nil { return err } logger.Println("------------------", fsEntity.Name) if _, ok := fsEntity.Members[userId]; ok || fsEntity.Type == "public" { fsEntities = append(fsEntities, fsEntity) } else if parent != nil { if _, ok := parent.Members[userId]; ok && fsEntity.Type != "private" { if parent.Members[userId].Read { fsEntities = append(fsEntities, fsEntity) } } } return }); err != nil { return err } } return }) return }) return } func (zcdbh *ZoneFilesDBHandler) GetFSEntity(path string, folderName string) (folder *ZoneFSEntity, err error) { err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.View(func(txn *badger.Txn) (err error) { item, err := txn.Get([]byte(folderName)) if err != nil { return } err = item.Value(func(val []byte) (err error) { err = json.Unmarshal(val, &folder) return }) return }) return }) return } func (zcdbh *ZoneFilesDBHandler) SetFSEntity(path string, oldName string, fsEntity *ZoneFSEntity) (err error) { bs, err := json.Marshal(fsEntity) if err != nil { return } if err = zcdbh.db(path, func(d *badger.DB) (err error) { err = d.Update(func(txn *badger.Txn) (err error) { if dErr := txn.Delete([]byte(oldName)); err != nil { logger.Println("error from here:", dErr) } if updateErr := txn.Set([]byte(fsEntity.Name), bs); updateErr != nil { return updateErr } return }) return }); err != nil { return } return }