aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go40
1 files changed, 33 insertions, 7 deletions
diff --git a/main.go b/main.go
index 8b70dec..64cf26c 100644
--- a/main.go
+++ b/main.go
@@ -1166,6 +1166,8 @@ func syncDirectory(c *syncContext, dbParent int64, fsPath string) error {
for iDB < len(db) && iFS < len(fs) {
if db[iDB].dbName == fs[iFS].fsName {
pairs = append(pairs, syncPair{&db[iDB], &fs[iFS]})
+ iDB++
+ iFS++
} else if db[iDB].dbName < fs[iFS].fsName {
pairs = append(pairs, syncPair{&db[iDB], nil})
iDB++
@@ -1220,7 +1222,37 @@ func syncRoot(c *syncContext, fsPath string) error {
for i := 0; i < cap(taskSemaphore); i++ {
taskSemaphore.release()
}
- return nil
+
+ // Delete empty directories, from the bottom of the tree up to,
+ // but not including, the inserted root.
+ //
+ // We need to do this at the end due to our recursive handling,
+ // as well as because of asynchronous file filtering.
+ stmt, err := c.tx.Prepare(`
+ WITH RECURSIVE subtree(id, parent, sha1, level) AS (
+ SELECT id, parent, sha1, 1 FROM node WHERE id = ?
+ UNION ALL
+ SELECT n.id, n.parent, n.sha1, s.level + 1
+ FROM node AS n JOIN subtree AS s ON n.parent = s.id
+ ) DELETE FROM node WHERE id IN (
+ SELECT id FROM subtree WHERE level <> 1 AND sha1 IS NULL
+ -- No idea why one can't put the "node" table in the subselect.
+ -- The whole query then matches nothing.
+ AND id NOT IN (SELECT parent FROM subtree)
+ )`)
+ if err != nil {
+ return err
+ }
+
+ for {
+ if result, err := stmt.Exec(dbParent); err != nil {
+ return err
+ } else if n, err := result.RowsAffected(); err != nil {
+ return err
+ } else if n == 0 {
+ return nil
+ }
+ }
}
const disposeCTE = `WITH RECURSIVE
@@ -1296,12 +1328,6 @@ func syncRun(ctx context.Context, tx *sql.Tx, roots []string) error {
return err
}
}
-
- // TODO: Garbage collect empty directories, recursively.
- // Ideally, stop at the affected DB roots (assuming we go bottom-up).
- //
- // We need to do this at the end, due to our recursive handling,
- // as well as because of asynchronous file filtering.
return nil
}