182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
|
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")
|
||
|
}
|