diff --git a/fs.go b/fs.go index a1c75dcda..688b2f65e 100644 --- a/fs.go +++ b/fs.go @@ -31,10 +31,18 @@ type FsObject interface { Size() int64 Open() (io.ReadCloser, error) Storable() bool - // Exists() bool Remove() error } +// Optional interfaces +type Purger interface { + // Purge all files in the root and the root directory + // + // Implement this if you have a way of deleting all the files + // quicker than just running Remove() on the result of List() + Purge() error +} + type FsObjectsChan chan FsObject type FsObjects []FsObject diff --git a/fs_drive.go b/fs_drive.go index 835e6f125..8dc080f76 100644 --- a/fs_drive.go +++ b/fs_drive.go @@ -1,9 +1,6 @@ // Drive interface package main -// FIXME could make a purge which deleted everything in the container -// easily - rmdir without the checks! - // FIXME list containers equivalent should list directories? // FIXME drive times only accurate to 1 ms (3 decimal places) @@ -505,9 +502,6 @@ func (f *FsDrive) Mkdir() error { // // Returns an error if it isn't empty func (f *FsDrive) Rmdir() error { - if f.root == "" { - return fmt.Errorf("Can't delete root directory") - } err := f.findRoot(false) if err != nil { return err @@ -519,6 +513,27 @@ func (f *FsDrive) Rmdir() error { if len(children.Items) > 0 { return fmt.Errorf("Directory not empty: %#v", children.Items) } + // Delete the directory if it isn't the root + if f.root != "" { + err = f.svc.Files.Delete(f.rootId).Do() + if err != nil { + return err + } + } + return nil +} + +// Purge deletes all the files and the container +// +// Returns an error if it isn't empty +func (f *FsDrive) Purge() error { + if f.root == "" { + return fmt.Errorf("Can't purge root directory") + } + err := f.findRoot(false) + if err != nil { + return err + } err = f.svc.Files.Delete(f.rootId).Do() if err != nil { return err @@ -635,4 +650,5 @@ func (fs *FsObjectDrive) Remove() error { // Check the interfaces are satisfied var _ Fs = &FsDrive{} +var _ Purger = &FsDrive{} var _ FsObject = &FsObjectDrive{} diff --git a/notes.txt b/notes.txt index 64d2d7596..44eb1854e 100644 --- a/notes.txt +++ b/notes.txt @@ -1,4 +1,5 @@ Todo + * Make a test suite which can run on all the given types of fs * Copy should use the sync code as it is more efficient at directory listing * Drive needs a modify window of 1ms * Factor fses into own packages @@ -46,6 +47,7 @@ Ideas * Google drive: https://developers.google.com/drive/ * rsync over ssh * dropbox: https://github.com/nickoneill/go-dropbox (no MD5s) + * grive seems to have its secrets in the source code which would make things easier! @@ -58,3 +60,14 @@ s3 * https://forums.aws.amazon.com/message.jspa?messageID=214062 * Otherwise can set metadata * Returns etag and last modified in bucket list + + +Bugs + +local & drive need to delete directories + +2013/01/18 16:31:32 Waiting for deletions to finish +2013/01/18 16:31:32 z3: FIXME Skipping directory +2013/01/18 16:31:32 z3/x: Deleted +2013/01/18 16:31:32 Deleting path +2013/01/18 16:31:32 Rmdir failed: remove z3: directory not empty diff --git a/swiftsync.go b/swiftsync.go index 7190ebc30..31c3f439b 100644 --- a/swiftsync.go +++ b/swiftsync.go @@ -354,9 +354,17 @@ func rmdir(fdst, fsrc Fs) { // // FIXME doesn't delete local directories func purge(fdst, fsrc Fs) { - DeleteFiles(fdst.List()) - log.Printf("Deleting path") - rmdir(fdst, fsrc) + if f, ok := fdst.(Purger); ok { + err := f.Purge() + if err != nil { + stats.Error() + log.Fatalf("Purge failed: %s", err) + } + } else { + DeleteFiles(fdst.List()) + log.Printf("Deleting path") + rmdir(fdst, fsrc) + } } type Command struct {