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 }