package db import ( "database/sql" "fmt" _ "modernc.org/sqlite" ) // DB wraps the SQLite database connection type DB struct { conn *sql.DB } // Open opens a connection to the SQLite database and initializes schema func Open(dbPath string) (*DB, error) { conn, err := sql.Open("sqlite", dbPath) if err != nil { return nil, fmt.Errorf("failed to open database: %w", err) } // Enable WAL mode for better concurrency if _, err := conn.Exec("PRAGMA journal_mode=WAL"); err != nil { conn.Close() return nil, fmt.Errorf("failed to enable WAL mode: %w", err) } // Enable foreign keys if _, err := conn.Exec("PRAGMA foreign_keys=ON"); err != nil { conn.Close() return nil, fmt.Errorf("failed to enable foreign keys: %w", err) } // Initialize schema if _, err := conn.Exec(schema); err != nil { conn.Close() return nil, fmt.Errorf("failed to initialize schema: %w", err) } db := &DB{conn: conn} // Seed tag categories and common tags if err := db.seedDatabase(); err != nil { conn.Close() return nil, fmt.Errorf("failed to seed database: %w", err) } return db, nil } // seedDatabase populates tag categories and common tags func (db *DB) seedDatabase() error { // Seed tag categories if _, err := db.conn.Exec(SeedTagCategories); err != nil { return fmt.Errorf("failed to seed tag categories: %w", err) } // Seed common tags if _, err := db.conn.Exec(SeedCommonTags); err != nil { return fmt.Errorf("failed to seed common tags: %w", err) } return nil } // Close closes the database connection func (db *DB) Close() error { if db.conn != nil { return db.conn.Close() } return nil } // Conn returns the underlying *sql.DB connection func (db *DB) Conn() *sql.DB { return db.conn }