Gisle Aune
4 years ago
13 changed files with 420 additions and 5 deletions
-
2cmd/rpdata-restore/main.go
-
127database/postgres/chapters.go
-
2database/postgres/db.go
-
20database/postgres/migrations/20210326165205_create_table_chapter.sql
-
9database/postgres/migrations/20210326165603_create_index_chapter_story_id.sql
-
1database/postgres/psqlcore/changes.sql.go
-
1database/postgres/psqlcore/channels.sql.go
-
177database/postgres/psqlcore/chapters.sql.go
-
13database/postgres/psqlcore/models.go
-
1database/postgres/psqlcore/stories.sql.go
-
33database/postgres/queries/chapters.sql
-
21database/postgres/stories.go
-
18models/chapter.go
@ -0,0 +1,127 @@ |
|||||
|
package postgres |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"database/sql" |
||||
|
"git.aiterp.net/rpdata/api/database/postgres/psqlcore" |
||||
|
"git.aiterp.net/rpdata/api/internal/generate" |
||||
|
"git.aiterp.net/rpdata/api/models" |
||||
|
) |
||||
|
|
||||
|
type chapterRepository struct { |
||||
|
insertWithIDs bool |
||||
|
db *sql.DB |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Find(ctx context.Context, id string) (*models.Chapter, error) { |
||||
|
chapter, err := psqlcore.New(r.db).SelectChapter(ctx, id) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return r.chapter(chapter), nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) List(ctx context.Context, filter models.ChapterFilter) ([]*models.Chapter, error) { |
||||
|
params := psqlcore.SelectChaptersParams{ |
||||
|
StoryID: "", |
||||
|
LimitSize: 10000, |
||||
|
} |
||||
|
if filter.StoryID != nil { |
||||
|
params.StoryID = *filter.StoryID |
||||
|
} |
||||
|
if filter.Limit > 0 { |
||||
|
params.LimitSize = int32(filter.Limit) |
||||
|
} |
||||
|
|
||||
|
chapters, err := psqlcore.New(r.db).SelectChapters(ctx, params) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return r.chapters(chapters), nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Insert(ctx context.Context, chapter models.Chapter) (*models.Chapter, error) { |
||||
|
if !r.insertWithIDs || len(chapter.ID) < 8 { |
||||
|
chapter.ID = generate.ChapterID() |
||||
|
} |
||||
|
|
||||
|
err := psqlcore.New(r.db).InsertChapter(ctx, psqlcore.InsertChapterParams{ |
||||
|
ID: chapter.ID, |
||||
|
StoryID: chapter.StoryID, |
||||
|
Title: chapter.Title, |
||||
|
Author: chapter.Author, |
||||
|
Source: chapter.Source, |
||||
|
CreatedDate: chapter.CreatedDate.UTC(), |
||||
|
FictionalDate: chapter.FictionalDate.UTC(), |
||||
|
EditedDate: chapter.EditedDate.UTC(), |
||||
|
CommentMode: string(chapter.CommentMode), |
||||
|
CommentsLocked: chapter.CommentsLocked, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Update(ctx context.Context, chapter models.Chapter, update models.ChapterUpdate) (*models.Chapter, error) { |
||||
|
chapter.ApplyUpdate(update) |
||||
|
|
||||
|
err := psqlcore.New(r.db).UpdateChapter(ctx, psqlcore.UpdateChapterParams{ |
||||
|
Title: chapter.Title, |
||||
|
Source: chapter.Source, |
||||
|
FictionalDate: chapter.FictionalDate.UTC(), |
||||
|
CommentMode: string(chapter.CommentMode), |
||||
|
CommentsLocked: chapter.CommentsLocked, |
||||
|
ID: chapter.ID, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Move(ctx context.Context, chapter models.Chapter, from, to models.Story) (*models.Chapter, error) { |
||||
|
err := psqlcore.New(r.db).UpdateChapterStoryID(ctx, psqlcore.UpdateChapterStoryIDParams{ |
||||
|
StoryID: to.ID, |
||||
|
ID: chapter.ID, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
chapter.StoryID = to.ID |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Delete(ctx context.Context, chapter models.Chapter) error { |
||||
|
return psqlcore.New(r.db).DeleteChapter(ctx, chapter.ID) |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) chapter(chapter psqlcore.StoryChapter) *models.Chapter { |
||||
|
return &models.Chapter{ |
||||
|
ID: chapter.ID, |
||||
|
StoryID: chapter.StoryID, |
||||
|
Title: chapter.Title, |
||||
|
Author: chapter.Author, |
||||
|
Source: chapter.Source, |
||||
|
CreatedDate: chapter.CreatedDate, |
||||
|
FictionalDate: chapter.FictionalDate, |
||||
|
EditedDate: chapter.EditedDate, |
||||
|
CommentMode: models.ChapterCommentMode(chapter.CommentMode), |
||||
|
CommentsLocked: chapter.CommentsLocked, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) chapters(chapters []psqlcore.StoryChapter) []*models.Chapter { |
||||
|
results := make([]*models.Chapter, 0, len(chapters)) |
||||
|
for _, chapter := range chapters { |
||||
|
results = append(results, r.chapter(chapter)) |
||||
|
} |
||||
|
|
||||
|
return results |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
-- +goose Up |
||||
|
-- +goose StatementBegin |
||||
|
CREATE TABLE story_chapter ( |
||||
|
id TEXT NOT NULL PRIMARY KEY, |
||||
|
story_id TEXT NOT NULL, |
||||
|
title TEXT NOT NULL, |
||||
|
author TEXT NOT NULL, |
||||
|
source TEXT NOT NULL, |
||||
|
created_date TIMESTAMP NOT NULL, |
||||
|
fictional_date TIMESTAMP NOT NULL, |
||||
|
edited_date TIMESTAMP NOT NULL, |
||||
|
comment_mode TEXT NOT NULL, |
||||
|
comments_locked BOOLEAN NOT NULL |
||||
|
); |
||||
|
-- +goose StatementEnd |
||||
|
|
||||
|
-- +goose Down |
||||
|
-- +goose StatementBegin |
||||
|
DROP TABLE story_chapter; |
||||
|
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||||
|
-- +goose Up |
||||
|
-- +goose StatementBegin |
||||
|
CREATE INDEX story_chapter_index_story_id ON story_chapter (story_id); |
||||
|
-- +goose StatementEnd |
||||
|
|
||||
|
-- +goose Down |
||||
|
-- +goose StatementBegin |
||||
|
DROP INDEX IF EXISTS story_chapter_index_story_id; |
||||
|
-- +goose StatementEnd |
@ -0,0 +1,177 @@ |
|||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||
|
// source: chapters.sql
|
||||
|
|
||||
|
package psqlcore |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
const deleteChapter = `-- name: DeleteChapter :exec |
||||
|
DELETE FROM story_chapter WHERE id=$1 |
||||
|
` |
||||
|
|
||||
|
func (q *Queries) DeleteChapter(ctx context.Context, id string) error { |
||||
|
_, err := q.db.ExecContext(ctx, deleteChapter, id) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
const deleteChaptersByStoryID = `-- name: DeleteChaptersByStoryID :exec |
||||
|
DELETE FROM story_chapter WHERE story_id=$1 |
||||
|
` |
||||
|
|
||||
|
func (q *Queries) DeleteChaptersByStoryID(ctx context.Context, storyID string) error { |
||||
|
_, err := q.db.ExecContext(ctx, deleteChaptersByStoryID, storyID) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
const insertChapter = `-- name: InsertChapter :exec |
||||
|
INSERT INTO story_chapter (id, story_id, title, author, source, created_date, fictional_date, edited_date, comment_mode, comments_locked) |
||||
|
VALUES ( |
||||
|
$1::TEXT, $2::TEXT, $3::TEXT, $4::TEXT, $5::TEXT, |
||||
|
$6::TIMESTAMP, $7::TIMESTAMP, $8::TIMESTAMP, |
||||
|
$9::TEXT, $10::BOOLEAN |
||||
|
) |
||||
|
` |
||||
|
|
||||
|
type InsertChapterParams struct { |
||||
|
ID string `json:"id"` |
||||
|
StoryID string `json:"story_id"` |
||||
|
Title string `json:"title"` |
||||
|
Author string `json:"author"` |
||||
|
Source string `json:"source"` |
||||
|
CreatedDate time.Time `json:"created_date"` |
||||
|
FictionalDate time.Time `json:"fictional_date"` |
||||
|
EditedDate time.Time `json:"edited_date"` |
||||
|
CommentMode string `json:"comment_mode"` |
||||
|
CommentsLocked bool `json:"comments_locked"` |
||||
|
} |
||||
|
|
||||
|
func (q *Queries) InsertChapter(ctx context.Context, arg InsertChapterParams) error { |
||||
|
_, err := q.db.ExecContext(ctx, insertChapter, |
||||
|
arg.ID, |
||||
|
arg.StoryID, |
||||
|
arg.Title, |
||||
|
arg.Author, |
||||
|
arg.Source, |
||||
|
arg.CreatedDate, |
||||
|
arg.FictionalDate, |
||||
|
arg.EditedDate, |
||||
|
arg.CommentMode, |
||||
|
arg.CommentsLocked, |
||||
|
) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
const selectChapter = `-- name: SelectChapter :one |
||||
|
SELECT id, story_id, title, author, source, created_date, fictional_date, edited_date, comment_mode, comments_locked FROM story_chapter WHERE id=$1::TEXT LIMIT 1 |
||||
|
` |
||||
|
|
||||
|
func (q *Queries) SelectChapter(ctx context.Context, dollar_1 string) (StoryChapter, error) { |
||||
|
row := q.db.QueryRowContext(ctx, selectChapter, dollar_1) |
||||
|
var i StoryChapter |
||||
|
err := row.Scan( |
||||
|
&i.ID, |
||||
|
&i.StoryID, |
||||
|
&i.Title, |
||||
|
&i.Author, |
||||
|
&i.Source, |
||||
|
&i.CreatedDate, |
||||
|
&i.FictionalDate, |
||||
|
&i.EditedDate, |
||||
|
&i.CommentMode, |
||||
|
&i.CommentsLocked, |
||||
|
) |
||||
|
return i, err |
||||
|
} |
||||
|
|
||||
|
const selectChapters = `-- name: SelectChapters :many |
||||
|
SELECT id, story_id, title, author, source, created_date, fictional_date, edited_date, comment_mode, comments_locked FROM story_chapter WHERE (sqlx.arg(story_id)::TEXT == '' OR story_id=$1::TEXT) ORDER BY created_date LIMIT $2::INT |
||||
|
` |
||||
|
|
||||
|
type SelectChaptersParams struct { |
||||
|
StoryID string `json:"story_id"` |
||||
|
LimitSize int32 `json:"limit_size"` |
||||
|
} |
||||
|
|
||||
|
func (q *Queries) SelectChapters(ctx context.Context, arg SelectChaptersParams) ([]StoryChapter, error) { |
||||
|
rows, err := q.db.QueryContext(ctx, selectChapters, arg.StoryID, arg.LimitSize) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
defer rows.Close() |
||||
|
items := []StoryChapter{} |
||||
|
for rows.Next() { |
||||
|
var i StoryChapter |
||||
|
if err := rows.Scan( |
||||
|
&i.ID, |
||||
|
&i.StoryID, |
||||
|
&i.Title, |
||||
|
&i.Author, |
||||
|
&i.Source, |
||||
|
&i.CreatedDate, |
||||
|
&i.FictionalDate, |
||||
|
&i.EditedDate, |
||||
|
&i.CommentMode, |
||||
|
&i.CommentsLocked, |
||||
|
); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
items = append(items, i) |
||||
|
} |
||||
|
if err := rows.Close(); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
if err := rows.Err(); err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
return items, nil |
||||
|
} |
||||
|
|
||||
|
const updateChapter = `-- name: UpdateChapter :exec |
||||
|
UPDATE story_chapter |
||||
|
SET title=$1, |
||||
|
source=$2, |
||||
|
fictional_date=$3, |
||||
|
comment_mode=$4, |
||||
|
comments_locked=$5 |
||||
|
WHERE id=$6 |
||||
|
` |
||||
|
|
||||
|
type UpdateChapterParams struct { |
||||
|
Title string `json:"title"` |
||||
|
Source string `json:"source"` |
||||
|
FictionalDate time.Time `json:"fictional_date"` |
||||
|
CommentMode string `json:"comment_mode"` |
||||
|
CommentsLocked bool `json:"comments_locked"` |
||||
|
ID string `json:"id"` |
||||
|
} |
||||
|
|
||||
|
func (q *Queries) UpdateChapter(ctx context.Context, arg UpdateChapterParams) error { |
||||
|
_, err := q.db.ExecContext(ctx, updateChapter, |
||||
|
arg.Title, |
||||
|
arg.Source, |
||||
|
arg.FictionalDate, |
||||
|
arg.CommentMode, |
||||
|
arg.CommentsLocked, |
||||
|
arg.ID, |
||||
|
) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
const updateChapterStoryID = `-- name: UpdateChapterStoryID :exec |
||||
|
UPDATE story_chapter |
||||
|
SET story_id=$1::TEXT |
||||
|
WHERE id=$2 |
||||
|
` |
||||
|
|
||||
|
type UpdateChapterStoryIDParams struct { |
||||
|
StoryID string `json:"story_id"` |
||||
|
ID string `json:"id"` |
||||
|
} |
||||
|
|
||||
|
func (q *Queries) UpdateChapterStoryID(ctx context.Context, arg UpdateChapterStoryIDParams) error { |
||||
|
_, err := q.db.ExecContext(ctx, updateChapterStoryID, arg.StoryID, arg.ID) |
||||
|
return err |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
-- name: SelectChapter :one |
||||
|
SELECT * FROM story_chapter WHERE id=$1::TEXT LIMIT 1; |
||||
|
|
||||
|
-- name: SelectChapters :many |
||||
|
SELECT * FROM story_chapter WHERE (sqlx.arg(story_id)::TEXT == '' OR story_id=sqlc.arg(story_id)::TEXT) ORDER BY created_date LIMIT sqlc.arg(limit_size)::INT; |
||||
|
|
||||
|
-- name: InsertChapter :exec |
||||
|
INSERT INTO story_chapter (id, story_id, title, author, source, created_date, fictional_date, edited_date, comment_mode, comments_locked) |
||||
|
VALUES ( |
||||
|
sqlc.arg(id)::TEXT, sqlc.arg(story_id)::TEXT, sqlc.arg(title)::TEXT, sqlc.arg(author)::TEXT, sqlc.arg(source)::TEXT, |
||||
|
sqlc.arg(created_date)::TIMESTAMP, sqlc.arg(fictional_date)::TIMESTAMP, sqlc.arg(edited_date)::TIMESTAMP, |
||||
|
sqlc.arg(comment_mode)::TEXT, sqlc.arg(comments_locked)::BOOLEAN |
||||
|
); |
||||
|
|
||||
|
-- name: UpdateChapterStoryID :exec |
||||
|
UPDATE story_chapter |
||||
|
SET story_id=sqlc.arg(story_id)::TEXT |
||||
|
WHERE id=sqlc.arg(id); |
||||
|
|
||||
|
-- name: UpdateChapter :exec |
||||
|
UPDATE story_chapter |
||||
|
SET title=sqlc.arg(title), |
||||
|
source=sqlc.arg(source), |
||||
|
fictional_date=sqlc.arg(fictional_date), |
||||
|
comment_mode=sqlc.arg(comment_mode), |
||||
|
comments_locked=sqlc.arg(comments_locked) |
||||
|
WHERE id=sqlc.arg(id); |
||||
|
|
||||
|
-- name: DeleteChapter :exec |
||||
|
DELETE FROM story_chapter WHERE id=$1; |
||||
|
|
||||
|
-- name: DeleteChaptersByStoryID :exec |
||||
|
DELETE FROM story_chapter WHERE story_id=$1; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue