Gisle Aune
4 years ago
32 changed files with 862 additions and 99 deletions
-
25cmd/rpdata-restore/main.go
-
8database/postgres/changes.go
-
2database/postgres/channel.go
-
2database/postgres/chapters.go
-
2database/postgres/character.go
-
2database/postgres/comments.go
-
6database/postgres/db.go
-
246database/postgres/logs.go
-
19database/postgres/migrations/20210327143154_create_table_log.sql
-
20database/postgres/migrations/20210327143158_create_table_post.sql
-
9database/postgres/migrations/20210327160328_create_index_post_search.sql
-
9database/postgres/migrations/20210327160357_create_index_log_open.sql
-
9database/postgres/migrations/20210327160406_create_index_log_characters.sql
-
9database/postgres/migrations/20210327160409_create_index_log_channel_name.sql
-
9database/postgres/migrations/20210327160414_create_index_log_event_name.sql
-
9database/postgres/migrations/20210327160427_create_index_log_date.sql
-
9database/postgres/migrations/20210327160502_create_index_post_kind.sql
-
266database/postgres/posts.go
-
16database/postgres/queries/changes.sql
-
26database/postgres/queries/channels.sql
-
5database/postgres/queries/chapters.sql
-
2database/postgres/queries/characters.sql
-
4database/postgres/queries/comments.sql
-
6database/postgres/queries/counter.sql
-
32database/postgres/queries/logs.sql
-
60database/postgres/queries/posts.sql
-
40database/postgres/queries/stories.sql
-
43database/postgres/queries/tags.sql
-
6database/postgres/stories.go
-
13database/postgres/tags.go
-
20models/log.go
-
15models/post.go
@ -0,0 +1,246 @@ |
|||
package postgres |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"fmt" |
|||
"git.aiterp.net/rpdata/api/database/postgres/psqlcore" |
|||
"git.aiterp.net/rpdata/api/internal/generate" |
|||
"git.aiterp.net/rpdata/api/models" |
|||
"strconv" |
|||
"time" |
|||
) |
|||
|
|||
type logRepository struct { |
|||
insertWithIDs bool |
|||
db *sql.DB |
|||
} |
|||
|
|||
func (r *logRepository) Find(ctx context.Context, id string) (*models.Log, error) { |
|||
log, err := psqlcore.New(r.db).SelectLog(ctx, id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return r.log(log), nil |
|||
} |
|||
|
|||
func (r *logRepository) List(ctx context.Context, filter models.LogFilter) ([]*models.Log, error) { |
|||
q := psqlcore.New(r.db) |
|||
params := psqlcore.SelectLogsParams{ |
|||
LimitSize: 0, |
|||
} |
|||
|
|||
if filter.Search != nil { |
|||
ids, err := q.SelectLogIDsFromPostSearch(ctx, *filter.Search) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
params.FilterShortID = true |
|||
params.ShortIds = ids |
|||
} |
|||
if filter.Open != nil { |
|||
params.FilterOpen = true |
|||
params.Open = *filter.Open |
|||
} |
|||
if filter.Channels != nil { |
|||
params.FilterChannelName = true |
|||
params.ChannelNames = filter.Channels |
|||
} |
|||
if filter.Events != nil { |
|||
params.FilterEventName = true |
|||
params.EventNames = filter.Events |
|||
} |
|||
if filter.MinDate != nil { |
|||
params.FilterEarlistDate = true |
|||
params.EarliestDate = *filter.MinDate |
|||
} |
|||
if filter.MaxDate != nil { |
|||
params.FilterLastestDate = true |
|||
params.LatestDate = *filter.MaxDate |
|||
} |
|||
if filter.Limit > 0 { |
|||
params.LimitSize = int32(filter.Limit) |
|||
} |
|||
|
|||
logs, err := q.SelectLogs(ctx, params) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return r.logs(logs), nil |
|||
} |
|||
|
|||
func (r *logRepository) Insert(ctx context.Context, log models.Log) (*models.Log, error) { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer func() { _ = tx.Rollback() }() |
|||
q := psqlcore.New(tx) |
|||
|
|||
if !r.insertWithIDs || log.ID == "" { |
|||
log.ID = generate.LogID(log) |
|||
} |
|||
|
|||
if !r.insertWithIDs || log.ShortID == "" { |
|||
next, err := q.IncrementCounter(ctx, "log_short_id") |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
log.ShortID = fmt.Sprintf("L%d", next) |
|||
} else { |
|||
n, err := strconv.Atoi(log.ShortID[1:]) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
err = q.BumpCounter(ctx, psqlcore.BumpCounterParams{ |
|||
ID: "log_short_id", |
|||
Value: int32(n), |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
} |
|||
|
|||
err = q.InsertLog(ctx, psqlcore.InsertLogParams{ |
|||
ID: log.ID, |
|||
ShortID: log.ShortID, |
|||
Date: log.Date.UTC(), |
|||
ChannelName: log.ChannelName, |
|||
EventName: log.EventName, |
|||
Title: log.Title, |
|||
Description: log.Description, |
|||
Open: log.Open, |
|||
CharacterIds: log.CharacterIDs, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
err = tx.Commit() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
_ = r.updateTags(log) |
|||
|
|||
return &log, nil |
|||
} |
|||
|
|||
func (r *logRepository) Update(ctx context.Context, log models.Log, update models.LogUpdate) (*models.Log, error) { |
|||
log.ApplyUpdate(update) |
|||
|
|||
err := psqlcore.New(r.db).UpdateLog(ctx, psqlcore.UpdateLogParams{ |
|||
Title: log.Title, |
|||
EventName: log.EventName, |
|||
Description: log.Description, |
|||
Open: log.Open, |
|||
CharacterIds: log.CharacterIDs, |
|||
ID: log.ID, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
_ = r.updateTags(log) |
|||
|
|||
return &log, nil |
|||
} |
|||
|
|||
func (r *logRepository) Delete(ctx context.Context, log models.Log) error { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer func() { _ = tx.Rollback() }() |
|||
q := psqlcore.New(tx) |
|||
|
|||
err = q.DeleteLog(ctx, log.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeletePostsByLogShortID(ctx, log.ShortID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
return tx.Commit() |
|||
} |
|||
|
|||
func (r *logRepository) log(log psqlcore.Log) *models.Log { |
|||
return &models.Log{ |
|||
ID: log.ID, |
|||
ShortID: log.ShortID, |
|||
Date: log.Date, |
|||
ChannelName: log.ChannelName, |
|||
EventName: log.EventName, |
|||
Title: log.Title, |
|||
Description: log.Description, |
|||
Open: log.Open, |
|||
CharacterIDs: log.CharacterIds, |
|||
} |
|||
} |
|||
|
|||
func (r *logRepository) logs(logs []psqlcore.Log) []*models.Log { |
|||
results := make([]*models.Log, 0, len(logs)) |
|||
for _, log := range logs { |
|||
results = append(results, r.log(log)) |
|||
} |
|||
|
|||
return results |
|||
} |
|||
|
|||
func (r *logRepository) updateTags(log models.Log) error { |
|||
ctx, cancel := context.WithTimeout(context.Background(), time.Second) |
|||
defer cancel() |
|||
|
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer func() { _ = tx.Rollback() }() |
|||
q := psqlcore.New(tx) |
|||
|
|||
err = q.ClearTagsByTarget(ctx, psqlcore.ClearTagsByTargetParams{TargetKind: "Log", TargetID: log.ID}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
if len(log.CharacterIDs) > 0 { |
|||
err := q.SetCharacterTagsFromIDs(ctx, psqlcore.SetCharacterTagsFromIDsParams{ |
|||
TargetKind: "log", |
|||
TargetID: log.ID, |
|||
CharacterIds: log.CharacterIDs, |
|||
}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
} |
|||
|
|||
err = q.SetLocationTagFromChannelName(ctx, psqlcore.SetLocationTagFromChannelNameParams{ |
|||
TargetKind: "log", |
|||
TargetID: log.ID, |
|||
ChannelName: log.ChannelName, |
|||
}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
if log.EventName != "" { |
|||
err := q.SetTag(ctx, psqlcore.SetTagParams{ |
|||
Tag: "Event:" + log.EventName, |
|||
TargetKind: "Log", |
|||
TargetID: log.ID, |
|||
}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
} |
|||
|
|||
return tx.Commit() |
|||
} |
@ -0,0 +1,19 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE log ( |
|||
id TEXT NOT NULL PRIMARY KEY, |
|||
short_id TEXT NOT NULL UNIQUE, |
|||
character_ids TEXT[] NOT NULL, |
|||
date TIMESTAMP NOT NULL, |
|||
channel_name TEXT NOT NULL, |
|||
event_name TEXT NOT NULL, |
|||
title TEXT NOT NULL, |
|||
description TEXT NOT NULL, |
|||
open BOOLEAN NOT NULL |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE log; |
|||
-- +goose StatementEnd |
@ -0,0 +1,20 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE log_post ( |
|||
id TEXT NOT NULL PRIMARY KEY, |
|||
log_short_id TEXT NOT NULL, |
|||
time TIMESTAMP NOT NULL, |
|||
kind TEXT NOT NULL, |
|||
nick TEXT NOT NULL, |
|||
text TEXT NOT NULL, |
|||
position INT NOT NULL, |
|||
ts_vector TSVECTOR NOT NULL, |
|||
|
|||
UNIQUE (log_short_id, position) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE log_post; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_post_index_search ON log_post USING GIN (ts_vector); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_post_index_search; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_index_open ON log (open); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_index_open |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_index_character_ids on log USING GIN (character_ids); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_index_character_ids; |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_index_channel_name ON log (channel_name); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_index_channel_name |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_index_event_name ON log (event_name); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_index_event_name |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_index_date ON log (date); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_index_date |
|||
-- +goose StatementEnd |
@ -0,0 +1,9 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE INDEX log_post_index_kind ON log_post (kind); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP INDEX IF EXISTS log_post_index_kind |
|||
-- +goose StatementEnd |
@ -0,0 +1,266 @@ |
|||
package postgres |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"errors" |
|||
"git.aiterp.net/rpdata/api/database/postgres/psqlcore" |
|||
"git.aiterp.net/rpdata/api/internal/generate" |
|||
"git.aiterp.net/rpdata/api/models" |
|||
"strings" |
|||
) |
|||
|
|||
type postRepository struct { |
|||
insertWithIDs bool |
|||
db *sql.DB |
|||
} |
|||
|
|||
func (r *postRepository) Find(ctx context.Context, id string) (*models.Post, error) { |
|||
post, err := psqlcore.New(r.db).SelectPost(ctx, id) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return r.post(post), nil |
|||
} |
|||
|
|||
func (r *postRepository) List(ctx context.Context, filter models.PostFilter) ([]*models.Post, error) { |
|||
q := psqlcore.New(r.db) |
|||
params := psqlcore.SelectPostsParams{LimitSize: 0} |
|||
if filter.LogID != nil { |
|||
params.FilterLogShortID = true |
|||
|
|||
if !strings.HasPrefix(*filter.LogID, "L") { |
|||
log, err := q.SelectLog(ctx, *filter.LogID) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
params.LogShortID = log.ShortID |
|||
} else { |
|||
params.LogShortID = *filter.LogID |
|||
} |
|||
} |
|||
if filter.Kinds != nil { |
|||
params.FilterKinds = true |
|||
params.Kinds = filter.Kinds |
|||
} |
|||
if filter.Search != nil { |
|||
params.FilterSearch = true |
|||
params.Search = *filter.Search |
|||
} |
|||
if filter.Limit > 0 { |
|||
params.LimitSize = int32(filter.Limit) |
|||
} |
|||
|
|||
posts, err := q.SelectPosts(ctx, params) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return r.posts(posts), nil |
|||
} |
|||
|
|||
func (r *postRepository) Insert(ctx context.Context, post models.Post) (*models.Post, error) { |
|||
if !r.insertWithIDs || len(post.ID) < 8 { |
|||
post.ID = generate.PostID() |
|||
} |
|||
|
|||
position, err := psqlcore.New(r.db).InsertPost(ctx, psqlcore.InsertPostParams{ |
|||
ID: post.ID, |
|||
LogShortID: post.LogID, |
|||
Time: post.Time.UTC(), |
|||
Kind: post.Kind, |
|||
Nick: post.Nick, |
|||
Text: post.Text, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
post.Position = int(position) |
|||
|
|||
return &post, nil |
|||
} |
|||
|
|||
func (r *postRepository) InsertMany(ctx context.Context, posts ...*models.Post) ([]*models.Post, error) { |
|||
allowedLogID := "" |
|||
for _, post := range posts { |
|||
if allowedLogID == "" { |
|||
allowedLogID = post.LogID |
|||
} else if allowedLogID != post.LogID { |
|||
return nil, errors.New("cannot insert multiple posts with different log IDs") |
|||
} |
|||
} |
|||
|
|||
params := psqlcore.InsertPostsParams{ |
|||
LogShortID: posts[0].LogID, |
|||
} |
|||
|
|||
for _, post := range posts { |
|||
if !r.insertWithIDs || len(post.ID) < 8 { |
|||
post.ID = generate.PostID() |
|||
} |
|||
|
|||
params.Ids = append(params.Ids, post.ID) |
|||
params.Kinds = append(params.Kinds, post.Kind) |
|||
params.Nicks = append(params.Nicks, post.Nick) |
|||
params.Offsets = append(params.Offsets, int32(len(params.Offsets)+1)) |
|||
params.Times = append(params.Times, post.Time.UTC()) |
|||
params.Texts = append(params.Texts, post.Text) |
|||
} |
|||
|
|||
offset, err := psqlcore.New(r.db).InsertPosts(ctx, params) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
for i, post := range posts { |
|||
post.Position = int(offset) + i |
|||
} |
|||
|
|||
return posts, nil |
|||
} |
|||
|
|||
func (r *postRepository) Update(ctx context.Context, post models.Post, update models.PostUpdate) (*models.Post, error) { |
|||
post.ApplyUpdate(update) |
|||
|
|||
err := psqlcore.New(r.db).UpdatePost(ctx, psqlcore.UpdatePostParams{ |
|||
Time: post.Time, |
|||
Kind: post.Kind, |
|||
Nick: post.Nick, |
|||
Text: post.Text, |
|||
ID: post.ID, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return &post, nil |
|||
} |
|||
|
|||
func (r *postRepository) Move(ctx context.Context, post models.Post, position int) ([]*models.Post, error) { |
|||
if position == post.Position { |
|||
return r.List(ctx, models.PostFilter{LogID: &post.LogID}) |
|||
} |
|||
|
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer func() { _ = tx.Rollback() }() |
|||
|
|||
_, err = tx.Exec("LOCK TABLE log_post IN SHARE UPDATE EXCLUSIVE MODE") |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
var lowest, highest int32 |
|||
|
|||
q := psqlcore.New(tx) |
|||
|
|||
err = q.MovePost(ctx, psqlcore.MovePostParams{ID: post.ID, Position: -1}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
if position > post.Position { |
|||
lowest = int32(post.Position) |
|||
highest = int32(position) |
|||
|
|||
err := q.ShiftPostsBetween(ctx, psqlcore.ShiftPostsBetweenParams{ |
|||
ShiftOffset: -1, |
|||
LogShortID: post.LogID, |
|||
FromPosition: lowest + 1, |
|||
ToPosition: highest, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
} else { |
|||
lowest = int32(position) |
|||
highest = int32(post.Position) |
|||
|
|||
err := q.ShiftPostsBetween(ctx, psqlcore.ShiftPostsBetweenParams{ |
|||
ShiftOffset: 1, |
|||
LogShortID: post.LogID, |
|||
FromPosition: lowest, |
|||
ToPosition: highest - 1, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
} |
|||
|
|||
err = q.MovePost(ctx, psqlcore.MovePostParams{ID: post.ID, Position: int32(position)}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
posts, err := q.SelectPostsByPositionRange(ctx, psqlcore.SelectPostsByPositionRangeParams{ |
|||
LogShortID: post.LogID, |
|||
FromPosition: lowest, |
|||
ToPosition: highest, |
|||
}) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
err = tx.Commit() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return r.posts(posts), nil |
|||
} |
|||
|
|||
func (r *postRepository) Delete(ctx context.Context, post models.Post) error { |
|||
tx, err := r.db.BeginTx(ctx, nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer func() { _ = tx.Rollback() }() |
|||
q := psqlcore.New(tx) |
|||
|
|||
_, err = tx.Exec("LOCK TABLE log_post IN SHARE UPDATE EXCLUSIVE MODE") |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.DeletePost(ctx, post.ID) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
err = q.ShiftPostsAfter(ctx, psqlcore.ShiftPostsAfterParams{ |
|||
ShiftOffset: -1, |
|||
LogShortID: post.LogID, |
|||
FromPosition: int32(post.Position + 1), |
|||
}) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
|
|||
return tx.Commit() |
|||
} |
|||
|
|||
func (r *postRepository) post(post psqlcore.LogPost) *models.Post { |
|||
return &models.Post{ |
|||
ID: post.ID, |
|||
LogID: post.LogShortID, |
|||
Time: post.Time, |
|||
Kind: post.Kind, |
|||
Nick: post.Nick, |
|||
Text: post.Text, |
|||
Position: int(post.Position), |
|||
} |
|||
} |
|||
|
|||
func (r *postRepository) posts(posts []psqlcore.LogPost) []*models.Post { |
|||
results := make([]*models.Post, 0, len(posts)) |
|||
for _, post := range posts { |
|||
results = append(results, r.post(post)) |
|||
} |
|||
|
|||
return results |
|||
} |
@ -1,8 +1,8 @@ |
|||
-- name: EnsureCounter :exec |
|||
INSERT INTO core_counter (id, value) VALUES ($1::text, 0) ON CONFLICT DO NOTHING; |
|||
INSERT INTO core_counter (id, value) VALUES (@id::text, 0) ON CONFLICT DO NOTHING; |
|||
|
|||
-- name: IncrementCounter :one |
|||
UPDATE core_counter SET value = value + 1 WHERE id = $1::text RETURNING value::int; |
|||
UPDATE core_counter SET value = value + 1 WHERE id = @id::text RETURNING value::int; |
|||
|
|||
-- name: BumpCounter :exec |
|||
UPDATE core_counter SET value = value + 1 WHERE id = sqlc.arg(id)::text AND value <= sqlc.arg(value)::int; |
|||
UPDATE core_counter SET value = value + 1 WHERE id = @id::text AND value <= @value::int; |
@ -0,0 +1,32 @@ |
|||
-- name: SelectLog :one |
|||
SELECT * FROM log WHERE id=$1 OR short_id=$1 LIMIT 1; |
|||
|
|||
-- name: SelectLogs :many |
|||
SELECT * FROM log |
|||
WHERE (@filter_short_id::BOOL = false OR short_id = ANY(@short_ids::TEXT[])) |
|||
AND (@filter_character_id::BOOL = false OR character_ids && (@character_ids::TEXT[])) |
|||
AND (@filter_channel_name::BOOL = false OR channel_name = ANY(@channel_names::TEXT[])) |
|||
AND (@filter_event_name::BOOL = false OR event_name = ANY(@event_names::TEXT[])) |
|||
AND (@filter_open::BOOL = false OR open = @open::BOOL) |
|||
AND (@filter_earlist_date::BOOL = false OR date >= @earliest_date::TIMESTAMP) |
|||
AND (@filter_lastest_date::BOOL = false OR date <= @latest_date::TIMESTAMP) |
|||
ORDER BY date |
|||
LIMIT NULLIF(@limit_size::INT, 0); |
|||
|
|||
-- name: InsertLog :exec |
|||
INSERT INTO log (id, short_id, character_ids, date, channel_name, event_name, title, description, open) |
|||
VALUES ( |
|||
@id, @short_id, @character_ids, @date, @channel_name, @event_name, @title, @description, @open |
|||
); |
|||
|
|||
-- name: UpdateLog :exec |
|||
UPDATE log |
|||
SET title = @title, |
|||
event_name = @event_name, |
|||
description = @description, |
|||
open = @open, |
|||
character_ids = @character_ids |
|||
WHERE id = @id; |
|||
|
|||
-- name: DeleteLog :exec |
|||
DELETE FROM log WHERE id=$1; |
@ -0,0 +1,60 @@ |
|||
-- name: SelectPost :one |
|||
SELECT * FROM log_post WHERE id=$1 LIMIT 1; |
|||
|
|||
-- name: SelectLogIDsFromPostSearch :many |
|||
SELECT DISTINCT(log_short_id) FROM log_post WHERE "ts_vector" @@ to_tsquery(@search::TEXT); |
|||
|
|||
-- name: SelectPostsByPositionRange :many |
|||
SELECT * FROM log_post WHERE log_short_id = @log_short_id AND position >= @from_position AND position = @to_position; |
|||
|
|||
-- name: SelectPosts :many |
|||
SELECT * FROM log_post |
|||
WHERE (@filter_ids::BOOL = false OR id = ANY(@ids::TEXT[])) |
|||
AND (@filter_kinds::BOOL = false OR kind = ANY(@kinds::TEXT[])) |
|||
AND (@filter_log_short_id::BOOL = false OR log_short_id = @log_short_id) |
|||
AND (@filter_search::BOOL = false OR "ts_vector" @@ to_tsquery(@search::TEXT)) |
|||
ORDER BY log_short_id, position |
|||
LIMIT NULLIF(@limit_size::INT, 0); |
|||
|
|||
-- name: InsertPost :one |
|||
INSERT INTO log_post (id, log_short_id, time, kind, nick, text, position, ts_vector) |
|||
SELECT @id, @log_short_id, @time, @kind, @nick, @text, COALESCE(MAX(position), 0)+1, to_tsvector(@nick || ' ' || @text) |
|||
FROM log_post |
|||
WHERE log_short_id=@log_short_id |
|||
RETURNING position; |
|||
|
|||
-- name: InsertPosts :one |
|||
INSERT INTO log_post (id, log_short_id, time, kind, nick, text, position, ts_vector) |
|||
SELECT UNNEST(@ids::TEXT[]), @log_short_id, UNNEST(@times::TIMESTAMP[]), UNNEST(@kinds::TEXT[]), |
|||
UNNEST(@nicks::TEXT[]), UNNEST(@texts::TEXT[]), COALESCE(MAX(position), 1) + UNNEST(@offsets::INT[]), |
|||
to_tsvector(UNNEST(@nicks::TEXT[]) || ' ' || UNNEST(@texts::TEXT[])) |
|||
FROM log_post |
|||
WHERE log_short_id = @log_short_id |
|||
RETURNING position; |
|||
|
|||
-- name: UpdatePost :exec |
|||
UPDATE log_post |
|||
SET time = @time, |
|||
kind = @kind, |
|||
nick = @nick, |
|||
text = @text, |
|||
ts_vector = to_tsvector(@nick || ' ' || @text) |
|||
WHERE id = @id; |
|||
|
|||
-- name: MovePost :exec |
|||
UPDATE log_post SET position = @position WHERE id = @id; |
|||
|
|||
-- name: ShiftPostsBetween :exec |
|||
UPDATE log_post SET position = position + @shift_offset::INT WHERE log_short_id = @log_short_id AND position >= @from_position AND position <= @to_position; |
|||
|
|||
-- name: ShiftPostsAfter :exec |
|||
UPDATE log_post SET position = position + @shift_offset::INT WHERE log_short_id = @log_short_id AND position >= @from_position; |
|||
|
|||
-- name: ShiftPostsBefore :exec |
|||
UPDATE log_post SET position = position + @shift_offset::INT WHERE log_short_id = @log_short_id AND position <= @to_position; |
|||
|
|||
-- name: DeletePost :exec |
|||
DELETE FROM log_post WHERE id = @id; |
|||
|
|||
-- name: DeletePostsByLogShortID :exec |
|||
DELETE FROM log_post WHERE log_short_id = @log_short_id; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue