finish setup insert method, refactor sql migration file

This commit is contained in:
lbenedar
2026-04-17 17:33:21 +03:00
parent 1b7c7e9ae3
commit 21abe68858
47 changed files with 2054 additions and 1056 deletions

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Author struct {
ID uint
@@ -9,3 +16,40 @@ type Author struct {
Discord string
// SystemAuthorsFlags SystemAuthorsFlags `json:"flags"`
}
func (a *Author) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO author (%s, name, url, email, discord)
VALUES ($1, $2, $3, $4, $5)
RETURNING id`, data.fieldName)
}
func (a *Author) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, a.Name, a.URL, a.Email, a.Discord}
err := tx.QueryRow(data.query, args...).Scan(&a.ID)
if err != nil {
return err
}
return nil
}
func (a *Author) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, a.Name, a.URL, a.Email, a.Discord}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&a.ID)
if err != nil {
return err
}
return nil
}

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Compatibility struct {
ID uint
@@ -7,3 +14,40 @@ type Compatibility struct {
Verified string
Maximum string
}
func (c Compatibility) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO compatibility (%s, minimum, verified, maximum)
VALUES ($1, $2, $3, $4)
RETURNING id`, data.fieldName)
}
func (c Compatibility) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, c.Minimum, c.Verified, c.Maximum}
err := tx.QueryRow(data.query, args...).Scan(&c.ID)
if err != nil {
return err
}
return nil
}
func (c Compatibility) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, c.Minimum, c.Verified, c.Maximum}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&c.ID)
if err != nil {
return err
}
return nil
}

View File

@@ -1,9 +1,60 @@
package db
import (
"context"
"github.com/jmoiron/sqlx"
)
type DocumentTypes struct {
ID uint
Data []DocumentTypeData
Data []*DocumentTypeData
}
func (d DocumentTypes) Query(data *InsertId[string]) {
data.query = `
INSERT INTO document_types (module_id)
VALUES ($1)
RETURNING id`
}
func (d DocumentTypes) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRow(data.query, args...).Scan(&d.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, tx, d.Data, &InsertId[uint]{id: d.ID})
return syncDB.Wait()
}
func (d DocumentTypes) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&d.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, tx, d.Data, &InsertId[uint]{id: d.ID})
return syncDB.Wait()
}
type DocumentTypeData struct {
@@ -12,3 +63,50 @@ type DocumentTypeData struct {
Type string
HtmlFields []string
}
func (d *DocumentTypeData) Query(data *InsertId[uint]) {
data.query = `
INSERT INTO document_types_data (document_types_id, type)
VALUES ($1, $2)
RETURNING id`
}
func (d *DocumentTypeData) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, d.Type}
err := tx.QueryRow(data.query, args...).Scan(&d.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
relData := &InsertId[uint]{id: d.ID, fieldName: "document_types_data_id", tableName: "document_types_data_html"}
InsertSimpleSliceParallel(syncDB, tx, d.HtmlFields, relData)
return syncDB.Wait()
}
func (d *DocumentTypeData) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, d.Type}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&d.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
relData := &InsertId[uint]{id: d.ID, fieldName: "document_types_data_id", tableName: "document_types_data_html"}
InsertSimpleSliceParallel(syncDB, tx, d.HtmlFields, relData)
return syncDB.Wait()
}

View File

