Files
book-comic-library/backend/internal/store/store.go
T

94 lines
2.0 KiB
Go

package store
import (
"errors"
"time"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool"
)
// ErrLastAdmin is returned by DeleteUser when attempting to delete the last admin.
var ErrLastAdmin = errors.New("cannot delete the last admin")
// ErrUniqueViolation is a sentinel for PostgreSQL unique constraint violations.
var ErrUniqueViolation = errors.New("unique violation")
// IsUniqueViolation reports whether err is a PostgreSQL unique constraint violation (23505).
func IsUniqueViolation(err error) bool {
var pgErr *pgconn.PgError
return errors.As(err, &pgErr) && pgErr.Code == "23505"
}
// Store provides database access. The pool is unexported; all access goes through methods.
type Store struct{ p *pgxpool.Pool }
func New(p *pgxpool.Pool) *Store { return &Store{p: p} }
// ---------- types ----------
type User struct {
ID int64
Username string
PasswordHash string
Role string
CreatedAt time.Time
}
type Library struct {
ID int64
Name string
RootPath string
CreatedAt time.Time
}
type Book struct {
ID, LibraryID int64
Path string
Title string
Format string
FileSize int64
ModTS int64
PageCount int // 0 means unknown (pdf/epub/txt)
State string
ErrMsg string
AddedAt time.Time
}
type BookMeta struct {
ID int64
Size int64
ModTS int64
Format string
}
type BookView struct {
Book
LibraryName string
Percent float64
}
type Progress struct {
LibraryID int64
LibraryName string
BookPath string
Title string // empty when book deleted
Locator []byte
Percent float64
UpdatedAt time.Time
}
type Bookmark struct {
ID int64
LibraryID int64
BookPath string
Locator []byte
Percent float64
Note string
CreatedAt time.Time
}
// Pool returns the underlying pool for test setup only.
// Production code should use Store methods exclusively.
func (s *Store) Pool() *pgxpool.Pool { return s.p }