github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/os/fsi/dsfs/low_level_dirs.go (about) 1 package dsfs 2 3 import ( 4 "os" 5 "time" 6 7 "github.com/pbberlin/tools/os/fsi/common" 8 9 ds "google.golang.org/appengine/datastore" 10 11 aelog "google.golang.org/appengine/log" 12 ) 13 14 // Retrieves a directory in one go. 15 // Also used to check existence; returning ds.ErrNoSuchEntity 16 func (fs *dsFileSys) dirByPath(name string) (DsDir, error) { 17 18 dir, bname := fs.SplitX(name) 19 20 fo := DsDir{} 21 fo.fSys = fs 22 23 preciseK := ds.NewKey(fs.c, tdir, dir+common.Filify(bname), 0, nil) 24 fo.Key = preciseK 25 26 err := fo.MemCacheGet(dir + common.Filify(bname)) 27 if err == nil { 28 fo.fSys = fs 29 fo.Key = preciseK 30 // log.Printf(" mcg %-16v %v", dir+bname, fo.Key) 31 return fo, nil 32 } 33 34 err = ds.Get(fs.c, preciseK, &fo) 35 if err == ds.ErrNoSuchEntity { 36 // uncomment to see where directories do not exist: 37 // log.Printf("no directory: %-20v ", path) 38 // runtimepb.StackTrace(4) 39 return fo, err 40 } else if err != nil { 41 aelog.Errorf(fs.Ctx(), "Error getting dir %v => %v", dir+common.Filify(bname), err) 42 } 43 44 fo.MemCacheSet() 45 return fo, err 46 } 47 48 // 49 // dirsByPath might not find recently added directories. 50 // Upon finding nothing, it therefore returns the 51 // "warning" fsi.EmptyQueryResult 52 // 53 // It is currently used by ReadDir 54 func (fs *dsFileSys) dirsByPath(name string) ([]os.FileInfo, error) { 55 56 dir, bname := fs.SplitX(name) 57 58 var fis []os.FileInfo 59 60 dirs, err := fs.SubtreeByPath(dir+bname, true) 61 for _, v := range dirs { 62 // log.Printf("%15v => %-24v", "", v.Dir+v.BName) 63 fi := os.FileInfo(v) 64 fis = append(fis, fi) 65 } 66 67 fs.dirsorter(fis) 68 69 return fis, err 70 71 } 72 73 func (fs *dsFileSys) saveDirByPath(name string) (DsDir, error) { 74 dir := DsDir{} 75 return fs.saveDirByPathExt(dir, name) 76 } 77 78 func (fs *dsFileSys) saveDirByPathExt(dirObj DsDir, name string) (DsDir, error) { 79 80 fo := DsDir{} 81 fo.isDir = true 82 fo.MModTime = dirObj.MModTime 83 84 if dirObj.MMode == 0 { 85 fo.MMode = 0755 86 } else { 87 fo.MMode = dirObj.MMode 88 } 89 90 if dirObj.MModTime.IsZero() { 91 fo.MModTime = time.Now() 92 } else { 93 fo.MModTime = dirObj.MModTime 94 } 95 96 fo.fSys = fs 97 98 dir, bname := fs.SplitX(name) 99 fo.Dir = dir 100 fo.BName = common.Filify(bname) 101 102 preciseK := ds.NewKey(fs.c, tdir, dir+common.Filify(bname), 0, nil) 103 fo.Key = preciseK 104 105 // fs.Ctx().Infof("Saving dir %-14q %q %v ", fo.Dir, fo.BName, fo.Key) 106 107 effKey, err := ds.Put(fs.c, preciseK, &fo) 108 if err != nil { 109 aelog.Errorf(fs.Ctx(), "Error saving dir %v => %v", dir+bname, err) 110 return fo, err 111 } 112 113 if !preciseK.Equal(effKey) { 114 aelog.Errorf(fs.Ctx(), "dir keys unequal %v - %v", preciseK, effKey) 115 } 116 117 fo.MemCacheSet() 118 119 // recurse upwards 120 _, err = fs.dirByPath(fo.Dir) 121 if err == ds.ErrNoSuchEntity { 122 _, err = fs.saveDirByPath(fo.Dir) 123 if err != nil { 124 return fo, err 125 } 126 } 127 128 return fo, nil 129 }