package webfilesystem import ( "errors" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) type V3FileHeader struct { MongoId primitive.ObjectID `bson:"_id" json:"-"` Name string `bson:"name" json:"name"` Type string `bson:"type" json:"type"` Icon string `bson:"-" json:"icon"` Data primitive.ObjectID `bson:"data_id" json:"-"` } type V3FileBinaryData struct { MongoId primitive.ObjectID `bson:"_id" json:"-"` Bin []byte `bson:"bin" json:"-"` } func (fs *WebFileSystem) V3ReadHeader(fileID primitive.ObjectID) (*V3FileHeader, error) { file := &V3FileHeader{} filter := primitive.M{ "_id": fileID, } err := fs.webfsFilesTable.FindOne(fs.ctx, filter).Decode(file) return file, err } func (fs *WebFileSystem) V3Read(fileID primitive.ObjectID, fileData interface{}) (*V3FileHeader, error) { fileHeader := &V3FileHeader{} filter := primitive.M{ "_id": fileID, } err := fs.webfsFilesTable.FindOne(fs.ctx, filter).Decode(fileHeader) if err != nil { return nil, err } if fileData != nil { filter := primitive.M{ "_id": fileHeader.Data, } err := fs.webfsFilesData.FindOne(fs.ctx, filter).Decode(fileData) if err != nil { return nil, err } } return fileHeader, nil } func (fs *WebFileSystem) V3Write(filePath string, file *V3FileHeader, data interface{}) (primitive.ObjectID, primitive.ObjectID, error) { headerId, dataId, err := fs.v3WriteFileToMongo(file, data) if err != nil { return primitive.NilObjectID, primitive.NilObjectID, err } parentPath := fs.GetParentPath(filePath) parentDir, err := fs.V3FindFile(parentPath) if err != nil { return primitive.NilObjectID, primitive.NilObjectID, err } if parentDir.IsZero() { return primitive.NilObjectID, primitive.NilObjectID, errors.New("parent dir not found") } err = fs.V3AppendChildToDirectory(headerId, parentDir) if err != nil { return primitive.NilObjectID, primitive.NilObjectID, err } return headerId, dataId, nil } func (fs *WebFileSystem) v3WriteFileToMongo(file *V3FileHeader, data interface{}) (primitive.ObjectID, primitive.ObjectID, error) { resData, err := fs.webfsFilesData.InsertOne(fs.ctx, data) if err != nil { return primitive.NilObjectID, primitive.NilObjectID, err } file.Data = resData.InsertedID.(primitive.ObjectID) resHeader, err := fs.webfsFilesTable.InsertOne(fs.ctx, file) if err != nil { return primitive.NilObjectID, primitive.NilObjectID, err } return resHeader.InsertedID.(primitive.ObjectID), resData.InsertedID.(primitive.ObjectID), err } func (fs *WebFileSystem) V3WriteUpdateData(file *V3FileHeader, data interface{}) error { update := bson.M{"$set": data} // println("updating data file: " + file.MongoId.String()) res, err := fs.webfsFilesData.UpdateByID(fs.ctx, file.Data, update) if err != nil { return err } if res.ModifiedCount < 1 { return errors.New("no data updated") } return err } func (fs *WebFileSystem) V3InitFS() error { //FIXME Can't set parent_id to itself rootData := V3DirectoryData{ MongoId: primitive.NewObjectID(), Parent: primitive.NewObjectID(), Children: []primitive.ObjectID{}, } rootHeader := V3FileHeader{ MongoId: primitive.NewObjectID(), Name: "/", Type: "directory", Icon: "", } _, _, err := fs.v3WriteFileToMongo(&rootHeader, &rootData) if err != nil { return err } return nil } func (fs *WebFileSystem) V3GetRootDir() (*V3FileHeader, *V3DirectoryData, error) { filter := primitive.M{ "name": "/", } res := fs.webfsFilesTable.FindOne(fs.ctx, filter) if res == nil { return nil, nil, errors.New("TODO") //TODO } rootDir := V3FileHeader{} err := res.Decode(&rootDir) if res == nil { return nil, nil, err } filterData := primitive.M{ "_id": rootDir.Data, } resData := fs.webfsFilesData.FindOne(fs.ctx, filterData) if resData.Err() != nil { return nil, nil, err } rootDirData := V3DirectoryData{} err = resData.Decode(&rootDirData) if err != nil { return nil, nil, err } return &rootDir, &rootDirData, nil } func (fs *WebFileSystem) V3Remove(filePath string) error { parentPath := fs.GetParentPath(filePath) parentDirId, err := fs.V3FindFile(parentPath) if err != nil { return err } //TODO: Check, if parent file is dir parentDirData := V3DirectoryData{} parentDir, err := fs.V3Read(parentDirId, &parentDirData) if err != nil { return err } fileId, err := fs.V3FindFile(filePath) if err != nil { return err } newChildren := []primitive.ObjectID{} for _, childId := range parentDirData.Children { if childId != fileId { newChildren = append(newChildren, childId) } } parentDirData.Children = newChildren err = fs.V3WriteUpdateData(parentDir, parentDirData) if err != nil { return err } return nil } func (fs *WebFileSystem) removeFromMongo(fileId primitive.ObjectID) error { return errors.New("todo not implemented yet") }