-
-
Notifications
You must be signed in to change notification settings - Fork 24
feat(): adds Media field IsMissing for persistent media #551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
6b16f58
18fa55c
fb7c9a7
17281cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| -- +goose Up | ||
|
|
||
| -- Add New IsMissing Field for rescan matching | ||
| ALTER TABLE Media | ||
| ADD IsMissing integer NOT NULL DEFAULT 0; | ||
|
|
||
| -- +goose Down | ||
|
|
||
| -- Remove New IsMissing Field for rescan matching | ||
wizzomafizzo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ALTER TABLE Media | ||
| DROP COLUMN IsMissing; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,7 +30,15 @@ import ( | |
| "github.com/rs/zerolog/log" | ||
| ) | ||
|
|
||
| const insertMediaSQL = `INSERT INTO Media (DBID, MediaTitleDBID, SystemDBID, Path) VALUES (?, ?, ?, ?)` | ||
| const insertMediaSQL = `INSERT INTO Media | ||
| (DBID, MediaTitleDBID, SystemDBID, Path, IsMissing) | ||
| VALUES (?, ?, ?, ?, ?) | ||
| ON CONFLICT (SystemDBID, Path) | ||
| DO UPDATE SET | ||
| IsMissing = 0 | ||
| ON CONFLICT (DBID) | ||
| DO UPDATE SET | ||
wizzomafizzo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| IsMissing = 0;` | ||
|
Comment on lines
+33
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: During a selective rescan, the Suggested FixModify the Prompt for AI Agent |
||
|
|
||
| func sqlFindMedia(ctx context.Context, db sqlQueryable, media database.Media) (database.Media, error) { | ||
| var row database.Media | ||
|
|
@@ -83,7 +91,7 @@ func sqlInsertMediaWithPreparedStmt(ctx context.Context, stmt *sql.Stmt, row dat | |
| dbID = row.DBID | ||
| } | ||
|
|
||
| res, err := stmt.ExecContext(ctx, dbID, row.MediaTitleDBID, row.SystemDBID, row.Path) | ||
| res, err := stmt.ExecContext(ctx, dbID, row.MediaTitleDBID, row.SystemDBID, row.Path, row.IsMissing) | ||
| if err != nil { | ||
| return row, fmt.Errorf("failed to execute prepared insert media statement: %w", err) | ||
| } | ||
|
|
@@ -113,7 +121,7 @@ func sqlInsertMedia(ctx context.Context, db *sql.DB, row database.Media) (databa | |
| } | ||
| }() | ||
|
|
||
| res, err := stmt.ExecContext(ctx, dbID, row.MediaTitleDBID, row.SystemDBID, row.Path) | ||
| res, err := stmt.ExecContext(ctx, dbID, row.MediaTitleDBID, row.SystemDBID, row.Path, row.IsMissing) | ||
| if err != nil { | ||
| return row, fmt.Errorf("failed to execute insert media statement: %w", err) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -161,6 +161,7 @@ | |
| Path: pf.Path, | ||
| MediaTitleDBID: int64(titleIndex), | ||
| SystemDBID: int64(systemIndex), | ||
| IsMissing: 0, | ||
| }) | ||
| if err != nil { | ||
| ss.MediaIndex-- // Rollback index increment on failure | ||
|
|
@@ -169,6 +170,16 @@ | |
| ss.MediaIDs[mediaKey] = mediaIndex | ||
wizzomafizzo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } else { | ||
| mediaIndex = foundMediaIndex | ||
| // Update anyway to mark found | ||
| db.InsertMedia(database.Media{ | ||
|
Check failure on line 174 in pkg/database/mediascanner/indexing_pipeline.go
|
||
| DBID: 0, // Use 0 for NULL binding to force CONFLICT constraint update | ||
| Path: pf.Path, | ||
| MediaTitleDBID: int64(titleIndex), | ||
| SystemDBID: int64(systemIndex), | ||
| IsMissing: 0, | ||
| }) | ||
wizzomafizzo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Don't process tags if found | ||
| return titleIndex, mediaIndex, nil | ||
wizzomafizzo marked this conversation as resolved.
Show resolved
Hide resolved
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Related to the above — since MediaIDs is empty, this else branch never actually runs right now. Every path takes the |
||
| } | ||
|
|
||
| // Extract extension tag only if filename tags are enabled | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -661,45 +661,58 @@ | |
| } | ||
| } | ||
|
|
||
| // Full truncate - foreign keys not needed since we're deleting everything | ||
| log.Info().Msgf("performing full database truncation (indexing %d systems)", len(currentSystemIDs)) | ||
| err = db.Truncate() | ||
| /* | ||
|
Check failure on line 664 in pkg/database/mediascanner/mediascanner.go
|
||
| // Full truncate - foreign keys not needed since we're deleting everything | ||
| log.Info().Msgf("performing full database truncation (indexing %d systems)", len(currentSystemIDs)) | ||
| err = db.Truncate() | ||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to truncate database: %w", err) | ||
| } | ||
| log.Info().Msg("database truncation completed")*/ | ||
| err := db.MarkAllMediaMissing() | ||
|
||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to truncate database: %w", err) | ||
| return 0, fmt.Errorf("failed to mark all media is missing %v: %w", currentSystemIDs, err) | ||
| } | ||
| log.Info().Msg("database truncation completed") | ||
| log.Info().Msg("all media marked missing for rescan") | ||
| } else { | ||
| // Selective indexing | ||
| // DELETE mode disables FKs for performance, but TruncateSystems() relies on CASCADE | ||
| // to properly delete Media/MediaTitles/MediaTags when a System is deleted | ||
| log.Info().Msgf( | ||
| /*log.Info().Msgf( | ||
| "performing selective truncation for systems: %v", | ||
| currentSystemIDs, | ||
| ) | ||
| err = db.TruncateSystems(currentSystemIDs) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to truncate systems %v: %w", currentSystemIDs, err) | ||
| } | ||
| log.Info().Msg("selective truncation completed") | ||
| log.Info().Msg("selective truncation completed")*/ | ||
|
|
||
wizzomafizzo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // For selective indexing, populate scan state with max IDs, global data, and | ||
| // maps for systems NOT being reindexed to avoid conflicts with existing data | ||
| log.Info().Msgf( | ||
| "Populating scan state for selective indexing (excluding systems: %v)", currentSystemIDs, | ||
| ) | ||
| if err = PopulateScanStateForSelectiveIndexing(ctx, db, &scanState, currentSystemIDs); err != nil { | ||
| // Check if this is a cancellation error | ||
| if errors.Is(err, context.Canceled) { | ||
| return handleCancellation( | ||
| ctx, db, "Media indexing cancelled during selective scan state population", | ||
| ) | ||
| } | ||
| log.Error().Err(err).Msg("failed to populate scan state for selective indexing") | ||
| return 0, fmt.Errorf("failed to populate scan state for selective indexing: %w", err) | ||
| err := db.MarkSystemsMediaMissing(currentSystemIDs) | ||
| if err != nil { | ||
| return 0, fmt.Errorf("failed to mark systems media is missing %v: %w", currentSystemIDs, err) | ||
| } | ||
| log.Info().Msg("successfully populated scan state for selective indexing") | ||
| log.Info().Msg("systems media marked missing for rescan") | ||
|
|
||
| } | ||
|
|
||
| // For rescan indexing, populate scan state with max IDs, global data, and | ||
| // maps for systems NOT being reindexed to avoid conflicts with existing data | ||
| log.Info().Msgf( | ||
| "Populating scan state for selective indexing (excluding systems: %v)", currentSystemIDs, | ||
| ) | ||
| if err = PopulateScanStateForSelectiveIndexing(ctx, db, &scanState, currentSystemIDs); err != nil { | ||
| // Check if this is a cancellation error | ||
| if errors.Is(err, context.Canceled) { | ||
| return handleCancellation( | ||
| ctx, db, "Media indexing cancelled during selective scan state population", | ||
| ) | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since data isn't truncated anymore, |
||
| log.Error().Err(err).Msg("failed to populate scan state for selective indexing") | ||
| return 0, fmt.Errorf("failed to populate scan state for selective indexing: %w", err) | ||
| } | ||
| log.Info().Msg("successfully populated scan state for selective indexing") | ||
wizzomafizzo marked this conversation as resolved.
Show resolved
Hide resolved
wizzomafizzo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if setErr := db.SetIndexingStatus(mediadb.IndexingStatusRunning); setErr != nil { | ||
| log.Error().Err(setErr).Msg("failed to set indexing status to running on fresh start") | ||
| } | ||
|
|
@@ -709,6 +722,7 @@ | |
|
|
||
| // Selective indexing already seeds tags via PopulateScanStateForSelectiveIndexing; | ||
| // only seed here for full truncate where TagTypesIndex is still 0. | ||
|
|
||
| if scanState.TagTypesIndex == 0 { | ||
| log.Info().Msg("seeding known tags for fresh indexing") | ||
| // SeedCanonicalTags runs in its own non-batch transaction for safety. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.