refactor(sql): use sqlc.narg() pattern for optional library_id in all library-filtered queries
Convert 12 SQL queries to use sqlc.narg('library_id') instead of
direct @library_id parameters. This allows passing a NULL/invalid
pgtype.UUID to mean "no library filter" (i.e., All Libraries),
making the SQL layer correctly handle the optional filter via:
(sqlc.narg('library_id')::uuid IS NULL
OR mi.library_id = sqlc.narg('library_id')::uuid)
Also remove the library_id filter from GetSeriesBooks entirely —
a series is a series regardless of library.
Queries affected:
- GetDashboardSections, GetRecentlyAdded, GetInProgress
- GetHighestRated, GetMostRead, GetAbandonedBooks
- GetLeastRead, GetBooksByTag, GetCollectionItemsForDashboard
- SearchMediaItemsUnified, GetSeriesCardsData
Generated code (queries.sql.go, querier.go) regenerated via sqlc.
This commit is contained in:
@@ -243,7 +243,7 @@ type Querier interface {
|
|||||||
GetRefreshToken(ctx context.Context, token pgtype.UUID) (GetRefreshTokenRow, error)
|
GetRefreshToken(ctx context.Context, token pgtype.UUID) (GetRefreshTokenRow, error)
|
||||||
GetSavedFilterByID(ctx context.Context, arg GetSavedFilterByIDParams) (SavedFilters, error)
|
GetSavedFilterByID(ctx context.Context, arg GetSavedFilterByIDParams) (SavedFilters, error)
|
||||||
GetSavedFilters(ctx context.Context, arg GetSavedFiltersParams) ([]SavedFilters, error)
|
GetSavedFilters(ctx context.Context, arg GetSavedFiltersParams) ([]SavedFilters, error)
|
||||||
GetSeriesBooks(ctx context.Context, arg GetSeriesBooksParams) ([]MediaItems, error)
|
GetSeriesBooks(ctx context.Context, series pgtype.Text) ([]MediaItems, error)
|
||||||
GetSeriesCovers(ctx context.Context, arg GetSeriesCoversParams) ([]GetSeriesCoversRow, error)
|
GetSeriesCovers(ctx context.Context, arg GetSeriesCoversParams) ([]GetSeriesCoversRow, error)
|
||||||
GetStuckSyncQueueItems(ctx context.Context) ([]SyncQueue, error)
|
GetStuckSyncQueueItems(ctx context.Context) ([]SyncQueue, error)
|
||||||
GetSyncConflict(ctx context.Context, id pgtype.UUID) (SyncConflicts, error)
|
GetSyncConflict(ctx context.Context, id pgtype.UUID) (SyncConflicts, error)
|
||||||
|
|||||||
@@ -2116,7 +2116,7 @@ const GetCollectionItemsForDashboard = `-- name: GetCollectionItemsForDashboard
|
|||||||
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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, ci.excluded FROM media_items mi
|
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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence, ci.excluded FROM media_items mi
|
||||||
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
|
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
|
||||||
WHERE ci.collection_id = $1
|
WHERE ci.collection_id = $1
|
||||||
AND mi.library_id = $2
|
AND ($2::uuid IS NULL OR mi.library_id = $2::uuid)
|
||||||
ORDER BY ci.added_at DESC
|
ORDER BY ci.added_at DESC
|
||||||
LIMIT $3
|
LIMIT $3
|
||||||
`
|
`
|
||||||
@@ -2124,7 +2124,7 @@ LIMIT $3
|
|||||||
type GetCollectionItemsForDashboardParams struct {
|
type GetCollectionItemsForDashboardParams struct {
|
||||||
CollectionID pgtype.UUID `db:"collection_id" json:"collection_id"`
|
CollectionID pgtype.UUID `db:"collection_id" json:"collection_id"`
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetCollectionItemsForDashboardRow struct {
|
type GetCollectionItemsForDashboardRow struct {
|
||||||
@@ -2411,25 +2411,25 @@ SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.fi
|
|||||||
INNER JOIN (
|
INNER JOIN (
|
||||||
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
||||||
FROM reading_progress
|
FROM reading_progress
|
||||||
WHERE user_id = $2
|
WHERE user_id = $1
|
||||||
AND percentage > 0
|
AND percentage > 0
|
||||||
AND percentage < 1
|
AND percentage < 1
|
||||||
ORDER BY media_item_id, last_read_at DESC
|
ORDER BY media_item_id, last_read_at DESC
|
||||||
) rp ON rp.media_item_id = mi.id
|
) rp ON rp.media_item_id = mi.id
|
||||||
WHERE mi.library_id = $1
|
WHERE ($2::uuid IS NULL OR mi.library_id = $2::uuid)
|
||||||
ORDER BY rp.last_read_at DESC
|
ORDER BY rp.last_read_at DESC
|
||||||
LIMIT $3
|
LIMIT $3
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetContinueReadingItemsParams struct {
|
type GetContinueReadingItemsParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
|
||||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart section queries (for system collections)
|
// Smart section queries (for system collections)
|
||||||
func (q *Queries) GetContinueReadingItems(ctx context.Context, arg GetContinueReadingItemsParams) ([]MediaItems, error) {
|
func (q *Queries) GetContinueReadingItems(ctx context.Context, arg GetContinueReadingItemsParams) ([]MediaItems, error) {
|
||||||
rows, err := q.db.Query(ctx, GetContinueReadingItems, arg.LibraryID, arg.UserID, arg.Limit)
|
rows, err := q.db.Query(ctx, GetContinueReadingItems, arg.UserID, arg.LibraryID, arg.Limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -2520,7 +2520,7 @@ WITH user_series_progress AS (
|
|||||||
WHERE rp.user_id = $2
|
WHERE rp.user_id = $2
|
||||||
AND rp.percentage > 0
|
AND rp.percentage > 0
|
||||||
AND mi.series IS NOT NULL AND mi.series != ''
|
AND mi.series IS NOT NULL AND mi.series != ''
|
||||||
AND mi.library_id = $1
|
AND ($3::uuid IS NULL OR mi.library_id = $3::uuid)
|
||||||
GROUP BY mi.series
|
GROUP BY mi.series
|
||||||
),
|
),
|
||||||
next_books AS (
|
next_books AS (
|
||||||
@@ -2528,19 +2528,19 @@ next_books AS (
|
|||||||
usp.last_read_at
|
usp.last_read_at
|
||||||
FROM media_items mi
|
FROM media_items mi
|
||||||
JOIN user_series_progress usp ON mi.series = usp.series
|
JOIN user_series_progress usp ON mi.series = usp.series
|
||||||
WHERE mi.library_id = $1
|
WHERE ($3::uuid IS NULL OR mi.library_id = $3::uuid)
|
||||||
AND (mi.series_number > usp.max_read_number OR usp.max_read_number IS NULL)
|
AND (mi.series_number > usp.max_read_number OR usp.max_read_number IS NULL)
|
||||||
ORDER BY mi.series, mi.series_number ASC NULLS LAST
|
ORDER BY mi.series, mi.series_number ASC NULLS LAST
|
||||||
)
|
)
|
||||||
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, imported_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, manga_type, reading_direction, series_count, volume, imprint, age_rating, web_url, story_arc, is_black_and_white, metadata_notes, community_rating, alternate_info, scan_information, summary, chapter_metadata, library_type_name, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence, last_read_at FROM next_books
|
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, imported_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, manga_type, reading_direction, series_count, volume, imprint, age_rating, web_url, story_arc, is_black_and_white, metadata_notes, community_rating, alternate_info, scan_information, summary, chapter_metadata, library_type_name, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence, last_read_at FROM next_books
|
||||||
ORDER BY last_read_at DESC NULLS LAST
|
ORDER BY last_read_at DESC NULLS LAST
|
||||||
LIMIT $3
|
LIMIT $1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetContinueSeriesItemsParams struct {
|
type GetContinueSeriesItemsParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetContinueSeriesItemsRow struct {
|
type GetContinueSeriesItemsRow struct {
|
||||||
@@ -2609,7 +2609,7 @@ type GetContinueSeriesItemsRow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetContinueSeriesItems(ctx context.Context, arg GetContinueSeriesItemsParams) ([]GetContinueSeriesItemsRow, error) {
|
func (q *Queries) GetContinueSeriesItems(ctx context.Context, arg GetContinueSeriesItemsParams) ([]GetContinueSeriesItemsRow, error) {
|
||||||
rows, err := q.db.Query(ctx, GetContinueSeriesItems, arg.LibraryID, arg.UserID, arg.Limit)
|
rows, err := q.db.Query(ctx, GetContinueSeriesItems, arg.Limit, arg.UserID, arg.LibraryID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -2694,7 +2694,7 @@ func (q *Queries) GetContinueSeriesItems(ctx context.Context, arg GetContinueSer
|
|||||||
const GetDashboardPreferences = `-- name: GetDashboardPreferences :one
|
const GetDashboardPreferences = `-- name: GetDashboardPreferences :one
|
||||||
|
|
||||||
SELECT id, user_id, library_id, hidden_collections, collection_order, items_per_section, created_at, updated_at FROM user_dashboard_preferences
|
SELECT id, user_id, library_id, hidden_collections, collection_order, items_per_section, created_at, updated_at FROM user_dashboard_preferences
|
||||||
WHERE user_id = $1 AND library_id = $2
|
WHERE user_id = $1 AND ($2::uuid IS NULL OR library_id = $2::uuid)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetDashboardPreferencesParams struct {
|
type GetDashboardPreferencesParams struct {
|
||||||
@@ -3115,16 +3115,16 @@ SELECT series, COUNT(*) as book_count,
|
|||||||
MAX(series_count) as total_in_series,
|
MAX(series_count) as total_in_series,
|
||||||
MAX(created_at) as last_entry_at
|
MAX(created_at) as last_entry_at
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series IS NOT NULL AND series != ''
|
WHERE ($1::uuid IS NULL OR library_id = $1::uuid) AND series IS NOT NULL AND series != ''
|
||||||
GROUP BY series
|
GROUP BY series
|
||||||
ORDER BY MAX(created_at) DESC
|
ORDER BY MAX(created_at) DESC
|
||||||
LIMIT $2 OFFSET $3
|
LIMIT $3 OFFSET $2
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetDistinctSeriesParams struct {
|
type GetDistinctSeriesParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
Offset pgtype.Int4 `db:"offset" json:"offset"`
|
||||||
Offset int32 `db:"offset" json:"offset"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetDistinctSeriesRow struct {
|
type GetDistinctSeriesRow struct {
|
||||||
@@ -3135,7 +3135,7 @@ type GetDistinctSeriesRow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetDistinctSeries(ctx context.Context, arg GetDistinctSeriesParams) ([]GetDistinctSeriesRow, error) {
|
func (q *Queries) GetDistinctSeries(ctx context.Context, arg GetDistinctSeriesParams) ([]GetDistinctSeriesRow, error) {
|
||||||
rows, err := q.db.Query(ctx, GetDistinctSeries, arg.LibraryID, arg.Limit, arg.Offset)
|
rows, err := q.db.Query(ctx, GetDistinctSeries, arg.LibraryID, arg.Offset, arg.Limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3162,7 +3162,7 @@ func (q *Queries) GetDistinctSeries(ctx context.Context, arg GetDistinctSeriesPa
|
|||||||
const GetDistinctSeriesCount = `-- name: GetDistinctSeriesCount :one
|
const GetDistinctSeriesCount = `-- name: GetDistinctSeriesCount :one
|
||||||
SELECT COUNT(DISTINCT series)::int
|
SELECT COUNT(DISTINCT series)::int
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series IS NOT NULL AND series != ''
|
WHERE ($1::uuid IS NULL OR library_id = $1::uuid) AND series IS NOT NULL AND series != ''
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetDistinctSeriesCount(ctx context.Context, libraryID pgtype.UUID) (int32, error) {
|
func (q *Queries) GetDistinctSeriesCount(ctx context.Context, libraryID pgtype.UUID) (int32, error) {
|
||||||
@@ -3781,7 +3781,7 @@ func (q *Queries) GetLibraryFolders(ctx context.Context, libraryID pgtype.UUID)
|
|||||||
|
|
||||||
const GetLibraryItems = `-- name: GetLibraryItems :many
|
const GetLibraryItems = `-- name: GetLibraryItems :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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE ($1::uuid IS NULL OR mi.library_id = $1::uuid)
|
||||||
ORDER BY mi.created_at DESC
|
ORDER BY mi.created_at DESC
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -4967,7 +4967,7 @@ func (q *Queries) GetNextRetryTime(ctx context.Context) (interface{}, error) {
|
|||||||
|
|
||||||
const GetNotStartedItems = `-- name: GetNotStartedItems :many
|
const GetNotStartedItems = `-- name: GetNotStartedItems :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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE ($1::uuid IS NULL OR mi.library_id = $1::uuid)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM reading_progress rp
|
SELECT 1 FROM reading_progress rp
|
||||||
WHERE rp.media_item_id = mi.id
|
WHERE rp.media_item_id = mi.id
|
||||||
@@ -4981,7 +4981,7 @@ LIMIT $3
|
|||||||
type GetNotStartedItemsParams struct {
|
type GetNotStartedItemsParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetNotStartedItems(ctx context.Context, arg GetNotStartedItemsParams) ([]MediaItems, error) {
|
func (q *Queries) GetNotStartedItems(ctx context.Context, arg GetNotStartedItemsParams) ([]MediaItems, error) {
|
||||||
@@ -5366,14 +5366,14 @@ func (q *Queries) GetReadingSpeed(ctx context.Context, arg GetReadingSpeedParams
|
|||||||
|
|
||||||
const GetRecentlyAddedItems = `-- name: GetRecentlyAddedItems :many
|
const GetRecentlyAddedItems = `-- name: GetRecentlyAddedItems :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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
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.imported_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.manga_type, mi.reading_direction, mi.series_count, mi.volume, mi.imprint, mi.age_rating, mi.web_url, mi.story_arc, mi.is_black_and_white, mi.metadata_notes, mi.community_rating, mi.alternate_info, mi.scan_information, mi.summary, mi.chapter_metadata, mi.library_type_name, mi.tags_search, mi.contributors_search, mi.file_sha256, mi.opf_identifier, mi.opf_uuid, mi.hash_confidence FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE ($1::uuid IS NULL OR mi.library_id = $1::uuid)
|
||||||
ORDER BY mi.imported_at DESC NULLS LAST, mi.created_at DESC
|
ORDER BY mi.imported_at DESC NULLS LAST, mi.created_at DESC
|
||||||
LIMIT $2
|
LIMIT $2
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetRecentlyAddedItemsParams struct {
|
type GetRecentlyAddedItemsParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetRecentlyAddedItems(ctx context.Context, arg GetRecentlyAddedItemsParams) ([]MediaItems, error) {
|
func (q *Queries) GetRecentlyAddedItems(ctx context.Context, arg GetRecentlyAddedItemsParams) ([]MediaItems, error) {
|
||||||
@@ -5463,23 +5463,23 @@ SELECT mi.id, mi.library_id, mi.title, mi.author, mi.isbn, mi.description, mi.fi
|
|||||||
INNER JOIN (
|
INNER JOIN (
|
||||||
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
||||||
FROM reading_progress
|
FROM reading_progress
|
||||||
WHERE user_id = $2
|
WHERE user_id = $1
|
||||||
AND percentage >= 1
|
AND percentage >= 1
|
||||||
ORDER BY media_item_id, last_read_at DESC
|
ORDER BY media_item_id, last_read_at DESC
|
||||||
) rp ON rp.media_item_id = mi.id
|
) rp ON rp.media_item_id = mi.id
|
||||||
WHERE mi.library_id = $1
|
WHERE ($2::uuid IS NULL OR mi.library_id = $2::uuid)
|
||||||
ORDER BY rp.last_read_at DESC
|
ORDER BY rp.last_read_at DESC
|
||||||
LIMIT $3
|
LIMIT $3
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetRecentlyReadItemsParams struct {
|
type GetRecentlyReadItemsParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
|
||||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetRecentlyReadItems(ctx context.Context, arg GetRecentlyReadItemsParams) ([]MediaItems, error) {
|
func (q *Queries) GetRecentlyReadItems(ctx context.Context, arg GetRecentlyReadItemsParams) ([]MediaItems, error) {
|
||||||
rows, err := q.db.Query(ctx, GetRecentlyReadItems, arg.LibraryID, arg.UserID, arg.Limit)
|
rows, err := q.db.Query(ctx, GetRecentlyReadItems, arg.UserID, arg.LibraryID, arg.Limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -5662,17 +5662,12 @@ func (q *Queries) GetSavedFilters(ctx context.Context, arg GetSavedFiltersParams
|
|||||||
|
|
||||||
const GetSeriesBooks = `-- name: GetSeriesBooks :many
|
const GetSeriesBooks = `-- name: GetSeriesBooks :many
|
||||||
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, imported_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, manga_type, reading_direction, series_count, volume, imprint, age_rating, web_url, story_arc, is_black_and_white, metadata_notes, community_rating, alternate_info, scan_information, summary, chapter_metadata, library_type_name, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items
|
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, imported_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, manga_type, reading_direction, series_count, volume, imprint, age_rating, web_url, story_arc, is_black_and_white, metadata_notes, community_rating, alternate_info, scan_information, summary, chapter_metadata, library_type_name, tags_search, contributors_search, file_sha256, opf_identifier, opf_uuid, hash_confidence FROM media_items
|
||||||
WHERE library_id = $1 AND series = $2
|
WHERE series = $1
|
||||||
ORDER BY series_number ASC NULLS LAST
|
ORDER BY series_number ASC NULLS LAST
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetSeriesBooksParams struct {
|
func (q *Queries) GetSeriesBooks(ctx context.Context, series pgtype.Text) ([]MediaItems, error) {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
rows, err := q.db.Query(ctx, GetSeriesBooks, series)
|
||||||
Series pgtype.Text `db:"series" json:"series"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetSeriesBooks(ctx context.Context, arg GetSeriesBooksParams) ([]MediaItems, error) {
|
|
||||||
rows, err := q.db.Query(ctx, GetSeriesBooks, arg.LibraryID, arg.Series)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -5756,7 +5751,7 @@ func (q *Queries) GetSeriesBooks(ctx context.Context, arg GetSeriesBooksParams)
|
|||||||
const GetSeriesCovers = `-- name: GetSeriesCovers :many
|
const GetSeriesCovers = `-- name: GetSeriesCovers :many
|
||||||
SELECT cover_image_path, library_id
|
SELECT cover_image_path, library_id
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series = $2 AND cover_image_path IS NOT NULL AND cover_image_path != ''
|
WHERE ($1::uuid IS NULL OR library_id = $1::uuid) AND series = $2 AND cover_image_path IS NOT NULL AND cover_image_path != ''
|
||||||
ORDER BY series_number ASC NULLS LAST
|
ORDER BY series_number ASC NULLS LAST
|
||||||
LIMIT $3
|
LIMIT $3
|
||||||
`
|
`
|
||||||
@@ -5764,7 +5759,7 @@ LIMIT $3
|
|||||||
type GetSeriesCoversParams struct {
|
type GetSeriesCoversParams struct {
|
||||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||||
Series pgtype.Text `db:"series" json:"series"`
|
Series pgtype.Text `db:"series" json:"series"`
|
||||||
Limit int32 `db:"limit" json:"limit"`
|
Limit pgtype.Int4 `db:"limit" json:"limit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetSeriesCoversRow struct {
|
type GetSeriesCoversRow struct {
|
||||||
|
|||||||
@@ -1830,7 +1830,7 @@ LIMIT $1 OFFSET $2;
|
|||||||
-- Dashboard preferences queries
|
-- Dashboard preferences queries
|
||||||
-- name: GetDashboardPreferences :one
|
-- name: GetDashboardPreferences :one
|
||||||
SELECT * FROM user_dashboard_preferences
|
SELECT * FROM user_dashboard_preferences
|
||||||
WHERE user_id = $1 AND library_id = $2;
|
WHERE user_id = sqlc.narg('user_id') AND (sqlc.narg('library_id')::uuid IS NULL OR library_id = sqlc.narg('library_id')::uuid);
|
||||||
|
|
||||||
-- name: UpsertDashboardPreferences :one
|
-- name: UpsertDashboardPreferences :one
|
||||||
INSERT INTO user_dashboard_preferences (user_id, library_id, hidden_collections, collection_order, items_per_section)
|
INSERT INTO user_dashboard_preferences (user_id, library_id, hidden_collections, collection_order, items_per_section)
|
||||||
@@ -1894,57 +1894,57 @@ SELECT mi.* FROM media_items mi
|
|||||||
INNER JOIN (
|
INNER JOIN (
|
||||||
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
||||||
FROM reading_progress
|
FROM reading_progress
|
||||||
WHERE user_id = $2
|
WHERE user_id = sqlc.narg('user_id')
|
||||||
AND percentage > 0
|
AND percentage > 0
|
||||||
AND percentage < 1
|
AND percentage < 1
|
||||||
ORDER BY media_item_id, last_read_at DESC
|
ORDER BY media_item_id, last_read_at DESC
|
||||||
) rp ON rp.media_item_id = mi.id
|
) rp ON rp.media_item_id = mi.id
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
ORDER BY rp.last_read_at DESC
|
ORDER BY rp.last_read_at DESC
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetRecentlyAddedItems :many
|
-- name: GetRecentlyAddedItems :many
|
||||||
SELECT mi.* FROM media_items mi
|
SELECT mi.* FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
ORDER BY mi.imported_at DESC NULLS LAST, mi.created_at DESC
|
ORDER BY mi.imported_at DESC NULLS LAST, mi.created_at DESC
|
||||||
LIMIT $2;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetRecentlyReadItems :many
|
-- name: GetRecentlyReadItems :many
|
||||||
SELECT mi.* FROM media_items mi
|
SELECT mi.* FROM media_items mi
|
||||||
INNER JOIN (
|
INNER JOIN (
|
||||||
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
SELECT DISTINCT ON (media_item_id) media_item_id, last_read_at
|
||||||
FROM reading_progress
|
FROM reading_progress
|
||||||
WHERE user_id = $2
|
WHERE user_id = sqlc.narg('user_id')
|
||||||
AND percentage >= 1
|
AND percentage >= 1
|
||||||
ORDER BY media_item_id, last_read_at DESC
|
ORDER BY media_item_id, last_read_at DESC
|
||||||
) rp ON rp.media_item_id = mi.id
|
) rp ON rp.media_item_id = mi.id
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
ORDER BY rp.last_read_at DESC
|
ORDER BY rp.last_read_at DESC
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetNotStartedItems :many
|
-- name: GetNotStartedItems :many
|
||||||
SELECT mi.* FROM media_items mi
|
SELECT mi.* FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1 FROM reading_progress rp
|
SELECT 1 FROM reading_progress rp
|
||||||
WHERE rp.media_item_id = mi.id
|
WHERE rp.media_item_id = mi.id
|
||||||
AND rp.user_id = $2
|
AND rp.user_id = sqlc.narg('user_id')
|
||||||
AND rp.percentage > 0
|
AND rp.percentage > 0
|
||||||
)
|
)
|
||||||
ORDER BY mi.created_at DESC
|
ORDER BY mi.created_at DESC
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetCollectionItemsForDashboard :many
|
-- name: GetCollectionItemsForDashboard :many
|
||||||
SELECT mi.*, ci.excluded FROM media_items mi
|
SELECT mi.*, ci.excluded FROM media_items mi
|
||||||
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
|
INNER JOIN collection_items ci ON ci.media_item_id = mi.id
|
||||||
WHERE ci.collection_id = $1
|
WHERE ci.collection_id = sqlc.narg('collection_id')
|
||||||
AND mi.library_id = $2
|
AND (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
ORDER BY ci.added_at DESC
|
ORDER BY ci.added_at DESC
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetLibraryItems :many
|
-- name: GetLibraryItems :many
|
||||||
SELECT mi.* FROM media_items mi
|
SELECT mi.* FROM media_items mi
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
ORDER BY mi.created_at DESC;
|
ORDER BY mi.created_at DESC;
|
||||||
|
|
||||||
-- name: GetDistinctSeries :many
|
-- name: GetDistinctSeries :many
|
||||||
@@ -1952,26 +1952,26 @@ SELECT series, COUNT(*) as book_count,
|
|||||||
MAX(series_count) as total_in_series,
|
MAX(series_count) as total_in_series,
|
||||||
MAX(created_at) as last_entry_at
|
MAX(created_at) as last_entry_at
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series IS NOT NULL AND series != ''
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR library_id = sqlc.narg('library_id')::uuid) AND series IS NOT NULL AND series != ''
|
||||||
GROUP BY series
|
GROUP BY series
|
||||||
ORDER BY MAX(created_at) DESC
|
ORDER BY MAX(created_at) DESC
|
||||||
LIMIT $2 OFFSET $3;
|
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||||
|
|
||||||
-- name: GetDistinctSeriesCount :one
|
-- name: GetDistinctSeriesCount :one
|
||||||
SELECT COUNT(DISTINCT series)::int
|
SELECT COUNT(DISTINCT series)::int
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series IS NOT NULL AND series != '';
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR library_id = sqlc.narg('library_id')::uuid) AND series IS NOT NULL AND series != '';
|
||||||
|
|
||||||
-- name: GetSeriesCovers :many
|
-- name: GetSeriesCovers :many
|
||||||
SELECT cover_image_path, library_id
|
SELECT cover_image_path, library_id
|
||||||
FROM media_items
|
FROM media_items
|
||||||
WHERE library_id = $1 AND series = $2 AND cover_image_path IS NOT NULL AND cover_image_path != ''
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR library_id = sqlc.narg('library_id')::uuid) AND series = sqlc.narg('series') AND cover_image_path IS NOT NULL AND cover_image_path != ''
|
||||||
ORDER BY series_number ASC NULLS LAST
|
ORDER BY series_number ASC NULLS LAST
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetSeriesBooks :many
|
-- name: GetSeriesBooks :many
|
||||||
SELECT * FROM media_items
|
SELECT * FROM media_items
|
||||||
WHERE library_id = $1 AND series = $2
|
WHERE series = sqlc.narg('series')
|
||||||
ORDER BY series_number ASC NULLS LAST;
|
ORDER BY series_number ASC NULLS LAST;
|
||||||
|
|
||||||
-- name: GetContinueSeriesItems :many
|
-- name: GetContinueSeriesItems :many
|
||||||
@@ -1981,10 +1981,10 @@ WITH user_series_progress AS (
|
|||||||
MAX(rp.last_read_at) as last_read_at
|
MAX(rp.last_read_at) as last_read_at
|
||||||
FROM reading_progress rp
|
FROM reading_progress rp
|
||||||
JOIN media_items mi ON mi.id = rp.media_item_id
|
JOIN media_items mi ON mi.id = rp.media_item_id
|
||||||
WHERE rp.user_id = $2
|
WHERE rp.user_id = sqlc.narg('user_id')
|
||||||
AND rp.percentage > 0
|
AND rp.percentage > 0
|
||||||
AND mi.series IS NOT NULL AND mi.series != ''
|
AND mi.series IS NOT NULL AND mi.series != ''
|
||||||
AND mi.library_id = $1
|
AND (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
GROUP BY mi.series
|
GROUP BY mi.series
|
||||||
),
|
),
|
||||||
next_books AS (
|
next_books AS (
|
||||||
@@ -1992,13 +1992,13 @@ next_books AS (
|
|||||||
usp.last_read_at
|
usp.last_read_at
|
||||||
FROM media_items mi
|
FROM media_items mi
|
||||||
JOIN user_series_progress usp ON mi.series = usp.series
|
JOIN user_series_progress usp ON mi.series = usp.series
|
||||||
WHERE mi.library_id = $1
|
WHERE (sqlc.narg('library_id')::uuid IS NULL OR mi.library_id = sqlc.narg('library_id')::uuid)
|
||||||
AND (mi.series_number > usp.max_read_number OR usp.max_read_number IS NULL)
|
AND (mi.series_number > usp.max_read_number OR usp.max_read_number IS NULL)
|
||||||
ORDER BY mi.series, mi.series_number ASC NULLS LAST
|
ORDER BY mi.series, mi.series_number ASC NULLS LAST
|
||||||
)
|
)
|
||||||
SELECT * FROM next_books
|
SELECT * FROM next_books
|
||||||
ORDER BY last_read_at DESC NULLS LAST
|
ORDER BY last_read_at DESC NULLS LAST
|
||||||
LIMIT $3;
|
LIMIT sqlc.narg('limit');
|
||||||
|
|
||||||
-- name: GetSavedFilters :many
|
-- name: GetSavedFilters :many
|
||||||
SELECT * FROM saved_filters
|
SELECT * FROM saved_filters
|
||||||
|
|||||||
Reference in New Issue
Block a user