feat: add Kobo shelf and entitlement SQL queries
This commit is contained in:
@@ -11,14 +11,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Querier interface {
|
type Querier interface {
|
||||||
|
// ============================================
|
||||||
|
// KOBO SHELF MANAGEMENT QUERIES (Phase 4)
|
||||||
|
// ============================================
|
||||||
|
AddBookToKoboShelf(ctx context.Context, arg AddBookToKoboShelfParams) (KoboShelves, error)
|
||||||
// Library Folders queries
|
// Library Folders queries
|
||||||
AddLibraryFolder(ctx context.Context, arg AddLibraryFolderParams) (LibraryFolders, error)
|
AddLibraryFolder(ctx context.Context, arg AddLibraryFolderParams) (LibraryFolders, error)
|
||||||
// Bulk update format group for all media items
|
// Bulk update format group for all media items
|
||||||
BulkUpdateFormatGroups(ctx context.Context) error
|
BulkUpdateFormatGroups(ctx context.Context) error
|
||||||
BulkUpdateProgressFromSync(ctx context.Context, arg BulkUpdateProgressFromSyncParams) ([]interface{}, error)
|
BulkUpdateProgressFromSync(ctx context.Context, arg BulkUpdateProgressFromSyncParams) ([]interface{}, error)
|
||||||
CheckForProgressConflicts(ctx context.Context, arg CheckForProgressConflictsParams) (int64, error)
|
|
||||||
CleanupExpiredRefreshTokens(ctx context.Context) error
|
CleanupExpiredRefreshTokens(ctx context.Context) error
|
||||||
ClearDeviceSyncQueue(ctx context.Context, deviceID pgtype.UUID) 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)
|
// PHASE 2: DEVICE MANAGEMENT & AUTH (Weeks 5-6)
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -35,6 +40,10 @@ type Querier interface {
|
|||||||
// Media Notes queries
|
// Media Notes queries
|
||||||
CreateMediaNote(ctx context.Context, arg CreateMediaNoteParams) (MediaNotes, error)
|
CreateMediaNote(ctx context.Context, arg CreateMediaNoteParams) (MediaNotes, error)
|
||||||
CreateMediaRating(ctx context.Context, arg CreateMediaRatingParams) (MediaRatings, 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
|
// Create reading history entry
|
||||||
CreateReadingHistory(ctx context.Context, arg CreateReadingHistoryParams) (ReadingHistory, error)
|
CreateReadingHistory(ctx context.Context, arg CreateReadingHistoryParams) (ReadingHistory, error)
|
||||||
// Refresh Tokens queries
|
// Refresh Tokens queries
|
||||||
@@ -48,6 +57,7 @@ type Querier interface {
|
|||||||
DeleteDevice(ctx context.Context, id pgtype.UUID) error
|
DeleteDevice(ctx context.Context, id pgtype.UUID) error
|
||||||
DeleteDeviceByToken(ctx context.Context, authToken string) error
|
DeleteDeviceByToken(ctx context.Context, authToken string) error
|
||||||
DeleteEbookNote(ctx context.Context, id pgtype.UUID) error
|
DeleteEbookNote(ctx context.Context, id pgtype.UUID) error
|
||||||
|
DeleteKoboEntitlement(ctx context.Context, arg DeleteKoboEntitlementParams) error
|
||||||
DeleteLibrary(ctx context.Context, id pgtype.UUID) error
|
DeleteLibrary(ctx context.Context, id pgtype.UUID) error
|
||||||
DeleteLibraryFolder(ctx context.Context, arg DeleteLibraryFolderParams) (LibraryFolders, error)
|
DeleteLibraryFolder(ctx context.Context, arg DeleteLibraryFolderParams) (LibraryFolders, error)
|
||||||
DeleteMediaHighlight(ctx context.Context, id pgtype.UUID) error
|
DeleteMediaHighlight(ctx context.Context, id pgtype.UUID) error
|
||||||
@@ -58,10 +68,17 @@ type Querier interface {
|
|||||||
DeleteSyncConflict(ctx context.Context, id pgtype.UUID) error
|
DeleteSyncConflict(ctx context.Context, id pgtype.UUID) error
|
||||||
DeleteSyncQueueItem(ctx context.Context, id pgtype.UUID) error
|
DeleteSyncQueueItem(ctx context.Context, id pgtype.UUID) error
|
||||||
DeleteUser(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)
|
GetAnnotationsForBook(ctx context.Context, arg GetAnnotationsForBookParams) ([]GetAnnotationsForBookRow, error)
|
||||||
GetDevice(ctx context.Context, id pgtype.UUID) (Devices, error)
|
GetDevice(ctx context.Context, id pgtype.UUID) (Devices, error)
|
||||||
GetDeviceByAuthToken(ctx context.Context, authToken string) (Devices, error)
|
GetDeviceByAuthToken(ctx context.Context, authToken string) (Devices, error)
|
||||||
GetDeviceByIdentifier(ctx context.Context, deviceIdentifier 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)
|
GetLibrary(ctx context.Context, id pgtype.UUID) (GetLibraryRow, error)
|
||||||
GetLibraryByFolder(ctx context.Context, folderPath string) (GetLibraryByFolderRow, error)
|
GetLibraryByFolder(ctx context.Context, folderPath string) (GetLibraryByFolderRow, error)
|
||||||
GetLibraryFolders(ctx context.Context, libraryID pgtype.UUID) ([]LibraryFolders, 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)
|
// PHASE 3: KOREADER SYNC PROTOCOL (Weeks 7-9)
|
||||||
// ============================================
|
// ============================================
|
||||||
GetMediaItemByFilePathForSync(ctx context.Context, filePath string) (MediaItems, error)
|
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)
|
GetMediaNote(ctx context.Context, id pgtype.UUID) (MediaNotes, error)
|
||||||
GetMediaNotes(ctx context.Context, arg GetMediaNotesParams) ([]MediaNotes, error)
|
GetMediaNotes(ctx context.Context, arg GetMediaNotesParams) ([]MediaNotes, error)
|
||||||
GetMediaRating(ctx context.Context, arg GetMediaRatingParams) (MediaRatings, 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)
|
GetUserPasswordHash(ctx context.Context, id pgtype.UUID) (string, error)
|
||||||
GetUserProgressForBooks(ctx context.Context, arg GetUserProgressForBooksParams) ([]GetUserProgressForBooksRow, error)
|
GetUserProgressForBooks(ctx context.Context, arg GetUserProgressForBooksParams) ([]GetUserProgressForBooksRow, error)
|
||||||
GetUserVisibleLibraries(ctx context.Context, userID pgtype.UUID) ([]GetUserVisibleLibrariesRow, 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)
|
ListDevicesByType(ctx context.Context, deviceType string) ([]Devices, error)
|
||||||
ListDevicesByUser(ctx context.Context, userID pgtype.UUID) ([]Devices, error)
|
ListDevicesByUser(ctx context.Context, userID pgtype.UUID) ([]Devices, error)
|
||||||
ListLibraries(ctx context.Context) ([]ListLibrariesRow, error)
|
ListLibraries(ctx context.Context) ([]ListLibrariesRow, error)
|
||||||
@@ -111,6 +130,7 @@ type Querier interface {
|
|||||||
ListSyncConflictsByMediaItem(ctx context.Context, arg ListSyncConflictsByMediaItemParams) ([]SyncConflicts, error)
|
ListSyncConflictsByMediaItem(ctx context.Context, arg ListSyncConflictsByMediaItemParams) ([]SyncConflicts, error)
|
||||||
ListSyncConflictsByUser(ctx context.Context, userID pgtype.UUID) ([]ListSyncConflictsByUserRow, error)
|
ListSyncConflictsByUser(ctx context.Context, userID pgtype.UUID) ([]ListSyncConflictsByUserRow, error)
|
||||||
ListUsers(ctx context.Context) ([]ListUsersRow, error)
|
ListUsers(ctx context.Context) ([]ListUsersRow, error)
|
||||||
|
RemoveBookFromKoboShelf(ctx context.Context, arg RemoveBookFromKoboShelfParams) error
|
||||||
ResolveSyncConflict(ctx context.Context, arg ResolveSyncConflictParams) (SyncConflicts, error)
|
ResolveSyncConflict(ctx context.Context, arg ResolveSyncConflictParams) (SyncConflicts, error)
|
||||||
RevokeAllUserRefreshTokens(ctx context.Context, userID pgtype.UUID) error
|
RevokeAllUserRefreshTokens(ctx context.Context, userID pgtype.UUID) error
|
||||||
RevokeDevice(ctx context.Context, id 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)
|
UpdateDeviceSyncTimestamp(ctx context.Context, id pgtype.UUID) (Devices, error)
|
||||||
UpdateEbookNote(ctx context.Context, arg UpdateEbookNoteParams) (MediaNotes, error)
|
UpdateEbookNote(ctx context.Context, arg UpdateEbookNoteParams) (MediaNotes, error)
|
||||||
UpdateEmail(ctx context.Context, arg UpdateEmailParams) 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)
|
UpdateLibrary(ctx context.Context, arg UpdateLibraryParams) (Libraries, error)
|
||||||
UpdateMediaHighlight(ctx context.Context, arg UpdateMediaHighlightParams) (MediaHighlights, error)
|
UpdateMediaHighlight(ctx context.Context, arg UpdateMediaHighlightParams) (MediaHighlights, error)
|
||||||
UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams) (MediaItems, error)
|
UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams) (MediaItems, error)
|
||||||
@@ -136,6 +159,7 @@ type Querier interface {
|
|||||||
// ============================================
|
// ============================================
|
||||||
// Update media item format group information
|
// Update media item format group information
|
||||||
UpdateMediaItemFormatGroup(ctx context.Context, arg UpdateMediaItemFormatGroupParams) error
|
UpdateMediaItemFormatGroup(ctx context.Context, arg UpdateMediaItemFormatGroupParams) error
|
||||||
|
UpdateMediaItemKoboMetadata(ctx context.Context, arg UpdateMediaItemKoboMetadataParams) (MediaItems, error)
|
||||||
UpdateMediaNote(ctx context.Context, arg UpdateMediaNoteParams) (MediaNotes, error)
|
UpdateMediaNote(ctx context.Context, arg UpdateMediaNoteParams) (MediaNotes, error)
|
||||||
UpdateMediaRating(ctx context.Context, arg UpdateMediaRatingParams) (MediaRatings, error)
|
UpdateMediaRating(ctx context.Context, arg UpdateMediaRatingParams) (MediaRatings, error)
|
||||||
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) 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.page_count,
|
||||||
mi.format_group,
|
mi.format_group,
|
||||||
mi.total_characters,
|
mi.total_characters,
|
||||||
mi.chapter_count
|
mi.chapter_count,
|
||||||
|
mi.entitlement_id,
|
||||||
|
mi.revision_number,
|
||||||
|
mi.file_size
|
||||||
FROM media_items mi
|
FROM media_items mi
|
||||||
JOIN library_visibility lv ON mi.library_id = lv.library_id
|
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
|
AND lv.is_visible = true
|
||||||
ORDER BY mi.title ASC
|
ORDER BY mi.title ASC
|
||||||
LIMIT 1000;
|
LIMIT 1000;
|
||||||
|
|
||||||
-- name: CheckForProgressConflicts :one
|
-- name: CheckForProgressConflicts :one
|
||||||
SELECT COUNT(*) as conflict_count
|
SELECT COUNT(*) as conflict_count
|
||||||
FROM reading_progress
|
FROM reading_progress
|
||||||
WHERE media_item_id = $1
|
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_timestamp > NOW() - INTERVAL '5 minutes'
|
||||||
AND last_sync_source != $3;
|
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