@@ -3,7 +3,6 @@ package db
import (
"context"
"fmt"
"sync"
"github.com/jmoiron/sqlx"
)
@@ -14,48 +13,49 @@ type Files struct {
Storages []FilesStorage
}
func (f *Files) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
query := fmt.Sprintf(`
func (f *Files) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO files (%s)
VALUES ($1)
RETURNING id`, data.fieldName)
}
func (f *Files) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRowx(query, args...).Scan(&f.ID)
err := tx.QueryRowx(data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
syncDB := SyncDbOperations{
wg: sync.WaitGroup{},
errChan: make(chan error),
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel[uint](&syncDB, tx, f.Storages, &InsertId[uint]{id: f.ID})
InsertSliceParallel(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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
syncDB := SyncDbOperations{
wg: sync.WaitGroup{},
errChan: make(chan error),
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(&syncDB, tx, f.Storages, &InsertId[uint]{id: f.ID})
InsertSliceParallel(syncDB, tx, f.Storages, &InsertId[uint]{id: f.ID})
return syncDB.Wait()
}
@@ -66,15 +66,21 @@ type FilesStorage struct {
Storage string
}
func (f FilesStorage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
query := `
INSERT INTO files (files_id, storage)
func (f FilesStorage) Query(data *InsertId[uint]) {
data.query = `
INSERT INTO files_storage (files_id, storage)
VALUES ($1, $2)
RETURNING id`
}
func (f FilesStorage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, f.Storage}
err := tx.QueryRowx(query, args...).Scan(&f.ID)
err := tx.QueryRowx(data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
@@ -83,14 +89,13 @@ func (f FilesStorage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
}
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`
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, f.Storage}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&f.ID)
if err != nil {
return err
}

View File

@@ -1,5 +1,13 @@
package db
import (
"context"
"fmt"
"strconv"
"github.com/jmoiron/sqlx"
)
type Folder struct {
ID uint
@@ -7,7 +15,59 @@ type Folder struct {
Sorting string
Color string
Packs []string
Folders []Folder
Folders []*Folder
}
func (f *Folder) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO folder (%s, name, sorting, color)
VALUES ($1, $2, $3, $4)
RETURNING id`, data.fieldName)
}
func (f *Folder) InsertObjects(tx *sqlx.Tx) error {
relId := &InsertId[string]{
id: strconv.FormatUint(uint64(f.ID), 10),
fieldName: "folder_id",
tableName: "folder_packs",
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSimpleSliceParallel(syncDB, tx, f.Packs, relId)
InsertSliceParallel(syncDB, tx, f.Folders, relId)
return syncDB.Wait()
}
func (f *Folder) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, f.Name, f.Sorting, f.Color}
err := tx.QueryRow(data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
return f.InsertObjects(tx)
}
func (f *Folder) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, f.Name, f.Sorting, f.Color}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
return f.InsertObjects(tx)
}
type WorldFolder struct {

View File

@@ -18,7 +18,7 @@ type Game struct {
ActiveUsers []string
Modules []*Module
PackageWarnings []*PackageWarning
Packs []Pack
Packs []*Pack
Messages []Message
Combats []Combat
CardDeck []CardDeck

View File

@@ -1,5 +1,11 @@
package db
import (
"context"
"github.com/jmoiron/sqlx"
)
type Grid struct {
ID uint
@@ -13,3 +19,43 @@ type Grid struct {
Units string
Style string
}
func (g *Grid) Query(data *InsertId[string]) {
data.query = `
INSERT INTO grid (system_id, type, size, distance, diagonals, thickness
alpha, color, units, style)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id`
}
func (g *Grid) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, g.Type, g.Size, g.Distance, g.Diagonals, g.Thickness,
g.Alpha, g.Color, g.Units, g.Style}
err := tx.QueryRowx(data.query, args...).Scan(&g.ID)
if err != nil {
return err
}
return nil
}
func (g *Grid) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, g.Type, g.Size, g.Distance, g.Diagonals, g.Thickness,
g.Alpha, g.Color, g.Units, g.Style}
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&g.ID)
if err != nil {
return err
}
return nil
}

View File

@@ -1,5 +1,11 @@
package db
import (
"context"
"github.com/jmoiron/sqlx"
)
type Index struct {
ID string
@@ -8,3 +14,40 @@ type Index struct {
Name string
Type string
}
func (i *Index) Query(data *InsertId[string]) {
data.query = `
INSERT INTO index_ (pack_id, id, folder, img, name, type)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id`
}
func (i *Index) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, i.ID, i.Folder, i.Img, i.Name, i.Type}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return nil
}
func (i *Index) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, i.ID, i.Folder, i.Img, i.Name, i.Type}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return nil
}

View File

@@ -2,18 +2,11 @@ package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Language struct {
ID uint
Lang string
Name string
Path string
}
type SetupLanguage struct {
ID string
@@ -21,38 +14,47 @@ type SetupLanguage struct {
Modules []SetupLanguageModule
}
func (l SetupLanguage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
const query = `
func (l *SetupLanguage) Query(data *InsertId[uint]) {
data.query = `
INSERT INTO setup_language (setup_id, label)
VALUES ($1, $2)
RETURNING id`
}
func (l *SetupLanguage) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, l.Label}
err := tx.QueryRowx(query, args...).Scan(&l.ID)
err := tx.QueryRowx(data.query, args...).Scan(&l.ID)
if err != nil {
return err
}
InsertSlice(tx, l.Modules, &InsertId[string]{id: l.ID})
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, 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`
func (l *SetupLanguage) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, l.Label}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&l.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&l.ID)
if err != nil {
return err
}
InsertSlice(tx, l.Modules, &InsertId[string]{id: l.ID})
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, tx, l.Modules, &InsertId[string]{id: l.ID})
return nil
}
@@ -64,15 +66,21 @@ type SetupLanguageModule struct {
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)
func (l SetupLanguageModule) Query(data *InsertId[string]) {
data.query = `
INSERT INTO setup_language_module (setup_language_id, id, label, path)
VALUES ($1, $2, $3, $4)
RETURNING id`
}
args := []any{data.id, l.Label, l.Path}
func (l SetupLanguageModule) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
err := tx.QueryRowx(query, args...).Scan(&l.ID)
args := []any{data.id, l.ID, l.Label, l.Path}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
@@ -81,14 +89,58 @@ func (l SetupLanguageModule) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
}
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`
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, l.Label, l.Path}
args := []any{data.id, l.ID, l.Label, l.Path}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&l.ID)
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return nil
}
type Language struct {
ID uint
Lang string
Name string
Path string
}
func (l *Language) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO language (%s, lang, name, path)
VALUES ($1, $2, $3, $4)
RETURNING id`, data.fieldName)
}
func (l *Language) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, l.Lang, l.Name, l.Path}
err := tx.QueryRow(data.query, args...).Scan(&l.ID)
if err != nil {
return err
}
return nil
}
func (l *Language) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, l.Lang, l.Name, l.Path}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&l.ID)
if err != nil {
return err
}

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Media struct {
ID uint
@@ -7,3 +14,40 @@ type Media struct {
URL string
Caption string
}
func (m *Media) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO media (%s, type, url, caption)
VALUES ($1, $2, $3, $4)
RETURNING id`, data.fieldName)
}
func (m *Media) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, m.Type, m.URL, m.Caption}
err := tx.QueryRow(data.query, args...).Scan(&m.ID)
if err != nil {
return err
}
return nil
}
func (m *Media) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, m.Type, m.URL, m.Caption}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&m.ID)
if err != nil {
return err
}
return nil
}

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Module struct {
ID string
@@ -11,30 +18,98 @@ type Module struct {
Bugs string
Changelog string
Version string
Socket bool
Manifest string
Download string
Manifest string
Socket bool
Protected bool
Exclusive bool
PersistentStorage bool
CoreTranslation bool
Library bool
Availability int
Locked bool
Owned bool
HasStorage bool
Active bool
Availability int
DocumentTypes DocumentTypes
Relationships Relationships
Compatibility Compatibility
Authors []Author
Media []Media
Scripts []string
Esmodules []string
Styles []Style
Languages []Language
Packs []Pack
PackFolders []Folder
Tags []string
// ModulesFlags ModulesFlags `json:"flags,omitempty"`
Authors []*Author
Media []*Media
Styles []*Style
Languages []*Language
Packs []*Pack
PackFolders []*Folder
}
func (m *Module) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO module (%s, id, title, description, url, license, readme, bugs,
changelog, version, manifest, download, socket, protected, exclusive_, persistent_storage,
core_translation, library, locked, owned, has_storage, active, availability)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17,
$18, $19, $20, $21, $22, $23)`, data.fieldName)
}
func (m *Module) InsertObjects(tx *sqlx.Tx) error {
relId := &InsertId[string]{id: m.ID, fieldName: "module_id"}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
go InsertWithCtxParallel(syncDB, tx, m.DocumentTypes, relId)
go InsertWithCtxParallel(syncDB, tx, m.Relationships, relId)
go InsertWithCtxParallel(syncDB, tx, m.Compatibility, relId)
scriptRelId := &InsertId[string]{id: m.ID, fieldName: "module_id", tableName: "scripts"}
go InsertSimpleSliceParallel(syncDB, tx, m.Scripts, scriptRelId)
esModulesRelId := &InsertId[string]{id: m.ID, fieldName: "module_id", tableName: "es_modules"}
go InsertSimpleSliceParallel(syncDB, tx, m.Esmodules, esModulesRelId)
tagsRelId := &InsertId[string]{id: m.ID, fieldName: "module_id", tableName: "tags"}
go InsertSimpleSliceParallel(syncDB, tx, m.Tags, tagsRelId)
go InsertSliceParallel(syncDB, tx, m.Authors, relId)
go InsertSliceParallel(syncDB, tx, m.Media, relId)
go InsertSliceParallel(syncDB, tx, m.Styles, relId)
go InsertSliceParallel(syncDB, tx, m.Languages, relId)
go InsertSliceParallel(syncDB, tx, m.Packs, relId)
go InsertSliceParallel(syncDB, tx, m.PackFolders, relId)
return syncDB.Wait()
}
func (m *Module) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, m.ID, m.Title, m.Description, m.URL, m.License, m.Readme, m.Bugs,
m.Changelog, m.Version, m.Manifest, m.Download, m.Socket, m.Protected, m.Exclusive, m.PersistentStorage,
m.CoreTranslation, m.Library, m.Locked, m.Owned, m.HasStorage, m.Active, m.Availability}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return m.InsertObjects(tx)
}
func (m *Module) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, m.ID, m.Title, m.Description, m.URL, m.License, m.Readme, m.Bugs,
m.Changelog, m.Version, m.Manifest, m.Download, m.Socket, m.Protected, m.Exclusive, m.PersistentStorage,
m.CoreTranslation, m.Library, m.Locked, m.Owned, m.HasStorage, m.Active, m.Availability}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return m.InsertObjects(tx)
}

View File

@@ -67,19 +67,25 @@ type SetupOptions struct {
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)
func (s *SetupOptions) Query(data *InsertId[uint]) {
data.query = `
INSERT INTO setup_options (setup_id, css_theme, data_path, hostname, language, local_hostname,
update_channel, port, compress_socket, compress_static, fullscreen, hot_reload, proxy_ssl,
telemetry, 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}
func (s *SetupOptions) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
err := tx.QueryRowx(query, args...).Scan(&s.ID)
args := []any{data.id, s.CSSTheme, s.DataPath, s.Hostname, s.Language, s.LocalHostname,
s.UpdateChannel, s.Port, s.CompressSocket, s.CompressStatic, s.Fullscreen, s.HotReload,
s.ProxySSL, s.Telemetry, s.Upnp, s.DeleteNEDB, s.NoBackups}
err := tx.QueryRowx(data.query, args...).Scan(&s.ID)
if err != nil {
return err
}
@@ -87,19 +93,16 @@ func (s *SetupOptions) Insert(tx *sqlx.Tx, setupId *InsertId[uint]) error {
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`
func (s *SetupOptions) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
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}
args := []any{data.id, s.CSSTheme, s.DataPath, s.Hostname, s.Language, s.LocalHostname,
s.UpdateChannel, s.Port, s.CompressSocket, s.CompressStatic, s.Fullscreen, s.HotReload,
s.ProxySSL, s.Telemetry, s.Upnp, s.DeleteNEDB, s.NoBackups}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&s.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&s.ID)
if err != nil {
return err
}

View File

@@ -1,5 +1,11 @@
package db
import (
"context"
"github.com/jmoiron/sqlx"
)
type Ownership struct {
ID uint
@@ -8,6 +14,43 @@ type Ownership struct {
Assistant string
}
func (o Ownership) Query(data *InsertId[string]) {
data.query = `
INSERT INTO ownership (%s, player, trusted, assistant)
VALUES ($1, $2, $3, $4)
RETURNING id`
}
func (o Ownership) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, o.Player, o.Trusted, o.Assistant}
err := tx.QueryRow(data.query, args...).Scan(&o.ID)
if err != nil {
return err
}
return nil
}
func (o Ownership) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, o.Player, o.Trusted, o.Assistant}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&o.ID)
if err != nil {
return err
}
return nil
}
type OwnershipString struct {
ID uint

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Pack struct {
ID string
@@ -12,8 +19,57 @@ type Pack struct {
PackageType string
PackageName string
Ownership Ownership
Index []Index
Folders []PackFolder
Index []*Index
Folders []*PackFolder
}
func (p *Pack) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO pack (%s, id, name, label, banner, path, type, system, package_type, package_name)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id`, data.fieldName)
}
func (p *Pack) InsertObjects(tx *sqlx.Tx) error {
relId := &InsertId[string]{id: p.ID, fieldName: "pack_id"}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, p.Ownership, relId)
InsertSliceParallel(syncDB, tx, p.Index, relId)
InsertSliceParallel(syncDB, tx, p.Folders, relId)
return syncDB.Wait()
}
func (p *Pack) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Name, p.Label, p.Banner, p.Path, p.Type, p.System, p.PackageType, p.PackageName}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return p.InsertObjects(tx)
}
func (p *Pack) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Name, p.Label, p.Banner, p.Path, p.Type, p.System, p.PackageType, p.PackageName}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return p.InsertObjects(tx)
}
type PackFolder struct {
@@ -21,7 +77,43 @@ type PackFolder struct {
Description string
Name string
Sort int
Sorting string
Type string
Sort int
}
func (p *PackFolder) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO pack_folder (%s, id, description, name, sorting, type, sort)
VALUES ($1, $2, $3, $4, $5, $6, $7)`, data.fieldName)
}
func (p *PackFolder) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Description, p.Name, p.Sorting, p.Type, p.Sort}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return nil
}
func (p *PackFolder) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Description, p.Name, p.Sorting, p.Type, p.Sort}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return nil
}

View File

@@ -7,99 +7,106 @@ import (
"github.com/jmoiron/sqlx"
)
type PackageWarningsData struct {
ID string
Type string
Warning []string
Error []string
Reinstallable bool
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
Value *PackageWarningsData
}
func (p *PackageWarning) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO package_warnings (%s, id)
VALUES ($1, $2)`, data.fieldName)
}
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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID}
_, err := tx.Execx(query, args...)
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
InsertWithCtx(tx, &p.Value, &InsertId[string]{id: p.ID})
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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID}
_, err := tx.Exec(query, args...)
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
InsertWithCtx(tx, &p.Value, &InsertId[string]{id: p.ID})
InsertWithCtx(tx, p.Value, &InsertId[string]{id: p.ID})
return nil
}
type PackageWarningsData struct {
ID string
Type string
Manifest string
Reinstallable bool
Warning []string
Error []string
}
func (p *PackageWarningsData) InsertObjects(tx *sqlx.Tx) error {
syncDB := NewSyncDB()
defer close(syncDB.errChan)
warningData := &InsertId[string]{id: p.ID, fieldName: "package_warnings_data_id", tableName: "package_warnings_data_warning"}
InsertSimpleSliceParallel(syncDB, tx, p.Warning, warningData)
errorData := &InsertId[string]{id: p.ID, fieldName: "package_warnings_data_id", tableName: "package_warnings_data_error"}
InsertSimpleSliceParallel(syncDB, tx, p.Warning, errorData)
return syncDB.Wait()
}
func (p *PackageWarningsData) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO package_warnings_data (%s, id, type, reinstallable, manifest)
VALUES ($1, $2, $3, $4, $5)`, data.fieldName)
}
func (p *PackageWarningsData) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Type, p.Reinstallable, p.Manifest}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return p.InsertObjects(tx)
}
func (p *PackageWarningsData) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, p.ID, p.Type, p.Reinstallable, p.Manifest}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return p.InsertObjects(tx)
}

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Relationships struct {
ID uint
@@ -9,11 +16,107 @@ type Relationships struct {
Conflicts []RelationshipsData
}
func (r Relationships) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO relationships (%s)
VALUES ($1)
RETURNING id`, data.fieldName)
}
func (r Relationships) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRowx(data.query, args...).Scan(&r.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, tx, r.Systems, &InsertId[uint]{id: r.ID, tableName: "relationships_systems"})
InsertSliceParallel(syncDB, tx, r.Requires, &InsertId[uint]{id: r.ID, tableName: "relationships_requires"})
InsertSliceParallel(syncDB, tx, r.Recommends, &InsertId[uint]{id: r.ID, tableName: "relationships_recommends"})
InsertSliceParallel(syncDB, tx, r.Conflicts, &InsertId[uint]{id: r.ID, tableName: "relationships_conflicts"})
return syncDB.Wait()
}
func (r Relationships) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id}
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&r.ID)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertSliceParallel(syncDB, tx, r.Systems, &InsertId[uint]{id: r.ID, tableName: "relationships_systems"})
InsertSliceParallel(syncDB, tx, r.Requires, &InsertId[uint]{id: r.ID, tableName: "relationships_requires"})
InsertSliceParallel(syncDB, tx, r.Recommends, &InsertId[uint]{id: r.ID, tableName: "relationships_recommends"})
InsertSliceParallel(syncDB, tx, r.Conflicts, &InsertId[uint]{id: r.ID, tableName: "relationships_conflicts"})
return syncDB.Wait()
}
type RelationshipsData struct {
ID string
RelationshipsType string
Type string
Manifest string
Compatibility Compatibility
Type string
Manifest string
Compatibility Compatibility
}
func (r RelationshipsData) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO %s (relationships_id, id, type, manifest)
VALUES ($1, $2, $3, $4, $5)`, data.tableName)
}
func (r RelationshipsData) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, r.ID, r.Type, r.Manifest}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, r.Compatibility, &InsertId[string]{id: r.ID, fieldName: fmt.Sprintf("%s_id", data.tableName)})
return nil
}
func (r RelationshipsData) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, r.ID, r.Type, r.Manifest}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, r.Compatibility, &InsertId[string]{id: r.ID, fieldName: fmt.Sprintf("%s_id", data.tableName)})
return nil
}

View File

@@ -20,15 +20,23 @@ type Release struct {
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)
func (r *Release) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO release_ (%s, generaion, build, node_version, max_generation, max_stable_generation,
time, channel, suffix)
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}
func (r *Release) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
err := tx.QueryRowx(query, args...).Scan(&r.ID)
args := []any{data.id, r.Generation, r.Build, r.NodeVersion, r.MaxGeneration, r.MaxStableGeneration,
r.Time, r.Channel, r.Suffix}
err := tx.QueryRowx(data.query, args...).Scan(&r.ID)
if err != nil {
return err
}
@@ -37,14 +45,14 @@ func (r *Release) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
}
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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, r.Generation, r.Channel, r.Suffix, r.Build, r.NodeVersion, r.MaxGeneration, r.MaxStableGeneration, r.Time}
args := []any{data.id, r.Generation, r.Build, r.NodeVersion, r.MaxGeneration, r.MaxStableGeneration,
r.Time, r.Channel, r.Suffix}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&r.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&r.ID)
if err != nil {
return err
}

View File

@@ -2,7 +2,7 @@ package db
import (
"context"
"sync"
"strconv"
"time"
"github.com/jmoiron/sqlx"
@@ -14,19 +14,45 @@ type Setup struct {
IsAdmin bool
IsSetup bool
CoreUpdate CoreUpdate //+
FeaturedContent FeaturedContent //+
Files Files //+
Options *SetupOptions //+
Release Release //+
Languages []SetupLanguage //+
CoreUpdate CoreUpdate
FeaturedContent FeaturedContent
Files Files
Options *SetupOptions
Release Release
Languages []*SetupLanguage
Modules []*Module
News []News //+
News []*News
PackageWarnings []*PackageWarning
Systems []*System
Worlds []*World
}
func (s *Setup) InsertObjects(tx *sqlx.Tx) error {
relData := &InsertId[uint]{id: s.ID, fieldName: "setup_id"}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, &s.CoreUpdate, relData)
InsertWithCtxParallel(syncDB, tx, &s.FeaturedContent, relData)
InsertWithCtxParallel(syncDB, tx, &s.Files, relData)
InsertWithCtxParallel(syncDB, tx, s.Options, relData)
InsertWithCtxParallel(syncDB, tx, &s.Release, relData)
InsertSliceParallel(syncDB, tx, s.Languages, relData)
InsertSliceParallel(syncDB, tx, s.Modules, relData)
InsertSliceParallel(syncDB, tx, s.News, relData)
InsertSliceParallel(syncDB, tx, s.PackageWarnings, relData)
relDataString := &InsertId[string]{
id: strconv.FormatUint(uint64(s.ID), 10),
fieldName: "setup_id",
}
InsertSliceParallel(syncDB, tx, s.Systems, relDataString)
InsertSliceParallel(syncDB, tx, s.Worlds, relDataString)
return syncDB.Wait()
}
func (s *Setup) Insert(db *sqlx.DB) error {
tx := db.MustBegin()
defer tx.Rollback()
@@ -45,23 +71,8 @@ func (s *Setup) Insert(db *sqlx.DB) error {
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()
err = s.InsertObjects(tx)
if err != nil {
return err
}
@@ -78,15 +89,21 @@ type FeaturedContent struct {
Image string
}
func (f *FeaturedContent) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
const query = `
func (f *FeaturedContent) Query(data *InsertId[uint]) {
data.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}
func (f *FeaturedContent) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
err := tx.QueryRowx(query, args...).Scan(&f.ID)
args := []any{data.id, f.Title, f.Caption, f.URL, f.Image}
err := tx.QueryRowx(data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
@@ -94,15 +111,14 @@ func (f *FeaturedContent) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
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`
func (f *FeaturedContent) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{setup.id, f.Title, f.Caption, f.URL, f.Image}
args := []any{data.id, f.Title, f.Caption, f.URL, f.Image}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&f.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&f.ID)
if err != nil {
return err
}
@@ -119,15 +135,21 @@ type News struct {
Image string
}
func (n News) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
const insertNews = `
func (n *News) Query(data *InsertId[uint]) {
data.query = `
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}
func (n *News) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
err := tx.QueryRow(insertNews, args...).Scan(&n.ID)
args := []any{data.id, n.Title, n.Caption, n.URL, n.Image}
err := tx.QueryRow(data.query, args...).Scan(&n.ID)
if err != nil {
return err
}
@@ -135,15 +157,14 @@ func (n News) Insert(tx *sqlx.Tx, setup *InsertId[uint]) error {
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`
func (n *News) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[uint]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{setup.id, n.Title, n.Caption, n.URL, n.Image}
args := []any{data.id, n.Title, n.Caption, n.URL, n.Image}
err := tx.QueryRowContext(ctx, insertNews, args...).Scan(&n.ID)
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&n.ID)
if err != nil {
return err
}

View File

@@ -1,7 +1,51 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Style struct {
ID uint
Src string
}
func (s *Style) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO style (%s, src)
VALUES ($1, $2)
RETURNING id`, data.fieldName)
}
func (s *Style) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, s.Src}
err := tx.QueryRow(data.query, args...).Scan(&s.ID)
if err != nil {
return err
}
return nil
}
func (s *Style) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, s.Src}
err := tx.QueryRowContext(ctx, data.query, args...).Scan(&s.ID)
if err != nil {
return err
}
return nil
}

View File

@@ -1,5 +1,12 @@
package db
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type System struct {
ID string
@@ -10,29 +17,101 @@ type System struct {
Bugs string
Changelog string
Version string
Socket bool
Manifest string
Download string
Protected bool
Exclusive bool
PersistentStorage bool
Background string
PrimaryTokenAttribute string
Availability int
Socket bool
Protected bool
Exclusive bool
PersistentStorage bool
Locked bool
Owned bool
HasStorage bool
Esmodules []string
Scripts []string
Tags []string
Compatibility Compatibility
Relationships Relationships
DocumentTypes DocumentTypes
Grid Grid
Authors []Author
Media []Media
Packs []Pack
Styles []Style
Languages []Language
PackFolders []Folder
Grid *Grid
Esmodules []string
Scripts []string
Tags []string
Authors []*Author
Media []*Media
Packs []*Pack
Styles []*Style
Languages []*Language
PackFolders []*Folder
}
func (s *System) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO system (%s, id, title, description, url, license, bugs, changelog, version, manifest,
download, background, primary_token_attribute, availability, socket, protected, exclusive_,
persistent_storage, locked, owned, has_storage)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)`,
data.fieldName)
}
func (s *System) InsertObjects(tx *sqlx.Tx) error {
relId := &InsertId[string]{id: s.ID, fieldName: "system_id"}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, s.Compatibility, relId)
InsertWithCtxParallel(syncDB, tx, s.Relationships, relId)
InsertWithCtxParallel(syncDB, tx, s.DocumentTypes, relId)
InsertWithCtxParallel(syncDB, tx, s.Grid, relId)
esModulesRelId := &InsertId[string]{id: s.ID, fieldName: "system_id", tableName: "es_modules"}
InsertSimpleSliceParallel(syncDB, tx, s.Esmodules, esModulesRelId)
scriptRelId := &InsertId[string]{id: s.ID, fieldName: "system_id", tableName: "scripts"}
InsertSimpleSliceParallel(syncDB, tx, s.Scripts, scriptRelId)
tagsRelId := &InsertId[string]{id: s.ID, fieldName: "system_id", tableName: "tags"}
InsertSimpleSliceParallel(syncDB, tx, s.Tags, tagsRelId)
InsertSliceParallel(syncDB, tx, s.Authors, relId)
InsertSliceParallel(syncDB, tx, s.Media, relId)
InsertSliceParallel(syncDB, tx, s.Styles, relId)
InsertSliceParallel(syncDB, tx, s.Languages, relId)
InsertSliceParallel(syncDB, tx, s.Packs, relId)
InsertSliceParallel(syncDB, tx, s.PackFolders, relId)
return syncDB.Wait()
}
func (s *System) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, s.ID, s.Title, s.Description, s.URL, s.License, s.Bugs,
s.Changelog, s.Version, s.Manifest, s.Download, s.Background,
s.PrimaryTokenAttribute, s.Availability, s.Socket, s.Protected, s.Exclusive,
s.PersistentStorage, s.Locked, s.Owned, s.HasStorage}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return s.InsertObjects(tx)
}
func (s *System) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, s.ID, s.Title, s.Description, s.URL, s.License, s.Bugs,
s.Changelog, s.Version, s.Manifest, s.Download, s.Background,
s.PrimaryTokenAttribute, s.Availability, s.Socket, s.Protected, s.Exclusive,
s.PersistentStorage, s.Locked, s.Owned, s.HasStorage}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return s.InsertObjects(tx)
}

