You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bog/infrastructure/sqlite/namespace/repository.go

155 lines
3.3 KiB
Go

package namespace
import (
"caj-larsson/bog/dataswamp/namespace"
"database/sql"
"errors"
"github.com/mattn/go-sqlite3"
)
type Repository struct {
db *sql.DB
}
func NewRepository(filename string) namespace.Repository {
db, err := sql.Open("sqlite3", filename)
if err != nil {
panic(err)
}
repo := Repository{
db: db,
}
repo.migrate()
return &repo
}
func (r Repository) migrate() error {
query := `
CREATE TABLE IF NOT EXISTS namespace(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
lastseen text,
allowance_time bigint,
quota_kb bigint,
quota_usage_kb bigint
);
`
_, err := r.db.Exec(query)
return err
}
func (r *Repository) Create(ns namespace.Namespace) (*namespace.Namespace, error) {
var record, err = fromEntity(ns)
if err != nil {
}
res, err := r.db.Exec(
"INSERT INTO namespace(name, lastseen, allowance_time, quota_kb, quota_usage_kb) values(?,?,?,?,?)",
record.Name, record.LastSeen, record.AllowanceSeconds, record.QuotaKB, record.QuotaUsedKB,
)
if err != nil {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) {
if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) {
return nil, namespace.ErrDuplicate
}
}
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
ns.ID = id
return &ns, nil
}
func (r Repository) All() ([]namespace.Namespace, error) {
rows, err := r.db.Query("SELECT * FROM namespace")
if err != nil {
return nil, err
}
defer rows.Close()
var all []namespace.Namespace
for rows.Next() {
var record NamespaceRecord
if err := rows.Scan(&record.ID, &record.Name, &record.LastSeen, &record.AllowanceSeconds, &record.QuotaKB, &record.QuotaUsedKB); err != nil {
return nil, err
}
var ns, err = record.toEntity()
if err != nil {
return nil, err
}
all = append(all, *ns)
}
return all, nil
}
func (r Repository) GetByName(name string) (*namespace.Namespace, error) {
row := r.db.QueryRow("SELECT id, name, lastseen, allowance_time, quota_kb, quota_usage_kb FROM namespace WHERE name = ?", name)
var record NamespaceRecord
if err := row.Scan(&record.ID, &record.Name, &record.LastSeen, &record.AllowanceSeconds, &record.QuotaKB, &record.QuotaUsedKB); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, namespace.ErrNotExists
}
return nil, err
}
var ns, err = record.toEntity()
if err != nil {
return nil, err
}
return ns, nil
}
func (r Repository) Update(id int64, updated namespace.Namespace) (*namespace.Namespace, error) {
if id == 0 {
return nil, errors.New("invalid updated ID")
}
var record, err = fromEntity(updated)
res, err := r.db.Exec("UPDATE namespace SET name = ?, lastseen = ?, allowance_time = ?, quota_kb = ?, quota_usage_kb = ? WHERE id = ?",
record.Name, record.LastSeen, record.AllowanceSeconds, &record.QuotaKB, &record.QuotaUsedKB, id)
if err != nil {
return nil, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, err
}
if rowsAffected == 0 {
return nil, namespace.ErrUpdateFailed
}
return &updated, nil
}
func (r Repository) Delete(id int64) error {
res, err := r.db.Exec("DELETE FROM namespace WHERE id = ?", id)
if err != nil {
return err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return namespace.ErrDeleteFailed
}
return err
}