Files
holos/internal/server/db/sqlite.go
Jeff McCune 4184619afc (#126) Refactor pkg to internal
pkg folder is not needed.  Move everything internal for now.
2024-04-12 13:56:16 -07:00

66 lines
1.9 KiB
Go

package db
import (
"database/sql"
"database/sql/driver"
"fmt"
"log/slog"
esql "entgo.io/ent/dialect/sql"
"github.com/holos-run/holos/internal/ent"
"github.com/holos-run/holos/internal/errors"
"github.com/holos-run/holos/internal/holos"
"modernc.org/sqlite"
)
// NewMemoryClientFactory returns a MemoryClientFactory implementation of ClientFactory
func NewMemoryClientFactory(cfg *holos.Config) *MemoryClientFactory {
return &MemoryClientFactory{cfg: cfg}
}
// MemoryClientFactory produces simple in-memory sqlite database clients for development and testing.
type MemoryClientFactory struct {
cfg *holos.Config
}
func (mc *MemoryClientFactory) New() (Conn, error) {
log := mc.cfg.Logger()
db, err := sql.Open("sqlite3", "file:db.sqlite3?mode=memory&cache=shared")
if err != nil {
log.Debug("could not open sql connection", "err", err)
return Conn{}, errors.Wrap(err)
}
// Fix database is locked errors when testing with sqlite3 in-memory and parallel test cases.
db.SetMaxOpenConns(1)
drv := esql.OpenDB("sqlite3", db)
client := withHooks(ent.NewClient(ent.Driver(drv)))
return Conn{client, db, drv}, nil
}
// sqliteDriver sets PRAGMA foreign_keys = on for each new connection with modernc.org/sqlite
// See: https://github.com/ent/ent/discussions/1667#discussioncomment-1132296
type sqliteDriver struct {
*sqlite.Driver
}
func (d sqliteDriver) Open(name string) (driver.Conn, error) {
conn, err := d.Driver.Open(name)
if err != nil {
return conn, err
}
c := conn.(interface {
Exec(stmt string, args []driver.Value) (driver.Result, error)
})
if _, err := c.Exec("PRAGMA foreign_keys = on;", nil); err != nil {
if errClose := conn.Close(); errClose != nil {
slog.Error("could not close", "err", errClose)
}
return nil, fmt.Errorf("could not enable foreign keys: %w", err)
}
return conn, nil
}
func init() {
sql.Register("sqlite3", sqliteDriver{Driver: &sqlite.Driver{}})
}