-- name: CreateUser :one INSERT INTO users (email, username, password_hash, first_name, last_name, theme, role) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id, email, username, theme, first_name, last_name, role, created_at, updated_at; -- name: GetUserByEmail :one SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1; -- name: GetUserByUsername :one SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE username = $1; -- name: GetUserByEmailOrUsername :one SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1; -- name: GetUserForLogin :one SELECT id, email, username, password_hash, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE email = $1 OR username = $1; -- name: GetUser :one SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users WHERE id = $1; -- name: GetUserPasswordHash :one SELECT password_hash FROM users WHERE id = $1; -- name: ListUsers :many SELECT id, email, username, theme, first_name, last_name, role, created_at, updated_at FROM users ORDER BY created_at DESC; -- Library Types queries -- name: GetLibraryTypes :many SELECT * FROM library_types ORDER BY name; -- name: GetLibraryType :one SELECT * FROM library_types WHERE id = $1; -- name: GetLibraryTypeByName :one SELECT * FROM library_types WHERE name = $1; -- Libraries queries -- name: CreateLibrary :one INSERT INTO libraries (name, description, library_type_id, created_by_admin_id) VALUES ($1, $2, $3, $4) RETURNING *; -- name: GetLibrary :one SELECT l.*, lt.name as type_name, lt.description as type_description FROM libraries l JOIN library_types lt ON l.library_type_id = lt.id WHERE l.id = $1; -- name: ListLibraries :many SELECT l.*, lt.name as type_name, lt.description as type_description FROM libraries l JOIN library_types lt ON l.library_type_id = lt.id ORDER BY l.created_at DESC; -- name: UpdateLibrary :one UPDATE libraries SET name = $2, description = $3, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteLibrary :exec DELETE FROM libraries WHERE id = $1; -- Library Folders queries -- name: AddLibraryFolder :one INSERT INTO library_folders (library_id, folder_path) VALUES ($1, $2) RETURNING *; -- name: GetLibraryFolders :many SELECT * FROM library_folders WHERE library_id = $1 ORDER BY created_at; -- name: DeleteLibraryFolder :one DELETE FROM library_folders WHERE library_id = $1 AND folder_path = $2 RETURNING *; -- Library Visibility queries -- name: SetLibraryVisibility :one INSERT INTO library_visibility (user_id, library_id, is_visible) VALUES ($1, $2, $3) ON CONFLICT (user_id, library_id) DO UPDATE SET is_visible = EXCLUDED.is_visible, updated_at = NOW() RETURNING *; -- name: GetLibraryVisibility :one SELECT * FROM library_visibility WHERE user_id = $1 AND library_id = $2; -- name: GetUserVisibleLibraries :many SELECT l.*, lt.name as type_name, lt.description as type_description, COALESCE(lv.is_visible, true) as is_visible FROM libraries l JOIN library_types lt ON l.library_type_id = lt.id LEFT JOIN library_visibility lv ON l.id = lv.library_id AND lv.user_id = $1 WHERE COALESCE(lv.is_visible, true) = true ORDER BY l.created_at DESC; -- Media Items queries -- name: CreateMediaItem :one INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING *; -- name: GetMediaItem :one SELECT * FROM media_items WHERE id = $1; -- name: ListMediaItems :many SELECT mi.*, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id ORDER BY mi.created_at DESC LIMIT $1 OFFSET $2; -- name: ListMediaItemsByLibrary :many SELECT mi.*, l.name as library_name, lt.name as library_type_name FROM media_items mi JOIN libraries l ON mi.library_id = l.id JOIN library_types lt ON l.library_type_id = lt.id WHERE mi.library_id = $1 ORDER BY mi.created_at DESC; -- name: UpdateMediaItem :one UPDATE media_items SET title = $2, author = $3, isbn = $4, description = $5, cover_image_path = $6, series = $7, series_number = $8, tags = $9, asin = $10, date_published = $11, publisher = $12, contributors = $13, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteMediaItem :exec DELETE FROM media_items WHERE id = $1; -- name: GetMediaItemByFilePath :one SELECT * FROM media_items WHERE file_path = $1; -- Backward compatibility - Ebooks queries (using views) -- name: GetEbook :one SELECT * FROM ebooks WHERE id = $1; -- name: ListEbooks :many SELECT * FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2; -- name: CreateEbook :one INSERT INTO media_items (library_id, title, author, isbn, description, file_path, file_size, mime_type, cover_image_path, series, series_number, tags, asin, date_published, publisher, contributors, added_by_admin_id) VALUES ((SELECT id FROM libraries WHERE library_type_id = (SELECT id FROM library_types WHERE name = 'ebooks') LIMIT 1), $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) RETURNING *; -- name: UpdateEbook :one UPDATE media_items SET title = $2, author = $3, isbn = $4, description = $5, cover_image_path = $6, series = $7, series_number = $8, tags = $9, asin = $10, date_published = $11, publisher = $12, contributors = $13, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteEbook :exec DELETE FROM media_items WHERE id = $1; -- name: GetReadingProgress :one SELECT * FROM reading_progress WHERE media_item_id = $1 AND user_id = $2; -- name: UpdateReadingProgress :one INSERT INTO reading_progress (media_item_id, user_id, current_page, total_pages, last_read_at) VALUES ($1, $2, $3, $4, NOW()) ON CONFLICT (media_item_id, user_id) DO UPDATE SET current_page = EXCLUDED.current_page, total_pages = EXCLUDED.total_pages, last_read_at = NOW() RETURNING *; -- name: DeleteReadingProgress :exec DELETE FROM reading_progress WHERE media_item_id = $1 AND user_id = $2; -- name: UpdateUserTheme :exec UPDATE users SET theme = $2, updated_at = NOW() WHERE id = $1; -- name: UpdateUserProfile :exec UPDATE users SET first_name = $2, last_name = $3, updated_at = NOW() WHERE id = $1; -- name: UpdateUsername :exec UPDATE users SET username = $2, updated_at = NOW() WHERE id = $1; -- name: UpdateEmail :exec UPDATE users SET email = $2, updated_at = NOW() WHERE id = $1; -- name: UpdatePassword :exec UPDATE users SET password_hash = $2, updated_at = NOW() WHERE id = $1; -- name: DeleteUser :exec DELETE FROM users WHERE id = $1; -- name: UpdateScanSettings :exec UPDATE users SET scan_frequency_minutes = $2, auto_scan_enabled = $3, updated_at = NOW() WHERE id = $1; -- name: GetScanSettings :one SELECT scan_frequency_minutes, auto_scan_enabled FROM users WHERE id = $1; -- name: CreateMediaRating :one INSERT INTO media_ratings (media_item_id, user_id, rating) VALUES ($1, $2, $3) ON CONFLICT (media_item_id, user_id) DO UPDATE SET rating = EXCLUDED.rating, updated_at = NOW() RETURNING *; -- name: GetMediaRating :one SELECT * FROM media_ratings WHERE media_item_id = $1 AND user_id = $2; -- name: GetMediaRatings :many SELECT mr.*, u.username FROM media_ratings mr JOIN users u ON mr.user_id = u.id WHERE mr.media_item_id = $1 ORDER BY mr.created_at DESC; -- name: UpdateMediaRating :one UPDATE media_ratings SET rating = $3, updated_at = NOW() WHERE media_item_id = $1 AND user_id = $2 RETURNING *; -- name: DeleteMediaRating :exec DELETE FROM media_ratings WHERE media_item_id = $1 AND user_id = $2; -- Backward compatibility - Ebooks ratings (using views) -- name: CreateEbookRating :one INSERT INTO media_ratings (media_item_id, user_id, rating) VALUES ($1, $2, $3) ON CONFLICT (media_item_id, user_id) DO UPDATE SET rating = EXCLUDED.rating, updated_at = NOW() RETURNING *; -- name: GetEbookRating :one SELECT * FROM ebook_ratings WHERE ebook_id = $1 AND user_id = $2; -- name: GetEbookRatings :many SELECT er.*, u.username FROM ebook_ratings er JOIN users u ON er.user_id = u.id WHERE er.ebook_id = $1 ORDER BY er.created_at DESC; -- name: UpdateEbookRating :one UPDATE media_ratings SET rating = $3, updated_at = NOW() WHERE media_item_id = $1 AND user_id = $2 RETURNING *; -- name: DeleteEbookRating :exec DELETE FROM media_ratings WHERE media_item_id = $1 AND user_id = $2; -- Note: User ebook folders replaced by library folders system -- Legacy folder management is now handled through libraries -- name: GetEbookByFilePath :one SELECT * FROM ebooks WHERE file_path = $1; -- Media Notes queries -- name: CreateMediaNote :one INSERT INTO media_notes (media_item_id, user_id, content, position) VALUES ($1, $2, $3, $4) RETURNING *; -- name: GetMediaNote :one SELECT * FROM media_notes WHERE id = $1; -- name: GetMediaNotes :many SELECT * FROM media_notes WHERE media_item_id = $1 AND user_id = $2 ORDER BY created_at DESC; -- name: UpdateMediaNote :one UPDATE media_notes SET content = $2, position = $3, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteMediaNote :exec DELETE FROM media_notes WHERE id = $1; -- Media Highlights queries -- name: CreateMediaHighlight :one INSERT INTO media_highlights (media_item_id, user_id, selection_text, start_position, end_position, color, note_id) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: GetMediaHighlight :one SELECT * FROM media_highlights WHERE id = $1; -- name: GetMediaHighlights :many SELECT * FROM media_highlights WHERE media_item_id = $1 AND user_id = $2 ORDER BY created_at DESC; -- name: UpdateMediaHighlight :one UPDATE media_highlights SET selection_text = $2, start_position = $3, end_position = $4, color = $5, note_id = $6, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteMediaHighlight :exec DELETE FROM media_highlights WHERE id = $1; -- Backward compatibility - Ebook Notes queries (using views) -- name: CreateEbookNote :one INSERT INTO media_notes (media_item_id, user_id, content, position) VALUES ($1, $2, $3, $4) RETURNING *; -- name: GetEbookNote :one SELECT * FROM ebook_notes WHERE id = $1; -- name: GetEbookNotes :many SELECT * FROM ebook_notes WHERE ebook_id = $1 AND user_id = $2 ORDER BY created_at DESC; -- name: UpdateEbookNote :one UPDATE media_notes SET content = $2, position = $3, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteEbookNote :exec DELETE FROM media_notes WHERE id = $1; -- Backward compatibility - Ebook Highlights queries (using views) -- name: CreateEbookHighlight :one INSERT INTO media_highlights (media_item_id, user_id, selection_text, start_position, end_position, color, note_id) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: GetEbookHighlight :one SELECT * FROM ebook_highlights WHERE id = $1; -- name: GetEbookHighlights :many SELECT * FROM ebook_highlights WHERE ebook_id = $1 AND user_id = $2 ORDER BY created_at DESC; -- name: UpdateEbookHighlight :one UPDATE media_highlights SET selection_text = $2, start_position = $3, end_position = $4, color = $5, note_id = $6, updated_at = NOW() WHERE id = $1 RETURNING *; -- name: DeleteEbookHighlight :exec DELETE FROM media_highlights WHERE id = $1; -- Refresh Tokens queries -- name: CreateRefreshToken :one INSERT INTO refresh_tokens (user_id, token, expires_at) VALUES ($1, $2, $3) RETURNING *; -- name: GetRefreshToken :one SELECT rt.*, u.email, u.username, u.role FROM refresh_tokens rt JOIN users u ON rt.user_id = u.id WHERE rt.token = $1 AND rt.revoked_at IS NULL AND rt.expires_at > NOW(); -- name: RevokeRefreshToken :exec UPDATE refresh_tokens SET revoked_at = NOW() WHERE token = $1; -- name: RevokeAllUserRefreshTokens :exec UPDATE refresh_tokens SET revoked_at = NOW() WHERE user_id = $1 AND revoked_at IS NULL; -- name: CleanupExpiredRefreshTokens :exec DELETE FROM refresh_tokens WHERE expires_at < NOW() OR (revoked_at IS NOT NULL AND revoked_at < NOW() - INTERVAL '7 days');