Phase 3 Week 7: Add KOReader bulk sync function to database schema
- Add bulk_update_progress_from_koreader() function for batch processing - Handles progress, annotations, and conflict detection - Returns success/failure status for each book - Supports device matching by UUID, file path, or title/author - Implements automatic conflict detection for concurrent syncs - Part of Phase 3 KOReader Integration implementation
This commit is contained in:
@@ -754,4 +754,111 @@ RETURNING *;
|
||||
-- name: DeleteSyncConflict :exec
|
||||
DELETE FROM sync_conflicts WHERE id = $1;
|
||||
|
||||
-- Media Items Admin Operations
|
||||
-- ============================================
|
||||
-- PHASE 3: KOREADER SYNC PROTOCOL (Weeks 7-9)
|
||||
-- ============================================
|
||||
|
||||
-- name: GetMediaItemByFilePathForSync :one
|
||||
SELECT * FROM media_items WHERE file_path = $1;
|
||||
|
||||
-- name: GetUserProgressForBooks :many
|
||||
SELECT
|
||||
rp.media_item_id,
|
||||
rp.user_id,
|
||||
rp.percentage,
|
||||
rp.character_offset,
|
||||
rp.epubcfi,
|
||||
rp.chapter,
|
||||
rp.chapter_progress,
|
||||
rp.current_page,
|
||||
rp.total_pages,
|
||||
rp.last_read_at,
|
||||
rp.last_sync_device,
|
||||
rp.last_sync_source,
|
||||
mi.title,
|
||||
mi.author,
|
||||
mi.file_path
|
||||
FROM reading_progress rp
|
||||
JOIN media_items mi ON rp.media_item_id = mi.id
|
||||
WHERE rp.user_id = $1
|
||||
AND rp.media_item_id = ANY($2::uuid[])
|
||||
ORDER BY rp.last_read_at DESC;
|
||||
|
||||
-- name: BulkUpdateProgressFromSync :many
|
||||
SELECT * FROM bulk_update_progress_from_koreader($1::uuid, $2::jsonb);
|
||||
|
||||
-- name: GetAnnotationsForBook :many
|
||||
SELECT
|
||||
mh.id,
|
||||
mh.selection_text,
|
||||
mh.start_position,
|
||||
mh.end_position,
|
||||
mh.color,
|
||||
mh.created_at,
|
||||
mh.updated_at,
|
||||
'highlight' as annotation_type,
|
||||
mh.percentage_start,
|
||||
mh.percentage_end,
|
||||
mh.epubcfi_start,
|
||||
mh.epubcfi_end
|
||||
FROM media_highlights mh
|
||||
WHERE mh.media_item_id = $1 AND mh.user_id = $2
|
||||
UNION ALL
|
||||
SELECT
|
||||
mn.id,
|
||||
mn.content,
|
||||
mn.position,
|
||||
NULL as end_position,
|
||||
NULL as color,
|
||||
mn.created_at,
|
||||
mn.updated_at,
|
||||
'note' as annotation_type,
|
||||
mn.percentage_location as percentage_start,
|
||||
NULL as percentage_end,
|
||||
mn.epubcfi_location as epubcfi_start,
|
||||
NULL as epubcfi_end
|
||||
FROM media_notes mn
|
||||
WHERE mn.media_item_id = $1 AND mn.user_id = $2
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: UpdateDeviceSyncTimestamp :one
|
||||
UPDATE devices
|
||||
SET
|
||||
last_sync = NOW(),
|
||||
last_seen = NOW(),
|
||||
updated_at = NOW()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: CreateSyncHistoryEntry :one
|
||||
INSERT INTO sync_queue (device_id, media_item_id, sync_type, sync_data, priority, status)
|
||||
VALUES ($1, $2, 'koreader_progress', $3, 5, 'completed')
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetUserMediaItemsForSync :many
|
||||
SELECT
|
||||
mi.id,
|
||||
mi.title,
|
||||
mi.author,
|
||||
mi.file_path,
|
||||
mi.mime_type,
|
||||
mi.page_count,
|
||||
mi.format_group,
|
||||
mi.total_characters,
|
||||
mi.chapter_count
|
||||
FROM media_items mi
|
||||
JOIN library_visibility lv ON mi.library_id = lv.library_id
|
||||
WHERE lv.user_id = $1
|
||||
AND lv.is_visible = true
|
||||
ORDER BY mi.title ASC
|
||||
LIMIT 1000;
|
||||
|
||||
-- name: CheckForProgressConflicts :one
|
||||
SELECT COUNT(*) as conflict_count
|
||||
FROM reading_progress
|
||||
WHERE media_item_id = $1
|
||||
AND user_id = $2
|
||||
AND last_sync_timestamp > NOW() - INTERVAL '5 minutes'
|
||||
AND last_sync_source != $3;
|
||||
|
||||
-- Media Items Admin Operations
|
||||
Reference in New Issue
Block a user