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  }