158 lines
4.1 KiB
Go
158 lines
4.1 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
type Game struct {
|
|
ID uint
|
|
CreatedAt time.Time
|
|
|
|
DemoMode bool
|
|
IdleLogout bool
|
|
Paused bool
|
|
UserID string
|
|
|
|
Addresses Addresses
|
|
Files Files
|
|
Options GameOptions
|
|
Release Release
|
|
World *World
|
|
System *System
|
|
CoreUpdate CoreUpdate
|
|
SystemUpdate SystemUpdate
|
|
ActiveUsers []string
|
|
Modules []*Module
|
|
PackageWarnings []*PackageWarning
|
|
Packs []*Pack
|
|
Messages []*Message
|
|
Combats []*Combat
|
|
CardDeck []*CardDeck
|
|
Users []*User
|
|
Macros []*Macro
|
|
Folders []*WorldFolder
|
|
Items []*Item
|
|
Settings []*Setting
|
|
Journals []*Journal
|
|
Tables []*Table
|
|
Playlists []*Playlist
|
|
Actors []*Actor
|
|
// Scenes []Scene
|
|
}
|
|
|
|
func (g *Game) InsertObjects(db *sqlx.DB) error {
|
|
relData := InsertId[uint]{id: g.ID, fieldName: "game_id"}
|
|
|
|
err := func() error {
|
|
tx := db.MustBegin()
|
|
defer tx.Rollback()
|
|
|
|
groupFunc, _ := errgroup.WithContext(context.Background())
|
|
|
|
InsertWithCtxParallel(groupFunc, tx, &g.Addresses, relData)
|
|
InsertWithCtxParallel(groupFunc, tx, &g.Files, relData)
|
|
InsertWithCtxParallel(groupFunc, tx, &g.Options, relData)
|
|
InsertWithCtxParallel(groupFunc, tx, &g.Release, relData)
|
|
InsertWithCtxParallel(groupFunc, tx, &g.CoreUpdate, relData)
|
|
InsertWithCtxParallel(groupFunc, tx, &g.SystemUpdate, relData)
|
|
|
|
relDataString := InsertId[string]{id: strconv.FormatUint(uint64(g.ID), 10), fieldName: "game_id"}
|
|
InsertWithCtxParallel(groupFunc, tx, g.World, relDataString)
|
|
InsertWithCtxParallel(groupFunc, tx, g.System, relDataString)
|
|
|
|
InsertSimpleSliceParallel(groupFunc, tx, g.ActiveUsers,
|
|
&InsertId[uint]{id: g.ID, fieldName: "game_id", tableName: "active_users"})
|
|
|
|
InsertSliceParallel(groupFunc, tx, g.Modules, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.PackageWarnings, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Packs, relDataString)
|
|
InsertSliceParallel(groupFunc, tx, g.Messages, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Combats, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.CardDeck, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Users, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Macros, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Folders, relData)
|
|
|
|
errFunc := groupFunc.Wait()
|
|
if errFunc != nil && !errors.Is(errFunc, sql.ErrNoRows) {
|
|
return errFunc
|
|
}
|
|
return tx.Commit()
|
|
}()
|
|
|
|
err = func() error {
|
|
tx := db.MustBegin()
|
|
defer tx.Rollback()
|
|
groupFunc, _ := errgroup.WithContext(context.Background())
|
|
|
|
InsertSliceParallel(groupFunc, tx, g.Settings, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Journals, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Tables, relData)
|
|
InsertSliceParallel(groupFunc, tx, g.Playlists, relData)
|
|
|
|
errFunc := groupFunc.Wait()
|
|
if errFunc != nil && !errors.Is(errFunc, sql.ErrNoRows) {
|
|
return errFunc
|
|
}
|
|
return tx.Commit()
|
|
}()
|
|
|
|
err = func() error {
|
|
tx := db.MustBegin()
|
|
defer tx.Rollback()
|
|
groupFunc, _ := errgroup.WithContext(context.Background())
|
|
|
|
InsertSliceParallelTimeout(groupFunc, tx, g.Items,
|
|
InsertId[string]{id: strconv.FormatUint(uint64(g.ID), 10), fieldName: "game_id"},
|
|
15*time.Second)
|
|
InsertSliceParallelTimeout(groupFunc, tx, g.Actors, relData, 15*time.Second)
|
|
|
|
errFunc := groupFunc.Wait()
|
|
if errFunc != nil && !errors.Is(errFunc, sql.ErrNoRows) {
|
|
return errFunc
|
|
}
|
|
return tx.Commit()
|
|
}()
|
|
|
|
return err
|
|
}
|
|
|
|
func (g *Game) Insert(db *sqlx.DB) error {
|
|
tx := db.MustBegin()
|
|
defer tx.Rollback()
|
|
|
|
const query = `
|
|
INSERT INTO game (demo_mode, idle_logout, paused, user_id)
|
|
VALUES ($1, $2, $3, $4)
|
|
RETURNING id, created_at`
|
|
|
|
args := []any{g.DemoMode, g.IdleLogout, g.Paused, g.UserID}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
err := tx.QueryRowxContext(ctx, query, args...).Scan(&g.ID, &g.CreatedAt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = g.InsertObjects(db)
|
|
if err != nil {
|
|
fmt.Printf("%v\n", err)
|
|
}
|
|
|
|
return err
|
|
}
|