Remove CharacterComponent and CharacterDetail components
- Deleted `CharacterComponent` and `CharacterDetail` files from the project. - Refactored related logic to improve code maintainability and reduce redundancy.
This commit is contained in:
@@ -123,7 +123,7 @@ export default class BookRepo {
|
||||
let book: BookQuery;
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT book_id, author_id, title, summary, sub_title, cover_image, desired_release_date, desired_word_count, words_count FROM erit_books WHERE book_id=? AND author_id=?';
|
||||
const query: string = 'SELECT book_id, author_id, title, summary, sub_title, cover_image, desired_release_date, desired_word_count, words_count, serie_id FROM erit_books WHERE book_id=? AND author_id=?';
|
||||
const params: SQLiteValue[] = [bookId, userId];
|
||||
book = db.get(query, params) as BookQuery;
|
||||
} catch (error: unknown) {
|
||||
@@ -456,4 +456,40 @@ export default class BookRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
static isBookExist(userId: string, bookId: string, lang: 'fr' | 'en'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT 1 FROM erit_books WHERE author_id = ? AND book_id = ? LIMIT 1';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
const result = db.get(query, params);
|
||||
return result !== undefined && result !== null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the series_id for a book from series_books table.
|
||||
* @param bookId - The book identifier
|
||||
* @param lang - The language for error messages
|
||||
* @returns The series_id or null if book is not in a series
|
||||
*/
|
||||
static fetchBookSeriesId(bookId: string, lang: 'fr' | 'en'): string | null {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT series_id FROM series_books WHERE book_id = ? LIMIT 1';
|
||||
const params: SQLiteValue[] = [bookId];
|
||||
const result = db.get(query, params) as { series_id: string } | undefined;
|
||||
return result?.series_id || null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
158
electron/database/repositories/removed-items.repository.ts
Normal file
158
electron/database/repositories/removed-items.repository.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { Database, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||
import System from '../System.js';
|
||||
|
||||
export interface RemovedItemRecord extends Record<string, SQLiteValue> {
|
||||
removal_id: string;
|
||||
table_name: string;
|
||||
entity_id: string;
|
||||
book_id: string | null;
|
||||
user_id: string;
|
||||
deleted_at: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository for tracking deleted items for sync purposes.
|
||||
*/
|
||||
export default class RemovedItemsRepository {
|
||||
/**
|
||||
* Inserts a removal record into the database.
|
||||
* @param removalId - The unique ID for this removal record.
|
||||
* @param tableName - The name of the table from which the item is deleted.
|
||||
* @param entityId - The UUID of the deleted entity.
|
||||
* @param bookId - Book ID (null for series items).
|
||||
* @param userId - The user ID who owns the item.
|
||||
* @param deletedAt - Timestamp of deletion.
|
||||
* @param lang - The language for error messages ('fr' or 'en').
|
||||
* @returns True if inserted successfully.
|
||||
*/
|
||||
public static insert(
|
||||
removalId: string,
|
||||
tableName: string,
|
||||
entityId: string,
|
||||
bookId: string | null,
|
||||
userId: string,
|
||||
deletedAt: number,
|
||||
lang: 'fr' | 'en'
|
||||
): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = `
|
||||
INSERT INTO removed_items (removal_id, table_name, entity_id, book_id, user_id, deleted_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(table_name, entity_id) DO UPDATE SET deleted_at = excluded.deleted_at
|
||||
`;
|
||||
const params: SQLiteValue[] = [removalId, tableName, entityId, bookId, userId, deletedAt];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible d'enregistrer la suppression.` : `Unable to record deletion.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves deletions since a specific timestamp.
|
||||
* Used to get deletions that occurred since last sync.
|
||||
* @param userId - The user ID.
|
||||
* @param since - Timestamp to get deletions after.
|
||||
* @param lang - The language for error messages ('fr' or 'en').
|
||||
* @returns Array of removed item records.
|
||||
*/
|
||||
public static getDeletionsSince(userId: string, since: number, lang: 'fr' | 'en'): RemovedItemRecord[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT * FROM removed_items WHERE user_id = ? AND deleted_at > ?';
|
||||
const params: SQLiteValue[] = [userId, since];
|
||||
const records: RemovedItemRecord[] = db.all(query, params) as RemovedItemRecord[];
|
||||
return records;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les suppressions.` : `Unable to retrieve deletions.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an entity was previously deleted.
|
||||
* @param tableName - The table name.
|
||||
* @param entityId - The entity ID.
|
||||
* @param lang - The language for error messages ('fr' or 'en').
|
||||
* @returns True if the entity was deleted locally.
|
||||
*/
|
||||
public static wasDeleted(tableName: string, entityId: string, lang: 'fr' | 'en'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT 1 FROM removed_items WHERE table_name = ? AND entity_id = ? LIMIT 1';
|
||||
const params: SQLiteValue[] = [tableName, entityId];
|
||||
const result = db.get(query, params);
|
||||
return result !== null;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de vérifier si l'élément a été supprimé.` : `Unable to check if item was deleted.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all tracked deletions for a specific book.
|
||||
* @param userId - The user ID.
|
||||
* @param bookId - The book ID.
|
||||
* @param lang - The language for error messages ('fr' or 'en').
|
||||
* @returns Array of removed item records for that book.
|
||||
*/
|
||||
public static getDeletionsForBook(userId: string, bookId: string, lang: 'fr' | 'en'): RemovedItemRecord[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT * FROM removed_items WHERE user_id = ? AND book_id = ?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
const records: RemovedItemRecord[] = db.all(query, params) as RemovedItemRecord[];
|
||||
return records;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les suppressions pour ce livre.` : `Unable to retrieve deletions for this book.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all deletion records for a user.
|
||||
* WARNING: Only use this when wiping user data completely.
|
||||
* @param userId - The user ID.
|
||||
* @param lang - The language for error messages ('fr' or 'en').
|
||||
* @returns True if cleared successfully.
|
||||
*/
|
||||
public static clearAllForUser(userId: string, lang: 'fr' | 'en'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'DELETE FROM removed_items WHERE user_id = ?';
|
||||
const params: SQLiteValue[] = [userId];
|
||||
const result: RunResult = db.run(query, params);
|
||||
return result.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de supprimer les enregistrements de suppression.` : `Unable to clear deletion records.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,4 +469,73 @@ export default class SeriesCharacterRepo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fetchCharactersTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesCharactersTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT character_id, series_id, user_id, first_name, last_name, nickname, age, gender, species, nationality, status, title, category, image, role, biography, history, speech_pattern, catchphrase, residence, notes, color, last_update FROM series_characters WHERE series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesCharactersTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages pour sync.` : `Unable to retrieve characters for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fetchCharacterAttributesTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesCharacterAttributesTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT sca.attr_id, sca.character_id, sca.user_id, sca.attribute_name, sca.attribute_value, sca.last_update FROM series_characters_attributes sca INNER JOIN series_characters sc ON sca.character_id = sc.character_id WHERE sc.series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesCharacterAttributesTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs pour sync.` : `Unable to retrieve attributes for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all characters for a series (alias for fetchCharacters that returns full table result).
|
||||
*/
|
||||
static fetchSeriesCharacters(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesCharactersTableResult[] {
|
||||
return this.fetchSeriesCharactersTable(userId, seriesId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all character attributes for a series by series ID.
|
||||
*/
|
||||
static fetchSeriesCharacterAttributesBySeriesId(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesCharacterAttributesTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT sca.attr_id, sca.character_id, sca.user_id, sca.attribute_name, sca.attribute_value, sca.last_update FROM series_characters_attributes sca INNER JOIN series_characters sc ON sca.character_id = sc.character_id WHERE sc.series_id = ? AND sc.user_id = ?';
|
||||
return db.all(query, [seriesId, userId]) as SeriesCharacterAttributesTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs par série.` : `Unable to retrieve attributes by series.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series character exists (alias for isCharacterExist).
|
||||
*/
|
||||
static seriesCharacterExists(userId: string, characterId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isCharacterExist(userId, characterId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series character attribute exists (alias for isAttributeExist).
|
||||
*/
|
||||
static seriesCharacterAttributeExists(userId: string, attrId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isAttributeExist(userId, attrId, lang);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,4 +620,194 @@ export default class SeriesLocationRepo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static fetchLocationsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT loc_id, series_id, user_id, loc_name, loc_original_name, last_update FROM series_locations WHERE series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesLocationsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les lieux pour sync.` : `Unable to retrieve locations for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static fetchLocationElementsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT sle.element_id, sle.location_id, sle.user_id, sle.element_name, sle.original_name, sle.element_description, sle.last_update FROM series_location_elements sle INNER JOIN series_locations sl ON sle.location_id = sl.loc_id WHERE sl.series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesLocationElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu pour sync.` : `Unable to retrieve location elements for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static fetchLocationSubElementsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationSubElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT slse.sub_element_id, slse.element_id, slse.user_id, slse.sub_elem_name, slse.original_name, slse.sub_elem_description, slse.last_update FROM series_location_sub_elements slse INNER JOIN series_location_elements sle ON slse.element_id = sle.element_id INNER JOIN series_locations sl ON sle.location_id = sl.loc_id WHERE sl.series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesLocationSubElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu pour sync.` : `Unable to retrieve location sub-elements for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all locations for a series (alias for fetchSeriesLocationsTable).
|
||||
*/
|
||||
public static fetchSeriesLocations(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationsTableResult[] {
|
||||
return this.fetchSeriesLocationsTable(userId, seriesId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all location elements for a series by series ID.
|
||||
*/
|
||||
public static fetchSeriesLocationElementsBySeriesId(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT sle.element_id, sle.location_id, sle.user_id, sle.element_name, sle.original_name, sle.element_description, sle.last_update FROM series_location_elements sle INNER JOIN series_locations sl ON sle.location_id = sl.loc_id WHERE sl.series_id = ? AND sl.user_id = ?';
|
||||
return db.all(query, [seriesId, userId]) as SeriesLocationElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu par série.` : `Unable to retrieve location elements by series.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all location sub-elements for a series by series ID.
|
||||
*/
|
||||
public static fetchSeriesLocationSubElementsBySeriesId(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesLocationSubElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT slse.sub_element_id, slse.element_id, slse.user_id, slse.sub_elem_name, slse.original_name, slse.sub_elem_description, slse.last_update FROM series_location_sub_elements slse INNER JOIN series_location_elements sle ON slse.element_id = sle.element_id INNER JOIN series_locations sl ON sle.location_id = sl.loc_id WHERE sl.series_id = ? AND sl.user_id = ?';
|
||||
return db.all(query, [seriesId, userId]) as SeriesLocationSubElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu par série.` : `Unable to retrieve location sub-elements by series.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series location exists (alias for isLocationExist).
|
||||
*/
|
||||
public static seriesLocationExists(userId: string, locationId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isLocationExist(userId, locationId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series location element exists (alias for isLocationElementExist).
|
||||
*/
|
||||
public static seriesLocationElementExists(userId: string, elementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isLocationElementExist(userId, elementId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series location sub-element exists (alias for isLocationSubElementExist).
|
||||
*/
|
||||
public static seriesLocationSubElementExists(userId: string, subElementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isLocationSubElementExist(userId, subElementId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series location for sync (alias with compatible signature).
|
||||
*/
|
||||
public static insertSyncSeriesLocation(locationId: string, seriesId: string, userId: string, locName: string, locOriginalName: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncLocation(locationId, seriesId, userId, locName, locOriginalName, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series location for sync (without originalName).
|
||||
*/
|
||||
public static updateSyncSeriesLocation(locationId: string, userId: string, locName: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_locations SET loc_name = ?, last_update = ? WHERE loc_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [locName, lastUpdate, locationId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.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 pour sync.` : `Unable to update series location for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series location element for sync (alias with compatible signature).
|
||||
*/
|
||||
public static insertSyncSeriesLocationElement(elementId: string, locationId: string, userId: string, elementName: string, originalName: string, elementDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncLocationElement(elementId, locationId, userId, elementName, originalName, elementDescription, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series location element for sync (without originalName).
|
||||
*/
|
||||
public static updateSyncSeriesLocationElement(elementId: string, userId: string, elementName: string, elementDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_location_elements SET element_name = ?, element_description = ?, last_update = ? WHERE element_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [elementName, elementDescription, lastUpdate, elementId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément de lieu série pour sync.` : `Unable to update series location element for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series location sub-element for sync (alias with compatible signature).
|
||||
*/
|
||||
public static insertSyncSeriesLocationSubElement(subElementId: string, elementId: string, userId: string, subElemName: string, originalName: string, subElemDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncLocationSubElement(subElementId, elementId, userId, subElemName, originalName, subElemDescription, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series location sub-element for sync (without originalName).
|
||||
*/
|
||||
public static updateSyncSeriesLocationSubElement(subElementId: string, userId: string, subElemName: string, subElemDescription: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_location_sub_elements SET sub_elem_name = ?, sub_elem_description = ?, last_update = ? WHERE sub_element_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [subElemName, subElemDescription, lastUpdate, subElementId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.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 sous-élément série pour sync.` : `Unable to update series sub-element for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ export interface SeriesSpellsTableResult extends Record<string, SQLiteValue> {
|
||||
user_id: string;
|
||||
name: string;
|
||||
name_hash: string;
|
||||
description: string;
|
||||
appearance: string;
|
||||
tags: string;
|
||||
description: string | null;
|
||||
appearance: string | null;
|
||||
tags: string | null;
|
||||
power_level: string | null;
|
||||
components: string | null;
|
||||
limitations: string | null;
|
||||
@@ -496,4 +496,152 @@ export default class SeriesSpellRepo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fetchSpellsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, series_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update FROM series_spells WHERE series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesSpellsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les sorts pour sync.` : `Unable to retrieve spells for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fetchSpellTagsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellTagsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, series_id, user_id, name, hashed_name, color, last_update FROM series_spell_tags WHERE series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesSpellTagsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les tags de sort pour sync.` : `Unable to retrieve spell tags for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all spells for a series (alias for fetchSeriesSpellsTable).
|
||||
*/
|
||||
static fetchSeriesSpells(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellsTableResult[] {
|
||||
return this.fetchSeriesSpellsTable(userId, seriesId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all spell tags for a series (alias for fetchSeriesSpellTagsTable).
|
||||
*/
|
||||
static fetchSeriesSpellTags(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellTagsTableResult[] {
|
||||
return this.fetchSeriesSpellTagsTable(userId, seriesId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series spell exists (alias for isSpellExist).
|
||||
*/
|
||||
static seriesSpellExists(userId: string, spellId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isSpellExist(userId, spellId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series spell tag exists (alias for isSpellTagExist).
|
||||
*/
|
||||
static seriesSpellTagExists(userId: string, tagId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isSpellTagExist(userId, tagId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a complete spell by ID for sync (array format).
|
||||
*/
|
||||
static fetchCompleteSpellById(spellId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT spell_id, series_id, user_id, name, name_hash, description, appearance, tags, power_level, components, limitations, notes, last_update FROM series_spells WHERE spell_id = ?';
|
||||
return db.all(query, [spellId]) as SeriesSpellsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le sort complet.` : `Unable to retrieve complete spell.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a complete spell tag by ID for sync (array format).
|
||||
*/
|
||||
static fetchCompleteSpellTagById(tagId: string, lang: 'fr' | 'en' = 'fr'): SeriesSpellTagsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT tag_id, series_id, user_id, name, hashed_name, color, last_update FROM series_spell_tags WHERE tag_id = ?';
|
||||
return db.all(query, [tagId]) as SeriesSpellTagsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le tag complet.` : `Unable to retrieve complete tag.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series spell for sync (alias with compatible signature).
|
||||
*/
|
||||
static insertSyncSeriesSpell(spellId: string, seriesId: 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 {
|
||||
return this.insertSyncSpell(spellId, seriesId, userId, name, nameHash, description, appearance, tags, powerLevel, components, limitations, notes, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series spell for sync (simplified signature).
|
||||
*/
|
||||
static updateSyncSeriesSpell(spellId: string, userId: string, name: 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 series_spells SET name = ?, description = ?, appearance = ?, tags = ?, power_level = ?, components = ?, limitations = ?, notes = ?, last_update = ? WHERE spell_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [name, description, appearance, tags, powerLevel, components, limitations, notes, lastUpdate, spellId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.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 pour sync.` : `Unable to update series spell for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series spell tag for sync (alias with compatible signature).
|
||||
*/
|
||||
static insertSyncSeriesSpellTag(tagId: string, seriesId: string, userId: string, name: string, hashedName: string, color: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncSpellTag(tagId, seriesId, userId, name, hashedName, color, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series spell tag for sync (simplified signature).
|
||||
*/
|
||||
static updateSyncSeriesSpellTag(tagId: string, userId: string, name: string, color: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_spell_tags SET name = ?, color = ?, last_update = ? WHERE tag_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [name, color, lastUpdate, tagId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.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 tag série pour sync.` : `Unable to update series tag for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,4 +429,127 @@ export default class SeriesWorldRepo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static fetchWorldsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesWorldsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT world_id, series_id, user_id, name, hashed_name, history, politics, economy, religion, languages, last_update FROM series_worlds WHERE series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesWorldsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes pour sync.` : `Unable to retrieve worlds for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static fetchWorldElementsTableForSync(seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesWorldElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT swe.element_id, swe.world_id, swe.user_id, swe.element_type, swe.name, swe.original_name, swe.description, swe.last_update FROM series_world_elements swe INNER JOIN series_worlds sw ON swe.world_id = sw.world_id WHERE sw.series_id = ?';
|
||||
return db.all(query, [seriesId]) as SeriesWorldElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de monde pour sync.` : `Unable to retrieve world elements for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all worlds for a series (alias for fetchSeriesWorldsTable).
|
||||
*/
|
||||
public static fetchSeriesWorlds(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesWorldsTableResult[] {
|
||||
return this.fetchSeriesWorldsTable(userId, seriesId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all world elements for a series by series ID.
|
||||
*/
|
||||
public static fetchSeriesWorldElementsBySeriesId(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): SeriesWorldElementsTableResult[] {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'SELECT swe.element_id, swe.world_id, swe.user_id, swe.element_type, swe.name, swe.original_name, swe.description, swe.last_update FROM series_world_elements swe INNER JOIN series_worlds sw ON swe.world_id = sw.world_id WHERE sw.series_id = ? AND sw.user_id = ?';
|
||||
return db.all(query, [seriesId, userId]) as SeriesWorldElementsTableResult[];
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de monde par série.` : `Unable to retrieve world elements by series.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series world exists (alias for isWorldExist).
|
||||
*/
|
||||
public static seriesWorldExists(userId: string, worldId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isWorldExist(userId, worldId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series world element exists (alias for isWorldElementExist).
|
||||
*/
|
||||
public static seriesWorldElementExists(userId: string, elementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isWorldElementExist(userId, elementId, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series world for sync (alias with compatible signature).
|
||||
*/
|
||||
public static insertSyncSeriesWorld(worldId: string, seriesId: string, userId: string, name: string, hashedName: string, history: string | null, politics: string | null, economy: string | null, religion: string | null, languages: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncWorld(worldId, seriesId, userId, name, hashedName, history, politics, economy, religion, languages, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series world for sync (without hashedName).
|
||||
*/
|
||||
public static updateSyncSeriesWorld(worldId: string, userId: string, name: string, history: string | null, politics: string | null, economy: string | null, religion: string | null, languages: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_worlds SET name = ?, history = ?, politics = ?, economy = ?, religion = ?, languages = ?, last_update = ? WHERE world_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [name, history, politics, economy, religion, languages, lastUpdate, worldId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.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 pour sync.` : `Unable to update series world for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a series world element for sync (alias with compatible signature).
|
||||
*/
|
||||
public static insertSyncSeriesWorldElement(elementId: string, worldId: string, userId: string, elementType: number, name: string, originalName: string, description: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.insertSyncWorldElement(elementId, worldId, userId, elementType, name, originalName, description, lastUpdate, lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a series world element for sync (without elementType and originalName).
|
||||
*/
|
||||
public static updateSyncSeriesWorldElement(elementId: string, userId: string, name: string, description: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const query: string = 'UPDATE series_world_elements SET name = ?, description = ?, last_update = ? WHERE element_id = ? AND user_id = ?';
|
||||
const params: SQLiteValue[] = [name, description, lastUpdate, elementId, userId];
|
||||
const updateResult: RunResult = db.run(query, params);
|
||||
return updateResult.changes > 0;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error) {
|
||||
console.error(`DB Error: ${error.message}`);
|
||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément de monde série pour sync.` : `Unable to update series world element for sync.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,4 +539,15 @@ export default class SeriesRepo {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a series exists for a user (alias for isSeriesExist).
|
||||
* @param userId - The unique identifier of the user
|
||||
* @param seriesId - The unique identifier of the series
|
||||
* @param lang - The language for error messages ('fr' or 'en')
|
||||
* @returns True if the series exists
|
||||
*/
|
||||
public static seriesExists(userId: string, seriesId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
return this.isSeriesExist(userId, seriesId, lang);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ export interface SpellResult extends Record<string, SQLiteValue> {
|
||||
spell_id: string;
|
||||
book_id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
appearance: string;
|
||||
tags: string;
|
||||
description: string | null;
|
||||
appearance: string | null;
|
||||
tags: string | null;
|
||||
power_level: string | null;
|
||||
components: string | null;
|
||||
limitations: string | null;
|
||||
@@ -21,9 +21,9 @@ export interface BookSpellsTable extends Record<string, SQLiteValue> {
|
||||
user_id: string;
|
||||
name: string;
|
||||
name_hash: string;
|
||||
description: string;
|
||||
appearance: string;
|
||||
tags: string;
|
||||
description: string | null;
|
||||
appearance: string | null;
|
||||
tags: string | null;
|
||||
power_level: string | null;
|
||||
components: string | null;
|
||||
limitations: string | null;
|
||||
@@ -301,7 +301,7 @@ export default class SpellRepo {
|
||||
* @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 {
|
||||
static insertSyncSpell(spellId: string, bookId: string, userId: string, name: string, nameHash: string, description: string | null, appearance: string | null, tags: string | null, 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 (?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||
@@ -359,7 +359,7 @@ export default class SpellRepo {
|
||||
* @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 {
|
||||
static updateSyncSpell(userId: string, spellId: string, name: string, nameHash: string, description: string | null, appearance: string | null, tags: string | null, 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=?';
|
||||
|
||||
Reference in New Issue
Block a user