diff --git a/.gitignore b/.gitignore index fd8974cf..2fa10b34 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ yarn.lock npm-debug.log* yarn-debug.log* yarn-error.log* + +# vscode +__debug_bin diff --git a/api/database/migrations/0001_user.up.sql b/api/database/migrations/0001_user.up.sql index 93ef1b50..ccb1d127 100644 --- a/api/database/migrations/0001_user.up.sql +++ b/api/database/migrations/0001_user.up.sql @@ -15,5 +15,5 @@ CREATE TABLE IF NOT EXISTS access_token ( expire timestamp NOT NULL, PRIMARY KEY (token_id), - FOREIGN KEY (user_id) REFERENCES user(user_id) + FOREIGN KEY (user_id) REFERENCES user(user_id) ON DELETE CASCADE ); diff --git a/api/database/migrations/0002_photo.up.sql b/api/database/migrations/0002_photo.up.sql index f3893298..15c8dcb5 100644 --- a/api/database/migrations/0002_photo.up.sql +++ b/api/database/migrations/0002_photo.up.sql @@ -22,8 +22,8 @@ CREATE TABLE IF NOT EXISTS album ( path varchar(512) NOT NULL UNIQUE, PRIMARY KEY (album_id), - FOREIGN KEY (parent_album) REFERENCES album(album_id), - FOREIGN KEY (owner_id) REFERENCES user(user_id) + FOREIGN KEY (parent_album) REFERENCES album(album_id) ON DELETE CASCADE, + FOREIGN KEY (owner_id) REFERENCES user(user_id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS photo ( @@ -34,8 +34,8 @@ CREATE TABLE IF NOT EXISTS photo ( exif_id int, PRIMARY KEY (photo_id), - FOREIGN KEY (album_id) REFERENCES album(album_id), - FOREIGN KEY (exif_id) REFERENCES photo_exif(exif_id) + FOREIGN KEY (album_id) REFERENCES album(album_id) ON DELETE CASCADE, + FOREIGN KEY (exif_id) REFERENCES photo_exif(exif_id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS photo_url ( @@ -48,5 +48,5 @@ CREATE TABLE IF NOT EXISTS photo_url ( content_type varchar(64) NOT NULL, PRIMARY KEY (url_id), - FOREIGN KEY (photo_id) REFERENCES photo(photo_id) + FOREIGN KEY (photo_id) REFERENCES photo(photo_id) ON DELETE CASCADE ); \ No newline at end of file diff --git a/api/scanner/scanner.go b/api/scanner/scanner.go index 1020c0b9..79297cf9 100644 --- a/api/scanner/scanner.go +++ b/api/scanner/scanner.go @@ -8,6 +8,8 @@ import ( "log" "os" "path" + "strconv" + "strings" "github.com/h2non/filetype" "github.com/viktorstrate/photoview/api/graphql/models" @@ -45,7 +47,9 @@ func ScanUser(database *sql.DB, userId int) error { } func scan(database *sql.DB, user *models.User) { + // Start scanning scanner_cache := make(scanner_cache) + album_paths_scanned := make([]interface{}, 0) type scanInfo struct { path string @@ -65,6 +69,8 @@ func scan(database *sql.DB, user *models.User) { albumPath := albumInfo.path albumParentId := albumInfo.parentId + album_paths_scanned = append(album_paths_scanned, albumPath) + // Read path dirContent, err := ioutil.ReadDir(albumPath) if err != nil { @@ -143,6 +149,8 @@ func scan(database *sql.DB, user *models.User) { } } + cleanupCache(database, album_paths_scanned) + log.Println("Done scanning") } @@ -226,3 +234,40 @@ func isPathImage(path string, cache *scanner_cache) bool { log.Printf("Unsupported image %s of type %s\n", path, imgType.MIME.Value) return false } + +func cleanupCache(database *sql.DB, scanned_albums []interface{}) { + if len(scanned_albums) == 0 { + return + } + + albums_questions := strings.Repeat("?,", len(scanned_albums))[:len(scanned_albums)*2-1] + rows, err := database.Query("SELECT album_id FROM album WHERE path NOT IN ("+albums_questions+")", scanned_albums...) + if err != nil { + log.Printf("ERROR: Could not get albums from database: %s\n", err) + return + } + + deleted_albums := 0 + deleted_ids := make([]interface{}, 0) + for rows.Next() { + var album_id int + rows.Scan(&album_id) + deleted_ids = append(deleted_ids, album_id) + cache_path := path.Join("./image-cache", strconv.Itoa(album_id)) + err := os.RemoveAll(cache_path) + if err != nil { + log.Printf("ERROR: Could not delete unused cache folder: %s\n%s\n", cache_path, err) + } else { + deleted_albums++ + } + } + + if len(deleted_ids) > 0 { + albums_questions = strings.Repeat("?,", len(deleted_ids))[:len(deleted_ids)*2-1] + if _, err := database.Exec("DELETE FROM album WHERE album_id IN ("+albums_questions+")", deleted_ids...); err != nil { + log.Printf("ERROR: Could not delete old albums from database:\n%s\n", err) + } + } + + log.Printf("Deleted %d unused albums from cache", deleted_albums) +}