add setup insert methods
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type StateType int
|
||||
@@ -44,7 +46,7 @@ type Options struct {
|
||||
}
|
||||
|
||||
type FoundryStateModel struct {
|
||||
DB *sql.DB
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
func (m FoundryStateModel) Insert(state *FoundryState) error {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package db
|
||||
|
||||
import "database/sql"
|
||||
import "github.com/jmoiron/sqlx"
|
||||
|
||||
// var (
|
||||
// ErrRecordNotFound = errors.New("record not found")
|
||||
@@ -21,7 +21,7 @@ type Models struct {
|
||||
// }
|
||||
// }
|
||||
|
||||
func NewModels(db *sql.DB) *Models {
|
||||
func NewModels(db *sqlx.DB) *Models {
|
||||
return &Models{
|
||||
FoundryState: FoundryStateModel{DB: db},
|
||||
}
|
||||
|
||||
@@ -1,7 +1,99 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Files struct {
|
||||
ID uint
|
||||
|
||||
Storages []string
|
||||
Storages []FilesStorage
|
||||
}
|
||||
|
||||
func (f *Files) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO files (%s)
|
||||
VALUES ($1)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
syncDB := SyncDbOperations{
|
||||
wg: sync.WaitGroup{},
|
||||
errChan: make(chan error),
|
||||
}
|
||||
|
||||
InsertSliceParallel[uint](&syncDB, tx, f.Storages, &InsertId[uint]{id: f.ID})
|
||||
|
||||
return syncDB.Wait()
|
||||
}
|
||||
|
||||
func (f *Files) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO files (%s)
|
||||
VALUES ($1)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
syncDB := SyncDbOperations{
|
||||
wg: sync.WaitGroup{},
|
||||
errChan: make(chan error),
|
||||
}
|
||||
|
||||
InsertSliceParallel(&syncDB, tx, f.Storages, &InsertId[uint]{id: f.ID})
|
||||
|
||||
return syncDB.Wait()
|
||||
}
|
||||
|
||||
type FilesStorage struct {
|
||||
ID uint
|
||||
|
||||
Storage string
|
||||
}
|
||||
|
||||
func (f FilesStorage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := `
|
||||
INSERT INTO files (files_id, storage)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, f.Storage}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f FilesStorage) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
const query = `
|
||||
INSERT INTO featured_content (files_id, storage)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, f.Storage}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package db
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FoundryDataType string
|
||||
|
||||
@@ -17,3 +20,7 @@ type FoundryData struct {
|
||||
Game *Game
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type FoundryDataModel struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ type Game struct {
|
||||
Files Files
|
||||
Options GameOptions
|
||||
Release Release
|
||||
World World
|
||||
System System
|
||||
World *World
|
||||
System *System
|
||||
CoreUpdate CoreUpdate
|
||||
SystemUpdate SystemUpdate
|
||||
ActiveUsers []string
|
||||
Modules []Module
|
||||
PackageWarnings []PackageWarning
|
||||
Modules []*Module
|
||||
PackageWarnings []*PackageWarning
|
||||
Packs []Pack
|
||||
Messages []Message
|
||||
Combats []Combat
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Language struct {
|
||||
ID uint
|
||||
|
||||
@@ -15,9 +21,77 @@ type SetupLanguage struct {
|
||||
Modules []SetupLanguageModule
|
||||
}
|
||||
|
||||
func (l SetupLanguage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
const query = `
|
||||
INSERT INTO setup_language (setup_id, label)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, l.Label}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&l.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
InsertSlice(tx, l.Modules, &InsertId[string]{id: l.ID})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l SetupLanguage) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
const query = `
|
||||
INSERT INTO setup_language (setup_id, label)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, l.Label}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&l.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
InsertSlice(tx, l.Modules, &InsertId[string]{id: l.ID})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetupLanguageModule struct {
|
||||
ID string
|
||||
|
||||
Label string
|
||||
Path string
|
||||
}
|
||||
|
||||
func (l SetupLanguageModule) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
|
||||
const query = `
|
||||
INSERT INTO setup_language_module (setup_language_id, label, path)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, l.Label, l.Path}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&l.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l SetupLanguageModule) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
|
||||
const query = `
|
||||
INSERT INTO setup_language_module (setup_language_id, label, path)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{data.id, l.Label, l.Path}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&l.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type GameOptions struct {
|
||||
ID uint
|
||||
|
||||
@@ -8,23 +14,95 @@ type GameOptions struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
func (g *GameOptions) Insert(tx *sqlx.Tx, gameId *InsertId[uint]) error {
|
||||
query := `
|
||||
INSERT INTO featured_content (game_id, language, update_channel, port)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{gameId.id, g.Language, g.UpdateChannel, g.Port}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&g.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GameOptions) InsertCtx(ctx context.Context, tx *sqlx.Tx, gameId *InsertId[uint]) error {
|
||||
query := `
|
||||
INSERT INTO featured_content (game_id, language, update_channel, port)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{gameId.id, g.Language, g.UpdateChannel, g.Port}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&g.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetupOptions struct {
|
||||
ID uint
|
||||
|
||||
CompressSocket bool
|
||||
CompressStatic bool
|
||||
CSSTheme string
|
||||
DataPath string
|
||||
Fullscreen bool
|
||||
Hostname string
|
||||
HotReload bool
|
||||
Language string
|
||||
LocalHostname string
|
||||
UpdateChannel string
|
||||
Port int
|
||||
CompressSocket bool
|
||||
CompressStatic bool
|
||||
Fullscreen bool
|
||||
HotReload bool
|
||||
ProxySSL bool
|
||||
Telemetry bool
|
||||
UpdateChannel string
|
||||
Upnp bool
|
||||
DeleteNEDB bool
|
||||
NoBackups bool
|
||||
}
|
||||
|
||||
func (s *SetupOptions) Insert(tx *sqlx.Tx, setupId *InsertId[uint]) error {
|
||||
query := `
|
||||
INSERT INTO featured_content (setup_id, compress_socket, compress_static, css_theme, data_path,
|
||||
fullscreen, hostname, hot_reload, language, local_hostname, port,
|
||||
proxy_ssl, telemetry, update_channel, upnp, delete_nedb, no_backups)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setupId.id, s.CompressSocket, s.CompressStatic, s.CSSTheme, s.DataPath,
|
||||
s.Fullscreen, s.Hostname, s.HotReload, s.Language, s.LocalHostname, s.Port,
|
||||
s.ProxySSL, s.Telemetry, s.UpdateChannel, s.Upnp, s.DeleteNEDB, s.NoBackups}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&s.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SetupOptions) InsertCtx(ctx context.Context, tx *sqlx.Tx, setupId *InsertId[uint]) error {
|
||||
query := `
|
||||
INSERT INTO featured_content (setup_id, compress_socket, compress_static, css_theme, data_path,
|
||||
fullscreen, hostname, hot_reload, language, local_hostname, port,
|
||||
proxy_ssl, telemetry, update_channel, upnp, delete_nedb, no_backups)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setupId.id, s.CompressSocket, s.CompressStatic, s.CSSTheme, s.DataPath,
|
||||
s.Fullscreen, s.Hostname, s.HotReload, s.Language, s.LocalHostname, s.Port,
|
||||
s.ProxySSL, s.Telemetry, s.UpdateChannel, s.Upnp, s.DeleteNEDB, s.NoBackups}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&s.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type PackageWarningsData struct {
|
||||
ID string
|
||||
|
||||
@@ -10,9 +17,89 @@ type PackageWarningsData struct {
|
||||
Manifest string
|
||||
}
|
||||
|
||||
func (p *PackageWarningsData) InsertSliceType(tx *sqlx.Tx, data *InsertId[string], sliceType string) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO package_warnings_data (%s, id, type, reinstallable, manifest)
|
||||
VALUES ($1, $2, $3, $4, $5)`, data.fieldName)
|
||||
|
||||
args := []any{data.id, p.ID, p.Type, p.Reinstallable, p.Manifest}
|
||||
|
||||
_, err := tx.Exec(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PackageWarningsData) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO package_warnings_data (%s, id, type, reinstallable, manifest)
|
||||
VALUES ($1, $2, $3, $4, $5)`, data.fieldName)
|
||||
|
||||
args := []any{data.id, p.ID, p.Type, p.Reinstallable, p.Manifest}
|
||||
|
||||
_, err := tx.Exec(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PackageWarningsData) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO package_warnings_data (%s, id, type, reinstallable, manifest)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id, p.ID, p.Type, p.Reinstallable, p.Manifest}
|
||||
|
||||
_, err := tx.ExecContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PackageWarning struct {
|
||||
ID string
|
||||
|
||||
Key string
|
||||
Value PackageWarningsData
|
||||
}
|
||||
|
||||
func (p *PackageWarning) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO package_warnings (%s, id)
|
||||
VALUES ($1, $2)`, data.fieldName)
|
||||
|
||||
args := []any{data.id, p.ID}
|
||||
|
||||
_, err := tx.Execx(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
InsertWithCtx(tx, &p.Value, &InsertId[string]{id: p.ID})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PackageWarning) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO package_warnings (%s, id)
|
||||
VALUES ($1, $2)`, data.fieldName)
|
||||
|
||||
args := []any{data.id, p.ID}
|
||||
|
||||
_, err := tx.Exec(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
InsertWithCtx(tx, &p.Value, &InsertId[string]{id: p.ID})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package db
|
||||
type Relationships struct {
|
||||
ID uint
|
||||
|
||||
Data []RelationshipsData
|
||||
Systems []RelationshipsData
|
||||
Requires []RelationshipsData
|
||||
Recommends []RelationshipsData
|
||||
Conflicts []RelationshipsData
|
||||
}
|
||||
|
||||
type RelationshipsData struct {
|
||||
|
||||
@@ -1,14 +1,53 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
ID uint
|
||||
|
||||
Generation int
|
||||
Channel string
|
||||
Suffix string
|
||||
Build int
|
||||
NodeVersion int
|
||||
MaxGeneration int
|
||||
MaxStableGeneration int
|
||||
Time int64
|
||||
Channel string
|
||||
Suffix string
|
||||
}
|
||||
|
||||
func (r *Release) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO release_ (%s, generation, channel, suffix, build, node_version, max_generation, max_stable_generation, time)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id, r.Generation, r.Channel, r.Suffix, r.Build, r.NodeVersion, r.MaxGeneration, r.MaxStableGeneration, r.Time}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&r.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Release) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO release_ (%s, generation, channel, suffix, build, node_version, max_generation, max_stable_generation, time)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id, r.Generation, r.Channel, r.Suffix, r.Build, r.NodeVersion, r.MaxGeneration, r.MaxStableGeneration, r.Time}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&r.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,21 +1,72 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
ID uint
|
||||
ID uint
|
||||
CreatedAt time.Time
|
||||
|
||||
IsAdmin bool
|
||||
IsSetup bool
|
||||
CoreUpdate CoreUpdate
|
||||
FeaturedContent FeaturedContent
|
||||
Files Files
|
||||
Options SetupOptions
|
||||
Release Release
|
||||
Languages []SetupLanguage
|
||||
Modules []Module
|
||||
News []News
|
||||
PackageWarnings []PackageWarning
|
||||
Systems []System
|
||||
Worlds []World
|
||||
CoreUpdate CoreUpdate //+
|
||||
FeaturedContent FeaturedContent //+
|
||||
Files Files //+
|
||||
Options *SetupOptions //+
|
||||
Release Release //+
|
||||
Languages []SetupLanguage //+
|
||||
Modules []*Module
|
||||
News []News //+
|
||||
PackageWarnings []*PackageWarning
|
||||
Systems []*System
|
||||
Worlds []*World
|
||||
}
|
||||
|
||||
func (s *Setup) Insert(db *sqlx.DB) error {
|
||||
tx := db.MustBegin()
|
||||
defer tx.Rollback()
|
||||
|
||||
const query = `
|
||||
INSERT INTO setup (is_admin, is_setup)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id, created_at`
|
||||
|
||||
args := []any{s.IsAdmin, s.IsSetup}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := tx.QueryRowContext(ctx, query, args...).Scan(&s.ID, &s.CreatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := InsertId[uint]{id: s.ID, fieldName: "setup_id"}
|
||||
|
||||
dataSync := SyncDbOperations{
|
||||
wg: sync.WaitGroup{},
|
||||
errChan: make(chan error),
|
||||
}
|
||||
defer close(dataSync.errChan)
|
||||
|
||||
go InsertSliceParallel(&dataSync, tx, s.News, &id)
|
||||
go InsertSliceParallel(&dataSync, tx, s.Languages, &id)
|
||||
|
||||
InsertWithCtx(tx, &s.FeaturedContent, &id)
|
||||
InsertWithCtx(tx, &s.Files, &id)
|
||||
InsertWithCtx(tx, &s.Release, &id)
|
||||
InsertWithCtx(tx, &s.CoreUpdate, &id)
|
||||
|
||||
err = dataSync.Wait()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
type FeaturedContent struct {
|
||||
@@ -27,6 +78,38 @@ type FeaturedContent struct {
|
||||
Image string
|
||||
}
|
||||
|
||||
func (f *FeaturedContent) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
|
||||
const query = `
|
||||
INSERT INTO featured_content (setup_id, title, caption, url, image)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setup.id, f.Title, f.Caption, f.URL, f.Image}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FeaturedContent) InsertCtx(ctx context.Context, tx *sqlx.Tx, setup *InsertId[uint]) error {
|
||||
const query = `
|
||||
INSERT INTO featured_content (setup_id, title, caption, url, image)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setup.id, f.Title, f.Caption, f.URL, f.Image}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type News struct {
|
||||
ID uint
|
||||
|
||||
@@ -35,3 +118,35 @@ type News struct {
|
||||
URL string
|
||||
Image string
|
||||
}
|
||||
|
||||
func (n News) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
|
||||
const insertNews = `
|
||||
INSERT INTO news (setup_id, title, caption, url, image)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setup.id, n.Title, n.Caption, n.URL, n.Image}
|
||||
|
||||
err := tx.QueryRow(insertNews, args...).Scan(&n.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n News) InsertCtx(ctx context.Context, tx *sqlx.Tx, setup *InsertId[uint]) error {
|
||||
const insertNews = `
|
||||
INSERT INTO news (setup_id, title, caption, url, image)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id`
|
||||
|
||||
args := []any{setup.id, n.Title, n.Caption, n.URL, n.Image}
|
||||
|
||||
err := tx.QueryRowContext(ctx, insertNews, args...).Scan(&n.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type CoreUpdate struct {
|
||||
ID uint
|
||||
|
||||
@@ -12,6 +19,38 @@ type CoreUpdate struct {
|
||||
WillDisableModules bool
|
||||
}
|
||||
|
||||
func (c *CoreUpdate) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO core_update (%s, has_update, can_update, could_reach_website, slow_response, version, channel, will_disable_modules)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.Version, c.Channel, c.WillDisableModules}
|
||||
|
||||
err := tx.QueryRowx(query, args...).Scan(&c.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CoreUpdate) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO core_update (%s, has_update, can_update, could_reach_website, slow_response, version, channel, will_disable_modules)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
RETURNING id`, data.fieldName)
|
||||
|
||||
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.Version, c.Channel, c.WillDisableModules}
|
||||
|
||||
err := tx.QueryRowxContext(ctx, query, args...).Scan(&c.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type SystemUpdate struct {
|
||||
ID uint
|
||||
|
||||
|
||||
116
internal/foundry/temp_models/db/utils.go
Normal file
116
internal/foundry/temp_models/db/utils.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type AllowedIds interface {
|
||||
~uint | ~string
|
||||
}
|
||||
|
||||
type InsertId[T AllowedIds] struct {
|
||||
id T
|
||||
fieldName string
|
||||
tableName string
|
||||
}
|
||||
|
||||
type SyncDbOperations struct {
|
||||
errChan chan error
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func (s *SyncDbOperations) Wait() error {
|
||||
return WaitSync(&s.wg, s.errChan)
|
||||
}
|
||||
|
||||
func WaitSync(wg *sync.WaitGroup, errChan chan error) error {
|
||||
wgDone := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(wgDone)
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-wgDone:
|
||||
return nil
|
||||
case err := <-errChan:
|
||||
close(wgDone)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
type Insertable[T AllowedIds] interface {
|
||||
Insert(tx *sqlx.Tx, relId *InsertId[T]) error
|
||||
InsertCtx(ctx context.Context, tx *sqlx.Tx, relId *InsertId[T]) error
|
||||
}
|
||||
|
||||
func InsertWithCtx[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data I, relId *InsertId[T]) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
return data.InsertCtx(ctx, tx, relId)
|
||||
}
|
||||
|
||||
func InsertSlice[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data []I, relId *InsertId[T]) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
for i := range data {
|
||||
err := data[i].InsertCtx(ctx, tx, relId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InsertSliceParallel[T AllowedIds, I Insertable[T]](syncDb *SyncDbOperations, tx *sqlx.Tx, data []I, relId *InsertId[T]) {
|
||||
syncDb.wg.Add(1)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
errChan := make(chan error)
|
||||
defer close(errChan)
|
||||
|
||||
for i := range data {
|
||||
go func() {
|
||||
wg.Add(1)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
errChan <- data[i].InsertCtx(ctx, tx, relId)
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
err := WaitSync(&wg, errChan)
|
||||
if err != nil {
|
||||
syncDb.errChan <- err
|
||||
}
|
||||
syncDb.wg.Done()
|
||||
}
|
||||
|
||||
func InsertSimpleSliceToTable[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data []I, relId *InsertId[T]) error {
|
||||
query := fmt.Sprintf(`
|
||||
INSERT INTO %s (%s, value)
|
||||
VALUES (:id, :value)`, relId.tableName, relId.fieldName)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
for i := range data {
|
||||
_, err := tx.ExecContext(ctx, query, relId.id, data[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -12,7 +12,10 @@ func (f *Files) ToDB(dest *db.Files) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
copy(dest.Storages, f.Storages)
|
||||
dest.Storages = make([]db.FilesStorage, len(f.Storages))
|
||||
for i := range f.Storages {
|
||||
dest.Storages[i].Storage = f.Storages[i]
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -44,50 +44,54 @@ type Module struct {
|
||||
// ModulesFlags ModulesFlags `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Module) ToDB(dest *db.Module) bool {
|
||||
func (m *Module) ToDB(dest **db.Module) bool {
|
||||
if dest == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dest.ID = m.ID
|
||||
dest.Title = m.Title
|
||||
dest.Description = m.Description
|
||||
dest.URL = m.URL
|
||||
dest.License = m.License
|
||||
dest.Readme = m.Readme
|
||||
dest.Bugs = m.Bugs
|
||||
dest.Changelog = m.Changelog
|
||||
dest.Version = m.Version
|
||||
dest.Socket = m.Socket
|
||||
dest.Manifest = m.Manifest
|
||||
dest.Download = m.Download
|
||||
dest.Protected = m.Protected
|
||||
dest.Exclusive = m.Exclusive
|
||||
dest.PersistentStorage = m.PersistentStorage
|
||||
dest.CoreTranslation = m.CoreTranslation
|
||||
dest.Library = m.Library
|
||||
dest.Availability = m.Availability
|
||||
dest.Locked = m.Locked
|
||||
dest.Owned = m.Owned
|
||||
dest.HasStorage = m.HasStorage
|
||||
dest.Active = m.Active
|
||||
module := &db.Module{
|
||||
ID: m.ID,
|
||||
Title: m.Title,
|
||||
Description: m.Description,
|
||||
URL: m.URL,
|
||||
License: m.License,
|
||||
Readme: m.Readme,
|
||||
Bugs: m.Bugs,
|
||||
Changelog: m.Changelog,
|
||||
Version: m.Version,
|
||||
Socket: m.Socket,
|
||||
Manifest: m.Manifest,
|
||||
Download: m.Download,
|
||||
Protected: m.Protected,
|
||||
Exclusive: m.Exclusive,
|
||||
PersistentStorage: m.PersistentStorage,
|
||||
CoreTranslation: m.CoreTranslation,
|
||||
Library: m.Library,
|
||||
Availability: m.Availability,
|
||||
Locked: m.Locked,
|
||||
Owned: m.Owned,
|
||||
HasStorage: m.HasStorage,
|
||||
Active: m.Active,
|
||||
}
|
||||
|
||||
copy(dest.Scripts, m.Scripts)
|
||||
copy(dest.Esmodules, m.Esmodules)
|
||||
copy(dest.Tags, m.Tags)
|
||||
copy(module.Scripts, m.Scripts)
|
||||
copy(module.Esmodules, m.Esmodules)
|
||||
copy(module.Tags, m.Tags)
|
||||
|
||||
m.Compatibility.ToDB(&dest.Compatibility)
|
||||
m.Relationships.ToDB(&dest.Relationships)
|
||||
m.DocumentTypes.ToDB(&dest.DocumentTypes)
|
||||
m.Compatibility.ToDB(&module.Compatibility)
|
||||
m.Relationships.ToDB(&module.Relationships)
|
||||
m.DocumentTypes.ToDB(&module.DocumentTypes)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
go CopySliceToDBParallel(&wg, &dest.Authors, m.Authors)
|
||||
go CopySliceToDBParallel(&wg, &dest.Media, m.Media)
|
||||
go CopySliceToDBParallel(&wg, &dest.Styles, m.Styles)
|
||||
go CopySliceToDBParallel(&wg, &dest.Languages, m.Languages)
|
||||
go CopySliceToDBParallel(&wg, &dest.Packs, m.Packs)
|
||||
go CopySliceToDBParallel(&wg, &dest.PackFolders, m.PackFolders)
|
||||
go CopySliceToDBParallel(&wg, &module.Authors, m.Authors)
|
||||
go CopySliceToDBParallel(&wg, &module.Media, m.Media)
|
||||
go CopySliceToDBParallel(&wg, &module.Styles, m.Styles)
|
||||
go CopySliceToDBParallel(&wg, &module.Languages, m.Languages)
|
||||
go CopySliceToDBParallel(&wg, &module.Packs, m.Packs)
|
||||
go CopySliceToDBParallel(&wg, &module.PackFolders, m.PackFolders)
|
||||
wg.Wait()
|
||||
|
||||
*dest = module
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -43,49 +43,53 @@ type System struct {
|
||||
// SystemFlags SystemFlags `json:"flags"`
|
||||
}
|
||||
|
||||
func (s *System) ToDB(dest *db.System) bool {
|
||||
func (s *System) ToDB(dest **db.System) bool {
|
||||
if dest == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dest.ID = s.ID
|
||||
dest.Title = s.Title
|
||||
dest.Description = s.Description
|
||||
dest.URL = s.URL
|
||||
dest.License = s.License
|
||||
dest.Bugs = s.Bugs
|
||||
dest.Changelog = s.Changelog
|
||||
dest.Version = s.Version
|
||||
dest.Socket = s.Socket
|
||||
dest.Manifest = s.Manifest
|
||||
dest.Download = s.Download
|
||||
dest.Protected = s.Protected
|
||||
dest.Exclusive = s.Exclusive
|
||||
dest.PersistentStorage = s.PersistentStorage
|
||||
dest.Background = s.Background
|
||||
dest.PrimaryTokenAttribute = s.PrimaryTokenAttribute
|
||||
dest.Availability = s.Availability
|
||||
dest.Locked = s.Locked
|
||||
dest.Owned = s.Owned
|
||||
dest.HasStorage = s.HasStorage
|
||||
system := &db.System{
|
||||
ID: s.ID,
|
||||
Title: s.Title,
|
||||
Description: s.Description,
|
||||
URL: s.URL,
|
||||
License: s.License,
|
||||
Bugs: s.Bugs,
|
||||
Changelog: s.Changelog,
|
||||
Version: s.Version,
|
||||
Socket: s.Socket,
|
||||
Manifest: s.Manifest,
|
||||
Download: s.Download,
|
||||
Protected: s.Protected,
|
||||
Exclusive: s.Exclusive,
|
||||
PersistentStorage: s.PersistentStorage,
|
||||
Background: s.Background,
|
||||
PrimaryTokenAttribute: s.PrimaryTokenAttribute,
|
||||
Availability: s.Availability,
|
||||
Locked: s.Locked,
|
||||
Owned: s.Owned,
|
||||
HasStorage: s.HasStorage,
|
||||
}
|
||||
|
||||
copy(dest.Scripts, s.Scripts)
|
||||
copy(dest.Esmodules, s.Esmodules)
|
||||
copy(dest.Tags, s.Tags)
|
||||
copy(system.Scripts, s.Scripts)
|
||||
copy(system.Esmodules, s.Esmodules)
|
||||
copy(system.Tags, s.Tags)
|
||||
|
||||
s.Compatibility.ToDB(&dest.Compatibility)
|
||||
s.Relationships.ToDB(&dest.Relationships)
|
||||
s.DocumentTypes.ToDB(&dest.DocumentTypes)
|
||||
s.Grid.ToDB(&dest.Grid)
|
||||
s.Compatibility.ToDB(&system.Compatibility)
|
||||
s.Relationships.ToDB(&system.Relationships)
|
||||
s.DocumentTypes.ToDB(&system.DocumentTypes)
|
||||
s.Grid.ToDB(&system.Grid)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
go CopySliceToDBParallel(&wg, &dest.Authors, s.Authors)
|
||||
go CopySliceToDBParallel(&wg, &dest.Media, s.Media)
|
||||
go CopySliceToDBParallel(&wg, &dest.Styles, s.Styles)
|
||||
go CopySliceToDBParallel(&wg, &dest.Languages, s.Languages)
|
||||
go CopySliceToDBParallel(&wg, &dest.Packs, s.Packs)
|
||||
go CopySliceToDBParallel(&wg, &dest.PackFolders, s.PackFolders)
|
||||
go CopySliceToDBParallel(&wg, &system.Authors, s.Authors)
|
||||
go CopySliceToDBParallel(&wg, &system.Media, s.Media)
|
||||
go CopySliceToDBParallel(&wg, &system.Styles, s.Styles)
|
||||
go CopySliceToDBParallel(&wg, &system.Languages, s.Languages)
|
||||
go CopySliceToDBParallel(&wg, &system.Packs, s.Packs)
|
||||
go CopySliceToDBParallel(&wg, &system.PackFolders, s.PackFolders)
|
||||
wg.Wait()
|
||||
|
||||
*dest = system
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ func HotbarToDB(dest *[]db.UserHotbar, src map[int]string) {
|
||||
}
|
||||
}
|
||||
|
||||
func PackageWarningsToDB(dest *[]db.PackageWarning, src map[string]PackageWarningsData) {
|
||||
*dest = make([]db.PackageWarning, len(src))
|
||||
func PackageWarningsToDB(dest *[]*db.PackageWarning, src map[string]PackageWarningsData) {
|
||||
*dest = make([]*db.PackageWarning, len(src))
|
||||
|
||||
i := 0
|
||||
for k, v := range src {
|
||||
|
||||
@@ -43,48 +43,52 @@ type World struct {
|
||||
// Flags any `json:"flags"`
|
||||
}
|
||||
|
||||
func (w *World) ToDB(dest *db.World) bool {
|
||||
func (w *World) ToDB(dest **db.World) bool {
|
||||
if dest == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
dest.ID = w.ID
|
||||
dest.Title = w.Title
|
||||
dest.Description = w.Description
|
||||
dest.Version = w.Version
|
||||
dest.Socket = w.Socket
|
||||
dest.Protected = w.Protected
|
||||
dest.Exclusive = w.Exclusive
|
||||
dest.PersistentStorage = w.PersistentStorage
|
||||
dest.System = w.System
|
||||
dest.Background = w.Background
|
||||
dest.JoinTheme = w.JoinTheme
|
||||
dest.CoreVersion = w.CoreVersion
|
||||
dest.SystemVersion = w.SystemVersion
|
||||
dest.LastPlayed = w.LastPlayed
|
||||
dest.Playtime = w.Playtime
|
||||
dest.NextSession = w.NextSession
|
||||
dest.Availability = w.Availability
|
||||
dest.Locked = w.Locked
|
||||
dest.Owned = w.Owned
|
||||
dest.HasStorage = w.HasStorage
|
||||
world := &db.World{
|
||||
ID: w.ID,
|
||||
Title: w.Title,
|
||||
Description: w.Description,
|
||||
Version: w.Version,
|
||||
Socket: w.Socket,
|
||||
Protected: w.Protected,
|
||||
Exclusive: w.Exclusive,
|
||||
PersistentStorage: w.PersistentStorage,
|
||||
System: w.System,
|
||||
Background: w.Background,
|
||||
JoinTheme: w.JoinTheme,
|
||||
CoreVersion: w.CoreVersion,
|
||||
SystemVersion: w.SystemVersion,
|
||||
LastPlayed: w.LastPlayed,
|
||||
Playtime: w.Playtime,
|
||||
NextSession: w.NextSession,
|
||||
Availability: w.Availability,
|
||||
Locked: w.Locked,
|
||||
Owned: w.Owned,
|
||||
HasStorage: w.HasStorage,
|
||||
}
|
||||
|
||||
copy(dest.Scripts, w.Scripts)
|
||||
copy(dest.Esmodules, w.Esmodules)
|
||||
copy(dest.Tags, w.Tags)
|
||||
copy(world.Scripts, w.Scripts)
|
||||
copy(world.Esmodules, w.Esmodules)
|
||||
copy(world.Tags, w.Tags)
|
||||
|
||||
w.Compatibility.ToDB(&dest.Compatibility)
|
||||
w.Relationships.ToDB(&dest.Relationships)
|
||||
w.Compatibility.ToDB(&world.Compatibility)
|
||||
w.Relationships.ToDB(&world.Relationships)
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
go CopySliceToDBParallel(&wg, &dest.Authors, w.Authors)
|
||||
go CopySliceToDBParallel(&wg, &dest.Media, w.Media)
|
||||
go CopySliceToDBParallel(&wg, &dest.Styles, w.Styles)
|
||||
go CopySliceToDBParallel(&wg, &dest.Languages, w.Languages)
|
||||
go CopySliceToDBParallel(&wg, &dest.Packs, w.Packs)
|
||||
go CopySliceToDBParallel(&wg, &dest.PackFolders, w.PackFolders)
|
||||
go CopySliceToDBParallel(&wg, &world.Authors, w.Authors)
|
||||
go CopySliceToDBParallel(&wg, &world.Media, w.Media)
|
||||
go CopySliceToDBParallel(&wg, &world.Styles, w.Styles)
|
||||
go CopySliceToDBParallel(&wg, &world.Languages, w.Languages)
|
||||
go CopySliceToDBParallel(&wg, &world.Packs, w.Packs)
|
||||
go CopySliceToDBParallel(&wg, &world.PackFolders, w.PackFolders)
|
||||
wg.Wait()
|
||||
|
||||
*dest = world
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/requests"
|
||||
"gitea.local.lab/Lbenedar/foundry_helper_service/internal/foundry/types"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type FoundryTransport struct {
|
||||
@@ -32,7 +32,7 @@ type FoundryTransport struct {
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewFoundryTransport(dbConn *sql.DB, logger *slog.Logger, httpConfig *requests.FoundryHttpRequest) *FoundryTransport {
|
||||
func NewFoundryTransport(dbConn *sqlx.DB, logger *slog.Logger, httpConfig *requests.FoundryHttpRequest) *FoundryTransport {
|
||||
return &FoundryTransport{
|
||||
CurrWsId: 0,
|
||||
ExchangeChan: types.ExchangeChannels{
|
||||
|
||||
Reference in New Issue
Block a user