Introduce series management functionality and repository updates
- Added `series-world.repo.ts` to handle database operations related to series worlds and their elements. - Implemented `series-sync.repo.ts` for managing synchronization between books and series. - Expanded `spell.ipc.ts` data models to include `seriesSpellId` for spell synchronization. - Refactored `insertSpellTag` method in `spelltag.repo.ts` for improved error handling and logic clarity.
This commit is contained in:
258
electron/database/repositories/series-sync.repo.ts
Normal file
258
electron/database/repositories/series-sync.repo.ts
Normal file
@@ -0,0 +1,258 @@
|
||||
import { Database, QueryResult, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||
import System from "../System.js";
|
||||
|
||||
export type SyncElementType = 'character' | 'world' | 'location' | 'spell';
|
||||
|
||||
export interface BookElementSeriesLink extends Record<string, SQLiteValue> {
|
||||
series_id: string | null;
|
||||
}
|
||||
|
||||
export default class SeriesSyncRepo {
|
||||
/**
|
||||
* Gets the series element ID linked to a book character.
|
||||
*/
|
||||
static getCharacterSeriesLink(userId: string, characterId: string, lang: 'fr' | 'en' = 'fr'): string | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT series_character_id AS series_id FROM book_characters WHERE character_id = ? AND user_id = ?';
|
||||
const result: BookElementSeriesLink | undefined = db.get(query, [characterId, userId]) as BookElementSeriesLink | undefined;
|
||||
return result ? result.series_id : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le lien série du personnage.` : `Unable to retrieve character series link.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the series element ID linked to a book world.
|
||||
*/
|
||||
static getWorldSeriesLink(userId: string, worldId: string, lang: 'fr' | 'en' = 'fr'): string | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT series_world_id AS series_id FROM book_world WHERE world_id = ? AND user_id = ?';
|
||||
const result: BookElementSeriesLink | undefined = db.get(query, [worldId, userId]) as BookElementSeriesLink | undefined;
|
||||
return result ? result.series_id : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le lien série du monde.` : `Unable to retrieve world series link.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the series element ID linked to a book location.
|
||||
*/
|
||||
static getLocationSeriesLink(userId: string, locationId: string, lang: 'fr' | 'en' = 'fr'): string | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT series_location_id AS series_id FROM book_location WHERE loc_id = ? AND user_id = ?';
|
||||
const result: BookElementSeriesLink | undefined = db.get(query, [locationId, userId]) as BookElementSeriesLink | undefined;
|
||||
return result ? result.series_id : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le lien série du lieu.` : `Unable to retrieve location series link.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the series element ID linked to a book spell.
|
||||
*/
|
||||
static getSpellSeriesLink(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): string | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT series_spell_id AS series_id FROM book_spells WHERE spell_id = ? AND user_id = ?';
|
||||
const result: BookElementSeriesLink | undefined = db.get(query, [spellId, userId]) as BookElementSeriesLink | undefined;
|
||||
return result ? result.series_id : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le lien série du sort.` : `Unable to retrieve spell series link.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in series_characters table.
|
||||
*/
|
||||
static updateSeriesCharacterField(userId: string, seriesCharacterId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
const allowedFields: string[] = ['first_name', 'last_name', 'nickname', 'age', 'gender', 'species', 'nationality', 'status', 'title', 'category', 'role', 'biography', 'history', 'speech_pattern', 'catchphrase', 'residence', 'notes', 'color'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE series_characters SET ${field} = ?, last_update = ? WHERE character_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesCharacterId, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le personnage série.` : `Unable to update series character.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in all book_characters linked to a series character.
|
||||
*/
|
||||
static updateLinkedBookCharactersField(userId: string, seriesCharacterId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): number {
|
||||
const allowedFields: string[] = ['first_name', 'last_name', 'nickname', 'age', 'gender', 'species', 'nationality', 'status', 'title', 'category', 'role', 'biography', 'history', 'speech_pattern', 'catchphrase', 'residence', 'notes', 'color'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE book_characters SET ${field} = ?, last_update = ? WHERE series_character_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesCharacterId, userId]);
|
||||
return result.changes;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les personnages liés.` : `Unable to update linked characters.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in series_worlds table.
|
||||
*/
|
||||
static updateSeriesWorldField(userId: string, seriesWorldId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
const allowedFields: string[] = ['name', 'history', 'politics', 'economy', 'religion', 'languages'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE series_worlds SET ${field} = ?, last_update = ? WHERE world_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesWorldId, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le monde série.` : `Unable to update series world.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in all book_world linked to a series world.
|
||||
*/
|
||||
static updateLinkedBookWorldsField(userId: string, seriesWorldId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): number {
|
||||
const allowedFields: string[] = ['name', 'history', 'politics', 'economy', 'religion', 'languages'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE book_world SET ${field} = ?, last_update = ? WHERE series_world_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesWorldId, userId]);
|
||||
return result.changes;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les mondes liés.` : `Unable to update linked worlds.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in series_locations table.
|
||||
*/
|
||||
static updateSeriesLocationField(userId: string, seriesLocationId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
const allowedFields: string[] = ['name'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE series_locations SET ${field} = ?, last_update = ? WHERE location_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesLocationId, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le lieu série.` : `Unable to update series location.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in all book_location linked to a series location.
|
||||
*/
|
||||
static updateLinkedBookLocationsField(userId: string, seriesLocationId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): number {
|
||||
const allowedFields: string[] = ['loc_name'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE book_location SET ${field} = ?, last_update = ? WHERE series_location_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesLocationId, userId]);
|
||||
return result.changes;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les lieux liés.` : `Unable to update linked locations.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in series_spells table.
|
||||
*/
|
||||
static updateSeriesSpellField(userId: string, seriesSpellId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
const allowedFields: string[] = ['name', 'description', 'type', 'level', 'range', 'duration', 'cost', 'effect', 'components', 'notes'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE series_spells SET ${field} = ?, last_update = ? WHERE spell_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesSpellId, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le sort série.` : `Unable to update series spell.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in all book_spells linked to a series spell.
|
||||
*/
|
||||
static updateLinkedBookSpellsField(userId: string, seriesSpellId: string, field: string, encryptedValue: string, lang: 'fr' | 'en' = 'fr'): number {
|
||||
const allowedFields: string[] = ['name', 'description', 'type', 'level', 'range', 'duration', 'cost', 'effect', 'components', 'notes'];
|
||||
if (!allowedFields.includes(field)) {
|
||||
throw new Error(lang === 'fr' ? `Champ non autorisé: ${field}` : `Field not allowed: ${field}`);
|
||||
}
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `UPDATE book_spells SET ${field} = ?, last_update = ? WHERE series_spell_id = ? AND user_id = ?`;
|
||||
const result: RunResult = db.run(query, [encryptedValue, System.timeStampInSeconds(), seriesSpellId, userId]);
|
||||
return result.changes;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les sorts liés.` : `Unable to update linked spells.`);
|
||||
}
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user