diff --git a/db/migrations/000001_create_foundry_state.down.sql b/db/migrations/000001_create_foundry_state.down.sql deleted file mode 100644 index 3552615..0000000 --- a/db/migrations/000001_create_foundry_state.down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE IF EXISTS options; -DROP TABLE IF EXISTS foundry_state; \ No newline at end of file diff --git a/db/migrations/000001_create_setup.down.sql b/db/migrations/000001_create_setup.down.sql new file mode 100644 index 0000000..d0fa079 --- /dev/null +++ b/db/migrations/000001_create_setup.down.sql @@ -0,0 +1,38 @@ +DROP TABLE IF EXISTS folder; +DROP TABLE IF EXISTS pack; +DROP TABLE IF EXISTS language; +DROP TABLE IF EXISTS style; +DROP TABLE IF EXISTS media; +DROP TABLE IF EXISTS author; +DROP TABLE IF EXISTS es_modules; +DROP TABLE IF EXISTS scripts; +DROP TABLE IF EXISTS tags; +DROP TABLE IF EXISTS relationships; +DROP TABLE IF EXISTS compatibility; +DROP TABLE IF EXISTS world; +DROP TABLE IF EXISTS grid; +DROP TABLE IF EXISTS system; +DROP TABLE IF EXISTS package_warnings_data_error; +DROP TABLE IF EXISTS package_warnings_data_warning; +DROP TABLE IF EXISTS package_warnings_data; +DROP TABLE IF EXISTS package_warnings; +DROP TABLE IF EXISTS news; +DROP TABLE IF EXISTS folder_packs; +DROP TABLE IF EXISTS folder; +DROP TABLE IF EXISTS pack_folder; +DROP TABLE IF EXISTS index_; +DROP TABLE IF EXISTS ownership; +DROP TABLE IF EXISTS relationships_data; +DROP TABLE IF EXISTS document_types_data_html; +DROP TABLE IF EXISTS document_types_data; +DROP TABLE IF EXISTS document_types; +DROP TABLE IF EXISTS module; +DROP TABLE IF EXISTS setup_language_module; +DROP TABLE IF EXISTS setup_language; +DROP TABLE IF EXISTS release_; +DROP TABLE IF EXISTS setup_options; +DROP TABLE IF EXISTS files_storage; +DROP TABLE IF EXISTS files; +DROP TABLE IF EXISTS featured_content; +DROP TABLE IF EXISTS core_update; +DROP TABLE IF EXISTS setup; \ No newline at end of file diff --git a/db/migrations/000001_create_setup.up.sql b/db/migrations/000001_create_setup.up.sql new file mode 100644 index 0000000..00a52be --- /dev/null +++ b/db/migrations/000001_create_setup.up.sql @@ -0,0 +1,526 @@ +CREATE TABLE IF NOT EXISTS setup ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + is_admin BOOLEAN NOT NULL DEFAULT FALSE, + is_setup BOOLEAN NOT NULL DEFAULT TRUE, + + created_at DATETIME NOT NULL DEFAULT current_timestamp +); + +CREATE TABLE IF NOT EXISTS core_update ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + has_update BOOLEAN NOT NULL DEFAULT FALSE, + can_update BOOLEAN NOT NULL DEFAULT FALSE, + could_reach_website BOOLEAN NOT NULL DEFAULT FALSE, + slow_response BOOLEAN NOT NULL DEFAULT FALSE, + will_disable_modules BOOLEAN NOT NULL DEFAULT FALSE, + version VARCHAR(64) NOT NULL, + channel VARCHAR(64) NOT NULL, + + setup_id INTEGER UNIQUE, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS featured_content ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + title VARCHAR(128) NOT NULL, + caption VARCHAR(128) NOT NULL, + url VARCHAR(128) NOT NULL, + image VARCHAR(128) NOT NULL, + + setup_id INTEGER UNIQUE, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS files ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + setup_id INTEGER UNIQUE, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS files_storage ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + storage TEXT NOT NULL, + + files_id INTEGER, + FOREIGN KEY (files_id) REFERENCES files(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS setup_options ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + css_theme VARCHAR(128) NOT NULL, + data_path VARCHAR(128) NOT NULL, + hostname VARCHAR(128) NOT NULL, + language VARCHAR(128) NOT NULL, + local_hostname VARCHAR(128) NOT NULL, + update_channel VARCHAR(128) NOT NULL, + port INTEGER NOT NULL, + compress_socket BOOLEAN NOT NULL DEFAULT FALSE, + compress_static BOOLEAN NOT NULL DEFAULT FALSE, + fullscreen BOOLEAN NOT NULL DEFAULT FALSE, + hot_reload BOOLEAN NOT NULL DEFAULT FALSE, + proxy_ssl BOOLEAN NOT NULL, + telemetry BOOLEAN NOT NULL, + upnp BOOLEAN NOT NULL, + delete_nedb BOOLEAN NOT NULL, + no_backups BOOLEAN NOT NULL, + + setup_id INTEGER UNIQUE, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS release_ ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + generation INTEGER NOT NULL, + build INTEGER NOT NULL, + node_version INTEGER NOT NULL, + max_generation INTEGER NOT NULL, + max_stable_generation INTEGER NOT NULL, + time DATETIME NOT NULL, + channel VARCHAR(128) NOT NULL, + suffix VARCHAR(128) NOT NULL, + + setup_id INTEGER UNIQUE, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS setup_language ( + id INTEGER PRIMARY KEY, + + label VARCHAR(128) NOT NULL, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS setup_language_module ( + id TEXT PRIMARY KEY, + + label VARCHAR(128) NOT NULL, + path VARCHAR(128) NOT NULL, + + setup_language_id INTEGER, + FOREIGN KEY (setup_language_id) REFERENCES setup_language(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS module ( + id TEXT PRIMARY KEY, + + title VARCHAR(128) NOT NULL, + description VARCHAR(128) NOT NULL, + url VARCHAR(128) NOT NULL, + license VARCHAR(128) NOT NULL, + readme VARCHAR(128) NOT NULL, + bugs VARCHAR(128) NOT NULL, + changelog VARCHAR(128) NOT NULL, + version VARCHAR(128) NOT NULL, + manifest VARCHAR(128) NOT NULL, + download VARCHAR(128) NOT NULL, + socket BOOLEAN NOT NULL DEFAULT FALSE, + protected BOOLEAN NOT NULL DEFAULT FALSE, + exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, + persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, + core_translation BOOLEAN NOT NULL DEFAULT FALSE, + library BOOLEAN NOT NULL DEFAULT FALSE, + locked BOOLEAN NOT NULL DEFAULT FALSE, + owned BOOLEAN NOT NULL DEFAULT FALSE, + has_storage BOOLEAN NOT NULL DEFAULT FALSE, + active BOOLEAN NOT NULL DEFAULT FALSE, + availability INTEGER NOT NULL DEFAULT FALSE, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS document_types ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + module_id TEXT UNIQUE, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS document_types_data ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + type VARCHAR(64) NOT NULL, + + document_types_id INTEGER, + FOREIGN KEY (document_types_id) REFERENCES document_types(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS document_types_data_html ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + value TEXT NOT NULL, + + document_types_data_id INTEGER, + FOREIGN KEY (document_types_data_id) REFERENCES document_types_data(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS relationships ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + module_id TEXT UNIQUE, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS relationships_systems ( + id TEXT PRIMARY KEY, + + relationships_type VARCHAR(32) NOT NULL, + type TEXT NOT NULL, + manifest TEXT NOT NULL, + + relationships_id INTEGER, + FOREIGN KEY (relationships_id) REFERENCES relationships(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS relationships_requires ( + id TEXT PRIMARY KEY, + + relationships_type VARCHAR(32) NOT NULL, + type TEXT NOT NULL, + manifest TEXT NOT NULL, + + relationships_id INTEGER, + FOREIGN KEY (relationships_id) REFERENCES relationships(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS relationships_recommends ( + id TEXT PRIMARY KEY, + + relationships_type VARCHAR(32) NOT NULL, + type TEXT NOT NULL, + manifest TEXT NOT NULL, + + relationships_id INTEGER, + FOREIGN KEY (relationships_id) REFERENCES relationships(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS relationships_conflicts ( + id TEXT PRIMARY KEY, + + relationships_type VARCHAR(32) NOT NULL, + type TEXT NOT NULL, + manifest TEXT NOT NULL, + + relationships_id INTEGER, + FOREIGN KEY (relationships_id) REFERENCES relationships(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS compatibility ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + minimum VARCHAR(64) NOT NULL, + verified VARCHAR(64) NOT NULL, + maximum VARCHAR(64) NOT NULL, + + module_id TEXT UNIQUE, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, + relationships_systems_id TEXT UNIQUE, + FOREIGN KEY (relationships_systems_id) REFERENCES relationships_systems(id) ON DELETE CASCADE + relationships_requires_id TEXT UNIQUE, + FOREIGN KEY (relationships_requires_id) REFERENCES relationships_requires(id) ON DELETE CASCADE + relationships_recommends_id TEXT UNIQUE, + FOREIGN KEY (relationships_recommends_id) REFERENCES relationships_recommends(id) ON DELETE CASCADE + relationships_conflicts_id TEXT UNIQUE, + FOREIGN KEY (relationships_conflicts_id) REFERENCES relationships_conflicts(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS scripts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + value TEXT NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS es_modules ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + value TEXT NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS tags ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + value VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS author ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + name VARCHAR(128) NOT NULL, + url VARCHAR(128) NOT NULL, + email VARCHAR(128) NOT NULL, + discord VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS media ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + type VARCHAR(128) NOT NULL, + url VARCHAR(128) NOT NULL, + caption VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS style ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + src VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS language ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + lang VARCHAR(128) NOT NULL, + name VARCHAR(128) NOT NULL, + path VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS pack ( + id TEXT PRIMARY KEY, + + name VARCHAR(128) NOT NULL, + label VARCHAR(128) NOT NULL, + banner VARCHAR(128) NOT NULL, + path VARCHAR(128) NOT NULL, + type VARCHAR(128) NOT NULL, + system VARCHAR(128) NOT NULL, + package_type VARCHAR(128) NOT NULL, + package_name VARCHAR(128) NOT NULL, + + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS ownership ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + player VARCHAR(128) NOT NULL, + trusted VARCHAR(128) NOT NULL, + assistant VARCHAR(128) NOT NULL, + + pack_id TEXT UNIQUE, + FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS index_ ( + id TEXT PRIMARY KEY, + + folder VARCHAR(128) NOT NULL, + img VARCHAR(128) NOT NULL, + name VARCHAR(128) NOT NULL, + type VARCHAR(128) NOT NULL, + + pack_id TEXT, + FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS pack_folder ( + id TEXT PRIMARY KEY, + + description VARCHAR(128) NOT NULL, + name VARCHAR(128) NOT NULL, + sorting VARCHAR(128) NOT NULL, + type VARCHAR(128) NOT NULL, + sort INTEGER NOT NULL, + + pack_id TEXT, + FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS folder ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + name VARCHAR(128) NOT NULL, + sorting VARCHAR(128) NOT NULL, + color VARCHAR(128) NOT NULL, + + folder_id INTEGER, + FOREIGN KEY (folder_id) REFERENCES folder(id) ON DELETE CASCADE, + module_id TEXT, + FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS folder_packs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + packs VARCHAR(128) NOT NULL, + + folder_id INTEGER, + FOREIGN KEY (folder_id) REFERENCES folder(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS news ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + title VARCHAR(64) NOT NULL, + caption VARCHAR(64) NOT NULL, + url VARCHAR(64) NOT NULL, + image VARCHAR(64) NOT NULL, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS package_warnings ( + id TEXT PRIMARY KEY, + + key_ VARCHAR(128) NOT NULL, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS package_warnings_data ( + id TEXT PRIMARY KEY, + + type VARCHAR(128) NOT NULL, + manifest VARCHAR(128) NOT NULL, + reinstallable BOOLEAN NOT NULL, + + package_warnings_id TEXT, + FOREIGN KEY (package_warnings_id) REFERENCES package_warnings(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS package_warnings_data_warning ( + id INTEGER PRIMARY KEY, + + value VARCHAR(128) NOT NULL, + + package_warnings_data_id TEXT, + FOREIGN KEY (package_warnings_data_id) REFERENCES package_warnings_data(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS package_warnings_data_error ( + id INTEGER PRIMARY KEY, + + value VARCHAR(128) NOT NULL, + + package_warnings_data_id TEXT, + FOREIGN KEY (package_warnings_data_id) REFERENCES package_warnings_data(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS system ( + id TEXT PRIMARY KEY, + + title VARCHAR(128) NOT NULL, + description VARCHAR(128) NOT NULL, + url VARCHAR(128) NOT NULL, + license VARCHAR(128) NOT NULL, + bugs VARCHAR(128) NOT NULL, + changelog VARCHAR(128) NOT NULL, + version VARCHAR(128) NOT NULL, + manifest VARCHAR(128) NOT NULL, + download VARCHAR(128) NOT NULL, + background VARCHAR(128) NOT NULL DEFAULT FALSE, + primary_token_attribute VARCHAR(128) NOT NULL DEFAULT FALSE, + availability INTEGER NOT NULL DEFAULT FALSE, + socket BOOLEAN NOT NULL DEFAULT FALSE, + protected BOOLEAN NOT NULL DEFAULT FALSE, + exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, + persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, + locked BOOLEAN NOT NULL DEFAULT FALSE, + owned BOOLEAN NOT NULL DEFAULT FALSE, + has_storage BOOLEAN NOT NULL DEFAULT FALSE, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +ALTER TABLE compatibility ADD COLUMN system_id TEXT UNIQUE REFERENCES system(id); +ALTER TABLE relationships ADD COLUMN system_id TEXT UNIQUE REFERENCES system(id); +ALTER TABLE document_types ADD COLUMN system_id TEXT UNIQUE REFERENCES system(id); + +CREATE TABLE IF NOT EXISTS grid ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + + type INTEGER NOT NULL, + size INTEGER NOT NULL, + distance INTEGER NOT NULL, + diagonals INTEGER NOT NULL, + thickness INTEGER NOT NULL, + alpha REAL NOT NULL, + color VARCHAR(128) NOT NULL, + units VARCHAR(128) NOT NULL, + style VARCHAR(128) NOT NULL, + + system_id TEXT UNIQUE, + FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE +); + +ALTER TABLE es_modules ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE scripts ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE tags ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE author ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE media ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE pack ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE style ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE language ADD COLUMN system_id TEXT REFERENCES system(id); +ALTER TABLE folder ADD COLUMN system_id TEXT REFERENCES system(id); + +CREATE TABLE IF NOT EXISTS world ( + id TEXT PRIMARY KEY, + + title VARCHAR(128) NOT NULL, + description VARCHAR(128) NOT NULL, + version VARCHAR(128) NOT NULL, + system VARCHAR(128) NOT NULL, + background VARCHAR(128) NOT NULL, + join_theme VARCHAR(128) NOT NULL, + core_version VARCHAR(128) NOT NULL, + system_version VARCHAR(128) NOT NULL, + last_played VARCHAR(128) NOT NULL, + playtime INTEGER NOT NULL, + availability INTEGER NOT NULL, + next_session DATETIME NOT NULL, + socket BOOLEAN NOT NULL DEFAULT FALSE, + protected BOOLEAN NOT NULL DEFAULT FALSE, + exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, + persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, + locked BOOLEAN NOT NULL DEFAULT FALSE, + owned BOOLEAN NOT NULL DEFAULT FALSE, + has_storage BOOLEAN NOT NULL DEFAULT FALSE, + + setup_id INTEGER, + FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE +); + +ALTER TABLE compatibility ADD COLUMN world_id TEXT UNIQUE REFERENCES world(id); +ALTER TABLE relationships ADD COLUMN world_id TEXT UNIQUE REFERENCES world(id); + +ALTER TABLE tags ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE scripts ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE es_modules ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE author ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE media ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE style ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE language ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE pack ADD COLUMN world_id TEXT REFERENCES world(id); +ALTER TABLE folder ADD COLUMN world_id TEXT REFERENCES world(id); diff --git a/db/migrations/000002_create_modules.down.sql b/db/migrations/000002_create_game.down.sql similarity index 100% rename from db/migrations/000002_create_modules.down.sql rename to db/migrations/000002_create_game.down.sql diff --git a/db/migrations/000001_create_foundry_state.up.sql b/db/migrations/000002_create_game.up.sql similarity index 51% rename from db/migrations/000001_create_foundry_state.up.sql rename to db/migrations/000002_create_game.up.sql index ff4bc9f..296449d 100644 --- a/db/migrations/000001_create_foundry_state.up.sql +++ b/db/migrations/000002_create_game.up.sql @@ -1,12 +1,3 @@ -CREATE TABLE IF NOT EXISTS setup ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - is_admin BOOLEAN NOT NULL DEFAULT FALSE, - is_setup BOOLEAN NOT NULL DEFAULT TRUE, - - created_at DATETIME NOT NULL DEFAULT current_timestamp -); - CREATE TABLE IF NOT EXISTS game ( id INTEGER PRIMARY KEY AUTOINCREMENT @@ -18,96 +9,6 @@ CREATE TABLE IF NOT EXISTS game ( created_at DATETIME NOT NULL DEFAULT current_timestamp ); -CREATE TABLE IF NOT EXISTS world ( - id TEXT PRIMARY KEY, - - socket BOOLEAN NOT NULL DEFAULT FALSE, - protected BOOLEAN NOT NULL DEFAULT FALSE, - exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, - persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, - locked BOOLEAN NOT NULL DEFAULT FALSE, - owned BOOLEAN NOT NULL DEFAULT FALSE, - has_storage BOOLEAN NOT NULL DEFAULT FALSE, - playtime INTEGER NOT NULL, - availability INTEGER NOT NULL, - next_session DATETIME NOT NULL, - - title VARCHAR(128) NOT NULL, - description VARCHAR(128) NOT NULL, - version VARCHAR(128) NOT NULL, - system VARCHAR(128) NOT NULL, - background VARCHAR(128) NOT NULL, - join_theme VARCHAR(128) NOT NULL, - core_version VARCHAR(128) NOT NULL, - system_version VARCHAR(128) NOT NULL, - last_played VARCHAR(128) NOT NULL, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE - game_id INTEGER UNIQUE, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS system ( - id TEXT PRIMARY KEY, - - title VARCHAR(128) NOT NULL, - description VARCHAR(128) NOT NULL, - url VARCHAR(128) NOT NULL, - license VARCHAR(128) NOT NULL, - bugs VARCHAR(128) NOT NULL, - changelog VARCHAR(128) NOT NULL, - version VARCHAR(128) NOT NULL, - socket BOOLEAN NOT NULL DEFAULT FALSE, - manifest VARCHAR(128) NOT NULL, - download VARCHAR(128) NOT NULL, - protected BOOLEAN NOT NULL DEFAULT FALSE, - exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, - persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, - background VARCHAR(128) NOT NULL DEFAULT FALSE, - primary_token_attribute VARCHAR(128) NOT NULL DEFAULT FALSE, - availability INTEGER NOT NULL DEFAULT FALSE, - locked BOOLEAN NOT NULL DEFAULT FALSE, - owned BOOLEAN NOT NULL DEFAULT FALSE, - has_storage BOOLEAN NOT NULL DEFAULT FALSE, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE - game_id INTEGER UNIQUE, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS module ( - id TEXT PRIMARY KEY, - - title VARCHAR(128) NOT NULL, - description VARCHAR(128) NOT NULL, - url VARCHAR(128) NOT NULL, - license VARCHAR(128) NOT NULL, - readme VARCHAR(128) NOT NULL, - bugs VARCHAR(128) NOT NULL, - changelog VARCHAR(128) NOT NULL, - version VARCHAR(128) NOT NULL, - socket BOOLEAN NOT NULL DEFAULT FALSE, - manifest VARCHAR(128) NOT NULL, - download VARCHAR(128) NOT NULL, - protected BOOLEAN NOT NULL DEFAULT FALSE, - exclusive_ BOOLEAN NOT NULL DEFAULT FALSE, - persistent_storage BOOLEAN NOT NULL DEFAULT FALSE, - core_translation BOOLEAN NOT NULL DEFAULT FALSE, - library BOOLEAN NOT NULL DEFAULT FALSE, - availability INTEGER NOT NULL DEFAULT FALSE, - locked BOOLEAN NOT NULL DEFAULT FALSE, - owned BOOLEAN NOT NULL DEFAULT FALSE, - has_storage BOOLEAN NOT NULL DEFAULT FALSE, - active BOOLEAN NOT NULL DEFAULT FALSE, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE - game_id INTEGER, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE -); - CREATE TABLE IF NOT EXISTS addresses ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -119,29 +20,6 @@ CREATE TABLE IF NOT EXISTS addresses ( FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS setup_options ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - compress_socket BOOLEAN NOT NULL DEFAULT FALSE, - compress_static BOOLEAN NOT NULL DEFAULT FALSE, - css_theme VARCHAR(128) NOT NULL, - data_path VARCHAR(128) NOT NULL, - fullscreen BOOLEAN NOT NULL DEFAULT FALSE, - hostname VARCHAR(128) NOT NULL, - hot_reload BOOLEAN NOT NULL DEFAULT FALSE, - language VARCHAR(128) NOT NULL, - local_hostname VARCHAR(128) NOT NULL, - port INTEGER NOT NULL, - proxy_ssl BOOLEAN NOT NULL, - telemetry BOOLEAN NOT NULL, - update_channel VARCHAR(128) NOT NULL, - upnp BOOLEAN NOT NULL, - delete_nedb BOOLEAN NOT NULL, - no_backups BOOLEAN NOT NULL, - - setup_id INTEGER UNIQUE, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE -); CREATE TABLE IF NOT EXISTS game_options ( id INTEGER PRIMARY KEY, @@ -483,51 +361,9 @@ CREATE TABLE IF NOT EXISTS active_users ( FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS grid ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - type INTEGER NOT NULL, - size INTEGER NOT NULL, - distance INTEGER NOT NULL, - diagonals INTEGER NOT NULL, - thickness INTEGER NOT NULL, - alpha REAL NOT NULL, - color VARCHAR(128) NOT NULL, - units VARCHAR(128) NOT NULL, - style VARCHAR(128) NOT NULL, - system_id TEXT UNIQUE, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE -); -CREATE TABLE IF NOT EXISTS relationships ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - module_id TEXT UNIQUE, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT UNIQUE, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT UNIQUE, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS release_ ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - generation INTEGER NOT NULL, - channel VARCHAR(128) NOT NULL, - suffix VARCHAR(128) NOT NULL, - build INTEGER NOT NULL, - node_version INTEGER NOT NULL, - max_generation INTEGER NOT NULL, - max_stable_generation INTEGER NOT NULL, - time INTEGER NOT NULL, - - setup_id INTEGER UNIQUE, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE, - game_id INTEGER UNIQUE, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE -); CREATE TABLE IF NOT EXISTS item ( id TEXT PRIMARY KEY, @@ -554,158 +390,6 @@ CREATE TABLE IF NOT EXISTS journal ( FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS relationships_data ( - id TEXT PRIMARY KEY, - - relationships_type VARCHAR(32) NOT NULL, - type TEXT NOT NULL, - manifest TEXT NOT NULL, - - relationships_id INTEGER UNIQUE, - FOREIGN KEY (relationships_id) REFERENCES relationships(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS compatibility ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - minimum VARCHAR(64) NOT NULL, - verified VARCHAR(64) NOT NULL, - maximum VARCHAR(64) NOT NULL, - - module_id TEXT UNIQUE, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT UNIQUE, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT UNIQUE, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE, - relationships_data_id TEXT UNIQUE, - FOREIGN KEY (relationships_data_id) REFERENCES relationships_data(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS author ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - name VARCHAR(128) NOT NULL, - url VARCHAR(128) NOT NULL, - email VARCHAR(128) NOT NULL, - discord VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS media ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - type VARCHAR(128) NOT NULL, - url VARCHAR(128) NOT NULL, - caption VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS scripts ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - scripts TEXT NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id INTEGER, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS es_modules ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - es_modules TEXT NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS style ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - src VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS language ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - lang VARCHAR(128) NOT NULL, - name VARCHAR(128) NOT NULL, - path VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS package_warnings ( - id TEXT PRIMARY KEY, - - key_ VARCHAR(128) NOT NULL, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE, - game_id INTEGER, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE, -); - -CREATE TABLE IF NOT EXISTS package_warnings_data ( - id TEXT PRIMARY KEY, - - type VARCHAR(128) NOT NULL, - reinstallable VARCHAR(128) NOT NULL, - manifest VARCHAR(128) NOT NULL, - - package_warnings_id TEXT, - FOREIGN KEY (package_warnings_id) REFERENCES package_warnings(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS package_warnings_data_warning ( - id INTEGER PRIMARY KEY, - - value VARCHAR(128) NOT NULL, - - package_warnings_data_id TEXT, - FOREIGN KEY (package_warnings_data_id) REFERENCES package_warnings_data(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS package_warnings_data_error ( - id INTEGER PRIMARY KEY, - - value VARCHAR(128) NOT NULL, - - package_warnings_data_id TEXT, - FOREIGN KEY (package_warnings_data_id) REFERENCES package_warnings_data(id) ON DELETE CASCADE -); CREATE TABLE IF NOT EXISTS world_folder ( id TEXT PRIMARY KEY, @@ -909,28 +593,6 @@ CREATE TABLE IF NOT EXISTS message_rolls ( FOREIGN KEY (message_id) REFERENCES message(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS pack ( - id TEXT PRIMARY KEY, - - name VARCHAR(128) NOT NULL, - label VARCHAR(128) NOT NULL, - banner VARCHAR(128) NOT NULL, - path VARCHAR(128) NOT NULL, - type VARCHAR(128) NOT NULL, - system VARCHAR(128) NOT NULL, - package_type VARCHAR(128) NOT NULL, - package_name VARCHAR(128) NOT NULL, - - game_id INTEGER, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE, - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - CREATE TABLE IF NOT EXISTS journal_page ( id TEXT PRIMARY KEY, @@ -974,19 +636,6 @@ CREATE TABLE IF NOT EXISTS journal_page_video ( FOREIGN KEY (journal_page_id) REFERENCES journal_page(id) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS ownership ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - player VARCHAR(128) NOT NULL, - trusted VARCHAR(128) NOT NULL, - assistant VARCHAR(128) NOT NULL, - - pack_id TEXT UNIQUE, - FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE, - card_deck_id TEXT UNIQUE, - FOREIGN KEY (card_deck_id) REFERENCES card_deck(id) ON DELETE CASCADE -); - CREATE TABLE IF NOT EXISTS ownership_string ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -1006,96 +655,6 @@ CREATE TABLE IF NOT EXISTS ownership_string ( ); -CREATE TABLE IF NOT EXISTS index_ ( - id TEXT PRIMARY KEY, - - folder VARCHAR(128) NOT NULL, - img VARCHAR(128) NOT NULL, - name VARCHAR(128) NOT NULL, - type VARCHAR(128) NOT NULL, - - pack_id TEXT, - FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS pack_folder ( - id TEXT PRIMARY KEY, - - description VARCHAR(128) NOT NULL, - name VARCHAR(128) NOT NULL, - sort INTEGER NOT NULL, - sorting VARCHAR(128) NOT NULL, - type VARCHAR(128) NOT NULL, - - pack_id TEXT, - FOREIGN KEY (pack_id) REFERENCES pack(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS folder ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - name VARCHAR(128) NOT NULL, - sorting VARCHAR(128) NOT NULL, - color VARCHAR(128) NOT NULL, - - folder_id INTEGER, - FOREIGN KEY (folder_id) REFERENCES folder(id) ON DELETE CASCADE, - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS folder_packs ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - packs VARCHAR(128) NOT NULL, - - folder_id INTEGER, - FOREIGN KEY (folder_id) REFERENCES folder(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS tags ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - tags VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE - system_id TEXT, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE - world_id TEXT, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS document_types ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - module_id TEXT UNIQUE, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE - system_id TEXT UNIQUE, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS document_types_data ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - type VARCHAR(64) NOT NULL, - - document_types_id INTEGER, - FOREIGN KEY (document_types_id) REFERENCES document_types(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS document_types_data_html ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - html_fields TEXT NOT NULL, - - document_types_data_id INTEGER, - FOREIGN KEY (document_types_data_id) REFERENCES document_types_data(id) ON DELETE CASCADE -); CREATE TABLE IF NOT EXISTS system_update ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -1106,107 +665,3 @@ CREATE TABLE IF NOT EXISTS system_update ( game_id INTEGER UNIQUE, FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE ); - -CREATE TABLE IF NOT EXISTS core_update ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - has_update BOOLEAN NOT NULL DEFAULT FALSE, - can_update BOOLEAN NOT NULL DEFAULT FALSE, - could_reach_website BOOLEAN NOT NULL DEFAULT FALSE, - slow_response BOOLEAN NOT NULL DEFAULT FALSE, - version VARCHAR(64) NOT NULL, - channel VARCHAR(64) NOT NULL, - will_disable_modules BOOLEAN NOT NULL DEFAULT FALSE, - - setup_id INTEGER UNIQUE, - game_id INTEGER UNIQUE, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE, - CONSTRAINT one_parent_only CHECK ( - (setup_id IS NOT NULL AND game_id IS NULL) OR - (setup_id IS NULL AND game_id IS NOT NULL) - ) -); - -CREATE TABLE IF NOT EXISTS featured_content ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - title VARCHAR(128) NOT NULL, - caption VARCHAR(128) NOT NULL, - url VARCHAR(128) NOT NULL, - image VARCHAR(128) NOT NULL, - - setup_id INTEGER UNIQUE, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS news ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - title VARCHAR(64) NOT NULL, - caption VARCHAR(64) NOT NULL, - url VARCHAR(64) NOT NULL, - image VARCHAR(64) NOT NULL, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS files ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - setup_id INTEGER UNIQUE, - game_id INTEGER UNIQUE, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE, - FOREIGN KEY (game_id) REFERENCES game(id) ON DELETE CASCADE, - CONSTRAINT one_parent_only CHECK ( - (setup_id IS NOT NULL AND game_id IS NULL) OR - (setup_id IS NULL AND game_id IS NOT NULL) - ) -); - -CREATE TABLE IF NOT EXISTS files_storage ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - storage TEXT NOT NULL, - - files_id INTEGER, - FOREIGN KEY (files_id) REFERENCES files(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS setup_language ( - id INTEGER PRIMARY KEY, - - label VARCHAR(128) NOT NULL, - - setup_id INTEGER, - FOREIGN KEY (setup_id) REFERENCES setup(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS setup_language_module ( - id TEXT PRIMARY KEY, - - label VARCHAR(128) NOT NULL, - path VARCHAR(128) NOT NULL, - - setup_language_id INTEGER, - FOREIGN KEY (setup_language_id) REFERENCES setup_language(id) ON DELETE CASCADE -); - - - -CREATE TABLE IF NOT EXISTS language ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - - lang VARCHAR(128) NOT NULL, - name VARCHAR(128) NOT NULL, - path VARCHAR(128) NOT NULL, - - module_id TEXT, - FOREIGN KEY (module_id) REFERENCES module(id) ON DELETE CASCADE, - system_id INTEGER, - FOREIGN KEY (system_id) REFERENCES system(id) ON DELETE CASCADE, - world_id INTEGER, - FOREIGN KEY (world_id) REFERENCES world(id) ON DELETE CASCADE -); - diff --git a/db/migrations/000002_create_modules.up.sql b/db/migrations/000002_create_modules.up.sql deleted file mode 100644 index 008b8bd..0000000 --- a/db/migrations/000002_create_modules.up.sql +++ /dev/null @@ -1,32 +0,0 @@ -CREATE TABLE IF NOT EXISTS modules ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - state_id INTEGER NOT NULL, - text_id VARCHAR(256) NOT NULL, - title VARCHAR(256) NOT NULL, - description TEXT NOT NULL, - url VARCHAR(256) NOT NULL, - version VARCHAR(64) NOT NULL, - availability INTEGER NOT NULL, - created_at DATETIME NOT NULL DEFAULT current_timestamp, - FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS modules_compatibility ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - module_id INTEGER UNIQUE, - minimum VARCHAR(64) NOT NULL, - verified VARCHAR(64) NOT NULL, - maximum VARCHAR(64) NOT NULL, - - FOREIGN KEY (module_id) REFERENCES modules(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS modules_languages ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - module_id INTEGER, - language VARCHAR(256) NOT NULL, - name VARCHAR(256) NOT NULL, - path VARCHAR(256) NOT NULL, - - FOREIGN KEY (module_id) REFERENCES modules(id) ON DELETE CASCADE -); \ No newline at end of file diff --git a/db/migrations/000003_create_systems.down.sql b/db/migrations/000003_create_systems.down.sql deleted file mode 100644 index f4bf689..0000000 --- a/db/migrations/000003_create_systems.down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE IF EXISTS systems_compatibility; -DROP TABLE IF EXISTS systems; diff --git a/db/migrations/000003_create_systems.up.sql b/db/migrations/000003_create_systems.up.sql deleted file mode 100644 index 245ab89..0000000 --- a/db/migrations/000003_create_systems.up.sql +++ /dev/null @@ -1,21 +0,0 @@ -CREATE TABLE IF NOT EXISTS systems ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - state_id INTEGER NOT NULL, - text_id VARCHAR(256) NOT NULL, - title VARCHAR(256) NOT NULL, - description TEXT NOT NULL, - url VARCHAR(256) NOT NULL, - download VARCHAR(256) NOT NULL, - created_at DATETIME NOT NULL DEFAULT current_timestamp, - FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS systems_compatibility ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - system_id INTEGER UNIQUE, - minimum VARCHAR(64) NOT NULL, - verified VARCHAR(64) NOT NULL, - maximum VARCHAR(64) NOT NULL, - - FOREIGN KEY (system_id) REFERENCES systems(id) ON DELETE CASCADE -); diff --git a/db/migrations/000004_create_worlds.down.sql b/db/migrations/000004_create_worlds.down.sql deleted file mode 100644 index 022ec85..0000000 --- a/db/migrations/000004_create_worlds.down.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE IF EXISTS worlds_compatibility; -DROP TABLE IF EXISTS worlds; diff --git a/db/migrations/000004_create_worlds.up.sql b/db/migrations/000004_create_worlds.up.sql deleted file mode 100644 index 459cd36..0000000 --- a/db/migrations/000004_create_worlds.up.sql +++ /dev/null @@ -1,24 +0,0 @@ -CREATE TABLE IF NOT EXISTS worlds ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - state_id INTEGER NOT NULL, - text_id VARCHAR(256) NOT NULL, - title VARCHAR(256) NOT NULL, - description TEXT NOT NULL, - system VARCHAR(256) NOT NULL, - core_version VARCHAR(256) NOT NULL, - system_version VARCHAR(256) NOT NULL, - playtime INTEGER NOT NULL, - next_session DATETIME NOT NULL, - created_at DATETIME NOT NULL DEFAULT current_timestamp, - FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS worlds_compatibility ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - world_id INTEGER UNIQUE, - minimum VARCHAR(64) NOT NULL, - verified VARCHAR(64) NOT NULL, - maximum VARCHAR(64) NOT NULL, - - FOREIGN KEY (world_id) REFERENCES worlds(id) ON DELETE CASCADE -); diff --git a/db/migrations/000005_create_users.down.sql b/db/migrations/000005_create_users.down.sql deleted file mode 100644 index 96aea92..0000000 --- a/db/migrations/000005_create_users.down.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP TABLE IF EXISTS users; -DROP TABLE IF EXISTS users_hotbar; -DROP TABLE IF EXISTS users_stats; \ No newline at end of file diff --git a/db/migrations/000005_create_users.up.sql b/db/migrations/000005_create_users.up.sql deleted file mode 100644 index 84cb8c2..0000000 --- a/db/migrations/000005_create_users.up.sql +++ /dev/null @@ -1,33 +0,0 @@ -CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - state_id INTEGER NOT NULL, - name VARCHAR(256) NOT NULL, - role INTEGER NOT NULL, - character VARCHAR(128) NOT NULL, - color VARCHAR(128) NOT NULL, - pronouns VARCHAR(128) NOT NULL, - created_at DATETIME NOT NULL DEFAULT current_timestamp, - FOREIGN KEY (state_id) REFERENCES foundry_state(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS users_hotbar ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER, - key TEXT NOT NULL, - value TEXT NOT NULL, - - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS users_stats ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER UNIQUE, - core_version TEXT NOT NULL, - system_id VARCHAR(64) NOT NULL, - system_version VARCHAR(64) NOT NULL, - created_time INTEGER NOT NULL, - modified_time INTEGER NOT NULL, - last_modified_by VARCHAR(256) NOT NULL, - - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -); diff --git a/internal/foundry/temp_models/db/authors.go b/internal/foundry/temp_models/db/authors.go index 19c302c..19b20ee 100644 --- a/internal/foundry/temp_models/db/authors.go +++ b/internal/foundry/temp_models/db/authors.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/compatibility.go b/internal/foundry/temp_models/db/compatibility.go index 1f9fecd..142783b 100644 --- a/internal/foundry/temp_models/db/compatibility.go +++ b/internal/foundry/temp_models/db/compatibility.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/document_types.go b/internal/foundry/temp_models/db/document_types.go index b63ed97..c939b17 100644 --- a/internal/foundry/temp_models/db/document_types.go +++ b/internal/foundry/temp_models/db/document_types.go @@ -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() +} diff --git a/internal/foundry/temp_models/db/files.go b/internal/foundry/temp_models/db/files.go index 44b7d5e..3acc061 100644 --- a/internal/foundry/temp_models/db/files.go +++ b/internal/foundry/temp_models/db/files.go @@ -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 } diff --git a/internal/foundry/temp_models/db/folder.go b/internal/foundry/temp_models/db/folder.go index 0ae438e..cda5bde 100644 --- a/internal/foundry/temp_models/db/folder.go +++ b/internal/foundry/temp_models/db/folder.go @@ -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 { diff --git a/internal/foundry/temp_models/db/game.go b/internal/foundry/temp_models/db/game.go index 3375d60..f5397c8 100644 --- a/internal/foundry/temp_models/db/game.go +++ b/internal/foundry/temp_models/db/game.go @@ -18,7 +18,7 @@ type Game struct { ActiveUsers []string Modules []*Module PackageWarnings []*PackageWarning - Packs []Pack + Packs []*Pack Messages []Message Combats []Combat CardDeck []CardDeck diff --git a/internal/foundry/temp_models/db/grid.go b/internal/foundry/temp_models/db/grid.go index dc4c9b7..6c91cda 100644 --- a/internal/foundry/temp_models/db/grid.go +++ b/internal/foundry/temp_models/db/grid.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/index.go b/internal/foundry/temp_models/db/index.go index 767425a..cd7d9ad 100644 --- a/internal/foundry/temp_models/db/index.go +++ b/internal/foundry/temp_models/db/index.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/language.go b/internal/foundry/temp_models/db/language.go index af4d97a..faeefca 100644 --- a/internal/foundry/temp_models/db/language.go +++ b/internal/foundry/temp_models/db/language.go @@ -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 } diff --git a/internal/foundry/temp_models/db/media.go b/internal/foundry/temp_models/db/media.go index 13f664b..7c76088 100644 --- a/internal/foundry/temp_models/db/media.go +++ b/internal/foundry/temp_models/db/media.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/module.go b/internal/foundry/temp_models/db/module.go index e0e6052..c3639f0 100644 --- a/internal/foundry/temp_models/db/module.go +++ b/internal/foundry/temp_models/db/module.go @@ -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) } diff --git a/internal/foundry/temp_models/db/options.go b/internal/foundry/temp_models/db/options.go index ffc67b2..a29ea1a 100644 --- a/internal/foundry/temp_models/db/options.go +++ b/internal/foundry/temp_models/db/options.go @@ -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 } diff --git a/internal/foundry/temp_models/db/ownership.go b/internal/foundry/temp_models/db/ownership.go index 5157847..b9ec0f3 100644 --- a/internal/foundry/temp_models/db/ownership.go +++ b/internal/foundry/temp_models/db/ownership.go @@ -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 diff --git a/internal/foundry/temp_models/db/pack.go b/internal/foundry/temp_models/db/pack.go index 8bd4ffa..f473558 100644 --- a/internal/foundry/temp_models/db/pack.go +++ b/internal/foundry/temp_models/db/pack.go @@ -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 } diff --git a/internal/foundry/temp_models/db/package_warnings.go b/internal/foundry/temp_models/db/package_warnings.go index 416b2f0..dd9f924 100644 --- a/internal/foundry/temp_models/db/package_warnings.go +++ b/internal/foundry/temp_models/db/package_warnings.go @@ -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) +} diff --git a/internal/foundry/temp_models/db/relationships.go b/internal/foundry/temp_models/db/relationships.go index d35340a..ebc8fcb 100644 --- a/internal/foundry/temp_models/db/relationships.go +++ b/internal/foundry/temp_models/db/relationships.go @@ -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 } diff --git a/internal/foundry/temp_models/db/release.go b/internal/foundry/temp_models/db/release.go index b5d418b..fd993fd 100644 --- a/internal/foundry/temp_models/db/release.go +++ b/internal/foundry/temp_models/db/release.go @@ -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 } diff --git a/internal/foundry/temp_models/db/setup.go b/internal/foundry/temp_models/db/setup.go index e9356bd..637c15f 100644 --- a/internal/foundry/temp_models/db/setup.go +++ b/internal/foundry/temp_models/db/setup.go @@ -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 } diff --git a/internal/foundry/temp_models/db/style.go b/internal/foundry/temp_models/db/style.go index e204517..e923c76 100644 --- a/internal/foundry/temp_models/db/style.go +++ b/internal/foundry/temp_models/db/style.go @@ -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 +} diff --git a/internal/foundry/temp_models/db/system.go b/internal/foundry/temp_models/db/system.go index b3ae561..d0cfac1 100644 --- a/internal/foundry/temp_models/db/system.go +++ b/internal/foundry/temp_models/db/system.go @@ -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) } diff --git a/internal/foundry/temp_models/db/update.go b/internal/foundry/temp_models/db/update.go index d4c8fcc..109e909 100644 --- a/internal/foundry/temp_models/db/update.go +++ b/internal/foundry/temp_models/db/update.go @@ -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 } diff --git a/internal/foundry/temp_models/db/utils.go b/internal/foundry/temp_models/db/utils.go index 44c2819..903dc9b 100644 --- a/internal/foundry/temp_models/db/utils.go +++ b/internal/foundry/temp_models/db/utils.go @@ -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 + } + }) +} diff --git a/internal/foundry/temp_models/db/world.go b/internal/foundry/temp_models/db/world.go index 9073c24..9036890 100644 --- a/internal/foundry/temp_models/db/world.go +++ b/internal/foundry/temp_models/db/world.go @@ -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) } diff --git a/internal/foundry/temp_models/json/authors.go b/internal/foundry/temp_models/json/authors.go index 2371ac0..7baa1fe 100644 --- a/internal/foundry/temp_models/json/authors.go +++ b/internal/foundry/temp_models/json/authors.go @@ -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 } diff --git a/internal/foundry/temp_models/json/document_types.go b/internal/foundry/temp_models/json/document_types.go index 7d2cd78..c3222bd 100644 --- a/internal/foundry/temp_models/json/document_types.go +++ b/internal/foundry/temp_models/json/document_types.go @@ -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 diff --git a/internal/foundry/temp_models/json/folder.go b/internal/foundry/temp_models/json/folder.go index 8c614f8..b9f7af5 100644 --- a/internal/foundry/temp_models/json/folder.go +++ b/internal/foundry/temp_models/json/folder.go @@ -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 } diff --git a/internal/foundry/temp_models/json/grid.go b/internal/foundry/temp_models/json/grid.go index 825e2e5..d458f9a 100644 --- a/internal/foundry/temp_models/json/grid.go +++ b/internal/foundry/temp_models/json/grid.go @@ -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 } diff --git a/internal/foundry/temp_models/json/index.go b/internal/foundry/temp_models/json/index.go index 20b1f1f..3042d27 100644 --- a/internal/foundry/temp_models/json/index.go +++ b/internal/foundry/temp_models/json/index.go @@ -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 } diff --git a/internal/foundry/temp_models/json/language.go b/internal/foundry/temp_models/json/language.go index b035dcc..db6498e 100644 --- a/internal/foundry/temp_models/json/language.go +++ b/internal/foundry/temp_models/json/language.go @@ -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 } diff --git a/internal/foundry/temp_models/json/media.go b/internal/foundry/temp_models/json/media.go index 463bc23..e336f51 100644 --- a/internal/foundry/temp_models/json/media.go +++ b/internal/foundry/temp_models/json/media.go @@ -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 } diff --git a/internal/foundry/temp_models/json/options.go b/internal/foundry/temp_models/json/options.go index 48485bd..a01dd44 100644 --- a/internal/foundry/temp_models/json/options.go +++ b/internal/foundry/temp_models/json/options.go @@ -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 } diff --git a/internal/foundry/temp_models/json/pack.go b/internal/foundry/temp_models/json/pack.go index 72ad294..a74e501 100644 --- a/internal/foundry/temp_models/json/pack.go +++ b/internal/foundry/temp_models/json/pack.go @@ -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 } diff --git a/internal/foundry/temp_models/json/setup.go b/internal/foundry/temp_models/json/setup.go index 9390de3..9e8ef26 100644 --- a/internal/foundry/temp_models/json/setup.go +++ b/internal/foundry/temp_models/json/setup.go @@ -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 } diff --git a/internal/foundry/temp_models/json/style.go b/internal/foundry/temp_models/json/style.go index c992789..da98bd7 100644 --- a/internal/foundry/temp_models/json/style.go +++ b/internal/foundry/temp_models/json/style.go @@ -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 } diff --git a/internal/foundry/temp_models/json/utils.go b/internal/foundry/temp_models/json/utils.go index d4f26bc..8480d8e 100644 --- a/internal/foundry/temp_models/json/utils.go +++ b/internal/foundry/temp_models/json/utils.go @@ -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++ } }