92 lines
2.0 KiB
Go
92 lines
2.0 KiB
Go
package lib
|
|
|
|
// ============================================================================
|
|
// Database Connection Management
|
|
// ============================================================================
|
|
// Connection lifecycle only. Schema is documented in docs/schema.sql.
|
|
// All operations go through db_queries.go.
|
|
// ============================================================================
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
var db *sql.DB
|
|
var refDB *sql.DB
|
|
|
|
// Slow query thresholds
|
|
var (
|
|
SlowQueryThreshold = 100 * time.Millisecond // Log at info level
|
|
WarnQueryThreshold = 500 * time.Millisecond // Log at warn level
|
|
SlowQueryEnabled = true
|
|
)
|
|
|
|
// logSlowQuery logs queries that exceed the threshold
|
|
func logSlowQuery(query string, duration time.Duration, args ...any) {
|
|
if !SlowQueryEnabled {
|
|
return
|
|
}
|
|
if duration < SlowQueryThreshold {
|
|
return
|
|
}
|
|
|
|
// Truncate query for logging
|
|
q := strings.TrimSpace(query)
|
|
if len(q) > 200 {
|
|
q = q[:200] + "..."
|
|
}
|
|
// Replace newlines/tabs with spaces
|
|
q = strings.Join(strings.Fields(q), " ")
|
|
|
|
if duration >= WarnQueryThreshold {
|
|
log.Printf("[SLOW QUERY WARN] %v | %s | args=%d", duration, q, len(args))
|
|
} else {
|
|
log.Printf("[SLOW QUERY] %v | %s | args=%d", duration, q, len(args))
|
|
}
|
|
}
|
|
|
|
// DBInit opens database connection
|
|
func DBInit(dbPath string) error {
|
|
var err error
|
|
db, err = sql.Open("sqlite3", dbPath)
|
|
return err
|
|
}
|
|
|
|
// DBClose closes database connection
|
|
func DBClose() {
|
|
if db != nil {
|
|
db.Close()
|
|
}
|
|
}
|
|
|
|
// DBPing checks if database is reachable
|
|
func DBPing() error {
|
|
if db == nil {
|
|
return fmt.Errorf("database not initialized")
|
|
}
|
|
return db.Ping()
|
|
}
|
|
|
|
// RefDBInit opens reference database connection
|
|
func RefDBInit(dbPath string) error {
|
|
var err error
|
|
refDB, err = sql.Open("sqlite3", dbPath)
|
|
return err
|
|
}
|
|
|
|
// RefDB returns the reference database connection
|
|
func RefDB() *sql.DB { return refDB }
|
|
|
|
// RefDBClose closes reference database connection
|
|
func RefDBClose() {
|
|
if refDB != nil {
|
|
refDB.Close()
|
|
}
|
|
}
|