Add comprehensive spell management functionality
- Introduced spell management with creation, editing, deletion, and tagging capabilities. - Added `Spell`, `SpellList`, `SpellTagManager` models with corresponding IPC handlers for data operations. - Implemented `SpellList` and `SpellTagChip` components for UI interactions with spells and tags. - Localized spell-related strings for English (e.g., error messages, tooltips, and prompts). - Enhanced database models and repositories with encryption and decryption workflows for secure data handling. - Updated API to include filtering, searching, and tag-based spell management options.
This commit is contained in:
368
electron/database/repositories/spell.repo.ts
Normal file
368
electron/database/repositories/spell.repo.ts
Normal file
@@ -0,0 +1,368 @@
|
||||
import { Database, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||
import System from '../System.js';
|
||||
|
||||
export interface SpellResult extends Record<string, SQLiteValue> {
|
||||
spell_id: string;
|
||||
book_id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
appearance: string;
|
||||
tags: string;
|
||||
power_level: string | null;
|
||||
components: string | null;
|
||||
limitations: string | null;
|
||||
notes: string | null;
|
||||
}
|
||||
|
||||
export interface BookSpellsTable extends Record<string, SQLiteValue> {
|
||||
spell_id: string;
|
||||
book_id: string;
|
||||
user_id: string;
|
||||
name: string;
|
||||
name_hash: string;
|
||||
description: string;
|
||||
appearance: string;
|
||||
tags: string;
|
||||
power_level: string | null;
|
||||
components: string | null;
|
||||
limitations: string | null;
|
||||
notes: string | null;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
export interface SyncedSpellResult extends Record<string, SQLiteValue> {
|
||||
spell_id: string;
|
||||
book_id: string;
|
||||
name: string;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
export default class SpellRepo {
|
||||
/**
|
||||
* Fetches all spells for a specific book owned by the user.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of spell results
|
||||
*/
|
||||
static fetchSpells(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): SpellResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, book_id, name, description, appearance, tags, power_level, components, limitations, notes FROM book_spells WHERE user_id=? AND book_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
return db.all(query, params) as SpellResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sorts.` : `Unable to retrieve spells.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a single spell by its ID.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The spell result or null if not found
|
||||
*/
|
||||
static fetchSpellById(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): SpellResult | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, book_id, name, description, appearance, tags, power_level, components, limitations, notes FROM book_spells WHERE user_id=? AND spell_id=?';
|
||||
const params: SQLiteValue[] = [userId, spellId];
|
||||
const spells: SpellResult[] = db.all(query, params) as SpellResult[];
|
||||
return spells.length > 0 ? spells[0] : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le sort.` : `Unable to retrieve spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new spell.
|
||||
* @param spellId - The unique identifier for the new spell
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name for duplicate detection
|
||||
* @param description - The encrypted description
|
||||
* @param appearance - The encrypted appearance
|
||||
* @param tags - The encrypted JSON tags array
|
||||
* @param powerLevel - The encrypted power level (nullable)
|
||||
* @param components - The encrypted components (nullable)
|
||||
* @param limitations - The encrypted limitations (nullable)
|
||||
* @param notes - The encrypted notes (nullable)
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The spell ID if successful
|
||||
*/
|
||||
static insertSpell(spellId: string, bookId: string, userId: string, name: string, nameHash: string, description: string, appearance: string, tags: string, powerLevel: string | null, components: string | null, limitations: string | null, notes: string | null, lang: 'fr' | 'en' = 'fr'): string {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'INSERT INTO book_spells (spell_id, book_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [spellId, bookId, userId, name, nameHash, description, appearance, tags, powerLevel, components, limitations, notes, System.timeStampInSeconds()];
|
||||
const result: RunResult = db.run(query, params);
|
||||
if (!result || result.changes === 0) {
|
||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du sort.` : `Error adding spell.`);
|
||||
}
|
||||
return spellId;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le sort.` : `Unable to add spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing spell.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name
|
||||
* @param description - The encrypted description
|
||||
* @param appearance - The encrypted appearance
|
||||
* @param tags - The encrypted JSON tags array
|
||||
* @param powerLevel - The encrypted power level (nullable)
|
||||
* @param components - The encrypted components (nullable)
|
||||
* @param limitations - The encrypted limitations (nullable)
|
||||
* @param notes - The encrypted notes (nullable)
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful
|
||||
*/
|
||||
static updateSpell(userId: string, spellId: string, name: string, nameHash: string, description: string, appearance: string, tags: string, powerLevel: string | null, components: string | null, limitations: string | null, notes: string | null, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE book_spells SET name=?, name_hash=?, description=?, appearance=?, tags=?, power_level=?, components=?, limitations=?, notes=?, last_update=? WHERE spell_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [name, nameHash, description, appearance, tags, powerLevel, components, limitations, notes, System.timeStampInSeconds(), spellId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le sort.` : `Unable to update spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a spell.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the deletion was successful
|
||||
*/
|
||||
static deleteSpell(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'DELETE FROM book_spells WHERE spell_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [spellId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le sort.` : `Unable to delete spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the tags field of a spell.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param tags - The new encrypted JSON tags array
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful
|
||||
*/
|
||||
static updateSpellTags(userId: string, spellId: string, tags: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE book_spells SET tags=?, last_update=? WHERE spell_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [tags, System.timeStampInSeconds(), spellId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les tags du sort.` : `Unable to update spell tags.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all spells for a book with full table data for sync.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of book spells table records
|
||||
*/
|
||||
static fetchBookSpellsTable(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): BookSpellsTable[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, book_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update FROM book_spells WHERE user_id=? AND book_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
return db.all(query, params) as BookSpellsTable[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sorts.` : `Unable to retrieve spells.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a complete spell record by its ID.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The spell table record or null
|
||||
*/
|
||||
static fetchSpellTableById(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): BookSpellsTable | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, book_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update FROM book_spells WHERE user_id=? AND spell_id=?';
|
||||
const params: SQLiteValue[] = [userId, spellId];
|
||||
const spells: BookSpellsTable[] = db.all(query, params) as BookSpellsTable[];
|
||||
return spells.length > 0 ? spells[0] : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le sort.` : `Unable to retrieve spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all synced spells for a user.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of synced spell results
|
||||
*/
|
||||
static fetchSyncedSpells(userId: string, lang: 'fr' | 'en' = 'fr'): SyncedSpellResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, book_id, name, last_update FROM book_spells WHERE user_id=?';
|
||||
const params: SQLiteValue[] = [userId];
|
||||
return db.all(query, params) as SyncedSpellResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sorts synchronisés.` : `Unable to retrieve synced spells.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates a spell from synchronization data.
|
||||
* @param spellId - The unique identifier for the spell
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name
|
||||
* @param description - The encrypted description
|
||||
* @param appearance - The encrypted appearance
|
||||
* @param tags - The encrypted JSON tags array
|
||||
* @param powerLevel - The encrypted power level (nullable)
|
||||
* @param components - The encrypted components (nullable)
|
||||
* @param limitations - The encrypted limitations (nullable)
|
||||
* @param notes - The encrypted notes (nullable)
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the insertion was successful
|
||||
*/
|
||||
static insertSyncSpell(spellId: string, bookId: string, userId: string, name: string, nameHash: string, description: string, appearance: string, tags: string, powerLevel: string | null, components: string | null, limitations: string | null, notes: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'INSERT OR REPLACE INTO book_spells (spell_id, book_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [spellId, bookId, userId, name, nameHash, description, appearance, tags, powerLevel, components, limitations, notes, lastUpdate];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le sort.` : `Unable to insert spell.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a spell exists.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the spell exists
|
||||
*/
|
||||
static isSpellExist(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT 1 FROM book_spells WHERE spell_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [spellId, userId];
|
||||
const existenceCheck = db.all(query, params);
|
||||
return existenceCheck.length > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du sort.` : `Unable to check spell existence.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a spell with timestamp for sync.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param spellId - The unique identifier of the spell
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name
|
||||
* @param description - The encrypted description
|
||||
* @param appearance - The encrypted appearance
|
||||
* @param tags - The encrypted JSON tags array
|
||||
* @param powerLevel - The encrypted power level (nullable)
|
||||
* @param components - The encrypted components (nullable)
|
||||
* @param limitations - The encrypted limitations (nullable)
|
||||
* @param notes - The encrypted notes (nullable)
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful
|
||||
*/
|
||||
static updateSyncSpell(userId: string, spellId: string, name: string, nameHash: string, description: string, appearance: string, tags: string, powerLevel: string | null, components: string | null, limitations: string | null, notes: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE book_spells SET name=?, name_hash=?, description=?, appearance=?, tags=?, power_level=?, components=?, limitations=?, notes=?, last_update=? WHERE spell_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [name, nameHash, description, appearance, tags, powerLevel, components, limitations, notes, lastUpdate, spellId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le sort.` : `Unable to update spell.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
292
electron/database/repositories/spelltag.repo.ts
Normal file
292
electron/database/repositories/spelltag.repo.ts
Normal file
@@ -0,0 +1,292 @@
|
||||
import { Database, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||
import System from '../System.js';
|
||||
|
||||
export interface SpellTagResult extends Record<string, SQLiteValue> {
|
||||
tag_id: string;
|
||||
book_id: string;
|
||||
name: string;
|
||||
color: string | null;
|
||||
}
|
||||
|
||||
export interface BookSpellTagsTable extends Record<string, SQLiteValue> {
|
||||
tag_id: string;
|
||||
book_id: string;
|
||||
user_id: string;
|
||||
name: string;
|
||||
name_hash: string;
|
||||
color: string | null;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
export interface SyncedSpellTagResult extends Record<string, SQLiteValue> {
|
||||
tag_id: string;
|
||||
book_id: string;
|
||||
name: string;
|
||||
last_update: number;
|
||||
}
|
||||
|
||||
export default class SpellTagRepo {
|
||||
/**
|
||||
* Fetches all spell tags for a specific book owned by the user.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of spell tag results
|
||||
*/
|
||||
static fetchSpellTags(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): SpellTagResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, book_id, name, color FROM book_spell_tags WHERE user_id=? AND book_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
return db.all(query, params) as SpellTagResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les tags de sorts.` : `Unable to retrieve spell tags.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new spell tag.
|
||||
* @param tagId - The unique identifier for the new tag
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param name - The encrypted name of the tag
|
||||
* @param nameHash - The hashed name for duplicate detection
|
||||
* @param color - The optional color hex code
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The tag ID if successful
|
||||
*/
|
||||
static insertSpellTag(tagId: string, bookId: string, userId: string, name: string, nameHash: string, color: string | null, lang: 'fr' | 'en' = 'fr'): string {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'INSERT INTO book_spell_tags (tag_id, book_id, user_id, name, name_hash, color, last_update) VALUES (?,?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [tagId, bookId, userId, name, nameHash, color, System.timeStampInSeconds()];
|
||||
const result: RunResult = db.run(query, params);
|
||||
if (!result || result.changes === 0) {
|
||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du tag.` : `Error adding tag.`);
|
||||
}
|
||||
return tagId;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
}
|
||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le tag de sort.` : `Unable to add spell tag.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing spell tag.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param tagId - The unique identifier of the tag
|
||||
* @param name - The encrypted name of the tag
|
||||
* @param nameHash - The hashed name
|
||||
* @param color - The optional color hex code
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful
|
||||
*/
|
||||
static updateSpellTag(userId: string, tagId: string, name: string, nameHash: string, color: string | null, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE book_spell_tags SET name=?, name_hash=?, color=?, last_update=? WHERE tag_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [name, nameHash, color, System.timeStampInSeconds(), tagId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le tag de sort.` : `Unable to update spell tag.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a spell tag.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param tagId - The unique identifier of the tag
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the deletion was successful
|
||||
*/
|
||||
static deleteSpellTag(userId: string, tagId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'DELETE FROM book_spell_tags WHERE tag_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [tagId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le tag de sort.` : `Unable to delete spell tag.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all spell tags for a book with full table data for sync.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of book spell tags table records
|
||||
*/
|
||||
static fetchBookSpellTagsTable(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): BookSpellTagsTable[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, book_id, user_id, name, name_hash, color, last_update FROM book_spell_tags WHERE user_id=? AND book_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
return db.all(query, params) as BookSpellTagsTable[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les tags de sorts.` : `Unable to retrieve spell tags.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a complete spell tag record by its ID.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param tagId - The unique identifier of the tag
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns The spell tag table record or null
|
||||
*/
|
||||
static fetchSpellTagTableById(userId: string, tagId: string, lang: 'fr' | 'en' = 'fr'): BookSpellTagsTable | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, book_id, user_id, name, name_hash, color, last_update FROM book_spell_tags WHERE user_id=? AND tag_id=?';
|
||||
const params: SQLiteValue[] = [userId, tagId];
|
||||
const spellTags: BookSpellTagsTable[] = db.all(query, params) as BookSpellTagsTable[];
|
||||
return spellTags.length > 0 ? spellTags[0] : null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le tag de sort.` : `Unable to retrieve spell tag.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all synced spell tags for a user.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns An array of synced spell tag results
|
||||
*/
|
||||
static fetchSyncedSpellTags(userId: string, lang: 'fr' | 'en' = 'fr'): SyncedSpellTagResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, book_id, name, last_update FROM book_spell_tags WHERE user_id=?';
|
||||
const params: SQLiteValue[] = [userId];
|
||||
return db.all(query, params) as SyncedSpellTagResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les tags de sorts synchronisés.` : `Unable to retrieve synced spell tags.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates a spell tag from synchronization data.
|
||||
* @param tagId - The unique identifier for the tag
|
||||
* @param bookId - The unique identifier of the book
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name
|
||||
* @param color - The optional color hex code
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the insertion was successful
|
||||
*/
|
||||
static insertSyncSpellTag(tagId: string, bookId: string, userId: string, name: string, nameHash: string, color: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'INSERT OR REPLACE INTO book_spell_tags (tag_id, book_id, user_id, name, name_hash, color, last_update) VALUES (?,?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [tagId, bookId, userId, name, nameHash, color, lastUpdate];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le tag de sort.` : `Unable to insert spell tag.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a spell tag exists.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param tagId - The unique identifier of the tag
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the tag exists
|
||||
*/
|
||||
static isSpellTagExist(userId: string, tagId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT 1 FROM book_spell_tags WHERE tag_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [tagId, userId];
|
||||
const existenceCheck = db.all(query, params);
|
||||
return existenceCheck.length > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du tag.` : `Unable to check tag existence.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a spell tag with timestamp for sync.
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param tagId - The unique identifier of the tag
|
||||
* @param name - The encrypted name
|
||||
* @param nameHash - The hashed name
|
||||
* @param color - The optional color hex code
|
||||
* @param lastUpdate - The timestamp of the last update
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the update was successful
|
||||
*/
|
||||
static updateSyncSpellTag(userId: string, tagId: string, name: string, nameHash: string, color: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE book_spell_tags SET name=?, name_hash=?, color=?, last_update=? WHERE tag_id=? AND user_id=?';
|
||||
const params: SQLiteValue[] = [name, nameHash, color, lastUpdate, tagId, userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`[SpellTagRepo] DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le tag de sort.` : `Unable to update spell tag.`);
|
||||
} else {
|
||||
console.error('[SpellTagRepo] An unknown error occurred.');
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : 'An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user