feat: implement library system database schema
- Add library_types table with ebooks, comics, manga types - Add libraries table for multiple library support - Add library_folders table for multi-folder libraries - Add library_visibility table for user access control - Add media_items table replacing ebooks for broader media support - Create backward compatibility views for existing API - Implement library service with type validation and file extension handling - Support modular extension for future media types Manga type includes cbz/cbr archives as requested
This commit is contained in:
+86
-15
@@ -9,17 +9,28 @@ import (
|
||||
)
|
||||
|
||||
type EbookRatings struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
// Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)
|
||||
Rating int32 `db:"rating" json:"rating"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
MediaItemID pgtype.UUID `db:"media_item_id" json:"media_item_id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
Rating int32 `db:"rating" json:"rating"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
||||
}
|
||||
|
||||
type EbookReadingProgress struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
MediaItemID pgtype.UUID `db:"media_item_id" json:"media_item_id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
CurrentPage pgtype.Int4 `db:"current_page" json:"current_page"`
|
||||
TotalPages pgtype.Int4 `db:"total_pages" json:"total_pages"`
|
||||
LastReadAt pgtype.Timestamptz `db:"last_read_at" json:"last_read_at"`
|
||||
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
||||
}
|
||||
|
||||
type Ebooks struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
@@ -40,22 +51,82 @@ type Ebooks struct {
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type Libraries struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
LibraryTypeID pgtype.UUID `db:"library_type_id" json:"library_type_id"`
|
||||
CreatedByAdminID pgtype.UUID `db:"created_by_admin_id" json:"created_by_admin_id"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type LibraryFolders struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||
FolderPath string `db:"folder_path" json:"folder_path"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type LibraryTypes struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
AllowedExtensions []string `db:"allowed_extensions" json:"allowed_extensions"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type LibraryVisibility struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||
IsVisible bool `db:"is_visible" json:"is_visible"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type MediaItems struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
LibraryID pgtype.UUID `db:"library_id" json:"library_id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Author pgtype.Text `db:"author" json:"author"`
|
||||
Isbn pgtype.Text `db:"isbn" json:"isbn"`
|
||||
Description pgtype.Text `db:"description" json:"description"`
|
||||
FilePath string `db:"file_path" json:"file_path"`
|
||||
FileSize pgtype.Int8 `db:"file_size" json:"file_size"`
|
||||
MimeType pgtype.Text `db:"mime_type" json:"mime_type"`
|
||||
CoverImagePath pgtype.Text `db:"cover_image_path" json:"cover_image_path"`
|
||||
Series pgtype.Text `db:"series" json:"series"`
|
||||
SeriesNumber pgtype.Int4 `db:"series_number" json:"series_number"`
|
||||
Tags pgtype.Text `db:"tags" json:"tags"`
|
||||
Asin pgtype.Text `db:"asin" json:"asin"`
|
||||
DatePublished pgtype.Date `db:"date_published" json:"date_published"`
|
||||
Publisher pgtype.Text `db:"publisher" json:"publisher"`
|
||||
Contributors pgtype.Text `db:"contributors" json:"contributors"`
|
||||
AddedByAdminID pgtype.UUID `db:"added_by_admin_id" json:"added_by_admin_id"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type MediaRatings struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
MediaItemID pgtype.UUID `db:"media_item_id" json:"media_item_id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
// Rating scale 1-10 (odd numbers = half-stars: 1,3,5,7,9 = 0.5,1.5,2.5,3.5,4.5 stars)
|
||||
Rating int32 `db:"rating" json:"rating"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type ReadingProgress struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
EbookID pgtype.UUID `db:"ebook_id" json:"ebook_id"`
|
||||
MediaItemID pgtype.UUID `db:"media_item_id" json:"media_item_id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
CurrentPage pgtype.Int4 `db:"current_page" json:"current_page"`
|
||||
TotalPages pgtype.Int4 `db:"total_pages" json:"total_pages"`
|
||||
LastReadAt pgtype.Timestamptz `db:"last_read_at" json:"last_read_at"`
|
||||
}
|
||||
|
||||
type UserEbookFolders struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
UserID pgtype.UUID `db:"user_id" json:"user_id"`
|
||||
FolderPath string `db:"folder_path" json:"folder_path"`
|
||||
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
|
||||
}
|
||||
|
||||
type Users struct {
|
||||
ID pgtype.UUID `db:"id" json:"id"`
|
||||
Email string `db:"email" json:"email"`
|
||||
|
||||
@@ -11,33 +11,65 @@ import (
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
AddUserEbookFolder(ctx context.Context, arg AddUserEbookFolderParams) (UserEbookFolders, error)
|
||||
CreateEbook(ctx context.Context, arg CreateEbookParams) (Ebooks, error)
|
||||
CreateEbookRating(ctx context.Context, arg CreateEbookRatingParams) (EbookRatings, error)
|
||||
// Library Folders queries
|
||||
AddLibraryFolder(ctx context.Context, arg AddLibraryFolderParams) (LibraryFolders, error)
|
||||
CreateEbook(ctx context.Context, arg CreateEbookParams) (MediaItems, error)
|
||||
// Backward compatibility - Ebooks ratings (using views)
|
||||
CreateEbookRating(ctx context.Context, arg CreateEbookRatingParams) (MediaRatings, error)
|
||||
// Libraries queries
|
||||
CreateLibrary(ctx context.Context, arg CreateLibraryParams) (Libraries, error)
|
||||
// Media Items queries
|
||||
CreateMediaItem(ctx context.Context, arg CreateMediaItemParams) (MediaItems, error)
|
||||
CreateMediaRating(ctx context.Context, arg CreateMediaRatingParams) (MediaRatings, error)
|
||||
CreateUser(ctx context.Context, arg CreateUserParams) (CreateUserRow, error)
|
||||
DeleteEbook(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteEbookRating(ctx context.Context, arg DeleteEbookRatingParams) error
|
||||
DeleteLibrary(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteLibraryFolder(ctx context.Context, arg DeleteLibraryFolderParams) (LibraryFolders, error)
|
||||
DeleteMediaItem(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteMediaRating(ctx context.Context, arg DeleteMediaRatingParams) error
|
||||
DeleteReadingProgress(ctx context.Context, arg DeleteReadingProgressParams) error
|
||||
DeleteUser(ctx context.Context, id pgtype.UUID) error
|
||||
DeleteUserEbookFolder(ctx context.Context, arg DeleteUserEbookFolderParams) (UserEbookFolders, error)
|
||||
// Backward compatibility - Ebooks queries (using views)
|
||||
GetEbook(ctx context.Context, id pgtype.UUID) (Ebooks, error)
|
||||
// Note: User ebook folders replaced by library folders system
|
||||
// Legacy folder management is now handled through libraries
|
||||
GetEbookByFilePath(ctx context.Context, filePath string) (Ebooks, error)
|
||||
GetEbookRating(ctx context.Context, arg GetEbookRatingParams) (EbookRatings, error)
|
||||
GetEbookRatings(ctx context.Context, ebookID pgtype.UUID) ([]GetEbookRatingsRow, error)
|
||||
GetLibrary(ctx context.Context, id pgtype.UUID) (GetLibraryRow, error)
|
||||
GetLibraryFolders(ctx context.Context, libraryID pgtype.UUID) ([]LibraryFolders, error)
|
||||
GetLibraryType(ctx context.Context, id pgtype.UUID) (LibraryTypes, error)
|
||||
GetLibraryTypeByName(ctx context.Context, name string) (LibraryTypes, error)
|
||||
// Library Types queries
|
||||
GetLibraryTypes(ctx context.Context) ([]LibraryTypes, error)
|
||||
GetLibraryVisibility(ctx context.Context, arg GetLibraryVisibilityParams) (LibraryVisibility, error)
|
||||
GetMediaItem(ctx context.Context, id pgtype.UUID) (MediaItems, error)
|
||||
GetMediaItemByFilePath(ctx context.Context, filePath string) (MediaItems, error)
|
||||
GetMediaRating(ctx context.Context, arg GetMediaRatingParams) (MediaRatings, error)
|
||||
GetMediaRatings(ctx context.Context, mediaItemID pgtype.UUID) ([]GetMediaRatingsRow, error)
|
||||
GetReadingProgress(ctx context.Context, arg GetReadingProgressParams) (ReadingProgress, error)
|
||||
GetScanSettings(ctx context.Context, id pgtype.UUID) (GetScanSettingsRow, error)
|
||||
GetUser(ctx context.Context, id pgtype.UUID) (GetUserRow, error)
|
||||
GetUserByEmail(ctx context.Context, email string) (GetUserByEmailRow, error)
|
||||
GetUserByEmailOrUsername(ctx context.Context, email string) (GetUserByEmailOrUsernameRow, error)
|
||||
GetUserByUsername(ctx context.Context, username string) (GetUserByUsernameRow, error)
|
||||
GetUserEbookFolders(ctx context.Context, userID pgtype.UUID) ([]UserEbookFolders, error)
|
||||
GetUserForLogin(ctx context.Context, email string) (GetUserForLoginRow, error)
|
||||
GetUserPasswordHash(ctx context.Context, id pgtype.UUID) (string, error)
|
||||
GetUserVisibleLibraries(ctx context.Context, userID pgtype.UUID) ([]GetUserVisibleLibrariesRow, error)
|
||||
ListEbooks(ctx context.Context, arg ListEbooksParams) ([]Ebooks, error)
|
||||
ListLibraries(ctx context.Context) ([]ListLibrariesRow, error)
|
||||
ListMediaItems(ctx context.Context, arg ListMediaItemsParams) ([]ListMediaItemsRow, error)
|
||||
ListMediaItemsByLibrary(ctx context.Context, libraryID pgtype.UUID) ([]ListMediaItemsByLibraryRow, error)
|
||||
ListUsers(ctx context.Context) ([]ListUsersRow, error)
|
||||
UpdateEbook(ctx context.Context, arg UpdateEbookParams) (Ebooks, error)
|
||||
UpdateEbookRating(ctx context.Context, arg UpdateEbookRatingParams) (EbookRatings, error)
|
||||
// Library Visibility queries
|
||||
SetLibraryVisibility(ctx context.Context, arg SetLibraryVisibilityParams) (LibraryVisibility, error)
|
||||
UpdateEbook(ctx context.Context, arg UpdateEbookParams) (MediaItems, error)
|
||||
UpdateEbookRating(ctx context.Context, arg UpdateEbookRatingParams) (MediaRatings, error)
|
||||
UpdateEmail(ctx context.Context, arg UpdateEmailParams) error
|
||||
UpdateLibrary(ctx context.Context, arg UpdateLibraryParams) (Libraries, error)
|
||||
UpdateMediaItem(ctx context.Context, arg UpdateMediaItemParams) (MediaItems, error)
|
||||
UpdateMediaRating(ctx context.Context, arg UpdateMediaRatingParams) (MediaRatings, error)
|
||||
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
|
||||
UpdateReadingProgress(ctx context.Context, arg UpdateReadingProgressParams) (ReadingProgress, error)
|
||||
UpdateScanSettings(ctx context.Context, arg UpdateScanSettingsParams) error
|
||||
|
||||
+989
-121
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,126 @@ 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;
|
||||
|
||||
@@ -31,12 +151,12 @@ SELECT * FROM ebooks WHERE id = $1;
|
||||
SELECT * FROM ebooks ORDER BY created_at DESC LIMIT $1 OFFSET $2;
|
||||
|
||||
-- name: CreateEbook :one
|
||||
INSERT INTO ebooks (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)
|
||||
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 ebooks SET
|
||||
UPDATE media_items SET
|
||||
title = $2,
|
||||
author = $3,
|
||||
isbn = $4,
|
||||
@@ -54,15 +174,15 @@ WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteEbook :exec
|
||||
DELETE FROM ebooks WHERE id = $1;
|
||||
DELETE FROM media_items WHERE id = $1;
|
||||
|
||||
-- name: GetReadingProgress :one
|
||||
SELECT * FROM reading_progress WHERE ebook_id = $1 AND user_id = $2;
|
||||
SELECT * FROM reading_progress WHERE media_item_id = $1 AND user_id = $2;
|
||||
|
||||
-- name: UpdateReadingProgress :one
|
||||
INSERT INTO reading_progress (ebook_id, user_id, current_page, total_pages, last_read_at)
|
||||
INSERT INTO reading_progress (media_item_id, user_id, current_page, total_pages, last_read_at)
|
||||
VALUES ($1, $2, $3, $4, NOW())
|
||||
ON CONFLICT (ebook_id, user_id)
|
||||
ON CONFLICT (media_item_id, user_id)
|
||||
DO UPDATE SET
|
||||
current_page = EXCLUDED.current_page,
|
||||
total_pages = EXCLUDED.total_pages,
|
||||
@@ -70,7 +190,7 @@ DO UPDATE SET
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteReadingProgress :exec
|
||||
DELETE FROM reading_progress WHERE ebook_id = $1 AND user_id = $2;
|
||||
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;
|
||||
@@ -96,10 +216,41 @@ UPDATE users SET scan_frequency_minutes = $2, auto_scan_enabled = $3, updated_at
|
||||
-- name: GetScanSettings :one
|
||||
SELECT scan_frequency_minutes, auto_scan_enabled FROM users WHERE id = $1;
|
||||
|
||||
-- name: CreateEbookRating :one
|
||||
INSERT INTO ebook_ratings (ebook_id, user_id, rating)
|
||||
-- name: CreateMediaRating :one
|
||||
INSERT INTO media_ratings (media_item_id, user_id, rating)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (ebook_id, user_id)
|
||||
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)
|
||||
SELECT $1, $2, $3
|
||||
WHERE EXISTS (SELECT 1 FROM media_items WHERE id = $1)
|
||||
ON CONFLICT (media_item_id, user_id)
|
||||
DO UPDATE SET
|
||||
rating = EXCLUDED.rating,
|
||||
updated_at = NOW()
|
||||
@@ -116,23 +267,17 @@ WHERE er.ebook_id = $1
|
||||
ORDER BY er.created_at DESC;
|
||||
|
||||
-- name: UpdateEbookRating :one
|
||||
UPDATE ebook_ratings SET
|
||||
UPDATE media_ratings SET
|
||||
rating = $3,
|
||||
updated_at = NOW()
|
||||
WHERE ebook_id = $1 AND user_id = $2
|
||||
WHERE media_item_id = $1 AND user_id = $2
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteEbookRating :exec
|
||||
DELETE FROM ebook_ratings WHERE ebook_id = $1 AND user_id = $2;
|
||||
DELETE FROM media_ratings WHERE media_item_id = $1 AND user_id = $2;
|
||||
|
||||
-- name: AddUserEbookFolder :one
|
||||
INSERT INTO user_ebook_folders (user_id, folder_path) VALUES ($1, $2) RETURNING *;
|
||||
|
||||
-- name: GetUserEbookFolders :many
|
||||
SELECT * FROM user_ebook_folders WHERE user_id = $1 ORDER BY created_at;
|
||||
|
||||
-- name: DeleteUserEbookFolder :one
|
||||
DELETE FROM user_ebook_folders WHERE user_id = $1 AND folder_path = $2 RETURNING *;
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user