128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
type Message struct {
|
|
ID string
|
|
|
|
Blind bool
|
|
Emote bool
|
|
Style int
|
|
Timestamp int64
|
|
Content string
|
|
Author string
|
|
Type string
|
|
Flavor string
|
|
Sound string
|
|
Stats Stats
|
|
Speaker Speaker
|
|
Whisper []string
|
|
Rolls []string
|
|
}
|
|
|
|
func (m *Message) Query(data *InsertId[uint]) {
|
|
data.query = `
|
|
INSERT INTO addresses (game_id, id, blind, emote, style, timestamp, content, author, type, flavor, sound)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`
|
|
}
|
|
|
|
func (m *Message) InsertObjects(tx *sqlx.Tx) error {
|
|
relId := InsertId[string]{id: m.ID, fieldName: "message_id"}
|
|
group, ctx := errgroup.WithContext(context.Background())
|
|
|
|
InsertWithCtxParallel(group, ctx, tx, m.Stats, relId)
|
|
InsertWithCtxParallel(group, ctx, tx, m.Speaker, relId)
|
|
|
|
InsertSimpleSliceParallel(group, tx, m.Whisper, &InsertId[string]{id: m.ID, fieldName: "message_id", tableName: "message_whisper"})
|
|
InsertSimpleSliceParallel(group, tx, m.Rolls, &InsertId[string]{id: m.ID, fieldName: "message_id", tableName: "message_rolls"})
|
|
|
|
err := group.Wait()
|
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *Message) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
|
if data.query == "" {
|
|
return ErrNoQuery
|
|
}
|
|
|
|
args := []any{data.id, m.ID, m.Blind, m.Emote, m.Style, m.Timestamp, m.Content, m.Author, m.Type, m.Flavor, m.Sound}
|
|
|
|
_, err := tx.Exec(data.query, args...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Message) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
|
if data.query == "" {
|
|
return ErrNoQuery
|
|
}
|
|
|
|
args := []any{data.id, m.ID, m.Blind, m.Emote, m.Style, m.Timestamp, m.Content, m.Author, m.Type, m.Flavor, m.Sound}
|
|
|
|
_, err := tx.ExecContext(ctx, data.query, args...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Speaker struct {
|
|
ID uint
|
|
|
|
Scene string
|
|
Actor string
|
|
Token string
|
|
Alias string
|
|
}
|
|
|
|
func (s Speaker) Query(data *InsertId[string]) {
|
|
data.query = fmt.Sprintf(`
|
|
INSERT INTO speaker (%s, scene, actor, token, alias)
|
|
VALUES ($1, $2, $3, $4, $5, $6)`, data.fieldName)
|
|
}
|
|
|
|
func (s Speaker) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
|
|
if data.query == "" {
|
|
return ErrNoQuery
|
|
}
|
|
|
|
args := []any{data.id, s.Scene, s.Actor, s.Token, s.Alias}
|
|
|
|
err := tx.QueryRowx(data.query, args...).Scan(&s.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s Speaker) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
|
|
if data.query == "" {
|
|
return ErrNoQuery
|
|
}
|
|
|
|
args := []any{data.id, s.Scene, s.Actor, s.Token, s.Alias}
|
|
|
|
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&s.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|