- Implement `CharacterRepo`, `LocationRepo`, and `UserRepo` for managing character, location, and user data with SQLite. - Add methods for performing CRUD operations on characters, locations, and users, including attributes and metadata handling. - Integrate error handling with multilingual support (`fr` and `en`). - Support data encryption and synchronization using the existing database utilities.
175 lines
9.1 KiB
TypeScript
175 lines
9.1 KiB
TypeScript
import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
|
import System from "../System";
|
|
|
|
export interface CharacterResult extends Record<string, SQLiteValue> {
|
|
character_id: string;
|
|
first_name: string;
|
|
last_name: string;
|
|
title: string;
|
|
category: string;
|
|
image: string;
|
|
role: string;
|
|
biography: string;
|
|
history: string;
|
|
char_meta: string;
|
|
}
|
|
|
|
export interface AttributeResult extends Record<string, SQLiteValue> {
|
|
attr_id: string;
|
|
attribute_name: string;
|
|
attribute_value: string;
|
|
attr_meta: string;
|
|
}
|
|
|
|
export interface CompleteCharacterResult extends Record<string, SQLiteValue> {
|
|
character_id: string;
|
|
first_name: string;
|
|
last_name: string;
|
|
category: string;
|
|
title: string;
|
|
role: string;
|
|
biography: string;
|
|
history: string;
|
|
char_meta: string;
|
|
attribute_name: string;
|
|
attribute_value: string;
|
|
attr_meta: string;
|
|
}
|
|
|
|
export default class CharacterRepo {
|
|
public static fetchCharacters(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): CharacterResult[] {
|
|
let result: CharacterResult[];
|
|
try {
|
|
const db: Database = System.getDb();
|
|
result = db.all('SELECT character_id,`first_name`,`last_name`,`title`,`category`,`image`,`role`,`biography`,`history`,`char_meta` FROM `book_characters` WHERE `book_id`=? AND user_id=?', [bookId, userId]) as CharacterResult[];
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages.` : `Unable to retrieve characters.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static addNewCharacter(userId: string, characterId: string, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, bookId: string, meta: string, lang: 'fr' | 'en' = 'fr'): string {
|
|
let result: RunResult;
|
|
try {
|
|
const db: Database = System.getDb();
|
|
result = db.run('INSERT INTO `book_characters` (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, char_meta) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [characterId, bookId, userId, encryptedName, encryptedLastName, encryptedCategory, encryptedTitle, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, meta]);
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le personnage.` : `Unable to add character.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
if (result.changes > 0) {
|
|
return characterId;
|
|
} else {
|
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du personnage.` : `Error adding character.`);
|
|
}
|
|
}
|
|
|
|
static insertAttribute(attributeId: string, characterId: string, userId: string, type: string, name: string, meta: string, lang: 'fr' | 'en' = 'fr'): string {
|
|
let result: RunResult;
|
|
try {
|
|
const db: Database = System.getDb();
|
|
result = db.run('INSERT INTO `book_characters_attributes` (attr_id, character_id, user_id, attribute_name, attribute_value,attr_meta) VALUES (?,?,?,?,?,?)', [attributeId, characterId, userId, type, name, meta]);
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'attribut.` : `Unable to add attribute.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
if (result.changes > 0) {
|
|
return attributeId;
|
|
} else {
|
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'attribut.` : `Error adding attribute.`);
|
|
}
|
|
}
|
|
|
|
static updateCharacter(userId: string, id: number | null, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, meta: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
|
try {
|
|
const db: Database = System.getDb();
|
|
const result: RunResult = db.run('UPDATE `book_characters` SET `first_name`=?,`last_name`=?,`title`=?,`category`=?,`image`=?,`role`=?,`biography`=?,`history`=?, char_meta=? WHERE `character_id`=? AND `user_id`=?', [encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, meta, id, userId]);
|
|
return result.changes > 0;
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le personnage.` : `Unable to update character.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
}
|
|
|
|
static deleteAttribute(userId: string, attributeId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
|
try {
|
|
const db: Database = System.getDb();
|
|
const result: RunResult = db.run('DELETE FROM `book_characters_attributes` WHERE `attr_id`=? AND `user_id`=?', [attributeId, userId]);
|
|
return result.changes > 0;
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible de supprimer l'attribut.` : `Unable to delete attribute.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
}
|
|
|
|
static fetchAttributes(characterId: string, userId: string, lang: 'fr' | 'en' = 'fr'): AttributeResult[] {
|
|
let result: AttributeResult[];
|
|
try {
|
|
const db: Database = System.getDb();
|
|
result = db.all('SELECT attr_id, attribute_name, attribute_value, attr_meta FROM `book_characters_attributes` WHERE `character_id`=? AND `user_id`=?', [characterId, userId]) as AttributeResult[];
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs.` : `Unable to retrieve attributes.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static fetchCompleteCharacters(userId: string, bookId: string, tags: string[], lang: 'fr' | 'en' = 'fr'): CompleteCharacterResult[] {
|
|
let result: CompleteCharacterResult[];
|
|
try {
|
|
const db: Database = System.getDb();
|
|
let query: string = 'SELECT charac.`character_id`,`first_name`,`last_name`,`category`,`title`,`role`,`biography`,`history`,`char_meta`,`attribute_name`,`attribute_value`,attr_meta FROM book_characters AS charac LEFT JOIN book_characters_attributes AS attr ON charac.character_id=attr.character_id WHERE charac.user_id=? AND charac.book_id=?';
|
|
let values: any[] = [userId, bookId];
|
|
if (tags && tags.length > 0) {
|
|
const placeholders: string = tags.map((): string => '?').join(',');
|
|
query += ` AND charac.character_id IN (${placeholders})`;
|
|
values.push(...tags);
|
|
}
|
|
result = db.all(query, values) as CompleteCharacterResult[];
|
|
} catch (e: unknown) {
|
|
if (e instanceof Error) {
|
|
console.error(`DB Error: ${e.message}`);
|
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages complets.` : `Unable to retrieve complete characters.`);
|
|
} else {
|
|
console.error("An unknown error occurred.");
|
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
}
|
|
}
|
|
if (result.length === 0) {
|
|
throw new Error(lang === 'fr' ? `Aucun personnage complet trouvé.` : `No complete characters found.`);
|
|
}
|
|
return result;
|
|
}
|
|
}
|