Skip to content

Commit 0f58101

Browse files
committed
软链接功能基本完成
1 parent 2231442 commit 0f58101

File tree

2 files changed

+108
-29
lines changed

2 files changed

+108
-29
lines changed

backend/db/db.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
192192
// No root so return old f
193193
return f, nil
194194
}
195-
_, err := tempF.readAbsoluteDirInfo(ctx, root)
195+
_, err := tempF.readAbsoluteFileInfo(ctx, root)
196196
if err != nil {
197197
if errors.Is(err, fs.ErrorDirNotFound) || errors.Is(err, fs.ErrorObjectOrDirNotFound) {
198198
// File doesn't exist so return old f
@@ -213,7 +213,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
213213

214214
// Return an FileInfo from a path
215215
// If it can't be found it returns the error fs.ErrorObjectNotFound.
216-
func (f *Fs) readAbsoluteDirInfo(ctx context.Context, path string) (*FileInfo, error) {
216+
func (f *Fs) readAbsoluteFileInfo(ctx context.Context, path string) (*FileInfo, error) {
217217
// 处理特殊情况,移除结果中的空字符串
218218
var segments = pathToSegments(path)
219219

@@ -228,7 +228,7 @@ func (f *Fs) readAbsoluteDirInfo(ctx context.Context, path string) (*FileInfo, e
228228
tx = f.db.Find(&foundFile, "name = ? and parent_id = ?", segment, retrievedFile.Id)
229229
}
230230
if tx.Error != nil {
231-
return nil, errors.Wrapf(tx.Error, "db readAbsoluteDirInfo error.path (%s),segment (%s)", path, segment)
231+
return nil, errors.Wrapf(tx.Error, "db readAbsoluteFileInfo error.path (%s),segment (%s)", path, segment)
232232
}
233233
if len(foundFile) == 0 {
234234
if i != len(segments)-1 {
@@ -282,6 +282,19 @@ func (f *Fs) FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut strin
282282
//if !ok {
283283
// return "", false, errors.New("couldn't find parent ID")
284284
//}
285+
var pathIDFile FileInfo
286+
find := f.db.Find(&pathIDFile, &FileInfo{Id: pathID})
287+
if find.Error != nil {
288+
return "", false, find.Error
289+
}
290+
//如果打开的软链接文件,需要特殊处理
291+
if !f.opt.IsLinkFileMode && pathIDFile.IsLink {
292+
linkToFileInfo, err := f.findRealLinkedToFileInfo(ctx, pathIDFile.LinkToPath, true)
293+
if err != nil {
294+
return "", false, err
295+
}
296+
pathID = linkToFileInfo.Id
297+
}
285298
var foundFile []FileInfo
286299
tx := f.db.Find(&foundFile, "name = ? and parent_id = ?", leaf, pathID)
287300
if tx.Error != nil {
@@ -375,6 +388,21 @@ func (f *Fs) findRootRelativePathFile(path string) (*FileInfo, error) {
375388
return &retrievedFile, nil
376389
}
377390

391+
func (f *Fs) findRealLinkedToFileInfo(ctx context.Context, linkToPath string, findDir bool) (linkToFileInfo *FileInfo, err error) {
392+
for linkToFileInfo == nil || linkToFileInfo.IsLink {
393+
linkToFileInfo, err = f.readAbsoluteFileInfo(ctx, linkToPath)
394+
if err != nil {
395+
return nil, err
396+
}
397+
if findDir && !linkToFileInfo.IsDir {
398+
return nil, fs.ErrorIsFile
399+
} else if !findDir && linkToFileInfo.IsDir {
400+
return nil, fs.ErrorIsDir
401+
}
402+
}
403+
return linkToFileInfo, nil
404+
}
405+
378406
// List entries normal need to implement fs.Directory or fs.Object ,dir is relative path,f.root is base path
379407
func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) {
380408
directoryID, err := f.dirCache.FindDir(ctx, dir, false)
@@ -390,15 +418,12 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e
390418
if db.Error != nil {
391419
return nil, errors.Wrapf(db.Error, "List: dir find error")
392420
}
393-
for dirFileInfo.IsLink {
394-
linkToDirInfo, err := f.readAbsoluteDirInfo(ctx, dirFileInfo.LinkToPath)
421+
if dirFileInfo.IsLink {
422+
realFileInfo, err := f.findRealLinkedToFileInfo(ctx, dirFileInfo.LinkToPath, true)
395423
if err != nil {
396424
return nil, err
397425
}
398-
dirFileInfo = *linkToDirInfo
399-
if !linkToDirInfo.IsLink {
400-
directoryID = linkToDirInfo.Id
401-
}
426+
directoryID = realFileInfo.Id
402427
}
403428
}
404429

backend/db/db_object.go

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ import (
2020
//
2121
// Will definitely have info but maybe not meta
2222
type Object struct {
23-
fs *Fs // what this object is part of
24-
remote string // The remote path base root relativePath path,have file name
25-
size int64 // size of the object
26-
modTime time.Time // modification time of the object
27-
id string // ID of the object
28-
parentId string
29-
fileName string
23+
fs *Fs // what this object is part of
24+
remote string // The remote path base root relativePath path,have file name
25+
size int64 // size of the object
26+
modTime time.Time // modification time of the object
27+
id string // ID of the object
28+
parentId string
29+
fileName string
30+
isLink bool
31+
linkToPath string
3032
}
3133

3234
// ------------------------------------------------------------
@@ -43,13 +45,15 @@ func NewObjectFromFileInfo(file *FileInfo, absolutePath string, f *Fs) *Object {
4345
}
4446
} else {
4547
return &Object{
46-
id: file.Id,
47-
parentId: file.ParentId,
48-
remote: absolutePath,
49-
modTime: file.ModTime,
50-
size: file.FileSize,
51-
fs: f,
52-
fileName: file.Name,
48+
id: file.Id,
49+
parentId: file.ParentId,
50+
remote: absolutePath,
51+
modTime: file.ModTime,
52+
size: file.FileSize,
53+
fs: f,
54+
fileName: file.Name,
55+
isLink: file.IsLink,
56+
linkToPath: file.LinkToPath,
5357
}
5458
}
5559
}
@@ -102,11 +106,20 @@ func (o *Object) Storable() bool {
102106
}
103107

104108
func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (in io.ReadCloser, err error) {
109+
realOpenFileId := o.id
110+
105111
//如果打开的软链接文件,需要特殊处理
112+
if !o.fs.opt.IsLinkFileMode && o.isLink {
113+
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, o.linkToPath, false)
114+
if err != nil {
115+
return nil, err
116+
}
117+
realOpenFileId = linkToFileInfo.Id
118+
}
106119

107120
fs.FixRangeOption(options, o.size)
108121
var fileInfo FileInfo
109-
result := o.fs.db.Select("content", "is_dir").First(&fileInfo, "id = ?", o.id)
122+
result := o.fs.db.Select("content", "is_dir").First(&fileInfo, "id = ?", realOpenFileId)
110123
if result.Error != nil {
111124
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
112125
return nil, fs.ErrorObjectNotFound
@@ -185,7 +198,6 @@ func convertWindowsPathToLinuxStyle(windowsPath string) string {
185198
//
186199
// The new object may have been created if an error is returned 可能本身这个object就不存在??
187200
func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (err error) {
188-
//如果是更新软链接文件内容,则需要更新链接到的文件的内容
189201

190202
allByte, err := io.ReadAll(in)
191203
if err != nil {
@@ -230,7 +242,12 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
230242
} else {
231243
fileInfo.LinkToPath = derivedPathFromRelative
232244
}
233-
245+
//// 文件夹链接大小定为-1,文件链接大小定为0
246+
//if linkToFileInfo.IsDir() {
247+
// fileInfo.FileSize = -1
248+
//} else {
249+
// fileInfo.FileSize = 0
250+
//}
234251
}
235252
tx := o.fs.db.Begin()
236253
if o.id == "" {
@@ -240,10 +257,47 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
240257
return errors.Wrapf(result.Error, "Error update object %s", o)
241258
}
242259
} else {
243-
result := tx.Model(&FileInfo{}).Where("id = ?", o.id).Updates(fileInfo)
244-
if result.Error != nil {
260+
//如果是更新软链接文件内容,则需要更新链接到的文件的内容
261+
//只有原本文件存在时,才会进行更新,如果文件不存在,则应该是走创建链接文件的逻辑,而不是这里
262+
var oldFileInfo FileInfo
263+
db := tx.Find(&oldFileInfo, &FileInfo{Id: o.id})
264+
if db.Error != nil && !errors.Is(db.Error, gorm.ErrRecordNotFound) {
245265
tx.Rollback()
246-
return errors.Wrapf(result.Error, "Error update object %s", o)
266+
return errors.Wrapf(db.Error, "Error update object %s", o)
267+
}
268+
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
269+
result := tx.Create(&fileInfo)
270+
if result.Error != nil {
271+
tx.Rollback()
272+
return errors.Wrapf(result.Error, "Error update object %s", o)
273+
}
274+
}
275+
276+
//如果打开的软链接文件,需要特殊处理
277+
if !o.fs.opt.IsLinkFileMode && oldFileInfo.IsLink {
278+
linkToFileInfo, err := o.fs.findRealLinkedToFileInfo(ctx, o.linkToPath, false)
279+
if err != nil {
280+
return err
281+
}
282+
// 更新真正链接到的文件的内容
283+
updates := tx.Model(&FileInfo{}).Where("id = ?", linkToFileInfo.Id).Updates(&FileInfo{
284+
FileSize: int64(len(allByte)),
285+
Content: allByte,
286+
ModTime: src.ModTime(ctx),
287+
})
288+
if updates.Error != nil {
289+
tx.Rollback()
290+
return errors.Wrapf(updates.Error, "Error update object %s", o)
291+
}
292+
//不用更新软链接本身的modTime
293+
tx.Commit()
294+
return nil
295+
} else {
296+
result := tx.Model(&FileInfo{}).Where("id = ?", o.id).Updates(fileInfo)
297+
if result.Error != nil {
298+
tx.Rollback()
299+
return errors.Wrapf(result.Error, "Error update object %s", o)
300+
}
247301
}
248302
}
249303

0 commit comments

Comments
 (0)