This commit is contained in:
@@ -65,7 +65,7 @@ func (d *DB) Characters() repositories.CharacterRepository {
|
||||
}
|
||||
|
||||
func (d *DB) Tags() repositories.TagRepository {
|
||||
panic("implement me")
|
||||
return &tagRepository{db: d.db}
|
||||
}
|
||||
|
||||
func (d *DB) Logs() repositories.LogRepository {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE common_tag (
|
||||
tag TEXT NOT NULL,
|
||||
target_kind TEXT NOT NULL,
|
||||
target_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (tag, target_kind, target_id)
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE common_tag;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX common_tag_index_target ON common_tag (target_kind, target_id);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS common_tag_index_target;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE story (
|
||||
id TEXT NOT NULL PRIMARY KEY,
|
||||
author TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
category TEXT NOT NULL,
|
||||
open BOOLEAN NOT NULL,
|
||||
listed BOOLEAN NOT NULL,
|
||||
sort_by_fictional_date BOOLEAN NOT NULL,
|
||||
created_date TIMESTAMP NOT NULL,
|
||||
fictional_date TIMESTAMP NOT NULL,
|
||||
updated_date TIMESTAMP NOT NULL
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE story;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX story_index_author ON story (author);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS story_index_author
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX story_index_fictional_date ON story (fictional_date);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS story_index_fictional_date
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX story_index_created_date ON story (created_date);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS story_index_created_date
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE INDEX story_index_updated_date ON story (updated_date);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP INDEX IF EXISTS story_index_updated_date
|
||||
-- +goose StatementEnd
|
||||
@@ -8,6 +8,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type CommonTag struct {
|
||||
Tag string `json:"tag"`
|
||||
TargetKind string `json:"target_kind"`
|
||||
TargetID string `json:"target_id"`
|
||||
}
|
||||
|
||||
type CoreCounter struct {
|
||||
ID string `json:"id"`
|
||||
Value sql.NullInt32 `json:"value"`
|
||||
@@ -41,3 +47,16 @@ type DataCharacter struct {
|
||||
Description string `json:"description"`
|
||||
TsVector interface{} `json:"ts_vector"`
|
||||
}
|
||||
|
||||
type Story struct {
|
||||
ID string `json:"id"`
|
||||
Author string `json:"author"`
|
||||
Name string `json:"name"`
|
||||
Category string `json:"category"`
|
||||
Open bool `json:"open"`
|
||||
Listed bool `json:"listed"`
|
||||
SortByFictionalDate bool `json:"sort_by_fictional_date"`
|
||||
CreatedDate time.Time `json:"created_date"`
|
||||
FictionalDate time.Time `json:"fictional_date"`
|
||||
UpdatedDate time.Time `json:"updated_date"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: stories.sql
|
||||
|
||||
package psqlcore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
const selectStories = `-- name: SelectStories :many
|
||||
SELECT id, author, name, category, open, listed, sort_by_fictional_date, created_date, fictional_date, updated_date FROM story
|
||||
WHERE ($1::bool = false OR id = ANY($2::text[]))
|
||||
AND ($3::bool = false OR name = $4::text)
|
||||
AND ($5::bool = false OR fictional_date >= $6::timestamp)
|
||||
AND ($7::bool = false OR fictional_date <= $8::timestamp)
|
||||
AND ($9::bool = false OR category = $10::text)
|
||||
AND ($11::bool = false OR open = $12::bool)
|
||||
AND ($13::bool = false OR unlisted = $14::bool)
|
||||
LIMIT $15::int
|
||||
`
|
||||
|
||||
type SelectStoriesParams struct {
|
||||
FilterID bool `json:"filter_id"`
|
||||
Ids []string `json:"ids"`
|
||||
FilterAuthor bool `json:"filter_author"`
|
||||
Author string `json:"author"`
|
||||
FilterEarlistFictionalDate bool `json:"filter_earlist_fictional_date"`
|
||||
EarliestFictionalDate time.Time `json:"earliest_fictional_date"`
|
||||
FilterLastestFictionalDate bool `json:"filter_lastest_fictional_date"`
|
||||
LatestFictionalDate time.Time `json:"latest_fictional_date"`
|
||||
FilterCategory bool `json:"filter_category"`
|
||||
Category string `json:"category"`
|
||||
FilterOpen bool `json:"filter_open"`
|
||||
Open bool `json:"open"`
|
||||
FilterUnlisted bool `json:"filter_unlisted"`
|
||||
Unlisted bool `json:"unlisted"`
|
||||
LimitSize int32 `json:"limit_size"`
|
||||
}
|
||||
|
||||
func (q *Queries) SelectStories(ctx context.Context, arg SelectStoriesParams) ([]Story, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectStories,
|
||||
arg.FilterID,
|
||||
pq.Array(arg.Ids),
|
||||
arg.FilterAuthor,
|
||||
arg.Author,
|
||||
arg.FilterEarlistFictionalDate,
|
||||
arg.EarliestFictionalDate,
|
||||
arg.FilterLastestFictionalDate,
|
||||
arg.LatestFictionalDate,
|
||||
arg.FilterCategory,
|
||||
arg.Category,
|
||||
arg.FilterOpen,
|
||||
arg.Open,
|
||||
arg.FilterUnlisted,
|
||||
arg.Unlisted,
|
||||
arg.LimitSize,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []Story{}
|
||||
for rows.Next() {
|
||||
var i Story
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Author,
|
||||
&i.Name,
|
||||
&i.Category,
|
||||
&i.Open,
|
||||
&i.Listed,
|
||||
&i.SortByFictionalDate,
|
||||
&i.CreatedDate,
|
||||
&i.FictionalDate,
|
||||
&i.UpdatedDate,
|
||||
); 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 selectStory = `-- name: SelectStory :one
|
||||
SELECT id, author, name, category, open, listed, sort_by_fictional_date, created_date, fictional_date, updated_date FROM story WHERE id = $1 LIMIT 1
|
||||
`
|
||||
|
||||
func (q *Queries) SelectStory(ctx context.Context, id string) (Story, error) {
|
||||
row := q.db.QueryRowContext(ctx, selectStory, id)
|
||||
var i Story
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Author,
|
||||
&i.Name,
|
||||
&i.Category,
|
||||
&i.Open,
|
||||
&i.Listed,
|
||||
&i.SortByFictionalDate,
|
||||
&i.CreatedDate,
|
||||
&i.FictionalDate,
|
||||
&i.UpdatedDate,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: tags.sql
|
||||
|
||||
package psqlcore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
const clearTag = `-- name: ClearTag :exec
|
||||
DELETE FROM common_tag
|
||||
WHERE tag=$1::TEXT
|
||||
AND target_kind=$2::TEXT
|
||||
AND target_id=$3::TEXT
|
||||
`
|
||||
|
||||
type ClearTagParams struct {
|
||||
Tag string `json:"tag"`
|
||||
TargetKind string `json:"target_kind"`
|
||||
TargetID string `json:"target_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) ClearTag(ctx context.Context, arg ClearTagParams) error {
|
||||
_, err := q.db.ExecContext(ctx, clearTag, arg.Tag, arg.TargetKind, arg.TargetID)
|
||||
return err
|
||||
}
|
||||
|
||||
const clearTagsByTarget = `-- name: ClearTagsByTarget :exec
|
||||
DELETE FROM common_tag
|
||||
WHERE target_kind=$1::TEXT
|
||||
AND target_id=$2::TEXT
|
||||
`
|
||||
|
||||
type ClearTagsByTargetParams struct {
|
||||
TargetKind string `json:"target_kind"`
|
||||
TargetID string `json:"target_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) ClearTagsByTarget(ctx context.Context, arg ClearTagsByTargetParams) error {
|
||||
_, err := q.db.ExecContext(ctx, clearTagsByTarget, arg.TargetKind, arg.TargetID)
|
||||
return err
|
||||
}
|
||||
|
||||
const selectDistinctTags = `-- name: SelectDistinctTags :many
|
||||
SELECT DISTINCT tag FROM common_tag
|
||||
`
|
||||
|
||||
func (q *Queries) SelectDistinctTags(ctx context.Context) ([]string, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectDistinctTags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []string{}
|
||||
for rows.Next() {
|
||||
var tag string
|
||||
if err := rows.Scan(&tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, tag)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const selectDistinctTagsByKind = `-- name: SelectDistinctTagsByKind :many
|
||||
SELECT DISTINCT tag FROM common_tag WHERE tag LIKE '$1::text%'
|
||||
`
|
||||
|
||||
func (q *Queries) SelectDistinctTagsByKind(ctx context.Context) ([]string, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectDistinctTagsByKind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []string{}
|
||||
for rows.Next() {
|
||||
var tag string
|
||||
if err := rows.Scan(&tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, tag)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const selectTagsByTag = `-- name: SelectTagsByTag :many
|
||||
SELECT tag, target_kind, target_id FROM common_tag WHERE tag = $1::text
|
||||
`
|
||||
|
||||
func (q *Queries) SelectTagsByTag(ctx context.Context, tagName string) ([]CommonTag, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectTagsByTag, tagName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []CommonTag{}
|
||||
for rows.Next() {
|
||||
var i CommonTag
|
||||
if err := rows.Scan(&i.Tag, &i.TargetKind, &i.TargetID); 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 selectTagsByTags = `-- name: SelectTagsByTags :many
|
||||
SELECT tag, target_kind, target_id FROM common_tag WHERE tag = ANY($1::text[])
|
||||
`
|
||||
|
||||
func (q *Queries) SelectTagsByTags(ctx context.Context, tagNames []string) ([]CommonTag, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectTagsByTags, pq.Array(tagNames))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []CommonTag{}
|
||||
for rows.Next() {
|
||||
var i CommonTag
|
||||
if err := rows.Scan(&i.Tag, &i.TargetKind, &i.TargetID); 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 selectTagsByTarget = `-- name: SelectTagsByTarget :many
|
||||
SELECT tag, target_kind, target_id FROM common_tag WHERE target_kind = $1 AND target_id = $2::text
|
||||
`
|
||||
|
||||
type SelectTagsByTargetParams struct {
|
||||
TargetKind string `json:"target_kind"`
|
||||
Column2 string `json:"column_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) SelectTagsByTarget(ctx context.Context, arg SelectTagsByTargetParams) ([]CommonTag, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectTagsByTarget, arg.TargetKind, arg.Column2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []CommonTag{}
|
||||
for rows.Next() {
|
||||
var i CommonTag
|
||||
if err := rows.Scan(&i.Tag, &i.TargetKind, &i.TargetID); 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 selectTagsByTargets = `-- name: SelectTagsByTargets :many
|
||||
SELECT tag, target_kind, target_id FROM common_tag WHERE target_kind = $1 AND target_id = ANY($2::text[])
|
||||
`
|
||||
|
||||
type SelectTagsByTargetsParams struct {
|
||||
TargetKind string `json:"target_kind"`
|
||||
Column2 []string `json:"column_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) SelectTagsByTargets(ctx context.Context, arg SelectTagsByTargetsParams) ([]CommonTag, error) {
|
||||
rows, err := q.db.QueryContext(ctx, selectTagsByTargets, arg.TargetKind, pq.Array(arg.Column2))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items := []CommonTag{}
|
||||
for rows.Next() {
|
||||
var i CommonTag
|
||||
if err := rows.Scan(&i.Tag, &i.TargetKind, &i.TargetID); 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 setTag = `-- name: SetTag :exec
|
||||
INSERT INTO common_tag (tag, target_kind, target_id)
|
||||
VALUES (
|
||||
$1::TEXT, $2::TEXT, $3::TEXT
|
||||
)
|
||||
ON CONFLICT DO NOTHING
|
||||
`
|
||||
|
||||
type SetTagParams struct {
|
||||
Tag string `json:"tag"`
|
||||
TargetKind string `json:"target_kind"`
|
||||
TargetID string `json:"target_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetTag(ctx context.Context, arg SetTagParams) error {
|
||||
_, err := q.db.ExecContext(ctx, setTag, arg.Tag, arg.TargetKind, arg.TargetID)
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
-- name: SelectStory :one
|
||||
SELECT * FROM story WHERE id = $1 LIMIT 1;
|
||||
|
||||
-- name: SelectStories :many
|
||||
SELECT * FROM story
|
||||
WHERE (sqlc.arg(filter_id)::bool = false OR id = ANY(sqlc.arg(ids)::text[]))
|
||||
AND (sqlc.arg(filter_author)::bool = false OR name = sqlc.arg(author)::text)
|
||||
AND (sqlc.arg(filter_earlist_fictional_date)::bool = false OR fictional_date >= sqlc.arg(earliest_fictional_date)::timestamp)
|
||||
AND (sqlc.arg(filter_lastest_fictional_date)::bool = false OR fictional_date <= sqlc.arg(latest_fictional_date)::timestamp)
|
||||
AND (sqlc.arg(filter_category)::bool = false OR category = sqlc.arg(category)::text)
|
||||
AND (sqlc.arg(filter_open)::bool = false OR open = sqlc.arg(open)::bool)
|
||||
AND (sqlc.arg(filter_unlisted)::bool = false OR unlisted = sqlc.arg(unlisted)::bool)
|
||||
LIMIT sqlc.arg(limit_size)::int;
|
||||
@@ -0,0 +1,35 @@
|
||||
-- name: SetTag :exec
|
||||
INSERT INTO common_tag (tag, target_kind, target_id)
|
||||
VALUES (
|
||||
sqlc.arg(tag)::TEXT, sqlc.arg(target_kind)::TEXT, sqlc.arg(target_id)::TEXT
|
||||
)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- name: ClearTag :exec
|
||||
DELETE FROM common_tag
|
||||
WHERE tag=sqlc.arg(tag)::TEXT
|
||||
AND target_kind=sqlc.arg(target_kind)::TEXT
|
||||
AND target_id=sqlc.arg(target_id)::TEXT;
|
||||
|
||||
-- name: ClearTagsByTarget :exec
|
||||
DELETE FROM common_tag
|
||||
WHERE target_kind=sqlc.arg(target_kind)::TEXT
|
||||
AND target_id=sqlc.arg(target_id)::TEXT;
|
||||
|
||||
-- name: SelectDistinctTags :many
|
||||
SELECT DISTINCT tag FROM common_tag;
|
||||
|
||||
-- name: SelectDistinctTagsByKind :many
|
||||
SELECT DISTINCT tag FROM common_tag WHERE tag LIKE '$1::text%';
|
||||
|
||||
-- name: SelectTagsByTag :many
|
||||
SELECT * FROM common_tag WHERE tag = sqlc.arg(tag_name)::text;
|
||||
|
||||
-- name: SelectTagsByTags :many
|
||||
SELECT * FROM common_tag WHERE tag = ANY(sqlc.arg(tag_names)::text[]);
|
||||
|
||||
-- name: SelectTagsByTarget :many
|
||||
SELECT * FROM common_tag WHERE target_kind = $1 AND target_id = $2::text;
|
||||
|
||||
-- name: SelectTagsByTargets :many
|
||||
SELECT * FROM common_tag WHERE target_kind = $1 AND target_id = ANY($2::text[]);
|
||||
@@ -0,0 +1,129 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"git.aiterp.net/rpdata/api/database/postgres/psqlcore"
|
||||
"git.aiterp.net/rpdata/api/models"
|
||||
)
|
||||
|
||||
type storyRepository struct {
|
||||
insertWithIDs bool
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (r *storyRepository) Find(ctx context.Context, id string) (*models.Story, error) {
|
||||
q := psqlcore.New(r.db)
|
||||
story, err := q.SelectStory(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tags, err := q.SelectTagsByTarget(ctx, psqlcore.SelectTagsByTargetParams{
|
||||
TargetKind: "Story",
|
||||
TargetID: story.ID,
|
||||
})
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.story(story, tags), nil
|
||||
}
|
||||
|
||||
func (r *storyRepository) List(ctx context.Context, filter models.StoryFilter) ([]*models.Story, error) {
|
||||
q := psqlcore.New(r.db)
|
||||
params := psqlcore.SelectStoriesParams{LimitSize: 100}
|
||||
|
||||
if len(filter.Tags) > 0 {
|
||||
params.FilterID = true
|
||||
if len(filter.Tags) == 1 {
|
||||
tags, err := q.SelectTagsByKindName(ctx, psqlcore.SelectTagsByKindNameParams{
|
||||
Kind: string(filter.Tags[0].Kind),
|
||||
Name: filter.Tags[0].Name,
|
||||
})
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
params.Ids = append(params.Ids, tag.TargetID)
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if len(params.Ids) == 0 {
|
||||
return []*models.Story{}, nil
|
||||
}
|
||||
}
|
||||
if filter.Limit > 0 {
|
||||
params.LimitSize = 1000000
|
||||
}
|
||||
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r *storyRepository) Insert(ctx context.Context, story models.Story) (*models.Story, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r *storyRepository) Update(ctx context.Context, story models.Story, update models.StoryUpdate) (*models.Story, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r *storyRepository) AddTag(ctx context.Context, story models.Story, tag models.Tag) error {
|
||||
return psqlcore.New(r.db).SetTag(ctx, psqlcore.SetTagParams{
|
||||
Kind: string(tag.Kind),
|
||||
Name: tag.Name,
|
||||
TargetKind: "Story",
|
||||
TargetID: story.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *storyRepository) RemoveTag(ctx context.Context, story models.Story, tag models.Tag) error {
|
||||
return psqlcore.New(r.db).ClearTag(ctx, psqlcore.ClearTagParams{
|
||||
Kind: string(tag.Kind),
|
||||
Name: tag.Name,
|
||||
TargetKind: "Story",
|
||||
TargetID: story.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *storyRepository) Delete(ctx context.Context, story models.Story) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r *storyRepository) story(story psqlcore.Story, tags []psqlcore.CommonTag) *models.Story {
|
||||
tags2 := make([]models.Tag, 0, 8)
|
||||
for _, tag := range tags {
|
||||
if tag.TargetKind == "Story" && tag.TargetID == story.ID {
|
||||
tags2 = append(tags2, models.Tag{
|
||||
Kind: models.TagKind(tag.Kind),
|
||||
Name: tag.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return &models.Story{
|
||||
ID: story.ID,
|
||||
Author: story.Author,
|
||||
Name: story.Name,
|
||||
Category: models.StoryCategory(story.Category),
|
||||
Open: story.Open,
|
||||
Listed: story.Listed,
|
||||
Tags: tags2,
|
||||
CreatedDate: story.CreatedDate,
|
||||
FictionalDate: story.FictionalDate,
|
||||
UpdatedDate: story.UpdatedDate,
|
||||
SortByFictionalDate: story.SortByFictionalDate,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *storyRepository) stories(stories []psqlcore.Story, tags []psqlcore.CommonTag) []*models.Story {
|
||||
results := make([]*models.Story, 0, len(stories))
|
||||
for _, story := range stories {
|
||||
results = append(results, r.story(story, tags))
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"git.aiterp.net/rpdata/api/database/postgres/psqlcore"
|
||||
"git.aiterp.net/rpdata/api/models"
|
||||
)
|
||||
|
||||
type tagRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (r *tagRepository) Find(ctx context.Context, kind models.TagKind, name string) (*models.Tag, error) {
|
||||
tag, err := psqlcore.New(r.db).SelectTagsByTag(ctx, fmt.Sprintf("%s:%s", kind, nmae))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &models.Tag{Kind: models.TagKind(tag.Kind), Name: tag.Name}, nil
|
||||
}
|
||||
|
||||
func (r *tagRepository) List(ctx context.Context, filter models.TagFilter) ([]*models.Tag, error) {
|
||||
var tags []string
|
||||
var err error
|
||||
if filter.Kind != nil {
|
||||
tags, err = psqlcore.New(r.db).SelectDistinctTagsByKind(ctx, string(*filter.Kind))
|
||||
} else {
|
||||
tags, err = psqlcore.New(r.db).SelectDistinctTags(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return models.DecodeTagArray(tags)
|
||||
}
|
||||
|
||||
func modelsTagsFromDataTags(tags []psqlcore.CommonTag) []*models.Tag {
|
||||
results := make([]*models.Tag, len(tags))
|
||||
for i, tag := range tags {
|
||||
results[i] = &models.Tag{Kind: models.TagKind(tag.Kind), Name: tag.Name}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
+3
-2
@@ -55,9 +55,10 @@ func EncodeTagArray(arr []Tag) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func DecodeTagArray(arr []string) ([]Tag, error) {
|
||||
result := make([]Tag, len(arr))
|
||||
func DecodeTagArray(arr []string) ([]*Tag, error) {
|
||||
result := make([]*Tag, 0, len(arr))
|
||||
for i, v := range arr {
|
||||
result = append(result, &Tag{})
|
||||
err := result[i].Decode(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user