aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2023-12-09 07:57:51 +0100
committerPřemysl Eric Janouch <p@janouch.name>2023-12-09 07:57:51 +0100
commitac2f065f9bbd12e9ffd9b60bf91a436129038263 (patch)
tree2fb37ace233561d5c5ab88e46486e4dcaba429d7 /main.go
parenta9ceed1d37c5a33b5479752a866c3289838f7fc4 (diff)
downloadgallery-ac2f065f9bbd12e9ffd9b60bf91a436129038263.tar.gz
gallery-ac2f065f9bbd12e9ffd9b60bf91a436129038263.tar.xz
gallery-ac2f065f9bbd12e9ffd9b60bf91a436129038263.zip
Maintain directories in a hierarchy
Diffstat (limited to 'main.go')
-rw-r--r--main.go57
1 files changed, 52 insertions, 5 deletions
diff --git a/main.go b/main.go
index 3324ae5..b6ef3e0 100644
--- a/main.go
+++ b/main.go
@@ -17,6 +17,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
+ "strings"
"time"
_ "github.com/mattn/go-sqlite3"
@@ -43,7 +44,7 @@ func thumbPath(sha1 string) string {
return filepath.Join(gd, "thumbs", sha1[:2], sha1+".webp")
}
-func dbCollect(query string) ([]string, error) {
+func dbCollectStrings(query string) ([]string, error) {
rows, err := db.Query(query)
if err != nil {
return nil, err
@@ -64,6 +65,44 @@ func dbCollect(query string) ([]string, error) {
return result, nil
}
+type directoryManager struct {
+ cache map[string]int64 // Unix-style paths to directory.id
+}
+
+func (dm *directoryManager) IDForDirectoryPath(path string) (int64, error) {
+ // Relative paths could be handled differently,
+ // but right now, they're assumed to start at the root.
+ list := strings.Split(filepath.ToSlash(filepath.Clean(path)), "/")
+ if len(list) > 1 && list[0] == "" {
+ list = list[1:]
+ }
+ if len(list) == 0 {
+ return 0, nil
+ }
+
+ var parent sql.NullInt64
+ for _, name := range list {
+ if err := db.QueryRow(
+ `SELECT id FROM directory WHERE name = ? AND parent IS ?`,
+ name, parent).Scan(&parent); err == nil {
+ continue
+ } else if !errors.Is(err, sql.ErrNoRows) {
+ return 0, err
+ }
+
+ if result, err := db.Exec(
+ `INSERT INTO directory(name, parent) VALUES (?, ?)`,
+ name, parent); err != nil {
+ return 0, err
+ } else if id, err := result.LastInsertId(); err != nil {
+ return 0, err
+ } else {
+ parent = sql.NullInt64{Int64: id, Valid: true}
+ }
+ }
+ return parent.Int64, nil
+}
+
// cmdInit initializes a "gallery directory" that contains gallery.sqlite,
// images, thumbs.
func cmdInit(args []string) error {
@@ -244,10 +283,17 @@ func importFunc(path string, d fs.DirEntry, err error) error {
return err
}
+ // TODO: Maintain the cache across calls.
+ dm := directoryManager{}
dbDirname, dbBasename := filepath.Split(path)
+ dbParent, err := dm.IDForDirectoryPath(dbDirname)
+ if err != nil {
+ return err
+ }
+
_, err = db.Exec(`INSERT INTO entry(
- path, basename, mtime, sha1
- ) VALUES (?, ?, ?, ?)`, dbDirname, dbBasename, s.ModTime().Unix(), hexSHA1)
+ parent, name, mtime, sha1
+ ) VALUES (?, ?, ?, ?)`, dbParent, dbBasename, s.ModTime().Unix(), hexSHA1)
return err
}
@@ -350,7 +396,7 @@ func cmdThumbnail(args []string) error {
if len(hexSHA1) == 0 {
// Get all unique images in the database with no thumbnail.
var err error
- hexSHA1, err = dbCollect(`SELECT sha1 FROM image
+ hexSHA1, err = dbCollectStrings(`SELECT sha1 FROM image
WHERE thumbw IS NULL OR thumbh IS NULL`)
if err != nil {
return err
@@ -411,7 +457,8 @@ func cmdDhash(args []string) error {
hasher, hexSHA1 := args[1], args[2:]
if len(hexSHA1) == 0 {
var err error
- hexSHA1, err = dbCollect(`SELECT sha1 FROM image WHERE dhash IS NULL`)
+ hexSHA1, err = dbCollectStrings(`SELECT sha1 FROM image
+ WHERE dhash IS NULL`)
if err != nil {
return err
}