feat(ebooks): add ISBN normalization and graceful library requirement handling
- Increase ISBN column from VARCHAR(13) to VARCHAR(17) to support ISBN-13 with hyphens - Add normalize_isbn() database function to automatically remove hyphens and spaces - Create trigger to auto-normalize ISBNs on INSERT/UPDATE operations - Update all Ebook and MediaItem queries to use ISBN normalization - Add GetEbookLibraryID query to check for existing ebook libraries - Add graceful error handling when no ebook library exists - Return helpful error message: 'no ebook library found. Please create an ebook library first' - Create comprehensive tests for ISBN normalization and library selection - Add Bruno test files for various ISBN formats and error scenarios - Update documentation with ISBN normalization details
This commit is contained in:
@@ -44,14 +44,14 @@ func (q *Queries) CleanupExpiredRefreshTokens(ctx context.Context) error {
|
||||
|
||||
const CreateEbook = `-- name: CreateEbook :one
|
||||
INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id)
|
||||
VALUES ((SELECT id FROM libraries WHERE library_type_id = (SELECT id FROM library_types WHERE name = 'ebooks') LIMIT 1), $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
VALUES ((SELECT id FROM libraries WHERE library_type_id = (SELECT id FROM library_types WHERE name = 'ebooks') LIMIT 1), $1, $2, normalize_isbn($3), $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING id, library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at
|
||||
`
|
||||
|
||||
type CreateEbookParams struct {
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
Isbn string `db:"isbn" json:"isbn"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
FilePath string `db:"file_path" json:"file_path"`
|
||||
FileSize pgtype.Int8 `db:"file_size" json:"file_size"`
|
||||
@@ -299,7 +299,7 @@ func (q *Queries) CreateMediaHighlight(ctx context.Context, arg CreateMediaHighl
|
||||
|
||||
const CreateMediaItem = `-- name: CreateMediaItem :one
|
||||
INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
VALUES ($1, $2, $3, normalize_isbn($4), $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
RETURNING id, library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id, created_at, updated_at
|
||||
`
|
||||
|
||||
@@ -307,7 +307,7 @@ type CreateMediaItemParams struct {
|
||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
Isbn string `db:"isbn" json:"isbn"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
FilePath string `db:"file_path" json:"file_path"`
|
||||
FileSize pgtype.Int8 `db:"file_size" json:"file_size"`
|
||||
@@ -781,6 +781,17 @@ func (q *Queries) GetEbookHighlights(ctx context.Context, arg GetEbookHighlights
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const GetEbookLibraryID = `-- name: GetEbookLibraryID :one
|
||||
SELECT id FROM libraries WHERE library_type_id = (SELECT id FROM library_types WHERE name = 'ebooks') LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) GetEbookLibraryID(ctx context.Context) (pgtype.UUID, error) {
|
||||
row := q.db.QueryRow(ctx, GetEbookLibraryID)
|
||||
var id pgtype.UUID
|
||||
err := row.Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
const GetEbookNote = `-- name: GetEbookNote :one
|
||||
SELECT id, media_item_id, user_id, content, position, created_at, updated_at, ebook_id FROM ebook_notes WHERE id = $1
|
||||
`
|
||||
@@ -1978,7 +1989,7 @@ const UpdateEbook = `-- name: UpdateEbook :one
|
||||
UPDATE media_items SET
|
||||
title = $2,
|
||||
author = $3,
|
||||
isbn = $4,
|
||||
isbn = normalize_isbn($4),
|
||||
description = $5,
|
||||
cover_image_path = $6,
|
||||
series = $7,
|
||||
@@ -1997,7 +2008,7 @@ type UpdateEbookParams struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
Isbn string `db:"isbn" json:"isbn"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"`
|
||||
Series pgtype.Text `db:"series" json:"series"`
|
||||
@@ -2249,7 +2260,7 @@ const UpdateMediaItem = `-- name: UpdateMediaItem :one
|
||||
UPDATE media_items SET
|
||||
title = $2,
|
||||
author = $3,
|
||||
isbn = $4,
|
||||
isbn = normalize_isbn($4),
|
||||
description = $5,
|
||||
cover_image_path = $6,
|
||||
series = $7,
|
||||
@@ -2268,7 +2279,7 @@ type UpdateMediaItemParams struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
Isbn string `db:"isbn" json:"isbn"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"`
|
||||
Series pgtype.Text `db:"series" json:"series"`
|
||||
|
||||
Reference in New Issue
Block a user