refactor(db): GetCollectionItemsForDashboard embeds the media row; excluded filter moves into SQL; third converter dies
SELECT mi.*, ci.excluded forced every caller to filter tombstone exclusions in Go over a 69-field row, then a 45-field hand converter (getCollectionItemsRowToMediaItems) copied it field-by-field into MediaItems for BuildSections. The query now filters (ci.excluded IS NOT TRUE) itself and returns sqlc.embed(mi) — callers consume .MediaItems directly, the Go filter loops die in both collection-detail ladders (JSON + SSR), and the converter is deleted. Pins, H1/H3 tests, unit suites green.
This commit is contained in:
1 parent
18727fef93
commit
77cf0b827b
7 files changed
+102
-218
No files matched your search
@@ -2,7 +2,6 @@ package services
|
||||
|
||||
import (
|
||||
"bookhoard/internal/database"
|
||||
"bookhoard/internal/utils"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -13,55 +12,6 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func getCollectionItemsRowToMediaItems(item database.GetCollectionItemsForDashboardRow) database.MediaItems {
|
||||
return database.MediaItems{
|
||||
ID: item.ID,
|
||||
LibraryID: item.LibraryID,
|
||||
Title: item.Title,
|
||||
Author: item.Author,
|
||||
Isbn: item.Isbn,
|
||||
Description: item.Description,
|
||||
FilePath: utils.ResolveMediaURL(item.LibraryID, pgtype.Text{String: item.FilePath, Valid: true}),
|
||||
FileSize: item.FileSize,
|
||||
MimeType: item.MimeType,
|
||||
CoverImagePath: pgtype.Text{String: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath), Valid: true},
|
||||
Series: item.Series,
|
||||
SeriesNumber: item.SeriesNumber,
|
||||
Tags: item.Tags,
|
||||
Asin: item.Asin,
|
||||
DatePublished: item.DatePublished,
|
||||
Publisher: item.Publisher,
|
||||
Contributors: item.Contributors,
|
||||
Language: item.Language,
|
||||
Edition: item.Edition,
|
||||
PageCount: item.PageCount,
|
||||
Genre: item.Genre,
|
||||
CopyrightYear: item.CopyrightYear,
|
||||
GoodreadsID: item.GoodreadsID,
|
||||
OpenlibraryID: item.OpenlibraryID,
|
||||
GoogleBooksID: item.GoogleBooksID,
|
||||
AddedByAdminID: item.AddedByAdminID,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
FormatGroup: item.FormatGroup,
|
||||
FormatMimetype: item.FormatMimetype,
|
||||
IsReflowable: item.IsReflowable,
|
||||
HasFixedLayout: item.HasFixedLayout,
|
||||
TotalCharacters: item.TotalCharacters,
|
||||
ChapterCount: item.ChapterCount,
|
||||
EntitlementID: item.EntitlementID,
|
||||
RevisionNumber: item.RevisionNumber,
|
||||
KoboContentID: item.KoboContentID,
|
||||
KoboMetadata: item.KoboMetadata,
|
||||
TagsSearch: item.TagsSearch,
|
||||
ContributorsSearch: item.ContributorsSearch,
|
||||
FileSha256: item.FileSha256,
|
||||
OpfIdentifier: item.OpfIdentifier,
|
||||
OpfUuid: item.OpfUuid,
|
||||
HashConfidence: item.HashConfidence,
|
||||
}
|
||||
}
|
||||
|
||||
type DashboardService struct {
|
||||
db *database.Queries
|
||||
collectionService *CollectionService
|
||||
@@ -277,11 +227,11 @@ func (s *DashboardService) getUserCollectionItems(ctx context.Context, coll data
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The query filters excluded rows in SQL and embeds the media row,
|
||||
// so the items are MediaItems as-is.
|
||||
var manualNonExcluded []database.MediaItems
|
||||
for _, item := range manualItems {
|
||||
if !item.Excluded.Valid || !item.Excluded.Bool {
|
||||
manualNonExcluded = append(manualNonExcluded, getCollectionItemsRowToMediaItems(item))
|
||||
}
|
||||
for _, row := range manualItems {
|
||||
manualNonExcluded = append(manualNonExcluded, row.MediaItems)
|
||||
}
|
||||
|
||||
var autoItems []database.MediaItems
|
||||
|
||||
Reference in new issue
Block a user