Browse Source

add stuff that may not compile.

master
Gisle Aune 3 years ago
parent
commit
410e07a6a2
  1. 2
      database/postgres/db.go
  2. 15
      database/postgres/migrations/20210323181041_create_table_tag.sql
  3. 9
      database/postgres/migrations/20210323181601_create_index_tag_target.sql
  4. 20
      database/postgres/migrations/20210323201210_create_table_story.sql
  5. 9
      database/postgres/migrations/20210323203036_create_index_author.sql
  6. 9
      database/postgres/migrations/20210323203042_create_index_fictional_date.sql
  7. 9
      database/postgres/migrations/20210323203049_create_index_created_date.sql
  8. 9
      database/postgres/migrations/20210323203054_create_index_updated_date.sql
  9. 19
      database/postgres/psqlcore/models.go
  10. 113
      database/postgres/psqlcore/stories.sql.go
  11. 235
      database/postgres/psqlcore/tags.sql.go
  12. 13
      database/postgres/queries/stories.sql
  13. 35
      database/postgres/queries/tags.sql
  14. 129
      database/postgres/stories.go
  15. 46
      database/postgres/tags.go
  16. 5
      models/tag.go

2
database/postgres/db.go

@ -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 {

15
database/postgres/migrations/20210323181041_create_table_tag.sql

@ -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

9
database/postgres/migrations/20210323181601_create_index_tag_target.sql

@ -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

20
database/postgres/migrations/20210323201210_create_table_story.sql

@ -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

9
database/postgres/migrations/20210323203036_create_index_author.sql

@ -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

9
database/postgres/migrations/20210323203042_create_index_fictional_date.sql

@ -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

9
database/postgres/migrations/20210323203049_create_index_created_date.sql

@ -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

9
database/postgres/migrations/20210323203054_create_index_updated_date.sql

@ -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

19
database/postgres/psqlcore/models.go

@ -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"`
}

113
database/postgres/psqlcore/stories.sql.go

@ -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
}

235
database/postgres/psqlcore/tags.sql.go

@ -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
}

13
database/postgres/queries/stories.sql

@ -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;

35
database/postgres/queries/tags.sql

@ -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[]);

129
database/postgres/stories.go

@ -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
}

46
database/postgres/tags.go

@ -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
}

5
models/tag.go

@ -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

Loading…
Cancel
Save