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:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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, ",")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user