Files
comicverse/database/database.go

116 lines
2.1 KiB
Go

package database
import (
"context"
"database/sql"
"errors"
"fmt"
"log/slog"
"forge.capytal.company/loreddev/x/tinyssert"
)
type Database struct {
sql *sql.DB
ctx context.Context
assert tinyssert.Assertions
log *slog.Logger
}
func New(cfg Config) (*Database, error) {
if cfg.SQL == nil {
return nil, errors.New("SQL database interface should not be nil")
}
if cfg.Context == nil {
return nil, errors.New("context interface should not be nil")
}
if cfg.Assertions == nil {
return nil, errors.New("assertions interface should not be nil")
}
if cfg.Logger == nil {
return nil, errors.New("logger should not be a nil pointer")
}
db := &Database{
sql: cfg.SQL,
ctx: cfg.Context,
assert: cfg.Assertions,
log: cfg.Logger,
}
if err := db.setup(); err != nil {
return nil, errors.New("error while setting up Database struct")
}
return db, nil
}
type Config struct {
SQL *sql.DB
Context context.Context
Assertions tinyssert.Assertions
Logger *slog.Logger
}
func (db *Database) setup() error {
db.assert.NotNil(db.sql)
db.assert.NotNil(db.ctx)
db.assert.NotNil(db.log)
log := db.log
log.Info("Setting up database")
log.Debug("Pinging database")
err := db.sql.PingContext(db.ctx)
if err != nil {
return errors.Join(errors.New("unable to ping database"), err)
}
log.Debug("Creating tables")
tables := []Table{
&Project{},
}
tx, err := db.sql.BeginTx(db.ctx, nil)
if err != nil {
return errors.Join(errors.New("unable to start transaction to create tables"), err)
}
for _, t := range tables {
_, err := tx.Exec(t.setup())
if err != nil {
return errors.Join(fmt.Errorf("error while trying to create table %T", t), err)
}
}
err = tx.Commit()
if err != nil {
return errors.Join(errors.New("unable to run transaction to create tables"), err)
}
return nil
}
func (db *Database) Insert(t Table) error {
q, err := t.insert()
if err != nil {
return errors.Join(fmt.Errorf("creating query to insert table %T resulted in error", t), err)
}
_, err = db.sql.ExecContext(db.ctx, q)
if err != nil {
return err
}
return nil
}
type Table interface {
setup() string
insert() (string, error)
}