diff options
-rw-r--r-- | main.go | 40 | ||||
-rwxr-xr-x | test.sh | 3 |
2 files changed, 35 insertions, 8 deletions
@@ -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 } @@ -7,7 +7,8 @@ mkdir -p $target cp -ra $HOME/Pictures/Anime $input ./gallery init $target -./gallery import $target $input +#./gallery import $target $input +./gallery sync $target $input ./gallery thumbnail $target ./gallery dhash $target $HOME/Projects/fiv/build/hash ./gallery tag $target autotagger "DanBooru autotagger" \ |