@@ -20,13 +20,15 @@ import (
2020//
2121// Will definitely have info but maybe not meta
2222type 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
104108func (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就不存在??
187200func (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