View File

@@ -14,20 +14,26 @@ type CoreUpdate struct {
CanUpdate bool
CouldReachWebsite bool
SlowResponse bool
WillDisableModules bool
Version string
Channel string
WillDisableModules bool
}
func (c *CoreUpdate) Query(data *InsertId[uint]) {
data.query = fmt.Sprintf(`
INSERT INTO core_update (%s, has_update, can_update, could_reach_website, slow_response, will_disable_modules, version, channel)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id`, data.fieldName)
}
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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.Version, c.Channel, c.WillDisableModules}
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.WillDisableModules, c.Version, c.Channel}
err := tx.QueryRowx(query, args...).Scan(&c.ID)
err := tx.QueryRowx(data.query, args...).Scan(&c.ID)
if err != nil {
return err
}
@@ -36,14 +42,13 @@ func (c *CoreUpdate) Insert(tx *sqlx.Tx, data *InsertId[uint]) error {
}
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)
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.Version, c.Channel, c.WillDisableModules}
args := []any{data.id, c.HasUpdate, c.CanUpdate, c.CouldReachWebsite, c.SlowResponse, c.WillDisableModules, c.Version, c.Channel}
err := tx.QueryRowxContext(ctx, query, args...).Scan(&c.ID)
err := tx.QueryRowxContext(ctx, data.query, args...).Scan(&c.ID)
if err != nil {
return err
}

