99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"log/slog"
|
|
|
|
"forge.capytal.company/loreddev/x/tinyssert"
|
|
)
|
|
|
|
var ErrNoRows = sql.ErrNoRows
|
|
|
|
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.Join(errors.New("error while setting up Database struct"), err)
|
|
}
|
|
|
|
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")
|
|
|
|
tx, err := db.sql.BeginTx(db.ctx, nil)
|
|
if err != nil {
|
|
return errors.Join(errors.New("unable to start transaction to create tables"), err)
|
|
}
|
|
|
|
setups := []func(*sql.Tx) error{
|
|
db.setupProjects,
|
|
}
|
|
|
|
for _, setup := range setups {
|
|
err := setup(tx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
return errors.Join(errors.New("unable to run transaction to create tables"), err)
|
|
}
|
|
|
|
return nil
|
|
}
|