package integration import ( "caj-larsson/bog/domain" "database/sql" "errors" "github.com/mattn/go-sqlite3" ) type SQLiteUserAgentRepository struct { db *sql.DB } func NewSQLiteUserAgentRepository(filename string) *SQLiteUserAgentRepository { db, err := sql.Open("sqlite3", filename) if err != nil { panic(err) } repo := SQLiteUserAgentRepository{ db: db, } repo.migrate() return &repo } func (r SQLiteUserAgentRepository) migrate() error { query := ` CREATE TABLE IF NOT EXISTS useragent( 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 SQLiteUserAgentRepository) Create(useragent domain.UserAgent) (*domain.UserAgent, error) { var record, err = fromEntity(useragent) if err != nil { } res, err := r.db.Exec( "INSERT INTO useragent(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, domain.ErrDuplicate } } return nil, err } id, err := res.LastInsertId() if err != nil { return nil, err } useragent.ID = id return &useragent, nil } func (r SQLiteUserAgentRepository) All() ([]domain.UserAgent, error) { rows, err := r.db.Query("SELECT * FROM useragent") if err != nil { return nil, err } defer rows.Close() var all []domain.UserAgent for rows.Next() { var record UserAgentDBRecord if err := rows.Scan(&record.ID, &record.Name, &record.LastSeen, &record.AllowanceSeconds, &record.QuotaKB, &record.QuotaUsedKB); err != nil { return nil, err } var useragent, err = record.toEntity() if err != nil { return nil, err } all = append(all, *useragent) } return all, nil } func (r SQLiteUserAgentRepository) GetByName(name string) (*domain.UserAgent, error) { row := r.db.QueryRow("SELECT id, name, lastseen, allowance_time, quota_kb, quota_usage_kb FROM useragent WHERE name = ?", name) var record UserAgentDBRecord 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, domain.ErrNotExists } return nil, err } var useragent, err = record.toEntity() if err != nil { return nil, err } return useragent, nil } func (r SQLiteUserAgentRepository) Update(id int64, updated domain.UserAgent) (*domain.UserAgent, error) { if id == 0 { return nil, errors.New("invalid updated ID") } var record, err = fromEntity(updated) res, err := r.db.Exec("UPDATE useragent 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, domain.ErrUpdateFailed } return &updated, nil } func (r SQLiteUserAgentRepository) Delete(id int64) error { res, err := r.db.Exec("DELETE FROM useragent WHERE id = ?", id) if err != nil { return err } rowsAffected, err := res.RowsAffected() if err != nil { return err } if rowsAffected == 0 { return domain.ErrDeleteFailed } return err }