This commit is contained in:
delete 2026-06-10 20:51:17 +03:00
commit b15b95781c
108 changed files with 14802 additions and 0 deletions

131
internal/db/store.go Normal file
View file

@ -0,0 +1,131 @@
package db
import (
"context"
"database/sql"
"errors"
"fmt"
)
type querier interface {
ExecContext(context.Context, string, ...any) (sql.Result, error)
QueryContext(context.Context, string, ...any) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...any) *sql.Row
}
type Store struct {
DB *sql.DB
Users *UserRepository
Projects *ProjectRepository
Tags *TagRepository
Releases *ReleaseRepository
APIKeys *APIKeyRepository
Sessions *SessionRepository
AuditLogs *AuditLogRepository
}
type TxStore struct {
Tx *sql.Tx
Users *UserRepository
Projects *ProjectRepository
Tags *TagRepository
Releases *ReleaseRepository
APIKeys *APIKeyRepository
Sessions *SessionRepository
AuditLogs *AuditLogRepository
}
type UserRepository struct {
q querier
}
type ProjectRepository struct {
q querier
}
type TagRepository struct {
q querier
}
type ReleaseRepository struct {
q querier
}
type APIKeyRepository struct {
q querier
}
type SessionRepository struct {
q querier
}
type AuditLogRepository struct {
q querier
}
func NewStore(database *sql.DB) *Store {
return &Store{
DB: database,
Users: &UserRepository{q: database},
Projects: &ProjectRepository{q: database},
Tags: &TagRepository{q: database},
Releases: &ReleaseRepository{q: database},
APIKeys: &APIKeyRepository{q: database},
Sessions: &SessionRepository{q: database},
AuditLogs: &AuditLogRepository{q: database},
}
}
func (s *Store) Close() error {
if s == nil || s.DB == nil {
return nil
}
return s.DB.Close()
}
func (s *Store) HealthCheck(ctx context.Context) error {
if s == nil || s.DB == nil {
return fmt.Errorf("database store is not initialized")
}
return s.DB.PingContext(ctx)
}
func (s *Store) WithTx(ctx context.Context, fn func(*TxStore) error) error {
if s == nil || s.DB == nil {
return fmt.Errorf("database store is not initialized")
}
tx, err := s.DB.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("begin transaction: %w", err)
}
if err := fn(newTxStore(tx)); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil && !errors.Is(rollbackErr, sql.ErrTxDone) {
return errors.Join(err, fmt.Errorf("rollback transaction: %w", rollbackErr))
}
return err
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("commit transaction: %w", err)
}
return nil
}
func newTxStore(tx *sql.Tx) *TxStore {
return &TxStore{
Tx: tx,
Users: &UserRepository{q: tx},
Projects: &ProjectRepository{q: tx},
Tags: &TagRepository{q: tx},
Releases: &ReleaseRepository{q: tx},
APIKeys: &APIKeyRepository{q: tx},
Sessions: &SessionRepository{q: tx},
AuditLogs: &AuditLogRepository{q: tx},
}
}