Add photo content-hash dedup and local↔S3 library sync.

Uploads skip per-gallery duplicates, checksums can be backfilled, and STORAGE_BACKEND plus sync tooling make switching storage backends safe.
This commit is contained in:
Michilis
2026-08-05 05:41:12 +00:00
parent dafa3711f8
commit 498d7d8a7d
31 changed files with 2216 additions and 64 deletions
+13
View File
@@ -54,6 +54,19 @@ func Open(cfg config.Config) (*DB, error) {
}
}
// IsUniqueViolation reports whether err is a duplicate-key error. The two
// drivers wrap it in unrelated types (pgconn.PgError vs sqlite.Error), and
// neither is worth importing here just for one check, so this matches on the
// message: pgx renders "(SQLSTATE 23505)", modernc/sqlite "UNIQUE constraint
// failed: ...".
func IsUniqueViolation(err error) bool {
if err == nil {
return false
}
msg := err.Error()
return strings.Contains(msg, "SQLSTATE 23505") || strings.Contains(msg, "UNIQUE constraint failed")
}
// Rebind converts ?-style placeholders to $n for Postgres. Queries in this
// package never contain literal question marks in strings.
func (db *DB) Rebind(query string) string {