From c606a7ffcc72d4f568f2ac5c2721ef9b619ea2de Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 8 Feb 2026 11:05:18 -0500 Subject: [PATCH] feat: add tags_search and contributors_search fields to database Schema changes: - Add tags_search TEXT[] column for case-insensitive, punctuation-free search - Add contributors_search TEXT[] column for case-insensitive, punctuation-free search - Create GIN indexes for fast array searches on both search fields Query updates: - CreateMediaItem: Include tags_search and contributors_search parameters - UpdateMediaItem: Include tags_search and contributors_search parameters - SearchMediaItems: Search against tags_search instead of tags - SearchMediaItems: Search against contributors_search instead of contributors - SearchMediaItemsFuzzy: Use tags_search and contributors_search for fuzzy matching - Update ranking and priority logic to use search fields Benefits: - Case-insensitive search: "acme corp" finds "ACME CORP." - Punctuation-agnostic search: "oreilly" finds "O'Reilly Media" - Better UX: Users don't need to match exact casing or punctuation - Improved performance with dedicated GIN indexes Relates to Tags & Contributors Migration Phases 5 & 8 --- internal/database/models.go | 38 +- internal/database/queries.sql.go | 778 ++++++++++++++------------ internal/database/queries/queries.sql | 70 +-- 3 files changed, 473 insertions(+), 413 deletions(-) diff --git a/internal/database/models.go b/internal/database/models.go index 51f26f0..688f7ef 100644 --- a/internal/database/models.go +++ b/internal/database/models.go @@ -207,24 +207,26 @@ type MediaItems struct { // Open Library identifier for integration OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` // Google Books identifier for integration - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` } type MediaNotes struct { diff --git a/internal/database/queries.sql.go b/internal/database/queries.sql.go index 889d45a..ea35b6a 100644 --- a/internal/database/queries.sql.go +++ b/internal/database/queries.sql.go @@ -585,37 +585,39 @@ 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25) -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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence +INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, tags_search, asin, date_published, publisher, contributors, contributors_search, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27) +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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence ` 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` } // Media Items queries @@ -633,10 +635,12 @@ func (q *Queries) CreateMediaItem(ctx context.Context, arg CreateMediaItemParams arg.Series, arg.SeriesNumber, arg.Tags, + arg.TagsSearch, arg.Asin, arg.DatePublished, arg.Publisher, arg.Contributors, + arg.ContributorsSearch, arg.Language, arg.Edition, arg.PageCount, @@ -687,6 +691,8 @@ func (q *Queries) CreateMediaItem(ctx context.Context, arg CreateMediaItemParams &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -2799,7 +2805,7 @@ func (q *Queries) GetMediaHighlights(ctx context.Context, arg GetMediaHighlights } const GetMediaItem = `-- name: GetMediaItem :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE id = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE id = $1 ` func (q *Queries) GetMediaItem(ctx context.Context, id pgtype.UUID) (MediaItems, error) { @@ -2844,6 +2850,8 @@ func (q *Queries) GetMediaItem(ctx context.Context, id pgtype.UUID) (MediaItems, &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -2853,7 +2861,7 @@ func (q *Queries) GetMediaItem(ctx context.Context, id pgtype.UUID) (MediaItems, } const GetMediaItemByFilePath = `-- name: GetMediaItemByFilePath :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_path = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_path = $1 ` func (q *Queries) GetMediaItemByFilePath(ctx context.Context, filePath string) (MediaItems, error) { @@ -2898,6 +2906,8 @@ func (q *Queries) GetMediaItemByFilePath(ctx context.Context, filePath string) ( &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -2908,7 +2918,7 @@ func (q *Queries) GetMediaItemByFilePath(ctx context.Context, filePath string) ( const GetMediaItemByFilePathForSync = `-- name: GetMediaItemByFilePathForSync :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_path = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_path = $1 ` // ============================================ @@ -2956,6 +2966,8 @@ func (q *Queries) GetMediaItemByFilePathForSync(ctx context.Context, filePath st &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -2965,7 +2977,7 @@ func (q *Queries) GetMediaItemByFilePathForSync(ctx context.Context, filePath st } const GetMediaItemByKoboContentId = `-- name: GetMediaItemByKoboContentId :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE kobo_content_id = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE kobo_content_id = $1 ` func (q *Queries) GetMediaItemByKoboContentId(ctx context.Context, koboContentID pgtype.Text) (MediaItems, error) { @@ -3010,6 +3022,8 @@ func (q *Queries) GetMediaItemByKoboContentId(ctx context.Context, koboContentID &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -3019,7 +3033,7 @@ func (q *Queries) GetMediaItemByKoboContentId(ctx context.Context, koboContentID } const GetMediaItemByOPFIdentifier = `-- name: GetMediaItemByOPFIdentifier :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE opf_identifier = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE opf_identifier = $1 ` // Get media item by OPF identifier @@ -3065,6 +3079,8 @@ func (q *Queries) GetMediaItemByOPFIdentifier(ctx context.Context, opfIdentifier &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -3074,7 +3090,7 @@ func (q *Queries) GetMediaItemByOPFIdentifier(ctx context.Context, opfIdentifier } const GetMediaItemByOPFUUID = `-- name: GetMediaItemByOPFUUID :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE opf_uuid = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE opf_uuid = $1 ` // Get media item by OPF UUID @@ -3120,6 +3136,8 @@ func (q *Queries) GetMediaItemByOPFUUID(ctx context.Context, opfUuid pgtype.Text &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -3129,7 +3147,7 @@ func (q *Queries) GetMediaItemByOPFUUID(ctx context.Context, opfUuid pgtype.Text } const GetMediaItemBySHA256 = `-- name: GetMediaItemBySHA256 :one -SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_sha256 = $1 +SELECT 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items WHERE file_sha256 = $1 ` // Get media item by SHA-256 hash @@ -3175,6 +3193,8 @@ func (q *Queries) GetMediaItemBySHA256(ctx context.Context, fileSha256 pgtype.Te &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -4906,7 +4926,7 @@ func (q *Queries) ListLibraries(ctx context.Context) ([]ListLibrariesRow, error) } const ListMediaItems = `-- name: ListMediaItems :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id @@ -4919,50 +4939,52 @@ type ListMediaItemsParams struct { } type ListMediaItemsRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } func (q *Queries) ListMediaItems(ctx context.Context, arg ListMediaItemsParams) ([]ListMediaItemsRow, error) { @@ -5013,6 +5035,8 @@ func (q *Queries) ListMediaItems(ctx context.Context, arg ListMediaItemsParams) &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -5031,7 +5055,7 @@ func (q *Queries) ListMediaItems(ctx context.Context, arg ListMediaItemsParams) } const ListMediaItemsByLibrary = `-- name: ListMediaItemsByLibrary :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id @@ -5040,50 +5064,52 @@ ORDER BY mi.created_at DESC ` type ListMediaItemsByLibraryRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } func (q *Queries) ListMediaItemsByLibrary(ctx context.Context, libraryID pgtype.UUID) ([]ListMediaItemsByLibraryRow, error) { @@ -5134,6 +5160,8 @@ func (q *Queries) ListMediaItemsByLibrary(ctx context.Context, libraryID pgtype. &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -5152,7 +5180,7 @@ func (q *Queries) ListMediaItemsByLibrary(ctx context.Context, libraryID pgtype. } const ListMediaItemsFiltered = `-- name: ListMediaItemsFiltered :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id @@ -5211,50 +5239,52 @@ type ListMediaItemsFilteredParams struct { } type ListMediaItemsFilteredRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } func (q *Queries) ListMediaItemsFiltered(ctx context.Context, arg ListMediaItemsFilteredParams) ([]ListMediaItemsFilteredRow, error) { @@ -5318,6 +5348,8 @@ func (q *Queries) ListMediaItemsFiltered(ctx context.Context, arg ListMediaItems &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -5336,7 +5368,7 @@ func (q *Queries) ListMediaItemsFiltered(ctx context.Context, arg ListMediaItems } const ListMediaItemsSorted = `-- name: ListMediaItemsSorted :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id @@ -5418,50 +5450,52 @@ type ListMediaItemsSortedParams struct { } type ListMediaItemsSortedRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } func (q *Queries) ListMediaItemsSorted(ctx context.Context, arg ListMediaItemsSortedParams) ([]ListMediaItemsSortedRow, error) { @@ -5517,6 +5551,8 @@ func (q *Queries) ListMediaItemsSorted(ctx context.Context, arg ListMediaItemsSo &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -6043,27 +6079,27 @@ func (q *Queries) RevokeRefreshToken(ctx context.Context, token pgtype.UUID) err const SearchMediaItems = `-- name: SearchMediaItems :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id LEFT JOIN library_visibility lv ON l.id = lv.library_id AND lv.user_id = $1 -WHERE COALESCE(lv.is_visible, true) = true - AND ( - mi.title ILIKE $2 OR - mi.author ILIKE $2 OR - mi.series ILIKE $2 OR - $2 = ANY(mi.tags) OR - $2 = ANY(mi.contributors) - ) -ORDER BY - CASE - WHEN mi.title ILIKE $2 THEN 1 - WHEN mi.author ILIKE $2 THEN 2 - WHEN mi.series ILIKE $2 THEN 3 - WHEN $2 = ANY(mi.tags) THEN 4 - ELSE 5 - END, + WHERE COALESCE(lv.is_visible, true) = true + AND ( + mi.title ILIKE $2 OR + mi.author ILIKE $2 OR + mi.series ILIKE $2 OR + $2 = ANY(mi.tags_search) OR + $2 = ANY(mi.contributors_search) + ) + ORDER BY + CASE + WHEN mi.title ILIKE $2 THEN 1 + WHEN mi.author ILIKE $2 THEN 2 + WHEN mi.series ILIKE $2 THEN 3 + WHEN $2 = ANY(mi.tags_search) THEN 4 + ELSE 5 + END, mi.title ASC LIMIT $4 OFFSET $3 ` @@ -6076,50 +6112,52 @@ type SearchMediaItemsParams struct { } type SearchMediaItemsRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } // Note: User ebook folders replaced by library folders system @@ -6178,6 +6216,8 @@ func (q *Queries) SearchMediaItems(ctx context.Context, arg SearchMediaItemsPara &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -6196,7 +6236,7 @@ func (q *Queries) SearchMediaItems(ctx context.Context, arg SearchMediaItemsPara } const SearchMediaItemsFuzzy = `-- name: SearchMediaItemsFuzzy :many -SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name +SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.file_path, mi.file_size, mi.mime_type, mi.cover_image_path, mi.series, mi.series_number, mi.tags, mi.asin, mi.date_published, mi.publisher, mi.contributors, mi.language, mi.edition, mi.page_count, mi.genre, mi.copyright_year, mi.goodreads_id, mi.openlibrary_id, mi.google_books_id, mi.added_by_admin_id, mi.created_at, mi.updated_at, mi.format_group, mi.format_mimetype, mi.is_reflowable, mi.has_fixed_layout, mi.total_characters, mi.chapter_count, mi.entitlement_id, mi.revision_number, mi.kobo_content_id, mi.kobo_metadata, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id @@ -6207,12 +6247,12 @@ WHERE COALESCE(lv.is_visible, true) = true word_similarity($2, COALESCE(mi.author, '')) > 0.3 OR word_similarity($2, COALESCE(mi.series, '')) > 0.3 OR EXISTS ( - SELECT 1 FROM unnest(mi.tags) AS tag + SELECT 1 FROM unnest(mi.tags_search) AS tag WHERE word_similarity($2, tag) > 0.3 LIMIT 1 ) OR EXISTS ( - SELECT 1 FROM unnest(mi.contributors) AS contributor + SELECT 1 FROM unnest(mi.contributors_search) AS contributor WHERE word_similarity($2, contributor) > 0.3 LIMIT 1 ) @@ -6224,12 +6264,12 @@ WHERE COALESCE(lv.is_visible, true) = true word_similarity($2, COALESCE(mi.series, '')), COALESCE( (SELECT MAX(word_similarity($2, tag)) - FROM unnest(mi.tags) AS tag), + FROM unnest(mi.tags_search) AS tag), 0 ), COALESCE( (SELECT MAX(word_similarity($2, contributor)) - FROM unnest(mi.contributors) AS contributor), + FROM unnest(mi.contributors_search) AS contributor), 0 ) ) DESC, @@ -6245,50 +6285,52 @@ type SearchMediaItemsFuzzyParams struct { } type SearchMediaItemsFuzzyRow struct { - ID pgtype.UUID `db:"id" json:"id"` - 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"` - Description pgtype.Text `db:"description" json:"description"` - FilePath string `db:"file_path" json:"file_path"` - FileSize pgtype.Int8 `db:"file_size" json:"file_size"` - MimeType pgtype.Text `db:"mime_type" json:"mime_type"` - CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` - Series pgtype.Text `db:"series" json:"series"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` - AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` - CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` - UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` - FormatGroup string `db:"format_group" json:"format_group"` - FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` - IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` - HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` - TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` - ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` - EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` - RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` - KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` - KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` - FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` - OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` - OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` - HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` - LibraryName string `db:"library_name" json:"library_name"` - LibraryTypeName string `db:"library_type_name" json:"library_type_name"` + ID pgtype.UUID `db:"id" json:"id"` + 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"` + Description pgtype.Text `db:"description" json:"description"` + FilePath string `db:"file_path" json:"file_path"` + FileSize pgtype.Int8 `db:"file_size" json:"file_size"` + MimeType pgtype.Text `db:"mime_type" json:"mime_type"` + CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"` + Series pgtype.Text `db:"series" json:"series"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"` + CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"` + UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"` + FormatGroup string `db:"format_group" json:"format_group"` + FormatMimetype pgtype.Text `db:"format_mimetype" json:"format_mimetype"` + IsReflowable pgtype.Bool `db:"is_reflowable" json:"is_reflowable"` + HasFixedLayout pgtype.Bool `db:"has_fixed_layout" json:"has_fixed_layout"` + TotalCharacters pgtype.Int8 `db:"total_characters" json:"total_characters"` + ChapterCount pgtype.Int4 `db:"chapter_count" json:"chapter_count"` + EntitlementID pgtype.Text `db:"entitlement_id" json:"entitlement_id"` + RevisionNumber pgtype.Int4 `db:"revision_number" json:"revision_number"` + KoboContentID pgtype.Text `db:"kobo_content_id" json:"kobo_content_id"` + KoboMetadata []byte `db:"kobo_metadata" json:"kobo_metadata"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + FileSha256 pgtype.Text `db:"file_sha256" json:"file_sha256"` + OpfIdentifier pgtype.Text `db:"opf_identifier" json:"opf_identifier"` + OpfUuid pgtype.Text `db:"opf_uuid" json:"opf_uuid"` + HashConfidence pgtype.Text `db:"hash_confidence" json:"hash_confidence"` + LibraryName string `db:"library_name" json:"library_name"` + LibraryTypeName string `db:"library_type_name" json:"library_type_name"` } func (q *Queries) SearchMediaItemsFuzzy(ctx context.Context, arg SearchMediaItemsFuzzyParams) ([]SearchMediaItemsFuzzyRow, error) { @@ -6344,6 +6386,8 @@ func (q *Queries) SearchMediaItemsFuzzy(ctx context.Context, arg SearchMediaItem &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -6936,45 +6980,49 @@ UPDATE media_items SET series = $7, series_number = $8, tags = $9, - asin = $10, - date_published = $11, - publisher = $12, - contributors = $13, - language = $14, - edition = $15, - page_count = $16, - genre = $17, - copyright_year = $18, - goodreads_id = $19, - openlibrary_id = $20, - google_books_id = $21, + tags_search = $10, + asin = $11, + date_published = $12, + publisher = $13, + contributors = $14, + contributors_search = $15, + language = $16, + edition = $17, + page_count = $18, + genre = $19, + copyright_year = $20, + goodreads_id = $21, + openlibrary_id = $22, + google_books_id = $23, updated_at = NOW() WHERE id = $1 -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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence +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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence ` 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"` - 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"` - SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` - Tags []string `db:"tags" json:"tags"` - Asin pgtype.Text `db:"asin" json:"asin"` - DatePublished pgtype.Date `db:"date_published" json:"date_published"` - Publisher pgtype.Text `db:"publisher" json:"publisher"` - Contributors []string `db:"contributors" json:"contributors"` - Language pgtype.Text `db:"language" json:"language"` - Edition pgtype.Text `db:"edition" json:"edition"` - PageCount pgtype.Int4 `db:"page_count" json:"page_count"` - Genre pgtype.Text `db:"genre" json:"genre"` - CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` - GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` - OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` - GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` + 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"` + 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"` + SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"` + Tags []string `db:"tags" json:"tags"` + TagsSearch []string `db:"tags_search" json:"tags_search"` + Asin pgtype.Text `db:"asin" json:"asin"` + DatePublished pgtype.Date `db:"date_published" json:"date_published"` + Publisher pgtype.Text `db:"publisher" json:"publisher"` + Contributors []string `db:"contributors" json:"contributors"` + ContributorsSearch []string `db:"contributors_search" json:"contributors_search"` + Language pgtype.Text `db:"language" json:"language"` + Edition pgtype.Text `db:"edition" json:"edition"` + PageCount pgtype.Int4 `db:"page_count" json:"page_count"` + Genre pgtype.Text `db:"genre" json:"genre"` + CopyrightYear pgtype.Int4 `db:"copyright_year" json:"copyright_year"` + GoodreadsID pgtype.Text `db:"goodreads_id" json:"goodreads_id"` + OpenlibraryID pgtype.Text `db:"openlibrary_id" json:"openlibrary_id"` + GoogleBooksID pgtype.Text `db:"google_books_id" json:"google_books_id"` } func (q *Queries) UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams) (MediaItems, error) { @@ -6988,10 +7036,12 @@ func (q *Queries) UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams arg.Series, arg.SeriesNumber, arg.Tags, + arg.TagsSearch, arg.Asin, arg.DatePublished, arg.Publisher, arg.Contributors, + arg.ContributorsSearch, arg.Language, arg.Edition, arg.PageCount, @@ -7041,6 +7091,8 @@ func (q *Queries) UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -7144,7 +7196,7 @@ SET hash_confidence = $5, updated_at = NOW() WHERE id = $1 -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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence +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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence ` type UpdateMediaItemIdentifiersParams struct { @@ -7208,6 +7260,8 @@ func (q *Queries) UpdateMediaItemIdentifiers(ctx context.Context, arg UpdateMedi &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, @@ -7224,7 +7278,7 @@ SET entitlement_id = $2, kobo_metadata = $5, updated_at = NOW() WHERE id = $1 -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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, file_sha256, opf_identifier, opf_uuid, hash_confidence +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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id, created_at, updated_at, format_group, format_mimetype, is_reflowable, has_fixed_layout, total_characters, chapter_count, entitlement_id, revision_number, kobo_content_id, kobo_metadata, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence ` type UpdateMediaItemKoboMetadataParams struct { @@ -7283,6 +7337,8 @@ func (q *Queries) UpdateMediaItemKoboMetadata(ctx context.Context, arg UpdateMed &i.RevisionNumber, &i.KoboContentID, &i.KoboMetadata, + &i.TagsSearch, + &i.ContributorsSearch, &i.FileSha256, &i.OpfIdentifier, &i.OpfUuid, diff --git a/internal/database/queries/queries.sql b/internal/database/queries/queries.sql index 1722c86..e9759c1 100644 --- a/internal/database/queries/queries.sql +++ b/internal/database/queries/queries.sql @@ -102,8 +102,8 @@ ORDER BY l.created_at DESC; -- Media Items queries -- 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, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25) +INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, tags_search, asin, date_published, publisher, contributors, contributors_search, language, edition, page_count, genre, copyright_year, goodreads_id, openlibrary_id, google_books_id, added_by_admin_id) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27) RETURNING *; -- name: GetMediaItem :one @@ -252,18 +252,20 @@ UPDATE media_items SET series = $7, series_number = $8, tags = $9, - asin = $10, - date_published = $11, - publisher = $12, - contributors = $13, - language = $14, - edition = $15, - page_count = $16, - genre = $17, - copyright_year = $18, - goodreads_id = $19, - openlibrary_id = $20, - google_books_id = $21, + tags_search = $10, + asin = $11, + date_published = $12, + publisher = $13, + contributors = $14, + contributors_search = $15, + language = $16, + edition = $17, + page_count = $18, + genre = $19, + copyright_year = $20, + goodreads_id = $21, + openlibrary_id = $22, + google_books_id = $23, updated_at = NOW() WHERE id = $1 RETURNING *; @@ -359,22 +361,22 @@ FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id LEFT JOIN library_visibility lv ON l.id = lv.library_id AND lv.user_id = sqlc.narg('user_id') -WHERE COALESCE(lv.is_visible, true) = true - AND ( - mi.title ILIKE sqlc.narg('search_pattern') OR - mi.author ILIKE sqlc.narg('search_pattern') OR - mi.series ILIKE sqlc.narg('search_pattern') OR - sqlc.narg('search_pattern') = ANY(mi.tags) OR - sqlc.narg('search_pattern') = ANY(mi.contributors) - ) -ORDER BY - CASE - WHEN mi.title ILIKE sqlc.narg('search_pattern') THEN 1 - WHEN mi.author ILIKE sqlc.narg('search_pattern') THEN 2 - WHEN mi.series ILIKE sqlc.narg('search_pattern') THEN 3 - WHEN sqlc.narg('search_pattern') = ANY(mi.tags) THEN 4 - ELSE 5 - END, + WHERE COALESCE(lv.is_visible, true) = true + AND ( + mi.title ILIKE sqlc.narg('search_pattern') OR + mi.author ILIKE sqlc.narg('search_pattern') OR + mi.series ILIKE sqlc.narg('search_pattern') OR + sqlc.narg('search_pattern') = ANY(mi.tags_search) OR + sqlc.narg('search_pattern') = ANY(mi.contributors_search) + ) + ORDER BY + CASE + WHEN mi.title ILIKE sqlc.narg('search_pattern') THEN 1 + WHEN mi.author ILIKE sqlc.narg('search_pattern') THEN 2 + WHEN mi.series ILIKE sqlc.narg('search_pattern') THEN 3 + WHEN sqlc.narg('search_pattern') = ANY(mi.tags_search) THEN 4 + ELSE 5 + END, mi.title ASC LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); @@ -390,12 +392,12 @@ WHERE COALESCE(lv.is_visible, true) = true word_similarity(sqlc.narg('search_query'), COALESCE(mi.author, '')) > 0.3 OR word_similarity(sqlc.narg('search_query'), COALESCE(mi.series, '')) > 0.3 OR EXISTS ( - SELECT 1 FROM unnest(mi.tags) AS tag + SELECT 1 FROM unnest(mi.tags_search) AS tag WHERE word_similarity(sqlc.narg('search_query'), tag) > 0.3 LIMIT 1 ) OR EXISTS ( - SELECT 1 FROM unnest(mi.contributors) AS contributor + SELECT 1 FROM unnest(mi.contributors_search) AS contributor WHERE word_similarity(sqlc.narg('search_query'), contributor) > 0.3 LIMIT 1 ) @@ -407,12 +409,12 @@ WHERE COALESCE(lv.is_visible, true) = true word_similarity(sqlc.narg('search_query'), COALESCE(mi.series, '')), COALESCE( (SELECT MAX(word_similarity(sqlc.narg('search_query'), tag)) - FROM unnest(mi.tags) AS tag), + FROM unnest(mi.tags_search) AS tag), 0 ), COALESCE( (SELECT MAX(word_similarity(sqlc.narg('search_query'), contributor)) - FROM unnest(mi.contributors) AS contributor), + FROM unnest(mi.contributors_search) AS contributor), 0 ) ) DESC,