Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions internal/store/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ type dbExecer interface {

// DB wraps the SQLite database connection.
type DB struct {
conn *sql.DB
tx *sql.Tx // current active transaction (nil = no transaction)
path string
conn *sql.DB
tx *sql.Tx // current active transaction (nil = no transaction)
path string
readOnly bool
}

// IsReadOnly returns true if the database was opened in read-only mode.
func (db *DB) IsReadOnly() bool { return db.readOnly }

// execer returns the active transaction if set, otherwise the raw connection.
func (db *DB) execer() dbExecer {
if db.tx != nil {
Expand Down Expand Up @@ -186,7 +190,7 @@ func OpenReadOnly(dataDir string) (*DB, error) {
return nil, fmt.Errorf("open readonly database: %w", err)
}
conn.SetMaxOpenConns(1)
return &DB{conn: conn, path: dbPath}, nil
return &DB{conn: conn, path: dbPath, readOnly: true}, nil
}

// Open opens (or creates) the SQLite database at the given directory.
Expand Down
4 changes: 4 additions & 0 deletions internal/store/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ func (db *DB) UpdateEntities(id string, entities []string) error {
}

// IncrementAccessCount bumps the access count and refreshes last_accessed_at.
// No-op when the database is read-only.
func (db *DB) IncrementAccessCount(id string) error {
if db.readOnly {
return nil
}
_, err := db.execer().Exec(
`UPDATE insights SET access_count = access_count + 1, last_accessed_at = ? WHERE id = ?`,
time.Now().UTC().Format(time.RFC3339), id)
Expand Down
4 changes: 4 additions & 0 deletions internal/store/oplog.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ const MaxOplogEntries = 5000

// LogOp records an operation to the oplog and trims old entries beyond MaxOplogEntries.
// Best-effort: failures are logged to stderr but do not propagate.
// No-op when the database is read-only.
func (db *DB) LogOp(operation, insightID, detail string) {
if db.readOnly {
return
}
if _, err := db.execer().Exec(
`INSERT INTO oplog (operation, insight_id, detail, created_at) VALUES (?, ?, ?, ?)`,
operation, insightID, detail, time.Now().UTC().Format(time.RFC3339)); err != nil {
Expand Down
Loading