Squash merge audio-player-component into main
This commit is contained in:
@@ -1,25 +1,94 @@
|
||||
// Package database provides SQLite database access.
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
_ "modernc.org/sqlite" // Register sqlite driver.
|
||||
"yellowjacket/backend/database/sql/sqlcgen"
|
||||
"yellowjacket/backend/system"
|
||||
)
|
||||
|
||||
//go:generate sqlc vet
|
||||
//go:generate sqlc generate
|
||||
//go:generate go tool sqlc generate
|
||||
|
||||
type DB struct{
|
||||
db *sql.DB
|
||||
//go:embed sql/schemas/*.sql
|
||||
var schemas embed.FS
|
||||
|
||||
// DB wraps the SQLite database connection and queries.
|
||||
type DB struct {
|
||||
db *sql.DB
|
||||
Ctx context.Context
|
||||
Queries *sqlcgen.Queries
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewDB(sqliteDBFilePath string) (*DB, error) {
|
||||
db, err := sql.Open("sqlite", ":memory:")
|
||||
// NewDB opens the database and applies schema migrations.
|
||||
func NewDB(logger *slog.Logger) (*DB, error) {
|
||||
dbCtx := context.Background()
|
||||
|
||||
userDataDir, err := system.GetUserDataDirPath()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get user data directory: %w", err)
|
||||
}
|
||||
|
||||
sqliteDBFilePath := path.Join(userDataDir, "yj.db")
|
||||
|
||||
logger.Debug("opening sqlite database", "filepath", sqliteDBFilePath)
|
||||
|
||||
db, err := sql.Open("sqlite", sqliteDBFilePath+"?_busy_timeout=5000&_journal_mode=WAL")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not connect to sqlite database: %w", err)
|
||||
}
|
||||
|
||||
db.SetMaxOpenConns(1) // SQLite only supports one writer at a time
|
||||
|
||||
// Execute SQL files from the embedded schemas directory
|
||||
logger.Debug("reading sql schema files from embedded directory")
|
||||
|
||||
dirEntries, err := schemas.ReadDir("sql/schemas")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read schemas directory: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("executing all sql schema files")
|
||||
|
||||
for _, dirEntry := range dirEntries {
|
||||
if !dirEntry.IsDir() {
|
||||
filePath := filepath.Join("sql/schemas", dirEntry.Name())
|
||||
sqlContent, err := fs.ReadFile(schemas, filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read file %s: %w", filePath, err)
|
||||
}
|
||||
|
||||
logger.Debug(
|
||||
"executing sql schema file",
|
||||
"filepath",
|
||||
filePath,
|
||||
"sql",
|
||||
string(sqlContent),
|
||||
)
|
||||
|
||||
_, err = db.ExecContext(dbCtx, string(sqlContent)) // Execute the SQL
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error executing sql from file %s: %w", filePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get generated queries
|
||||
queries := sqlcgen.New(db)
|
||||
|
||||
return &DB{
|
||||
db: db,
|
||||
}, nil
|
||||
db: db,
|
||||
Ctx: dbCtx,
|
||||
Queries: queries,
|
||||
logger: logger,
|
||||
}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user