github.com/pbberlin/tools@v0.0.0-20160910141205-7aa5421c2169/os/fsi/dsfs/low_level_dirs_query.go (about) 1 package dsfs 2 3 import ( 4 "strings" 5 6 "github.com/pbberlin/tools/os/fsi" 7 "github.com/pbberlin/tools/os/fsi/common" 8 9 "google.golang.org/appengine/datastore" 10 aelog "google.golang.org/appengine/log" 11 ) 12 13 // subtreeByPath retrieves a subdirectories of a given directory. 14 // It is relying on an indexed string property "Dir" 15 // containing a string representation of the full path. 16 // 17 // It might be fast for deep, uncached directory subtree, 18 // that have been saved in nested manner. 19 // 20 // However, it might not find recently added directories. 21 // Upon finding nothing, it therefore returns the 22 // "warning" fsi.EmptyQueryResult 23 // 24 // The func could easily be enhanced chunked scanning. 25 // 26 // It is currently used by ReadDir and by the test package. 27 // It is public for the test package. 28 func (fs *dsFileSys) SubtreeByPath(name string, onlyDirectChildren bool) ([]DsDir, error) { 29 30 dir, bname := fs.SplitX(name) 31 name = dir + common.Filify(bname) 32 if !strings.HasSuffix(name, sep) { 33 name += sep 34 } 35 36 var q *datastore.Query 37 38 if onlyDirectChildren { 39 q = datastore.NewQuery(tdir). 40 Filter("Dir=", name). 41 Order("Dir") 42 // Limit(4) 43 } else { 44 pathInc := IncrementString(name) 45 q = datastore.NewQuery(tdir). 46 Filter("Dir>=", name). 47 Filter("Dir<", pathInc). 48 Order("Dir") 49 } 50 51 // log.Printf("%v", q) 52 53 var children []DsDir 54 keys, err := q.GetAll(fs.Ctx(), &children) 55 if err != nil { 56 aelog.Errorf(fs.Ctx(), "Error getting all children of %v => %v", dir+bname, err) 57 return children, err 58 } 59 60 if len(children) < 1 { 61 return children, fsi.EmptyQueryResult 62 } 63 64 // Very evil: We filter out root node, since it's 65 // has the same dir as the level-1 directories. 66 keyRoot := datastore.NewKey(fs.Ctx(), tdir, fs.RootDir(), 0, nil) 67 idxRoot := -1 68 69 for i := 0; i < len(children); i++ { 70 children[i].fSys = fs 71 children[i].Key = keys[i] 72 if keys[i].Equal(keyRoot) { 73 // log.Printf("root idx %v", i) 74 idxRoot = i 75 } 76 } 77 78 if idxRoot > -1 { 79 children = append(children[:idxRoot], children[idxRoot+1:]...) 80 } 81 82 return children, nil 83 84 }