feat: add Kobo shelf and entitlement SQL queries
This commit is contained in:
@@ -11,14 +11,19 @@ import (
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
// ============================================
|
||||
// KOBO SHELF MANAGEMENT QUERIES (Phase 4)
|
||||
// ============================================
|
||||
AddBookToKoboShelf(ctx context.Context, arg AddBookToKoboShelfParams) (KoboShelves, error)
|
||||
// Library Folders queries
|
||||
AddLibraryFolder(ctx context.Context, arg AddLibraryFolderParams) (LibraryFolders, error)
|
||||
// Bulk update format group for all media items
|
||||
BulkUpdateFormatGroups(ctx context.Context) error
|
||||
BulkUpdateProgressFromSync(ctx context.Context, arg BulkUpdateProgressFromSyncParams) ([]interface{}, error)
|
||||
CheckForProgressConflicts(ctx context.Context, arg CheckForProgressConflictsParams) (int64, error)
|
||||
CleanupExpiredRefreshTokens(ctx context.Context) error
|
||||
ClearDeviceSyncQueue(ctx context.Context, deviceID pgtype.UUID) error
|
||||
ClearKoboShelf(ctx context.Context, deviceID pgtype.UUID) error
|
||||
ClearKoboShelfByName(ctx context.Context, arg ClearKoboShelfByNameParams) error
|
||||
// ============================================
|
||||
// PHASE 2: DEVICE MANAGEMENT & AUTH (Weeks 5-6)
|
||||
// ============================================
|
||||
@@ -35,6 +40,10 @@ type Querier interface {
|
||||
// Media Notes queries
|
||||
CreateMediaNote(ctx context.Context, arg CreateMediaNoteParams) (MediaNotes, error)
|
||||
CreateMediaRating(ctx context.Context, arg CreateMediaRatingParams) (MediaRatings, error)
|
||||
// ============================================
|
||||
// KOBO ENTITLEMENT QUERIES (Phase 4)
|
||||
// ============================================
|
||||
CreateOrUpdateKoboEntitlement(ctx context.Context, arg CreateOrUpdateKoboEntitlementParams) (KoboEntitlements, error)
|
||||
// Create reading history entry
|
||||
CreateReadingHistory(ctx context.Context, arg CreateReadingHistoryParams) (ReadingHistory, error)
|
||||
// Refresh Tokens queries
|
||||
@@ -48,6 +57,7 @@ type Querier interface {
|
||||
DeleteDevice(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteDeviceByToken(ctx context.Context, authToken string) error
|
||||
DeleteEbookNote(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteKoboEntitlement(ctx context.Context, arg DeleteKoboEntitlementParams) error
|
||||
DeleteLibrary(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteLibraryFolder(ctx context.Context, arg DeleteLibraryFolderParams) (LibraryFolders, error)
|
||||
DeleteMediaHighlight(ctx context.Context, id pgtype.UUID) error
|
||||
@@ -58,10 +68,17 @@ type Querier interface {
|
||||
DeleteSyncConflict(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteSyncQueueItem(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteUser(ctx context.Context, id pgtype.UUID) error
|
||||
GenerateKoboEntitlementId(ctx context.Context) (interface{}, error)
|
||||
GetAnnotationsForBook(ctx context.Context, arg GetAnnotationsForBookParams) ([]GetAnnotationsForBookRow, error)
|
||||
GetDevice(ctx context.Context, id pgtype.UUID) (Devices, error)
|
||||
GetDeviceByAuthToken(ctx context.Context, authToken string) (Devices, error)
|
||||
GetDeviceByIdentifier(ctx context.Context, deviceIdentifier string) (Devices, error)
|
||||
GetKoboEntitlementByContentId(ctx context.Context, arg GetKoboEntitlementByContentIdParams) (GetKoboEntitlementByContentIdRow, error)
|
||||
GetKoboEntitlementByEntitlementId(ctx context.Context, arg GetKoboEntitlementByEntitlementIdParams) (GetKoboEntitlementByEntitlementIdRow, error)
|
||||
GetKoboEntitlementsForDevice(ctx context.Context, deviceID pgtype.UUID) ([]GetKoboEntitlementsForDeviceRow, error)
|
||||
GetKoboShelfBookCount(ctx context.Context, deviceID pgtype.UUID) (int64, error)
|
||||
GetKoboShelfBooks(ctx context.Context, deviceID pgtype.UUID) ([]GetKoboShelfBooksRow, error)
|
||||
GetKoboShelfBooksByShelfName(ctx context.Context, arg GetKoboShelfBooksByShelfNameParams) ([]GetKoboShelfBooksByShelfNameRow, error)
|
||||
GetLibrary(ctx context.Context, id pgtype.UUID) (GetLibraryRow, error)
|
||||
GetLibraryByFolder(ctx context.Context, folderPath string) (GetLibraryByFolderRow, error)
|
||||
GetLibraryFolders(ctx context.Context, libraryID pgtype.UUID) ([]LibraryFolders, error)
|
||||
@@ -78,6 +95,7 @@ type Querier interface {
|
||||
// PHASE 3: KOREADER SYNC PROTOCOL (Weeks 7-9)
|
||||
// ============================================
|
||||
GetMediaItemByFilePathForSync(ctx context.Context, filePath string) (MediaItems, error)
|
||||
GetMediaItemByKoboContentId(ctx context.Context, koboContentID pgtype.Text) (MediaItems, error)
|
||||
GetMediaNote(ctx context.Context, id pgtype.UUID) (MediaNotes, error)
|
||||
GetMediaNotes(ctx context.Context, arg GetMediaNotesParams) ([]MediaNotes, error)
|
||||
GetMediaRating(ctx context.Context, arg GetMediaRatingParams) (MediaRatings, error)
|
||||
@@ -100,6 +118,7 @@ type Querier interface {
|
||||
GetUserPasswordHash(ctx context.Context, id pgtype.UUID) (string, error)
|
||||
GetUserProgressForBooks(ctx context.Context, arg GetUserProgressForBooksParams) ([]GetUserProgressForBooksRow, error)
|
||||
GetUserVisibleLibraries(ctx context.Context, userID pgtype.UUID) ([]GetUserVisibleLibrariesRow, error)
|
||||
IsBookOnKoboShelf(ctx context.Context, arg IsBookOnKoboShelfParams) (bool, error)
|
||||
ListDevicesByType(ctx context.Context, deviceType string) ([]Devices, error)
|
||||
ListDevicesByUser(ctx context.Context, userID pgtype.UUID) ([]Devices, error)
|
||||
ListLibraries(ctx context.Context) ([]ListLibrariesRow, error)
|
||||
@@ -111,6 +130,7 @@ type Querier interface {
|
||||
ListSyncConflictsByMediaItem(ctx context.Context, arg ListSyncConflictsByMediaItemParams) ([]SyncConflicts, error)
|
||||
ListSyncConflictsByUser(ctx context.Context, userID pgtype.UUID) ([]ListSyncConflictsByUserRow, error)
|
||||
ListUsers(ctx context.Context) ([]ListUsersRow, error)
|
||||
RemoveBookFromKoboShelf(ctx context.Context, arg RemoveBookFromKoboShelfParams) error
|
||||
ResolveSyncConflict(ctx context.Context, arg ResolveSyncConflictParams) (SyncConflicts, error)
|
||||
RevokeAllUserRefreshTokens(ctx context.Context, userID pgtype.UUID) error
|
||||
RevokeDevice(ctx context.Context, id pgtype.UUID) error
|
||||
@@ -128,6 +148,9 @@ type Querier interface {
|
||||
UpdateDeviceSyncTimestamp(ctx context.Context, id pgtype.UUID) (Devices, error)
|
||||
UpdateEbookNote(ctx context.Context, arg UpdateEbookNoteParams) (MediaNotes, error)
|
||||
UpdateEmail(ctx context.Context, arg UpdateEmailParams) error
|
||||
UpdateKoboEntitlementRevision(ctx context.Context, arg UpdateKoboEntitlementRevisionParams) error
|
||||
UpdateKoboEntitlementStatus(ctx context.Context, arg UpdateKoboEntitlementStatusParams) error
|
||||
UpdateKoboShelfBookPosition(ctx context.Context, arg UpdateKoboShelfBookPositionParams) error
|
||||
UpdateLibrary(ctx context.Context, arg UpdateLibraryParams) (Libraries, error)
|
||||
UpdateMediaHighlight(ctx context.Context, arg UpdateMediaHighlightParams) (MediaHighlights, error)
|
||||
UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams) (MediaItems, error)
|
||||
@@ -136,6 +159,7 @@ type Querier interface {
|
||||
// ============================================
|
||||
// Update media item format group information
|
||||
UpdateMediaItemFormatGroup(ctx context.Context, arg UpdateMediaItemFormatGroupParams) error
|
||||
UpdateMediaItemKoboMetadata(ctx context.Context, arg UpdateMediaItemKoboMetadataParams) (MediaItems, error)
|
||||
UpdateMediaNote(ctx context.Context, arg UpdateMediaNoteParams) (MediaNotes, error)
|
||||
UpdateMediaRating(ctx context.Context, arg UpdateMediaRatingParams) (MediaRatings, error)
|
||||
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -845,15 +845,18 @@ SELECT
|
||||
mi.page_count,
|
||||
mi.format_group,
|
||||
mi.total_characters,
|
||||
mi.chapter_count
|
||||
mi.chapter_count,
|
||||
mi.entitlement_id,
|
||||
mi.revision_number,
|
||||
mi.file_size
|
||||
FROM media_items mi
|
||||
JOIN library_visibility lv ON mi.library_id = lv.library_id
|
||||
WHERE lv.user_id = $1
|
||||
WHERE lv.user_id = $1
|
||||
AND lv.is_visible = true
|
||||
ORDER BY mi.title ASC
|
||||
LIMIT 1000;
|
||||
ORDER BY mi.title ASC
|
||||
LIMIT 1000;
|
||||
|
||||
-- name: CheckForProgressConflicts :one
|
||||
-- name: CheckForProgressConflicts :one
|
||||
SELECT COUNT(*) as conflict_count
|
||||
FROM reading_progress
|
||||
WHERE media_item_id = $1
|
||||
@@ -861,4 +864,123 @@ WHERE media_item_id = $1
|
||||
AND last_sync_timestamp > NOW() - INTERVAL '5 minutes'
|
||||
AND last_sync_source != $3;
|
||||
|
||||
-- Media Items Admin Operations
|
||||
-- ============================================
|
||||
-- KOBO SHELF MANAGEMENT QUERIES (Phase 4)
|
||||
-- ============================================
|
||||
|
||||
-- name: AddBookToKoboShelf :one
|
||||
INSERT INTO kobo_shelves (device_id, media_item_id, shelf_name, shelf_position)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (device_id, media_item_id)
|
||||
DO UPDATE SET
|
||||
shelf_name = EXCLUDED.shelf_name,
|
||||
shelf_position = EXCLUDED.shelf_position,
|
||||
last_synced_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: RemoveBookFromKoboShelf :exec
|
||||
DELETE FROM kobo_shelves WHERE device_id = $1 AND media_item_id = $2;
|
||||
|
||||
-- name: GetKoboShelfBooks :many
|
||||
SELECT ks.*, mi.title, mi.author, mi.file_path, mi.mime_type, mi.entitlement_id, mi.kobo_content_id, mi.revision_number
|
||||
FROM kobo_shelves ks
|
||||
JOIN media_items mi ON ks.media_item_id = mi.id
|
||||
WHERE ks.device_id = $1
|
||||
ORDER BY ks.shelf_position ASC, ks.added_at ASC;
|
||||
|
||||
-- name: GetKoboShelfBooksByShelfName :many
|
||||
SELECT ks.*, mi.title, mi.author, mi.file_path, mi.mime_type, mi.entitlement_id, mi.kobo_content_id, mi.revision_number
|
||||
FROM kobo_shelves ks
|
||||
JOIN media_items mi ON ks.media_item_id = mi.id
|
||||
WHERE ks.device_id = $1 AND ks.shelf_name = $2
|
||||
ORDER BY ks.shelf_position ASC, ks.added_at ASC;
|
||||
|
||||
-- name: UpdateKoboShelfBookPosition :exec
|
||||
UPDATE kobo_shelves
|
||||
SET shelf_position = $3, last_synced_at = NOW()
|
||||
WHERE device_id = $1 AND media_item_id = $2;
|
||||
|
||||
-- name: ClearKoboShelf :exec
|
||||
DELETE FROM kobo_shelves WHERE device_id = $1;
|
||||
|
||||
-- name: ClearKoboShelfByName :exec
|
||||
DELETE FROM kobo_shelves WHERE device_id = $1 AND shelf_name = $2;
|
||||
|
||||
-- name: IsBookOnKoboShelf :one
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM kobo_shelves
|
||||
WHERE device_id = $1 AND media_item_id = $2
|
||||
) as on_shelf;
|
||||
|
||||
-- name: GetKoboShelfBookCount :one
|
||||
SELECT COUNT(*) as book_count
|
||||
FROM kobo_shelves
|
||||
WHERE device_id = $1;
|
||||
|
||||
-- ============================================
|
||||
-- KOBO ENTITLEMENT QUERIES (Phase 4)
|
||||
-- ============================================
|
||||
|
||||
-- name: CreateOrUpdateKoboEntitlement :one
|
||||
INSERT INTO kobo_entitlements (device_id, media_item_id, entitlement_id, content_id, revision_number, purchase_date, kobo_metadata)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
ON CONFLICT (device_id, entitlement_id)
|
||||
DO UPDATE SET
|
||||
content_id = EXCLUDED.content_id,
|
||||
revision_number = EXCLUDED.revision_number,
|
||||
purchase_date = COALESCE(EXCLUDED.purchase_date, kobo_entitlements.purchase_date),
|
||||
book_status = 'installed',
|
||||
sync_status = 'synced',
|
||||
kobo_metadata = EXCLUDED.kobo_metadata,
|
||||
updated_at = NOW()
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetKoboEntitlementsForDevice :many
|
||||
SELECT ke.*, mi.title, mi.author, mi.file_path
|
||||
FROM kobo_entitlements ke
|
||||
JOIN media_items mi ON ke.media_item_id = mi.id
|
||||
WHERE ke.device_id = $1
|
||||
ORDER BY ke.accession_date DESC;
|
||||
|
||||
-- name: GetKoboEntitlementByContentId :one
|
||||
SELECT ke.*, mi.title, mi.author, mi.file_path
|
||||
FROM kobo_entitlements ke
|
||||
JOIN media_items mi ON ke.media_item_id = mi.id
|
||||
WHERE ke.device_id = $1 AND ke.content_id = $2;
|
||||
|
||||
-- name: GetKoboEntitlementByEntitlementId :one
|
||||
SELECT ke.*, mi.title, mi.author, mi.file_path
|
||||
FROM kobo_entitlements ke
|
||||
JOIN media_items mi ON ke.media_item_id = mi.id
|
||||
WHERE ke.device_id = $1 AND ke.entitlement_id = $2;
|
||||
|
||||
-- name: UpdateKoboEntitlementStatus :exec
|
||||
UPDATE kobo_entitlements
|
||||
SET book_status = $3, sync_status = 'synced', updated_at = NOW()
|
||||
WHERE device_id = $1 AND entitlement_id = $2;
|
||||
|
||||
-- name: UpdateKoboEntitlementRevision :exec
|
||||
UPDATE kobo_entitlements
|
||||
SET revision_number = $3, updated_at = NOW()
|
||||
WHERE device_id = $1 AND entitlement_id = $2;
|
||||
|
||||
-- name: DeleteKoboEntitlement :exec
|
||||
DELETE FROM kobo_entitlements WHERE device_id = $1 AND entitlement_id = $2;
|
||||
|
||||
-- name: GenerateKoboEntitlementId :one
|
||||
SELECT 'kobo_' || uuid_generate_v4()::TEXT as entitlement_id;
|
||||
|
||||
-- name: UpdateMediaItemKoboMetadata :one
|
||||
UPDATE media_items
|
||||
SET entitlement_id = $2,
|
||||
kobo_content_id = $3,
|
||||
revision_number = COALESCE($4, revision_number) + 1,
|
||||
kobo_metadata = $5,
|
||||
updated_at = NOW()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetMediaItemByKoboContentId :one
|
||||
SELECT * FROM media_items WHERE kobo_content_id = $1;
|
||||
|
||||
-- Media Items Admin Operations
|
||||
Reference in New Issue
Block a user