View File

@@ -2,6 +2,7 @@ package db
import (
"context"
"errors"
"fmt"
"sync"
"time"
@@ -9,6 +10,10 @@ import (
"github.com/jmoiron/sqlx"
)
var (
ErrNoQuery = errors.New("Query has not been set")
)
type AllowedIds interface {
~uint | ~string
}
@@ -17,14 +22,22 @@ type InsertId[T AllowedIds] struct {
id T
fieldName string
tableName string
query string
}
type SyncDbOperations struct {
type SyncDB struct {
errChan chan error
wg sync.WaitGroup
}
func (s *SyncDbOperations) Wait() error {
func NewSyncDB() *SyncDB {
return &SyncDB{
wg: sync.WaitGroup{},
errChan: make(chan error),
}
}
func (s *SyncDB) Wait() error {
return WaitSync(&s.wg, s.errChan)
}
@@ -46,6 +59,7 @@ func WaitSync(wg *sync.WaitGroup, errChan chan error) error {
}
type Insertable[T AllowedIds] interface {
Query(data *InsertId[T])
Insert(tx *sqlx.Tx, relId *InsertId[T]) error
InsertCtx(ctx context.Context, tx *sqlx.Tx, relId *InsertId[T]) error
}
@@ -54,13 +68,30 @@ func InsertWithCtx[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data I, relId *In
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
data.Query(relId)
return data.InsertCtx(ctx, tx, relId)
}
func InsertWithCtxParallel[T AllowedIds, I Insertable[T]](syncDb *SyncDB, tx *sqlx.Tx, data I, relId *InsertId[T]) {
syncDb.wg.Go(func() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
data.Query(relId)
err := data.InsertCtx(ctx, tx, relId)
if err != nil {
syncDb.errChan <- err
}
})
}
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()
if len(data) > 0 {
data[0].Query(relId)
}
for i := range data {
err := data[i].InsertCtx(ctx, tx, relId)
if err != nil {
@@ -70,41 +101,42 @@ func InsertSlice[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data []I, relId *In
return nil
}
func InsertSliceParallel[T AllowedIds, I Insertable[T]](syncDb *SyncDbOperations, tx *sqlx.Tx, data []I, relId *InsertId[T]) {
syncDb.wg.Add(1)
func InsertSliceParallel[T AllowedIds, I Insertable[T]](syncDb *SyncDB, tx *sqlx.Tx, data []I, relId *InsertId[T]) {
syncDb.wg.Go(func() {
wg := sync.WaitGroup{}
errChan := make(chan error)
defer close(errChan)
wg := sync.WaitGroup{}
errChan := make(chan error)
defer close(errChan)
var err error
if len(data) > 0 {
data[0].Query(relId)
}
for i := range data {
wg.Go(func() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
for i := range data {
go func() {
wg.Add(1)
err = data[i].InsertCtx(ctx, tx, relId)
if err != nil {
errChan <- err
}
})
}
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()
err = WaitSync(&wg, errChan)
if err != nil {
syncDb.errChan <- err
}
})
}
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)
func InsertSimpleSlice[T AllowedIds, I any](tx *sqlx.Tx, data []I, relId *InsertId[T]) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := fmt.Sprintf(`
INSERT INTO %s (%s, value)
VALUES ($1, $2)`, relId.tableName, relId.fieldName)
for i := range data {
_, err := tx.ExecContext(ctx, query, relId.id, data[i])
if err != nil {
@@ -114,3 +146,31 @@ func InsertSimpleSliceToTable[T AllowedIds, I Insertable[T]](tx *sqlx.Tx, data [
return nil
}
func InsertSimpleSliceParallel[T AllowedIds, I any](syncDb *SyncDB, tx *sqlx.Tx, data []I, relId *InsertId[T]) {
syncDb.wg.Go(func() {
wg := sync.WaitGroup{}
errChan := make(chan error)
defer close(errChan)
query := fmt.Sprintf(`
INSERT INTO %s (%s, value)
VALUES ($1, $2)`, relId.tableName, relId.fieldName)
for i := range data {
wg.Go(func() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
_, err := tx.ExecContext(ctx, query, relId.id, data[i])
if err != nil {
errChan <- err
}
})
}
err := WaitSync(&wg, errChan)
if err != nil {
syncDb.errChan <- err
}
})
}

View File

@@ -1,20 +1,16 @@
package db
import "time"
import (
"context"
"fmt"
"time"
"github.com/jmoiron/sqlx"
)
type World struct {
ID string
Socket bool
Protected bool
Exclusive bool
PersistentStorage bool
Locked bool
Owned bool
HasStorage bool
Playtime int
Availability int
NextSession time.Time
Title string
Description string
Version string
@@ -24,15 +20,93 @@ type World struct {
CoreVersion string
SystemVersion string
LastPlayed string
Playtime int
Availability int
NextSession time.Time
Socket bool
Protected bool
Exclusive bool
PersistentStorage bool
Locked bool
Owned bool
HasStorage bool
Compatibility Compatibility
Relationships Relationships
Tags []string
Scripts []string
Esmodules []string
Compatibility Compatibility
Relationships Relationships
Authors []Author
Media []Media
Styles []Style
Languages []Language
Packs []Pack
PackFolders []Folder
Authors []*Author
Media []*Media
Styles []*Style
Languages []*Language
Packs []*Pack
PackFolders []*Folder
}
func (w *World) Query(data *InsertId[string]) {
data.query = fmt.Sprintf(`
INSERT INTO world (%s, id, title, description, version, system, background, join_theme,
core_version, system_version, last_played, playtime, availability, next_session, socket,
protected, exclusive_, persistent_storage, locked, owned, has_storage)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)`,
data.fieldName)
}
func (w *World) InsertObjects(tx *sqlx.Tx) error {
relId := &InsertId[string]{id: w.ID, fieldName: "world_id"}
syncDB := NewSyncDB()
defer close(syncDB.errChan)
InsertWithCtxParallel(syncDB, tx, w.Compatibility, relId)
InsertWithCtxParallel(syncDB, tx, w.Relationships, relId)
esModulesRelId := &InsertId[string]{id: w.ID, fieldName: "world_id", tableName: "es_modules"}
InsertSimpleSliceParallel(syncDB, tx, w.Esmodules, esModulesRelId)
scriptRelId := &InsertId[string]{id: w.ID, fieldName: "world_id", tableName: "scripts"}
InsertSimpleSliceParallel(syncDB, tx, w.Scripts, scriptRelId)
tagsRelId := &InsertId[string]{id: w.ID, fieldName: "world_id", tableName: "tags"}
InsertSimpleSliceParallel(syncDB, tx, w.Tags, tagsRelId)
InsertSliceParallel(syncDB, tx, w.Authors, relId)
InsertSliceParallel(syncDB, tx, w.Media, relId)
InsertSliceParallel(syncDB, tx, w.Styles, relId)
InsertSliceParallel(syncDB, tx, w.Languages, relId)
InsertSliceParallel(syncDB, tx, w.Packs, relId)
InsertSliceParallel(syncDB, tx, w.PackFolders, relId)
return syncDB.Wait()
}
func (w *World) Insert(tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, w.ID, w.Title, w.Description, w.Version, w.System, w.Background, w.JoinTheme,
w.CoreVersion, w.SystemVersion, w.LastPlayed, w.Playtime, w.Availability, w.NextSession, w.Socket,
w.Protected, w.Exclusive, w.PersistentStorage, w.Locked, w.Owned, w.HasStorage}
_, err := tx.Exec(data.query, args...)
if err != nil {
return err
}
return w.InsertObjects(tx)
}
func (w *World) InsertCtx(ctx context.Context, tx *sqlx.Tx, data *InsertId[string]) error {
if data.query == "" {
return ErrNoQuery
}
args := []any{data.id, w.ID, w.Title, w.Description, w.Version, w.System, w.Background, w.JoinTheme,
w.CoreVersion, w.SystemVersion, w.LastPlayed, w.Playtime, w.Availability, w.NextSession, w.Socket,
w.Protected, w.Exclusive, w.PersistentStorage, w.Locked, w.Owned, w.HasStorage}
_, err := tx.ExecContext(ctx, data.query, args...)
if err != nil {
return err
}
return w.InsertObjects(tx)
}

View File

@@ -10,15 +10,19 @@ type Author struct {
// SystemAuthorsFlags SystemAuthorsFlags `json:"flags"`
}
func (a *Author) ToDB(dest *db.Author) bool {
func (a *Author) ToDB(dest **db.Author) bool {
if dest == nil {
return false
}
dest.Name = a.Name
dest.URL = a.URL
dest.Email = a.Email
dest.Discord = a.Discord
author := &db.Author{
Name: a.Name,
URL: a.URL,
Email: a.Email,
Discord: a.Discord,
}
*dest = author
return true
}

View File

@@ -13,12 +13,12 @@ func (d *DocumentTypes) ToDB(dest *db.DocumentTypes) bool {
return false
}
dest.Data = make([]db.DocumentTypeData, 2)
dest.Data = make([]*db.DocumentTypeData, 2)
d.Actor.ToDB(&dest.Data[0])
d.Actor.ToDB(dest.Data[0])
dest.Data[0].Type = "Actor"
d.Item.ToDB(&dest.Data[1])
d.Item.ToDB(dest.Data[1])
dest.Data[1].Type = "Item"
return true

View File

@@ -10,17 +10,20 @@ type Folder struct {
Folders []*Folder `json:"folders,omitempty"`
}
func (f *Folder) ToDB(dest *db.Folder) bool {
func (f *Folder) ToDB(dest **db.Folder) bool {
if dest == nil {
return false
}
dest.Name = f.Name
dest.Sorting = f.Sorting
dest.Color = f.Color
copy(dest.Packs, f.Packs)
folder := &db.Folder{
Name: f.Name,
Sorting: f.Sorting,
Color: f.Color,
}
copy(folder.Packs, f.Packs)
CopySliceToDB(&folder.Folders, f.Folders)
CopySliceToDB(&dest.Folders, f.Folders)
*dest = folder
return true
}

View File

@@ -14,20 +14,24 @@ type Grid struct {
Thickness int `json:"thickness,omitempty"`
}
func (g *Grid) ToDB(dest *db.Grid) bool {
func (g *Grid) ToDB(dest **db.Grid) bool {
if dest == nil {
return false
}
dest.Type = g.Type
dest.Size = g.Size
dest.Color = g.Color
dest.Alpha = g.Alpha
dest.Distance = g.Distance
dest.Units = g.Units
dest.Diagonals = g.Diagonals
dest.Style = g.Style
dest.Thickness = g.Thickness
grid := &db.Grid{
Type: g.Type,
Size: g.Size,
Color: g.Color,
Alpha: g.Alpha,
Distance: g.Distance,
Units: g.Units,
Diagonals: g.Diagonals,
Style: g.Style,
Thickness: g.Thickness,
}
*dest = grid
return true
}

View File

@@ -10,16 +10,20 @@ type Index struct {
Type string `json:"type"`
}
func (i *Index) ToDB(dest *db.Index) bool {
func (i *Index) ToDB(dest **db.Index) bool {
if dest == nil {
return false
}
dest.ID = i.Id
dest.Folder = i.Folder
dest.Img = i.Img
dest.Name = i.Name
dest.Type = i.Type
index := &db.Index{
ID: i.Id,
Folder: i.Folder,
Img: i.Img,
Name: i.Name,
Type: i.Type,
}
*dest = index
return true
}

View File

@@ -9,14 +9,18 @@ type Language struct {
// SystemLanguagesFlags SystemLanguagesFlags `json:"flags"`
}
func (l *Language) ToDB(dest *db.Language) bool {
func (l *Language) ToDB(dest **db.Language) bool {
if dest == nil {
return false
}
dest.Lang = l.Lang
dest.Name = l.Name
dest.Path = l.Path
lang := &db.Language{
Lang: l.Lang,
Name: l.Name,
Path: l.Path,
}
*dest = lang
return true
}
@@ -27,15 +31,19 @@ type SetupLanguage struct {
Modules []*SetupLanguageModule `json:"modules"`
}
func (s *SetupLanguage) ToDB(dest *db.SetupLanguage) bool {
func (s *SetupLanguage) ToDB(dest **db.SetupLanguage) bool {
if dest == nil {
return false
}
dest.ID = s.ID
dest.Label = s.Label
lang := &db.SetupLanguage{
ID: s.ID,
Label: s.Label,
}
CopySliceToDB(&dest.Modules, s.Modules)
CopySliceToDB(&lang.Modules, s.Modules)
*dest = lang
return true
}

View File

@@ -8,14 +8,18 @@ type Media struct {
Caption string `json:"caption"`
}
func (m *Media) ToDB(dest *db.Media) bool {
func (m *Media) ToDB(dest **db.Media) bool {
if dest == nil {
return false
}
dest.Type = m.Type
dest.URL = m.URL
dest.Caption = m.Caption
media := &db.Media{
Type: m.Type,
URL: m.URL,
Caption: m.Caption,
}
*dest = media
return true
}

View File

@@ -32,45 +32,49 @@ type SetupOptions struct {
HotReload bool `json:"hotReload"`
Language string `json:"language"`
LocalHostname string `json:"localHostname"`
Port int `json:"port"`
ProxySSL bool `json:"proxySSL"`
Telemetry bool `json:"telemetry"`
UpdateChannel string `json:"updateChannel"`
Upnp bool `json:"upnp"`
DeleteNEDB bool `json:"deleteNEDB"`
NoBackups bool `json:"noBackups"`
// PasswordSalt any `json:"passwordSalt"`
Port int `json:"port"`
// Protocol any `json:"protocol"`
// ProxyPort any `json:"proxyPort"`
ProxySSL bool `json:"proxySSL"`
// RoutePrefix any `json:"routePrefix"`
// SslCert any `json:"sslCert"`
// SslKey any `json:"sslKey"`
Telemetry bool `json:"telemetry"`
UpdateChannel string `json:"updateChannel"`
Upnp bool `json:"upnp"`
// UpnpLeaseDuration any `json:"upnpLeaseDuration"`
// World any `json:"world"`
DeleteNEDB bool `json:"deleteNEDB"`
// AdminPassword string `json:"adminPassword"`
NoBackups bool `json:"noBackups"`
}
func (s *SetupOptions) ToDB(dest *db.SetupOptions) bool {
func (s *SetupOptions) ToDB(dest **db.SetupOptions) bool {
if dest == nil {
return false
}
dest.CompressSocket = s.CompressSocket
dest.CompressStatic = s.CompressStatic
dest.CSSTheme = s.CSSTheme
dest.DataPath = s.DataPath
dest.Fullscreen = s.Fullscreen
dest.Hostname = s.Hostname
dest.HotReload = s.HotReload
dest.Language = s.Language
dest.LocalHostname = s.LocalHostname
dest.Port = s.Port
dest.ProxySSL = s.ProxySSL
dest.Telemetry = s.Telemetry
dest.UpdateChannel = s.UpdateChannel
dest.Upnp = s.Upnp
dest.DeleteNEDB = s.DeleteNEDB
dest.NoBackups = s.NoBackups
options := &db.SetupOptions{
CompressSocket: s.CompressSocket,
CompressStatic: s.CompressStatic,
CSSTheme: s.CSSTheme,
DataPath: s.DataPath,
Fullscreen: s.Fullscreen,
Hostname: s.Hostname,
HotReload: s.HotReload,
Language: s.Language,
LocalHostname: s.LocalHostname,
Port: s.Port,
ProxySSL: s.ProxySSL,
Telemetry: s.Telemetry,
UpdateChannel: s.UpdateChannel,
Upnp: s.Upnp,
DeleteNEDB: s.DeleteNEDB,
NoBackups: s.NoBackups,
}
*dest = options
return true
}

View File

@@ -22,27 +22,32 @@ type Pack struct {
// SystemPacksFlags SystemPacksFlags `json:"flags"`
}
func (p *Pack) ToDB(dest *db.Pack) bool {
func (p *Pack) ToDB(dest **db.Pack) bool {
if dest == nil {
return false
}
dest.Name = p.Name
dest.Label = p.Label
dest.Banner = p.Banner
dest.Path = p.Path
dest.Type = p.Type
dest.System = p.System
p.Ownership.ToDB(&dest.Ownership)
dest.PackageType = p.PackageType
dest.PackageName = p.PackageName
dest.ID = p.Id
pack := &db.Pack{
Name: p.Name,
Label: p.Label,
Banner: p.Banner,
Path: p.Path,
Type: p.Type,
System: p.System,
PackageType: p.PackageType,
PackageName: p.PackageName,
ID: p.Id,
}
p.Ownership.ToDB(&pack.Ownership)
wg := sync.WaitGroup{}
go CopySliceToDBParallel(&wg, &dest.Index, p.Index)
go CopySliceToDBParallel(&wg, &dest.Folders, p.Folders)
go CopySliceToDBParallel(&wg, &pack.Index, p.Index)
go CopySliceToDBParallel(&wg, &pack.Folders, p.Folders)
wg.Wait()
*dest = pack
return true
}
@@ -58,17 +63,21 @@ type PackFolder struct {
// Packs0FoldersFlags any `json:"flags"`
}
func (p *PackFolder) ToDB(dest *db.PackFolder) bool {
func (p *PackFolder) ToDB(dest **db.PackFolder) bool {
if dest == nil {
return false
}
dest.ID = p.ID
dest.Description = p.Description
dest.Name = p.Name
dest.Sort = p.Sort
dest.Sorting = p.Sorting
dest.Type = p.Type
packFolder := &db.PackFolder{
ID: p.ID,
Description: p.Description,
Name: p.Name,
Sort: p.Sort,
Sorting: p.Sorting,
Type: p.Type,
}
*dest = packFolder
return true
}

View File

@@ -76,15 +76,19 @@ type News struct {
Image string `json:"image"`
}
func (n *News) ToDB(dest *db.News) bool {
func (n *News) ToDB(dest **db.News) bool {
if dest == nil {
return false
}
dest.Title = n.Title
dest.Caption = n.Caption
dest.URL = n.Caption
dest.Image = n.Image
news := &db.News{
Title: n.Title,
Caption: n.Caption,
URL: n.Caption,
Image: n.Image,
}
*dest = news
return true
}

View File

@@ -6,12 +6,16 @@ type Style struct {
Src string `json:"src"`
}
func (s *Style) ToDB(dest *db.Style) bool {
func (s *Style) ToDB(dest **db.Style) bool {
if dest == nil {
return false
}
dest.Src = s.Src
style := &db.Style{
Src: s.Src,
}
*dest = style
return true
}

View File

@@ -34,7 +34,7 @@ func PackageWarningsToDB(dest *[]*db.PackageWarning, src map[string]PackageWarni
i := 0
for k, v := range src {
(*dest)[i].Key = k
v.ToDB(&(*dest)[i].Value)
v.ToDB((*dest)[i].Value)
i++
}
}