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 // 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() }