docs(06-03): add SAFETY comments to all 12 hand-crafted SQL statements

- 7 SAFETY comments in search.go (FTS5 MATCH/INSERT/DELETE operations)
- 3 SAFETY comments in library.go (FTS5 INSERT/DELETE in commitNewAudioFile, updateAudioFileMetadata)
- 1 SAFETY comment in rescan.go (FTS5 DELETE in clearAllLibraryData)
- 1 SAFETY comment in persistence.go (variable-count multi-row INSERT)
- Cross-references link library.go/rescan.go back to search.go
- Two-part format: why sqlc can't handle it + what makes it safe
This commit is contained in:
2026-03-04 19:33:55 -05:00
parent 2221a68459
commit 7dfe003e63
4 changed files with 12 additions and 0 deletions
+7
View File
@@ -31,6 +31,7 @@ func (d *DB) SearchFTS(
// special characters are treated as literals.
ftsQuery := buildFTSQuery(query)
// SAFETY: FTS5 MATCH syntax unsupported by sqlc. Query is parameterized; no string interpolation.
rows, err := d.db.QueryContext(d.Ctx, `
SELECT
tm.file_path,
@@ -77,6 +78,7 @@ func (d *DB) SearchFTSByFilename(
ftsQuery := "file_path : " +
strings.Join(tokens, " ")
// SAFETY: FTS5 MATCH syntax unsupported by sqlc. Query is parameterized; no string interpolation.
rows, err := d.db.QueryContext(d.Ctx, `
SELECT
tm.file_path,
@@ -106,6 +108,7 @@ func (d *DB) InsertSearchIndex(
rowid int64,
filePath, title, artist, album string,
) error {
// SAFETY: FTS5 virtual table INSERT unsupported by sqlc. All values are parameterized.
_, err := d.db.ExecContext(d.Ctx, `
INSERT INTO search_index(rowid, file_path, title, artist, album)
VALUES (?, ?, ?, ?, ?)
@@ -116,6 +119,7 @@ func (d *DB) InsertSearchIndex(
// DeleteSearchIndex removes a row from the FTS5 search_index.
func (d *DB) DeleteSearchIndex(rowid int64) error {
// SAFETY: FTS5 virtual table DELETE unsupported by sqlc. Rowid is parameterized.
_, err := d.db.ExecContext(d.Ctx, `
DELETE FROM search_index WHERE rowid = ?
`, rowid)
@@ -125,6 +129,7 @@ func (d *DB) DeleteSearchIndex(rowid int64) error {
// ClearSearchIndex removes all rows from the FTS5 search_index.
func (d *DB) ClearSearchIndex() error {
// SAFETY: FTS5 virtual table DELETE unsupported by sqlc. No parameters; unconditional delete.
_, err := d.db.ExecContext(d.Ctx, `
DELETE FROM search_index
`)
@@ -141,6 +146,7 @@ func (d *DB) RebuildSearchIndex() error {
)
}
// SAFETY: FTS5 virtual table INSERT unsupported by sqlc. All values sourced from track_metadata VIEW; no user input.
_, err := d.db.ExecContext(d.Ctx, `
INSERT INTO search_index(rowid, file_path, title, artist, album)
SELECT id, file_path, title, artist_name, album
@@ -189,6 +195,7 @@ func (d *DB) SearchFTSTracks(
ftsQuery := buildFTSQuery(query)
// SAFETY: FTS5 MATCH syntax unsupported by sqlc. Query is parameterized; no string interpolation.
rows, err := d.db.QueryContext(d.Ctx, `
SELECT
tm.file_path,
+3
View File
@@ -793,6 +793,7 @@ func (l *Library) saveAudioFile(
album := tags.Album
// SAFETY: FTS5 virtual table, see search.go:InsertSearchIndex. All values parameterized.
if _, err := tx.ExecContext(
l.ctx,
`INSERT INTO search_index(rowid, file_path, title, artist, album)
@@ -874,6 +875,7 @@ func (l *Library) updateAudioFileMetadata(
album := tags.Album
// SAFETY: FTS5 virtual table, see search.go:DeleteSearchIndex. Rowid parameterized.
if _, err := tx.ExecContext(
l.ctx,
`DELETE FROM search_index WHERE rowid = ?`,
@@ -888,6 +890,7 @@ func (l *Library) updateAudioFileMetadata(
metrics.addWarning(result.absolutePath, "commit", err)
}
// SAFETY: FTS5 virtual table, see search.go:InsertSearchIndex. All values parameterized.
if _, err := tx.ExecContext(
l.ctx,
`INSERT INTO search_index(rowid, file_path, title, artist, album)
+1
View File
@@ -161,6 +161,7 @@ func (l *Library) clearLibraryTables() error {
}
// Clear FTS5 search index.
// SAFETY: FTS5 virtual table, see search.go:ClearSearchIndex. No parameters; unconditional delete.
if _, err := tx.ExecContext(
l.ctx, `DELETE FROM search_index`,
); err != nil {
+1
View File
@@ -151,6 +151,7 @@ func (q *Queue) insertTrackBatch(tx *sql.Tx, batch []Track) error {
args = append(args, track.AudioFileID, track.Position)
}
// SAFETY: Multi-row INSERT with variable row count unsupported by sqlc. Placeholder count matches args length; no string interpolation.
query := "INSERT INTO queue_tracks (audio_file_id, position) VALUES " +
strings.Join(valuePlaceholders, ",")