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 }