github.com/pbberlin/tools@v0.0.0-20160910141205-7aa5421c2169/os/fsi/dsfs/low_level_files.go (about) 1 package dsfs 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/pbberlin/tools/os/fsi" 8 "github.com/pbberlin/tools/os/fsi/common" 9 "github.com/pbberlin/tools/runtimepb" 10 "google.golang.org/appengine/datastore" 11 12 aelog "google.golang.org/appengine/log" 13 ) 14 15 func (fs *dsFileSys) fileByPath(name string) (DsFile, error) { 16 17 dir, bname := fs.SplitX(name) 18 19 fo := DsFile{} 20 fo.fSys = fs 21 22 // 23 if dir == fs.RootDir() && bname == "" { 24 return fo, fsi.ErrRootDirNoFile 25 } 26 27 foDir, err := fs.dirByPath(dir) 28 if err == datastore.ErrNoSuchEntity { 29 return fo, err 30 } else if err != nil { 31 aelog.Errorf(fs.Ctx(), "Error reading dir for file %v => %v", dir+bname, err) 32 return fo, err 33 } 34 35 fileKey := datastore.NewKey(fs.Ctx(), tfil, bname, 0, foDir.Key) 36 fo.Key = fileKey 37 err = datastore.Get(fs.c, fileKey, &fo) 38 if err == datastore.ErrNoSuchEntity { 39 return fo, err 40 } else if err != nil { 41 s := fmt.Sprintf("%v", fileKey) 42 aelog.Errorf(fs.Ctx(), "Error reading file %v (%v) => %v", dir+bname, s, err) 43 } 44 45 return fo, err 46 47 } 48 49 // similar to ReadDir but returning only files 50 func (fs *dsFileSys) filesByPath(name string) ([]DsFile, error) { 51 52 dir, bname := fs.SplitX(name) 53 54 var files []DsFile 55 56 foDir, err := fs.dirByPath(dir + common.Filify(bname)) 57 if err == datastore.ErrNoSuchEntity { 58 return files, err 59 } else if err != nil { 60 aelog.Errorf(fs.Ctx(), "Error reading dir for files %v => %v", dir+bname, err) 61 return files, err 62 } 63 64 // fs.Ctx().Infof(" Files by Path %-20v - got dir %-10v - %v", dir+bname, foDir.Name(), foDir.Key) 65 66 q := datastore.NewQuery(tfil).Ancestor(foDir.Key) 67 keys, err := q.GetAll(fs.Ctx(), &files) 68 if err != nil { 69 aelog.Errorf(fs.Ctx(), "Error fetching files children of %v => %v", foDir.Key, err) 70 return files, err 71 } 72 73 // fs.Ctx().Infof(" Files by Path %-20v - got files %v", dir+bname, len(files)) 74 75 for i := 0; i < len(files); i++ { 76 files[i].Key = keys[i] 77 files[i].fSys = fs 78 } 79 80 fs.filesorter(files) 81 82 return files, err 83 } 84 85 // 86 // 87 // Path is the directory, BName contains the base name. 88 func (fs *dsFileSys) saveFileByPath(f *DsFile, name string) error { 89 90 dir, bname := fs.SplitX(name) 91 f.Dir = dir 92 // bname was only submitted in the fileobject 93 // correct previous 94 if f.BName != "" && f.BName != bname { 95 dir = dir + bname // re-append 96 if !strings.HasSuffix(dir, sep) { 97 dir += sep 98 } 99 bname = f.BName 100 f.Dir = dir 101 } 102 f.BName = common.Filify(bname) 103 104 // f.MModTime = time.Now() 105 f.fSys = fs 106 107 // 108 // -------------now the datastore part------------------------- 109 110 foDir, err := fs.dirByPath(dir) 111 if err == datastore.ErrNoSuchEntity { 112 return err 113 } else if err != nil { 114 aelog.Errorf(fs.Ctx(), "Error reading dir for file %v => %v", dir+bname, err) 115 return err 116 } 117 118 suggKey := datastore.NewKey(fs.Ctx(), tfil, f.BName, 0, foDir.Key) 119 f.Key = suggKey 120 121 effKey, err := datastore.Put(fs.Ctx(), suggKey, f) 122 if err != nil { 123 aelog.Errorf(fs.Ctx(), "Error saving file %v => %v", dir+bname, err) 124 return err 125 } 126 if !suggKey.Equal(effKey) { 127 aelog.Errorf(fs.Ctx(), "file keys unequal %v - %v; %v %s", suggKey, effKey, f.Dir+f.BName, f.Data) 128 runtimepb.StackTrace(6) 129 } 130 131 // f.MemCacheSet() 132 133 return nil 134 }