110 lines
3.5 KiB
Go
110 lines
3.5 KiB
Go
package store
|
|
|
|
import "context"
|
|
|
|
const bookCols = "id, library_id, path, title, format, file_size, mod_ts, page_count, state, error_msg, added_at"
|
|
|
|
func (s *Store) InsertBook(ctx context.Context, libID int64, path, title, format string, size, modTS int64, pageCount int) (int64, error) {
|
|
var id int64
|
|
err := s.p.QueryRow(ctx,
|
|
`INSERT INTO books (library_id, path, title, format, file_size, mod_ts, page_count)
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING id`,
|
|
libID, path, title, format, size, modTS, pageCount).Scan(&id)
|
|
return id, err
|
|
}
|
|
|
|
func (s *Store) GetBook(ctx context.Context, id int64) (Book, error) {
|
|
var b Book
|
|
err := s.p.QueryRow(ctx, "SELECT "+bookCols+" FROM books WHERE id=$1", id).Scan(
|
|
&b.ID, &b.LibraryID, &b.Path, &b.Title, &b.Format,
|
|
&b.FileSize, &b.ModTS, &b.PageCount, &b.State, &b.ErrMsg, &b.AddedAt)
|
|
return b, err
|
|
}
|
|
|
|
func (s *Store) ListBookMeta(ctx context.Context, libID int64) (map[string]BookMeta, error) {
|
|
rows, err := s.p.Query(ctx,
|
|
"SELECT id, path, file_size, mod_ts, format FROM books WHERE library_id=$1", libID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
out := map[string]BookMeta{}
|
|
for rows.Next() {
|
|
var m BookMeta
|
|
var path string
|
|
if err := rows.Scan(&m.ID, &path, &m.Size, &m.ModTS, &m.Format); err != nil {
|
|
return nil, err
|
|
}
|
|
out[path] = m
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
func (s *Store) UpdateBookFile(ctx context.Context, id, size, modTS int64, pageCount int) error {
|
|
_, err := s.p.Exec(ctx,
|
|
`UPDATE books SET file_size=$2, mod_ts=$3, page_count=$4, state='ready', error_msg='' WHERE id=$1`,
|
|
id, size, modTS, pageCount)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) DeleteBookByPath(ctx context.Context, libID int64, path string) error {
|
|
_, err := s.p.Exec(ctx, "DELETE FROM books WHERE library_id=$1 AND path=$2", libID, path)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) DeleteBook(ctx context.Context, id int64) error {
|
|
_, err := s.p.Exec(ctx, "DELETE FROM books WHERE id=$1", id)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) SetBookState(ctx context.Context, id int64, state, msg string) error {
|
|
_, err := s.p.Exec(ctx, "UPDATE books SET state=$2, error_msg=$3 WHERE id=$1", id, state, msg)
|
|
return err
|
|
}
|
|
|
|
func (s *Store) ListBooks(ctx context.Context, libID int64, q, prefix string, userID int64) ([]BookView, error) {
|
|
rows, err := s.p.Query(ctx,
|
|
`SELECT b.id, b.library_id, b.path, b.title, b.format, b.file_size, b.mod_ts,
|
|
b.page_count, b.state, b.error_msg, b.added_at, l.name, COALESCE(p.percent, 0)
|
|
FROM books b JOIN libraries l ON l.id = b.library_id
|
|
LEFT JOIN reading_progress p ON p.user_id = $4 AND p.library_id = b.library_id AND p.book_path = b.path
|
|
WHERE ($1 = 0 OR b.library_id = $1)
|
|
AND ($2 = '' OR lower(b.title) LIKE '%' || lower($2) || '%')
|
|
AND ($3 = '' OR b.path LIKE $3 || '%')
|
|
ORDER BY l.name, b.path`, libID, q, prefix, userID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var out []BookView
|
|
for rows.Next() {
|
|
var v BookView
|
|
err := rows.Scan(&v.ID, &v.LibraryID, &v.Path, &v.Title, &v.Format,
|
|
&v.FileSize, &v.ModTS, &v.PageCount, &v.State, &v.ErrMsg, &v.AddedAt,
|
|
&v.LibraryName, &v.Percent)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, v)
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
func (s *Store) BookHashes(ctx context.Context) (map[int64][2]int64, error) {
|
|
rows, err := s.p.Query(ctx, "SELECT id, file_size, mod_ts FROM books")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
out := map[int64][2]int64{}
|
|
for rows.Next() {
|
|
var id int64
|
|
var v [2]int64
|
|
if err := rows.Scan(&id, &v[0], &v[1]); err != nil {
|
|
return nil, err
|
|
}
|
|
out[id] = v
|
|
}
|
|
return out, rows.Err()
|
|
}
|