Refactor BookRepo methods and improve error handling
- Add JSDoc comments for better maintainability and code clarity in `BookRepo` methods. - Streamline query definitions using variables to improve readability. - Consolidate error handling logic across all methods. - Ensure multilingual support in error messages for consistent user feedback. - Remove redundant error branches and simplify unknown error processing.
This commit is contained in:
@@ -22,13 +22,23 @@ export interface ActQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class ActRepository {
|
export default class ActRepository {
|
||||||
|
/**
|
||||||
|
* Fetches all acts for a specific book and 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 ActQuery objects containing act index and summary.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
public static fetchAllActs(userId: string, bookId: string, lang: 'fr' | 'en'): ActQuery[] {
|
public static fetchAllActs(userId: string, bookId: string, lang: 'fr' | 'en'): ActQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT act_index, summary FROM book_act_summaries WHERE book_id=? AND user_id=?', [bookId, userId]) as ActQuery[];
|
const query: string = 'SELECT act_index, summary FROM book_act_summaries WHERE book_id=? AND user_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as ActQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les actes.` : `Unable to retrieve acts.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les actes.` : `Unable to retrieve acts.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -36,14 +46,28 @@ export default class ActRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the summary of an existing act.
|
||||||
|
* @param userId - The unique identifier of the user.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param actId - The unique identifier of the act summary.
|
||||||
|
* @param summary - The new summary text.
|
||||||
|
* @param lastUpdate - The timestamp of the last update in seconds.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the update was successful, false otherwise.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
public static updateActSummary(userId: string, bookId: string, actId: number, summary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
public static updateActSummary(userId: string, bookId: string, actId: number, summary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_act_summaries SET summary=?, last_update=? WHERE user_id=? AND book_id=? AND act_sum_id=?', [summary, lastUpdate, userId, bookId, actId]);
|
const query: string = 'UPDATE book_act_summaries SET summary=?, last_update=? WHERE user_id=? AND book_id=? AND act_sum_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [summary, lastUpdate, userId, bookId, actId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le résumé de l'acte.` : `Unable to update act summary.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le résumé de l'acte.` : `Unable to update act summary.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -51,45 +75,81 @@ export default class ActRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new act summary into the database.
|
||||||
|
* @param actSummaryId - The unique identifier for the new act summary.
|
||||||
|
* @param userId - The unique identifier of the user.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param actId - The act index number.
|
||||||
|
* @param actSummary - The summary text for the act.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns The act summary ID if insertion was successful.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
static insertActSummary(actSummaryId: string, userId: string, bookId: string, actId: number, actSummary: string, lang: 'fr' | 'en'): string {
|
static insertActSummary(actSummaryId: string, userId: string, bookId: string, actId: number, actSummary: string, lang: 'fr' | 'en'): string {
|
||||||
let result:RunResult
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?,?,?,?,?,?)', [actSummaryId, bookId, userId, actId, actSummary, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [actSummaryId, bookId, userId, actId, actSummary, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le résumé de l'acte.` : `Unable to add act summary.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le résumé de l'acte.` : `Unable to add act summary.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!insertResult) {
|
||||||
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du résumé de l'acte.` : `Error adding act summary.`);
|
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du résumé de l'acte.` : `Error adding act summary.`);
|
||||||
}
|
}
|
||||||
return actSummaryId;
|
return actSummaryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all act summaries for a specific book.
|
||||||
|
* @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 A promise resolving to an array of BookActSummariesTable objects.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
static async fetchBookActSummaries(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookActSummariesTable[]> {
|
static async fetchBookActSummaries(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookActSummariesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT act_sum_id, book_id, user_id, act_index, summary, last_update FROM book_act_summaries WHERE user_id=? AND book_id=?', [userId, bookId]) as BookActSummariesTable[];
|
const query: string = 'SELECT act_sum_id, book_id, user_id, act_index, summary, last_update FROM book_act_summaries WHERE user_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as BookActSummariesTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés des actes.` : `Unable to retrieve act summaries.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés des actes.` : `Unable to retrieve act summaries.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced act summaries 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 SyncedActSummaryResult objects containing sync metadata.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
static fetchSyncedActSummaries(userId: string, lang: 'fr' | 'en'): SyncedActSummaryResult[] {
|
static fetchSyncedActSummaries(userId: string, lang: 'fr' | 'en'): SyncedActSummaryResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT act_sum_id, book_id, last_update FROM book_act_summaries WHERE user_id = ?', [userId]) as SyncedActSummaryResult[];
|
const query: string = 'SELECT act_sum_id, book_id, last_update FROM book_act_summaries WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedActSummaries: SyncedActSummaryResult[] = db.all(query, params) as SyncedActSummaryResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedActSummaries;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés d'actes synchronisés.` : `Unable to retrieve synced act summaries.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés d'actes synchronisés.` : `Unable to retrieve synced act summaries.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -97,48 +157,80 @@ export default class ActRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced act summary from remote data.
|
||||||
|
* @param actSumId - The unique identifier of the act summary.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param userId - The unique identifier of the user.
|
||||||
|
* @param actIndex - The act index number.
|
||||||
|
* @param summary - The summary text (can be null).
|
||||||
|
* @param lastUpdate - The timestamp of the last update in seconds.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the insertion was successful, false otherwise.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
static insertSyncActSummary(actSumId: string, bookId: string, userId: string, actIndex: number, summary: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncActSummary(actSumId: string, bookId: string, userId: string, actIndex: number, summary: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = 'INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?, ?, ?, ?, ?, ?)';
|
||||||
`INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [actSumId, bookId, userId, actIndex, summary, lastUpdate];
|
||||||
[actSumId, bookId, userId, actIndex, summary, lastUpdate]
|
const insertResult: RunResult = db.run(query, params);
|
||||||
);
|
return insertResult.changes > 0;
|
||||||
return result.changes > 0;
|
} catch (error: unknown) {
|
||||||
} catch (e: unknown) {
|
if (error instanceof Error) {
|
||||||
if (e instanceof Error) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le résumé d'acte.` : `Unable to insert act summary.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le résumé d'acte.` : `Unable to insert act summary.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteActSummaryById(id: string, lang: "fr" | "en"):Promise<BookActSummariesTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches a complete act summary by its unique identifier.
|
||||||
|
* @param id - The unique identifier of the act summary.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns A promise resolving to an array of BookActSummariesTable objects.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
|
static async fetchCompleteActSummaryById(id: string, lang: "fr" | "en"): Promise<BookActSummariesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT act_sum_id, book_id, user_id, act_index, summary, last_update
|
||||||
`SELECT act_sum_id, book_id, user_id, act_index, summary, last_update
|
|
||||||
FROM book_act_summaries
|
FROM book_act_summaries
|
||||||
WHERE act_sum_id = ?`,
|
WHERE act_sum_id = ?`;
|
||||||
[id]
|
const params: SQLiteValue[] = [id];
|
||||||
) as BookActSummariesTable[];
|
const actSummary: BookActSummariesTable[] = db.all(query, params) as BookActSummariesTable[];
|
||||||
} catch (e:unknown){
|
return actSummary;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le résumé d'acte complet.` : `Unable to retrieve complete act summary.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le résumé d'acte complet.` : `Unable to retrieve complete act summary.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static actSummarizeExist(userId: string, bookId: string, act_index: number,lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks if an act summary exists for a given user, book, and act index.
|
||||||
|
* @param userId - The unique identifier of the user.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param actIndex - The act index number to check.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the act summary exists, false otherwise.
|
||||||
|
* @throws Error if the database operation fails.
|
||||||
|
*/
|
||||||
|
static actSummarizeExist(userId: string, bookId: string, actIndex: number, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result:QueryResult|null = db.get('SELECT 1 FROM book_act_summaries WHERE user_id =? AND book_id =? AND act_index = ?', [userId, bookId, act_index]) || null;
|
const query: string = 'SELECT 1 FROM book_act_summaries WHERE user_id =? AND book_id =? AND act_index = ?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [userId, bookId, actIndex];
|
||||||
} catch (e: unknown) {
|
const existenceCheck: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existenceCheck !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du résumé de l'acte.` : `Unable to check act summary existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du résumé de l'acte.` : `Unable to check act summary existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -47,197 +47,318 @@ export interface BookCoverQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class BookRepo {
|
export default class BookRepo {
|
||||||
|
/**
|
||||||
|
* Retrieves all books for a user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of user's books
|
||||||
|
*/
|
||||||
public static fetchBooks(userId: string, lang: 'fr' | 'en'): BookQuery[] {
|
public static fetchBooks(userId: string, lang: 'fr' | 'en'): BookQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT book_id, type, author_id, title, sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image FROM erit_books WHERE author_id = ? ORDER BY book_id DESC', [userId]) as BookQuery[];
|
const query: string = 'SELECT book_id, type, author_id, title, sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image FROM erit_books WHERE author_id = ? ORDER BY book_id DESC';
|
||||||
|
const params: SQLiteValue[] = [userId];
|
||||||
|
return db.all(query, params) as BookQuery[];
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(error.message);
|
console.error(error.message);
|
||||||
throw new Error(lang === 'fr' ? 'Impossible de récupérer la liste des livres.' : 'Unable to retrieve book list.');
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer la liste des livres.' : 'Unable to retrieve book list.');
|
||||||
} else {
|
}
|
||||||
console.error(error);
|
console.error(error);
|
||||||
throw new Error(lang === 'fr' ? 'Une erreur inconnue est survenue.' : 'An unknown error occurred.');
|
throw new Error(lang === 'fr' ? 'Une erreur inconnue est survenue.' : 'An unknown error occurred.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static updateBookCover(bookId:string,coverImageName:string,userId:string, lang: 'fr' | 'en'):boolean{
|
/**
|
||||||
|
* Updates a book's cover image.
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param coverImageName - The cover image file name
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the update was successful
|
||||||
|
*/
|
||||||
|
public static updateBookCover(bookId: string, coverImageName: string, userId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result:RunResult = db.run('UPDATE `erit_books` SET cover_image=?, last_update=? WHERE `book_id`=? AND author_id=?', [coverImageName, System.timeStampInSeconds(), bookId, userId]);
|
const query: string = 'UPDATE erit_books SET cover_image=?, last_update=? WHERE book_id=? AND author_id=?';
|
||||||
return result.changes>0;
|
const params: SQLiteValue[] = [coverImageName, System.timeStampInSeconds(), bookId, userId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la couverture du livre.` : `Unable to update book cover.`);
|
|
||||||
} else {
|
|
||||||
console.error("An unknown error occurred.");
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static fetchBook(bookId: string, userId: string, lang: 'fr' | 'en'): BookQuery {
|
|
||||||
let result: BookQuery;
|
|
||||||
try {
|
|
||||||
const db: Database = System.getDb();
|
|
||||||
result = db.get('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=?', [bookId, userId]) as BookQuery;
|
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${error.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du livre.` : `Unable to retrieve book information.`);
|
throw new Error(lang === 'fr' ? 'Impossible de mettre à jour la couverture du livre.' : 'Unable to update book cover.');
|
||||||
} else {
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
|
||||||
throw new Error(lang === 'fr' ? `Livre non trouvé.` : `Book not found.`);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
public static verifyBookExist(hashedTitle:string,hashedSubTitle:string,userId:string, lang: 'fr' | 'en'):boolean{
|
|
||||||
try {
|
|
||||||
const db: Database = System.getDb();
|
|
||||||
const result:QueryResult|null = db.get('SELECT book_id FROM erit_books WHERE hashed_title=? AND author_id=? AND erit_books.hashed_sub_title=?', [hashedTitle,userId,hashedSubTitle]);
|
|
||||||
return result!==null;
|
|
||||||
} catch (err: unknown) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
console.error(`DB Error: ${err.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du livre.` : `Unable to verify book existence.`);
|
|
||||||
} else {
|
|
||||||
console.error("An unknown error occurred.");
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static insertBook(bookId: string, userId: string, encryptedTitle: string, hashedTitle: string, encryptedSubTitle: string, hashedSubTitle: string, encryptedSummary: string, type: string, serie: number, publicationDate: string, desiredWordCount: number, lang: 'fr' | 'en'): string {
|
/**
|
||||||
let result: RunResult;
|
* Retrieves a book by its identifier.
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The book information
|
||||||
|
*/
|
||||||
|
public static fetchBook(bookId: string, userId: string, lang: 'fr' | 'en'): BookQuery {
|
||||||
|
let book: BookQuery;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO erit_books (book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [bookId, type, userId, encryptedTitle, hashedTitle, encryptedSubTitle, hashedSubTitle, encryptedSummary, serie, publicationDate ? publicationDate : null, desiredWordCount, System.timeStampInSeconds()]);
|
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=?';
|
||||||
} catch (err: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (err instanceof Error) {
|
book = db.get(query, params) as BookQuery;
|
||||||
console.error(`DB Error: ${err.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le livre.` : `Unable to add book.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les informations du livre.' : 'Unable to retrieve book information.');
|
||||||
|
}
|
||||||
|
console.error("An unknown error occurred.");
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
}
|
||||||
|
if (!book) {
|
||||||
|
throw new Error(lang === 'fr' ? 'Livre non trouvé.' : 'Book not found.');
|
||||||
|
}
|
||||||
|
return book;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies if a book already exists for a user.
|
||||||
|
* @param hashedTitle - The hashed book title
|
||||||
|
* @param hashedSubTitle - The hashed book subtitle
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the book exists
|
||||||
|
*/
|
||||||
|
public static verifyBookExist(hashedTitle: string, hashedSubTitle: string, userId: string, lang: 'fr' | 'en'): boolean {
|
||||||
|
try {
|
||||||
|
const db: Database = System.getDb();
|
||||||
|
const query: string = 'SELECT book_id FROM erit_books WHERE hashed_title=? AND author_id=? AND hashed_sub_title=?';
|
||||||
|
const params: SQLiteValue[] = [hashedTitle, userId, hashedSubTitle];
|
||||||
|
const book: QueryResult | null = db.get(query, params);
|
||||||
|
return book !== null;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible de vérifier l'existence du livre." : 'Unable to verify book existence.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du livre.` : `Error adding book.`);
|
/**
|
||||||
|
* Inserts a new book into the database.
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param encryptedTitle - The encrypted title
|
||||||
|
* @param hashedTitle - The hashed title
|
||||||
|
* @param encryptedSubTitle - The encrypted subtitle
|
||||||
|
* @param hashedSubTitle - The hashed subtitle
|
||||||
|
* @param encryptedSummary - The encrypted summary
|
||||||
|
* @param type - The book type
|
||||||
|
* @param serie - The series identifier
|
||||||
|
* @param publicationDate - The desired publication date
|
||||||
|
* @param desiredWordCount - The desired word count
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The created book identifier
|
||||||
|
*/
|
||||||
|
public static insertBook(bookId: string, userId: string, encryptedTitle: string, hashedTitle: string, encryptedSubTitle: string, hashedSubTitle: string, encryptedSummary: string, type: string, serie: number, publicationDate: string, desiredWordCount: number, lang: 'fr' | 'en'): string {
|
||||||
|
let insertResult: RunResult;
|
||||||
|
try {
|
||||||
|
const db: Database = System.getDb();
|
||||||
|
const query: string = 'INSERT INTO erit_books (book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
|
const params: SQLiteValue[] = [bookId, type, userId, encryptedTitle, hashedTitle, encryptedSubTitle, hashedSubTitle, encryptedSummary, serie, publicationDate ? publicationDate : null, desiredWordCount, System.timeStampInSeconds()];
|
||||||
|
insertResult = db.run(query, params);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible d'ajouter le livre." : 'Unable to add book.');
|
||||||
|
}
|
||||||
|
console.error("An unknown error occurred.");
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
}
|
||||||
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? "Erreur lors de l'ajout du livre." : 'Error adding book.');
|
||||||
}
|
}
|
||||||
return bookId;
|
return bookId;
|
||||||
}
|
}
|
||||||
public static fetchBookCover(userId:string,bookId:string, lang: 'fr' | 'en'):BookCoverQuery{
|
|
||||||
|
/**
|
||||||
|
* Retrieves a book's cover image.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The cover information
|
||||||
|
*/
|
||||||
|
public static fetchBookCover(userId: string, bookId: string, lang: 'fr' | 'en'): BookCoverQuery {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.get('SELECT cover_image FROM erit_books WHERE author_id=? AND book_id=?', [userId, bookId]) as BookCoverQuery;
|
const query: string = 'SELECT cover_image FROM erit_books WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
return db.get(query, params) as BookCoverQuery;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer la couverture du livre.` : `Unable to retrieve book cover.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer la couverture du livre.' : 'Unable to retrieve book cover.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a book's basic information.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param title - The new title
|
||||||
|
* @param hashedTitle - The hashed title
|
||||||
|
* @param subTitle - The new subtitle
|
||||||
|
* @param hashedSubTitle - The hashed subtitle
|
||||||
|
* @param summary - The new summary
|
||||||
|
* @param publicationDate - The new publication date
|
||||||
|
* @param wordCount - The new desired word count
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the update was successful
|
||||||
|
*/
|
||||||
static updateBookBasicInformation(userId: string, title: string, hashedTitle: string, subTitle: string, hashedSubTitle: string, summary: string, publicationDate: string, wordCount: number, bookId: string, lang: 'fr' | 'en'): boolean {
|
static updateBookBasicInformation(userId: string, title: string, hashedTitle: string, subTitle: string, hashedSubTitle: string, summary: string, publicationDate: string, wordCount: number, bookId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE erit_books SET title=?, hashed_title=?, sub_title=?, hashed_sub_title=?, summary=?, serie_id=?, desired_release_date=?, desired_word_count=?, last_update=? WHERE author_id=? AND book_id=?',
|
const query: string = 'UPDATE erit_books SET title=?, hashed_title=?, sub_title=?, hashed_sub_title=?, summary=?, serie_id=?, desired_release_date=?, desired_word_count=?, last_update=? WHERE author_id=? AND book_id=?';
|
||||||
[title, hashedTitle, subTitle, hashedSubTitle, summary, 0, publicationDate ? System.dateToMySqlDate(publicationDate) : null, wordCount, System.timeStampInSeconds(), userId, bookId]);
|
const params: SQLiteValue[] = [title, hashedTitle, subTitle, hashedSubTitle, summary, 0, publicationDate ? System.dateToMySqlDate(publicationDate) : null, wordCount, System.timeStampInSeconds(), userId, bookId];
|
||||||
return result.changes > 0;
|
const updateResult: RunResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
return updateResult.changes > 0;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les informations du livre.` : `Unable to update book information.`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
} else {
|
throw new Error(lang === 'fr' ? 'Impossible de mettre à jour les informations du livre.' : 'Unable to update book information.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a book from the database.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier to delete
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the deletion was successful
|
||||||
|
*/
|
||||||
public static deleteBook(userId: string, bookId: string, lang: 'fr' | 'en'): boolean {
|
public static deleteBook(userId: string, bookId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM erit_books WHERE author_id=? AND book_id=?', [userId,bookId]);
|
const query: string = 'DELETE FROM erit_books WHERE author_id=? AND book_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le livre.` : `Unable to delete book.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de supprimer le livre.' : 'Unable to delete book.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
static async fetchEritBooksTable(userId:string,bookId:string, lang: 'fr' | 'en'):Promise<EritBooksTable[]>{
|
|
||||||
try {
|
|
||||||
const db: Database = System.getDb();
|
|
||||||
return db.all('SELECT book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update FROM erit_books WHERE book_id=? AND author_id=?', [bookId, userId]) as EritBooksTable[];
|
|
||||||
} catch (e:unknown) {
|
|
||||||
if (e instanceof Error) {
|
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du livre.` : `Unable to retrieve book information.`);
|
|
||||||
} else {
|
|
||||||
console.error("An unknown error occurred.");
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all columns from erit_books table for a book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The complete book data
|
||||||
|
*/
|
||||||
|
static async fetchEritBooksTable(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<EritBooksTable[]> {
|
||||||
|
try {
|
||||||
|
const db: Database = System.getDb();
|
||||||
|
const query: string = 'SELECT book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update FROM erit_books WHERE book_id=? AND author_id=?';
|
||||||
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
|
return db.all(query, params) as EritBooksTable[];
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les informations du livre.' : 'Unable to retrieve book information.');
|
||||||
|
}
|
||||||
|
console.error("An unknown error occurred.");
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves synced books for a user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of books with sync information
|
||||||
|
*/
|
||||||
static fetchSyncedBooks(userId: string, lang: 'fr' | 'en'): SyncedBookResult[] {
|
static fetchSyncedBooks(userId: string, lang: 'fr' | 'en'): SyncedBookResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT book_id, type, title, sub_title, last_update FROM erit_books WHERE author_id = ?', [userId]) as SyncedBookResult[];
|
const query: string = 'SELECT book_id, type, title, sub_title, last_update FROM erit_books WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as SyncedBookResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les livres synchronisés.` : `Unable to retrieve synced books.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les livres synchronisés.' : 'Unable to retrieve synced books.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced book from the server.
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param type - The book type
|
||||||
|
* @param title - The encrypted title
|
||||||
|
* @param hashedTitle - The hashed title
|
||||||
|
* @param subTitle - The encrypted subtitle
|
||||||
|
* @param hashedSubTitle - The hashed subtitle
|
||||||
|
* @param summary - The encrypted summary
|
||||||
|
* @param serieId - The series identifier
|
||||||
|
* @param desiredReleaseDate - The desired release date
|
||||||
|
* @param desiredWordCount - The desired word count
|
||||||
|
* @param wordsCount - The current word count
|
||||||
|
* @param coverImage - The cover image file name
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the insertion was successful
|
||||||
|
*/
|
||||||
static insertSyncBook(bookId: string, userId: string, type: string, title: string, hashedTitle: string, subTitle: string | null, hashedSubTitle: string | null, summary: string | null, serieId: number | null, desiredReleaseDate: string | null, desiredWordCount: number | null, wordsCount: number | null, coverImage: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncBook(bookId: string, userId: string, type: string, title: string, hashedTitle: string, subTitle: string | null, hashedSubTitle: string | null, summary: string | null, serieId: number | null, desiredReleaseDate: string | null, desiredWordCount: number | null, wordsCount: number | null, coverImage: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = 'INSERT INTO erit_books (book_id, author_id, type, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||||
`INSERT INTO erit_books (book_id, author_id, type, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update)
|
const params: SQLiteValue[] = [bookId, userId, type, title, hashedTitle, subTitle, hashedSubTitle, summary, serieId, desiredReleaseDate, desiredWordCount, wordsCount, coverImage, lastUpdate];
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
const insertResult: RunResult = db.run(query, params);
|
||||||
[bookId, userId, type, title, hashedTitle, subTitle, hashedSubTitle, summary, serieId, desiredReleaseDate, desiredWordCount, wordsCount, coverImage, lastUpdate]
|
return insertResult.changes > 0;
|
||||||
);
|
} catch (error: unknown) {
|
||||||
return result.changes > 0;
|
if (error instanceof Error) {
|
||||||
} catch (e: unknown) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
if (e instanceof Error) {
|
throw new Error(lang === 'fr' ? "Impossible d'insérer le livre synchronisé." : 'Unable to insert synced book.');
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le livre synchronisé.` : `Unable to insert synced book.`);
|
|
||||||
} else {
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
}
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteBookById(bookId: string, lang: "fr" | "en") {
|
/**
|
||||||
|
* Retrieves a complete book by its identifier (without author verification).
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The complete book data
|
||||||
|
*/
|
||||||
|
static async fetchCompleteBookById(bookId: string, lang: 'fr' | 'en'): Promise<EritBooksTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(`SELECT * FROM erit_books WHERE book_id = ?`, [bookId]) as EritBooksTable[];
|
const query: string = 'SELECT * FROM erit_books WHERE book_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as EritBooksTable[];
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le livre complet.` : `Unable to retrieve complete book.`);
|
} catch (error: unknown) {
|
||||||
} else {
|
if (error instanceof Error) {
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer le livre complet.' : 'Unable to retrieve complete book.');
|
||||||
|
}
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
||||||
import System from "../System.js";
|
import System from "../System.js";
|
||||||
import {BookQuery, EritBooksTable, SyncedBookResult} from "@/electron/database/repositories/book.repository";
|
|
||||||
|
|
||||||
export interface ChapterQueryResult extends Record<string, SQLiteValue>{
|
export interface ChapterQueryResult extends Record<string, SQLiteValue> {
|
||||||
chapter_id: string;
|
chapter_id: string;
|
||||||
title: string;
|
title: string;
|
||||||
chapter_order: number;
|
chapter_order: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ActChapterQuery extends Record<string, SQLiteValue>{
|
export interface ActChapterQuery extends Record<string, SQLiteValue> {
|
||||||
chapter_info_id: number;
|
chapter_info_id: number;
|
||||||
chapter_id: string;
|
chapter_id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -20,7 +19,7 @@ export interface ActChapterQuery extends Record<string, SQLiteValue>{
|
|||||||
goal: string;
|
goal: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChapterStoryQueryResult extends Record<string, SQLiteValue>{
|
export interface ChapterStoryQueryResult extends Record<string, SQLiteValue> {
|
||||||
chapter_info_id: number;
|
chapter_info_id: number;
|
||||||
act_id: number;
|
act_id: number;
|
||||||
summary: string;
|
summary: string;
|
||||||
@@ -34,7 +33,7 @@ export interface ChapterStoryQueryResult extends Record<string, SQLiteValue>{
|
|||||||
plot_summary: string;
|
plot_summary: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LastChapterResult extends Record<string, SQLiteValue>{
|
export interface LastChapterResult extends Record<string, SQLiteValue> {
|
||||||
chapter_id: string;
|
chapter_id: string;
|
||||||
version: number;
|
version: number;
|
||||||
}
|
}
|
||||||
@@ -83,413 +82,620 @@ export interface ChapterBookResult extends Record<string, SQLiteValue> {
|
|||||||
content: string | null;
|
content: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ChapterRepo{
|
export default class ChapterRepo {
|
||||||
public static checkNameDuplication(userId:string,bookId:string,hashedTitle:string, lang: 'fr' | 'en' = 'fr'):boolean{
|
/**
|
||||||
|
* Checks if a chapter name already exists for a book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param hashedTitle - The hashed chapter title
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if a chapter with this name exists
|
||||||
|
*/
|
||||||
|
public static checkNameDuplication(userId: string, bookId: string, hashedTitle: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result = db.get('SELECT chapter_id FROM book_chapters WHERE author_id=? AND book_id=? AND hashed_title=?', [userId,bookId,hashedTitle]);
|
const query: string = 'SELECT chapter_id FROM book_chapters WHERE author_id=? AND book_id=? AND hashed_title=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [userId, bookId, hashedTitle];
|
||||||
} catch (e: unknown) {
|
const chapter: QueryResult | null = db.get(query, params);
|
||||||
if (e instanceof Error) {
|
return chapter !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier la duplication du nom.` : `Unable to verify name duplication.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de vérifier la duplication du nom.' : 'Unable to verify name duplication.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new chapter into the database.
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param title - The encrypted chapter title
|
||||||
|
* @param hashedTitle - The hashed chapter title
|
||||||
|
* @param wordsCount - The word count
|
||||||
|
* @param chapterOrder - The chapter order position
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The created chapter identifier
|
||||||
|
*/
|
||||||
public static insertChapter(chapterId: string, userId: string, bookId: string, title: string, hashedTitle: string, wordsCount: number, chapterOrder: number, lang: 'fr' | 'en' = 'fr'): string {
|
public static insertChapter(chapterId: string, userId: string, bookId: string, title: string, hashedTitle: string, wordsCount: number, chapterOrder: number, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_chapters (chapter_id, author_id, book_id, title, hashed_title, words_count, chapter_order, last_update) VALUES (?,?,?,?,?,?,?,?)', [chapterId, userId, bookId, title, hashedTitle, wordsCount, chapterOrder, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_chapters (chapter_id, author_id, book_id, title, hashed_title, words_count, chapter_order, last_update) VALUES (?,?,?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [chapterId, userId, bookId, title, hashedTitle, wordsCount, chapterOrder, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le chapitre.` : `Unable to add chapter.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible d'ajouter le chapitre." : 'Unable to add chapter.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
if (!result || result.changes === 0) {
|
throw new Error(lang === 'fr' ? "Une erreur s'est passé lors de l'ajout du chapitre." : 'Error adding chapter.');
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est passé lors de l'ajout du chapitre.` : `Error adding chapter.`);
|
|
||||||
}
|
}
|
||||||
return chapterId;
|
return chapterId;
|
||||||
}
|
}
|
||||||
public static fetchAllChapterForActs(userId:string,bookId:string, lang: 'fr' | 'en' = 'fr'):ActChapterQuery[]{
|
|
||||||
|
/**
|
||||||
|
* Retrieves all chapters with their act information for a book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of chapters with act information
|
||||||
|
*/
|
||||||
|
public static fetchAllChapterForActs(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): ActChapterQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT ci.chapter_info_id AS chapter_info_id, ci.chapter_id AS chapter_id, chapter.title, chapter.chapter_order, ci.act_id, ci.incident_id AS incident_id, ci.plot_point_id AS plot_point_id, ci.summary, ci.goal FROM book_chapter_infos AS ci INNER JOIN book_chapters AS chapter ON chapter.chapter_id = ci.chapter_id WHERE ci.book_id = ? AND ci.author_id = ?', [bookId, userId]) as ActChapterQuery[];
|
const query: string = 'SELECT ci.chapter_info_id AS chapter_info_id, ci.chapter_id AS chapter_id, chapter.title, chapter.chapter_order, ci.act_id, ci.incident_id AS incident_id, ci.plot_point_id AS plot_point_id, ci.summary, ci.goal FROM book_chapter_infos AS ci INNER JOIN book_chapters AS chapter ON chapter.chapter_id = ci.chapter_id WHERE ci.book_id = ? AND ci.author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as ActChapterQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres pour les actes.` : `Unable to retrieve chapters for acts.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les chapitres pour les actes.' : 'Unable to retrieve chapters for acts.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all chapters from a book ordered by chapter order.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of chapters
|
||||||
|
*/
|
||||||
public static fetchAllChapterFromABook(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): ChapterQueryResult[] {
|
public static fetchAllChapterFromABook(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): ChapterQueryResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_id, title, chapter_order FROM book_chapters WHERE book_id=? AND author_id=? ORDER BY chapter_order', [bookId, userId]) as ChapterQueryResult[];
|
const query: string = 'SELECT chapter_id, title, chapter_order FROM book_chapters WHERE book_id=? AND author_id=? ORDER BY chapter_order';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as ChapterQueryResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres.` : `Unable to retrieve chapters.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les chapitres.' : 'Unable to retrieve chapters.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a chapter from the database.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier to delete
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the deletion was successful
|
||||||
|
*/
|
||||||
public static deleteChapter(userId: string, chapterId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
public static deleteChapter(userId: string, chapterId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_chapters WHERE author_id=? AND chapter_id=?', [userId, chapterId]);
|
const query: string = 'DELETE FROM book_chapters WHERE author_id=? AND chapter_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, chapterId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le chapitre.` : `Unable to delete chapter.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de supprimer le chapitre.' : 'Unable to delete chapter.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts chapter information linking a chapter to an act.
|
||||||
|
* @param chapterInfoId - The chapter info identifier
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param actId - The act identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param plotId - The plot point identifier (optional)
|
||||||
|
* @param incidentId - The incident identifier (optional)
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The created chapter info identifier
|
||||||
|
*/
|
||||||
static insertChapterInformation(chapterInfoId: string, userId: string, chapterId: string, actId: number, bookId: string, plotId: string | null, incidentId: string | null, lang: 'fr' | 'en' = 'fr'): string {
|
static insertChapterInformation(chapterInfoId: string, userId: string, chapterId: string, actId: number, bookId: string, plotId: string | null, incidentId: string | null, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let existResult;
|
let existingChapter: QueryResult | null;
|
||||||
let result: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
existResult = db.get('SELECT chapter_info_id FROM book_chapter_infos WHERE chapter_id=? AND act_id=? AND book_id=? AND plot_point_id=? AND incident_id=? AND author_id=?', [chapterId, actId, bookId, plotId, incidentId, userId]);
|
const checkQuery: string = 'SELECT chapter_info_id FROM book_chapter_infos WHERE chapter_id=? AND act_id=? AND book_id=? AND plot_point_id=? AND incident_id=? AND author_id=?';
|
||||||
} catch (e: unknown) {
|
const checkParams: SQLiteValue[] = [chapterId, actId, bookId, plotId, incidentId, userId];
|
||||||
if (e instanceof Error) {
|
existingChapter = db.get(checkQuery, checkParams);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'information du chapitre.` : `Unable to verify chapter information existence.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible de vérifier l'existence de l'information du chapitre." : 'Unable to verify chapter information existence.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
if (existingChapter !== null) {
|
||||||
if (existResult !== null) {
|
throw new Error(lang === 'fr' ? 'Le chapitre est déjà lié.' : 'Chapter is already linked.');
|
||||||
throw new Error(lang === 'fr' ? `Le chapitre est déjà lié.` : `Chapter is already linked.`);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, book_id, author_id, incident_id, plot_point_id, summary, goal, last_update) VALUES (?,?,?,?,?,?,?,?,?,?)', [chapterInfoId, chapterId, actId, bookId, userId, incidentId, plotId, '', '', System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, book_id, author_id, incident_id, plot_point_id, summary, goal, last_update) VALUES (?,?,?,?,?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [chapterInfoId, chapterId, actId, bookId, userId, incidentId, plotId, '', '', System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'information du chapitre.` : `Unable to add chapter information.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible d'ajouter l'information du chapitre." : 'Unable to add chapter information.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
if (!result || result.changes === 0) {
|
throw new Error(lang === 'fr' ? "Une erreur s'est produite pendant la liaison du chapitre." : 'Error linking chapter.');
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite pendant la liaison du chapitre.` : `Error linking chapter.`);
|
|
||||||
}
|
}
|
||||||
return chapterInfoId;
|
return chapterInfoId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static updateChapter(userId: string, chapterId: string, encryptedTitle: string, hashTitle: string, chapterOrder: number, lastUpdate:number, lang: 'fr' | 'en' = 'fr'): boolean {
|
/**
|
||||||
|
* Updates a chapter's basic information.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param encryptedTitle - The encrypted title
|
||||||
|
* @param hashTitle - The hashed title
|
||||||
|
* @param chapterOrder - The chapter order position
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the update was successful
|
||||||
|
*/
|
||||||
|
public static updateChapter(userId: string, chapterId: string, encryptedTitle: string, hashTitle: string, chapterOrder: number, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_chapters SET title=?, hashed_title=?, chapter_order=?, last_update=? WHERE author_id=? AND chapter_id=?', [encryptedTitle, hashTitle, chapterOrder, lastUpdate, userId, chapterId]);
|
const query: string = 'UPDATE book_chapters SET title=?, hashed_title=?, chapter_order=?, last_update=? WHERE author_id=? AND chapter_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [encryptedTitle, hashTitle, chapterOrder, lastUpdate, userId, chapterId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le chapitre.` : `Unable to update chapter.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de mettre à jour le chapitre.' : 'Unable to update chapter.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates chapter information (summary and goal).
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param actId - The act identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param incidentId - The incident identifier (optional)
|
||||||
|
* @param plotId - The plot point identifier (optional)
|
||||||
|
* @param summary - The chapter summary
|
||||||
|
* @param goal - The chapter goal
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the update was successful
|
||||||
|
*/
|
||||||
public static updateChapterInfos(userId: string, chapterId: string, actId: number, bookId: string, incidentId: string | null, plotId: string | null, summary: string, goal: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
public static updateChapterInfos(userId: string, chapterId: string, actId: number, bookId: string, incidentId: string | null, plotId: string | null, summary: string, goal: string | null, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
let sql: string = `UPDATE book_chapter_infos SET summary=?,goal=?,last_update=? WHERE chapter_id = ? AND act_id = ? AND book_id = ?`;
|
let query: string = 'UPDATE book_chapter_infos SET summary=?,goal=?,last_update=? WHERE chapter_id = ? AND act_id = ? AND book_id = ?';
|
||||||
const params: (string|null|number)[] = [summary, goal, lastUpdate, chapterId, actId, bookId];
|
const params: SQLiteValue[] = [summary, goal, lastUpdate, chapterId, actId, bookId];
|
||||||
if (incidentId) {
|
if (incidentId) {
|
||||||
sql += ` AND incident_id=?`;
|
query += ' AND incident_id=?';
|
||||||
params.push(incidentId);
|
params.push(incidentId);
|
||||||
} else {
|
} else {
|
||||||
sql += ` AND incident_id IS NULL`;
|
query += ' AND incident_id IS NULL';
|
||||||
}
|
}
|
||||||
if (plotId) {
|
if (plotId) {
|
||||||
sql += ` AND plot_point_id=?`;
|
query += ' AND plot_point_id=?';
|
||||||
params.push(plotId);
|
params.push(plotId);
|
||||||
} else {
|
} else {
|
||||||
sql += ` AND plot_point_id IS NULL`;
|
query += ' AND plot_point_id IS NULL';
|
||||||
}
|
}
|
||||||
sql += ` AND author_id=?`;
|
query += ' AND author_id=?';
|
||||||
params.push(userId);
|
params.push(userId);
|
||||||
const result: RunResult = db.run(sql, params);
|
const updateResult: RunResult = db.run(query, params);
|
||||||
return result.changes > 0;
|
return updateResult.changes > 0;
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les informations du chapitre.` : `Unable to update chapter information.`);
|
throw new Error(lang === 'fr' ? 'Impossible de mettre à jour les informations du chapitre.' : 'Unable to update chapter information.');
|
||||||
} else {
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the last opened chapter for a book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The last chapter information or null
|
||||||
|
*/
|
||||||
public static fetchLastChapter(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LastChapterResult | null {
|
public static fetchLastChapter(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LastChapterResult | null {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result = db.get('SELECT chapter_id as chapter_id,version FROM user_last_chapter WHERE user_id=? AND book_id=?', [userId, bookId]) as LastChapterResult | null;
|
const query: string = 'SELECT chapter_id as chapter_id,version FROM user_last_chapter WHERE user_id=? AND book_id=?';
|
||||||
return result;
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
} catch (e: unknown) {
|
return db.get(query, params) as LastChapterResult | null;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le dernier chapitre ouvert.` : `Unable to retrieve last opened chapter.`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
} else {
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer le dernier chapitre ouvert.' : 'Unable to retrieve last opened chapter.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates or inserts the last chapter record for a user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param version - The chapter version
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the operation was successful
|
||||||
|
*/
|
||||||
public static updateLastChapterRecord(userId: string, bookId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
public static updateLastChapterRecord(userId: string, bookId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE user_last_chapter SET chapter_id=?, version=? WHERE user_id=? AND book_id=?', [chapterId, version, userId, bookId]);
|
const updateQuery: string = 'UPDATE user_last_chapter SET chapter_id=?, version=? WHERE user_id=? AND book_id=?';
|
||||||
if (result.changes > 0) {
|
const updateParams: SQLiteValue[] = [chapterId, version, userId, bookId];
|
||||||
|
const updateResult: RunResult = db.run(updateQuery, updateParams);
|
||||||
|
if (updateResult.changes > 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
const insertResult: RunResult = db.run('INSERT INTO user_last_chapter (user_id, book_id, chapter_id, version) VALUES (?,?,?,?)', [userId, bookId, chapterId, version]);
|
|
||||||
return insertResult.changes > 0;
|
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
const insertQuery: string = 'INSERT INTO user_last_chapter (user_id, book_id, chapter_id, version) VALUES (?,?,?,?)';
|
||||||
if (e instanceof Error) {
|
const insertParams: SQLiteValue[] = [userId, bookId, chapterId, version];
|
||||||
console.error(`DB Error: ${e.message}`);
|
const insertResult: RunResult = db.run(insertQuery, insertParams);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'enregistrer le dernier chapitre.` : `Unable to save last chapter.`);
|
return insertResult.changes > 0;
|
||||||
} else {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible d'enregistrer le dernier chapitre." : 'Unable to save last chapter.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static fetchChapterStory(userId: string, chapterId: string, lang: 'fr' | 'en' = 'fr'):ChapterStoryQueryResult[] {
|
/**
|
||||||
|
* Retrieves chapter story information including act, incident, and plot point data.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of chapter story information
|
||||||
|
*/
|
||||||
|
public static fetchChapterStory(userId: string, chapterId: string, lang: 'fr' | 'en' = 'fr'): ChapterStoryQueryResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_info_id, chapter.act_id, act_sum.summary, chapter.summary AS chapter_summary, chapter.goal AS chapter_goal, chapter.incident_id, incident.title AS incident_title, incident.summary AS incident_summary, chapter.plot_point_id, plot.title AS plot_title, plot.summary AS plot_summary FROM book_chapter_infos AS chapter LEFT JOIN book_incidents AS incident ON chapter.incident_id=incident.incident_id LEFT JOIN book_plot_points AS plot ON chapter.plot_point_id=plot.plot_point_id LEFT JOIN book_act_summaries AS act_sum ON chapter.act_id=act_sum.act_sum_id AND chapter.book_id=act_sum.book_id WHERE chapter.chapter_id=? AND chapter.author_id=?', [chapterId, userId]) as ChapterStoryQueryResult[];
|
const query: string = 'SELECT chapter_info_id, chapter.act_id, act_sum.summary, chapter.summary AS chapter_summary, chapter.goal AS chapter_goal, chapter.incident_id, incident.title AS incident_title, incident.summary AS incident_summary, chapter.plot_point_id, plot.title AS plot_title, plot.summary AS plot_summary FROM book_chapter_infos AS chapter LEFT JOIN book_incidents AS incident ON chapter.incident_id=incident.incident_id LEFT JOIN book_plot_points AS plot ON chapter.plot_point_id=plot.plot_point_id LEFT JOIN book_act_summaries AS act_sum ON chapter.act_id=act_sum.act_sum_id AND chapter.book_id=act_sum.book_id WHERE chapter.chapter_id=? AND chapter.author_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [chapterId, userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as ChapterStoryQueryResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer l'histoire du chapitre.` : `Unable to retrieve chapter story.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible de récupérer l'histoire du chapitre." : 'Unable to retrieve chapter story.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes chapter information by its identifier.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterInfoId - The chapter info identifier to delete
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the deletion was successful
|
||||||
|
*/
|
||||||
static deleteChapterInformation(userId: string, chapterInfoId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
static deleteChapterInformation(userId: string, chapterInfoId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_chapter_infos WHERE chapter_info_id=? AND author_id=?', [chapterInfoId, userId]);
|
const query: string = 'DELETE FROM book_chapter_infos WHERE chapter_info_id=? AND author_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [chapterInfoId, userId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer les informations du chapitre.` : `Unable to delete chapter information.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de supprimer les informations du chapitre.' : 'Unable to delete chapter information.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
static isChapterExist(userId: string, chapter_id: string, lang: "fr" | "en"): boolean {
|
|
||||||
try {
|
|
||||||
const db: Database = System.getDb();
|
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM book_chapters WHERE chapter_id=? AND author_id=?', [chapter_id, userId]) || null;
|
|
||||||
return result !== null;
|
|
||||||
} catch (e: unknown) {
|
|
||||||
if (e instanceof Error) {
|
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du chapitre.` : `Unable to check chapter existence.`);
|
|
||||||
} else {
|
|
||||||
console.error("An unknown error occurred.");
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static isChapterInfoExist(userId: string, chapter_id: string, lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a chapter exists.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the chapter exists
|
||||||
|
*/
|
||||||
|
static isChapterExist(userId: string, chapterId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_chapter_infos` WHERE `chapter_id`=? AND `author_id`=?', [chapter_id, userId]) || null;
|
const query: string = 'SELECT 1 FROM book_chapters WHERE chapter_id=? AND author_id=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [chapterId, userId];
|
||||||
} catch (e: unknown) {
|
const chapter: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return chapter !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence des informations du chapitre.` : `Unable to check chapter info existence.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible de vérifier l'existence du chapitre." : 'Unable to check chapter existence.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static fetchCompleteBookChapters(id: string, lang: 'fr' | 'en'): ChapterBookResult[] {
|
/**
|
||||||
let result: ChapterBookResult[];
|
* Checks if chapter info exists.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the chapter info exists
|
||||||
|
*/
|
||||||
|
static isChapterInfoExist(userId: string, chapterId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.all('SELECT title, chapter_order, content.content FROM book_chapters AS chapter LEFT JOIN book_chapter_content AS content ON chapter.chapter_id = content.chapter_id AND content.version = (SELECT MAX(version) FROM book_chapter_content WHERE chapter_id = chapter.chapter_id AND version > 1) WHERE chapter.book_id = ? ORDER BY chapter.chapter_order', [id]) as ChapterBookResult[];
|
const query: string = 'SELECT 1 FROM book_chapter_infos WHERE chapter_id=? AND author_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [chapterId, userId];
|
||||||
if (e instanceof Error) {
|
const chapterInfo: QueryResult | null = db.get(query, params) || null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
return chapterInfo !== null;
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres.` : `Unable to retrieve chapters.`);
|
} catch (error: unknown) {
|
||||||
} else {
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? "Impossible de vérifier l'existence des informations du chapitre." : 'Unable to check chapter info existence.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "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 chapitre trouvé.` : `No chapters found.`);
|
/**
|
||||||
|
* Retrieves complete book chapters with their content.
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of chapters with content
|
||||||
|
*/
|
||||||
|
static fetchCompleteBookChapters(bookId: string, lang: 'fr' | 'en'): ChapterBookResult[] {
|
||||||
|
let chapters: ChapterBookResult[];
|
||||||
|
try {
|
||||||
|
const db: Database = System.getDb();
|
||||||
|
const query: string = 'SELECT title, chapter_order, content.content FROM book_chapters AS chapter LEFT JOIN book_chapter_content AS content ON chapter.chapter_id = content.chapter_id AND content.version = (SELECT MAX(version) FROM book_chapter_content WHERE chapter_id = chapter.chapter_id AND version > 1) WHERE chapter.book_id = ? ORDER BY chapter.chapter_order';
|
||||||
|
const params: SQLiteValue[] = [bookId];
|
||||||
|
chapters = db.all(query, params) as ChapterBookResult[];
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les chapitres.' : 'Unable to retrieve chapters.');
|
||||||
}
|
}
|
||||||
return result;
|
console.error("An unknown error occurred.");
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
|
if (chapters.length === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? 'Aucun chapitre trouvé.' : 'No chapters found.');
|
||||||
|
}
|
||||||
|
return chapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all chapters for a book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of book chapters
|
||||||
|
*/
|
||||||
static async fetchBookChapters(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookChaptersTable[]> {
|
static async fetchBookChapters(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookChaptersTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update FROM book_chapters WHERE author_id=? AND book_id=?', [userId, bookId]) as BookChaptersTable[];
|
const query: string = 'SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update FROM book_chapters WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as BookChaptersTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres.` : `Unable to retrieve chapters.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les chapitres.' : 'Unable to retrieve chapters.');
|
||||||
|
}
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves chapter information for a specific chapter.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of chapter info records
|
||||||
|
*/
|
||||||
static async fetchBookChapterInfos(userId: string, chapterId: string, lang: 'fr' | 'en'): Promise<BookChapterInfosTable[]> {
|
static async fetchBookChapterInfos(userId: string, chapterId: string, lang: 'fr' | 'en'): Promise<BookChapterInfosTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update FROM book_chapter_infos WHERE author_id=? AND chapter_id=?', [userId, chapterId]) as BookChapterInfosTable[];
|
const query: string = 'SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update FROM book_chapter_infos WHERE author_id=? AND chapter_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, chapterId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as BookChapterInfosTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les infos des chapitres.` : `Unable to retrieve chapter infos.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les infos des chapitres.' : 'Unable to retrieve chapter infos.');
|
||||||
|
}
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Retrieves synced chapters for a user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of synced chapters
|
||||||
|
*/
|
||||||
static fetchSyncedChapters(userId: string, lang: 'fr' | 'en'): SyncedChapterResult[] {
|
static fetchSyncedChapters(userId: string, lang: 'fr' | 'en'): SyncedChapterResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_id, book_id, title, last_update FROM book_chapters WHERE author_id = ?', [userId]) as SyncedChapterResult[];
|
const query: string = 'SELECT chapter_id, book_id, title, last_update FROM book_chapters WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as SyncedChapterResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres synchronisés.` : `Unable to retrieve synced chapters.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les chapitres synchronisés.' : 'Unable to retrieve synced chapters.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves synced chapter infos for a user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns List of synced chapter infos
|
||||||
|
*/
|
||||||
static fetchSyncedChapterInfos(userId: string, lang: 'fr' | 'en'): SyncedChapterInfoResult[] {
|
static fetchSyncedChapterInfos(userId: string, lang: 'fr' | 'en'): SyncedChapterInfoResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT chapter_info_id, chapter_id, book_id, last_update FROM book_chapter_infos WHERE author_id = ?', [userId]) as SyncedChapterInfoResult[];
|
const query: string = 'SELECT chapter_info_id, chapter_id, book_id, last_update FROM book_chapter_infos WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
return db.all(query, params) as SyncedChapterInfoResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les infos des chapitres synchronisés.` : `Unable to retrieve synced chapter infos.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les infos des chapitres synchronisés.' : 'Unable to retrieve synced chapter infos.');
|
||||||
|
}
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced chapter from the server.
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param authorId - The author identifier
|
||||||
|
* @param title - The encrypted title
|
||||||
|
* @param hashedTitle - The hashed title
|
||||||
|
* @param wordsCount - The word count
|
||||||
|
* @param chapterOrder - The chapter order
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the insertion was successful
|
||||||
|
*/
|
||||||
static insertSyncChapter(chapterId: string, bookId: string, authorId: string, title: string, hashedTitle: string | null, wordsCount: number | null, chapterOrder: number | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncChapter(chapterId: string, bookId: string, authorId: string, title: string, hashedTitle: string | null, wordsCount: number | null, chapterOrder: number | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = 'INSERT INTO book_chapters (chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
||||||
`INSERT INTO book_chapters (chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update)
|
const params: SQLiteValue[] = [chapterId, bookId, authorId, title, hashedTitle, wordsCount, chapterOrder, lastUpdate];
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
const insertResult: RunResult = db.run(query, params);
|
||||||
[chapterId, bookId, authorId, title, hashedTitle, wordsCount, chapterOrder, lastUpdate]
|
return insertResult.changes > 0;
|
||||||
);
|
} catch (error: unknown) {
|
||||||
return result.changes > 0;
|
if (error instanceof Error) {
|
||||||
} catch (e: unknown) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
if (e instanceof Error) {
|
throw new Error(lang === 'fr' ? "Impossible d'insérer le chapitre." : 'Unable to insert chapter.');
|
||||||
console.error(`DB Error: ${e.message}`);
|
}
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le chapitre.` : `Unable to insert chapter.`);
|
|
||||||
} else {
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts synced chapter info from the server.
|
||||||
|
* @param chapterInfoId - The chapter info identifier
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param actId - The act identifier
|
||||||
|
* @param incidentId - The incident identifier
|
||||||
|
* @param plotPointId - The plot point identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param authorId - The author identifier
|
||||||
|
* @param summary - The chapter summary
|
||||||
|
* @param goal - The chapter goal
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns true if the insertion was successful
|
||||||
|
*/
|
||||||
static insertSyncChapterInfo(chapterInfoId: string, chapterId: string, actId: number | null, incidentId: string | null, plotPointId: string | null, bookId: string, authorId: string, summary: string | null, goal: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncChapterInfo(chapterInfoId: string, chapterId: string, actId: number | null, incidentId: string | null, plotPointId: string | null, bookId: string, authorId: string, summary: string | null, goal: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(`INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [chapterInfoId, chapterId, actId, incidentId, plotPointId, bookId, authorId, summary, goal, lastUpdate]);
|
const query: string = 'INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [chapterInfoId, chapterId, actId, incidentId, plotPointId, bookId, authorId, summary, goal, lastUpdate];
|
||||||
} catch (e: unknown) {
|
const insertResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return insertResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer les infos du chapitre.` : `Unable to insert chapter info.`);
|
if (error instanceof Error) {
|
||||||
} else {
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Impossible d'insérer les infos du chapitre." : 'Unable to insert chapter info.');
|
||||||
}
|
}
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteChapterById(id: string, lang: "fr" | "en"):Promise<BookChaptersTable[]> {
|
/**
|
||||||
|
* Retrieves a complete chapter by its identifier.
|
||||||
|
* @param chapterId - The chapter identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The complete chapter data
|
||||||
|
*/
|
||||||
|
static async fetchCompleteChapterById(chapterId: string, lang: 'fr' | 'en'): Promise<BookChaptersTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = 'SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update FROM book_chapters WHERE chapter_id = ?';
|
||||||
`SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update
|
const params: SQLiteValue[] = [chapterId];
|
||||||
FROM book_chapters
|
return db.all(query, params) as BookChaptersTable[];
|
||||||
WHERE chapter_id = ?`,
|
} catch (error: unknown) {
|
||||||
[id]
|
if (error instanceof Error) {
|
||||||
) as BookChaptersTable[];
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer le chapitre complet.' : 'Unable to retrieve complete chapter.');
|
||||||
} catch (e:unknown){
|
|
||||||
if (e instanceof Error) {
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le chapitre complet.` : `Unable to retrieve complete chapter.`);
|
|
||||||
} else {
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
}
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteChapterInfoById(id: string, lang: "fr" | "en"):Promise<BookChapterInfosTable[]> {
|
/**
|
||||||
|
* Retrieves complete chapter info by its identifier.
|
||||||
|
* @param chapterInfoId - The chapter info identifier
|
||||||
|
* @param lang - The language for error messages
|
||||||
|
* @returns The complete chapter info data
|
||||||
|
*/
|
||||||
|
static async fetchCompleteChapterInfoById(chapterInfoId: string, lang: 'fr' | 'en'): Promise<BookChapterInfosTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = 'SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update FROM book_chapter_infos WHERE chapter_info_id = ?';
|
||||||
`SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update
|
const params: SQLiteValue[] = [chapterInfoId];
|
||||||
FROM book_chapter_infos
|
return db.all(query, params) as BookChapterInfosTable[];
|
||||||
WHERE chapter_info_id = ?`,
|
} catch (error: unknown) {
|
||||||
[id]
|
if (error instanceof Error) {
|
||||||
) as BookChapterInfosTable[];
|
throw new Error(lang === 'fr' ? 'Impossible de récupérer les informations de chapitre complètes.' : 'Unable to retrieve complete chapter info.');
|
||||||
} catch (e:unknown){
|
|
||||||
if (e instanceof Error) {
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations de chapitre complètes.` : `Unable to retrieve complete chapter info.`);
|
|
||||||
} else {
|
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
|
||||||
}
|
}
|
||||||
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, QueryResult, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
|
|
||||||
export interface ChapterContentQueryResult extends Record<string, SQLiteValue>{
|
export interface ChapterContentQueryResult extends Record<string, SQLiteValue> {
|
||||||
chapter_id: string;
|
chapter_id: string;
|
||||||
version: number;
|
version: number;
|
||||||
content: string;
|
content: string;
|
||||||
@@ -14,7 +14,7 @@ export interface ContentQueryResult extends Record<string, SQLiteValue> {
|
|||||||
content: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompanionContentQueryResult extends Record<string, SQLiteValue>{
|
export interface CompanionContentQueryResult extends Record<string, SQLiteValue> {
|
||||||
version: number;
|
version: number;
|
||||||
content: string;
|
content: string;
|
||||||
words_count: number;
|
words_count: number;
|
||||||
@@ -38,14 +38,36 @@ export interface SyncedChapterContentResult extends Record<string, SQLiteValue>
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class ChapterContentRepository {
|
export default class ChapterContentRepository {
|
||||||
|
/**
|
||||||
|
* Fetches the last chapter content for a given book.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param bookId - The ID of the book.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns An array of chapter content results ordered by chapter order and version descending.
|
||||||
|
*/
|
||||||
public static fetchLastChapterContent(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): ChapterContentQueryResult[] {
|
public static fetchLastChapterContent(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): ChapterContentQueryResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query: string = `SELECT book_chapters.chapter_id as chapter_id, COALESCE(book_chapter_content.version, 2) AS version, COALESCE(book_chapter_content.content, '') AS content, COALESCE(book_chapter_content.words_count, 0) AS words_count, book_chapters.title, book_chapters.chapter_order FROM book_chapters LEFT JOIN book_chapter_content ON book_chapters.chapter_id = book_chapter_content.chapter_id WHERE book_chapters.author_id = ? AND book_chapters.book_id = ? ORDER BY book_chapters.chapter_order DESC, book_chapter_content.version DESC LIMIT 1`;
|
const query: string = `
|
||||||
return db.all(query, [userId, bookId]) as ChapterContentQueryResult[];
|
SELECT
|
||||||
} catch (e: unknown) {
|
book_chapters.chapter_id as chapter_id,
|
||||||
if (e instanceof Error) {
|
COALESCE(book_chapter_content.version, 2) AS version,
|
||||||
console.error(`DB Error: ${e.message}`);
|
COALESCE(book_chapter_content.content, '') AS content,
|
||||||
|
COALESCE(book_chapter_content.words_count, 0) AS words_count,
|
||||||
|
book_chapters.title,
|
||||||
|
book_chapters.chapter_order
|
||||||
|
FROM book_chapters
|
||||||
|
LEFT JOIN book_chapter_content ON book_chapters.chapter_id = book_chapter_content.chapter_id
|
||||||
|
WHERE book_chapters.author_id = ? AND book_chapters.book_id = ?
|
||||||
|
ORDER BY book_chapters.chapter_order DESC, book_chapter_content.version DESC
|
||||||
|
LIMIT 1
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
|
const chapterContents: ChapterContentQueryResult[] = db.all(query, params) as ChapterContentQueryResult[];
|
||||||
|
return chapterContents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le dernier chapitre.` : `Unable to retrieve last chapter.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le dernier chapitre.` : `Unable to retrieve last chapter.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -53,20 +75,37 @@ export default class ChapterContentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the content of a chapter. If no existing content is found, inserts a new record.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param version - The version number of the content.
|
||||||
|
* @param encryptContent - The encrypted content string.
|
||||||
|
* @param wordsCount - The word count of the content.
|
||||||
|
* @param lastUpdate - The timestamp of the last update.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the update or insert was successful.
|
||||||
|
*/
|
||||||
public static updateChapterContent(userId: string, chapterId: string, version: number, encryptContent: string, wordsCount: number, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
public static updateChapterContent(userId: string, chapterId: string, version: number, encryptContent: string, wordsCount: number, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_chapter_content SET content=?, words_count=?, last_update=? WHERE chapter_id=? AND author_id=? AND version=?', [encryptContent, wordsCount, lastUpdate, chapterId, userId, version]);
|
const updateQuery: string = 'UPDATE book_chapter_content SET content=?, words_count=?, last_update=? WHERE chapter_id=? AND author_id=? AND version=?';
|
||||||
if (result.changes > 0) {
|
const updateParams: SQLiteValue[] = [encryptContent, wordsCount, lastUpdate, chapterId, userId, version];
|
||||||
|
const updateResult: RunResult = db.run(updateQuery, updateParams);
|
||||||
|
|
||||||
|
if (updateResult.changes > 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const contentId:string = System.createUniqueId();
|
const contentId: string = System.createUniqueId();
|
||||||
const insertResult: RunResult = db.run('INSERT INTO book_chapter_content (content_id,chapter_id, author_id, version, content, words_count, last_update) VALUES (?,?,?,?,?,?,?)', [contentId, chapterId, userId, version, encryptContent, wordsCount, lastUpdate]);
|
const insertQuery: string = 'INSERT INTO book_chapter_content (content_id, chapter_id, author_id, version, content, words_count, last_update) VALUES (?,?,?,?,?,?,?)';
|
||||||
|
const insertParams: SQLiteValue[] = [contentId, chapterId, userId, version, encryptContent, wordsCount, lastUpdate];
|
||||||
|
const insertResult: RunResult = db.run(insertQuery, insertParams);
|
||||||
return insertResult.changes > 0;
|
return insertResult.changes > 0;
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le contenu du chapitre.` : `Unable to update chapter content.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le contenu du chapitre.` : `Unable to update chapter content.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -75,13 +114,24 @@ export default class ChapterContentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static fetchCompanionContent(userId: string, chapterIdNum: string, versionNum: number, lang: 'fr' | 'en' = 'fr'): CompanionContentQueryResult[] {
|
/**
|
||||||
|
* Fetches companion content for a specific chapter and version.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param version - The version number to fetch.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns An array of companion content results.
|
||||||
|
*/
|
||||||
|
static fetchCompanionContent(userId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): CompanionContentQueryResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT version, content, words_count FROM book_chapter_content WHERE author_id=? AND chapter_id=? AND version=?', [userId, chapterIdNum, versionNum]) as CompanionContentQueryResult[];
|
const query: string = 'SELECT version, content, words_count FROM book_chapter_content WHERE author_id=? AND chapter_id=? AND version=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, chapterId, version];
|
||||||
if (e instanceof Error) {
|
const companionContents: CompanionContentQueryResult[] = db.all(query, params) as CompanionContentQueryResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return companionContents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu compagnon.` : `Unable to retrieve companion content.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu compagnon.` : `Unable to retrieve companion content.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -89,53 +139,91 @@ export default class ChapterContentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches chapter content by its order position within a book.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterOrder - The order position of the chapter.
|
||||||
|
* @param bookId - The ID of the book.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns The content query result for the specified chapter.
|
||||||
|
* @throws Error if no chapter is found with the specified order.
|
||||||
|
*/
|
||||||
static fetchChapterContentByChapterOrder(userId: string, chapterOrder: number, bookId: string, lang: 'fr' | 'en' = 'fr'): ContentQueryResult {
|
static fetchChapterContentByChapterOrder(userId: string, chapterOrder: number, bookId: string, lang: 'fr' | 'en' = 'fr'): ContentQueryResult {
|
||||||
let result: ContentQueryResult | null;
|
let chapterContent: ContentQueryResult | null;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.get('SELECT content.content FROM book_chapters as chapter INNER JOIN book_chapter_content AS content ON chapter.chapter_id=content.chapter_id WHERE chapter.chapter_order=? AND content.version=2 AND chapter.book_id=? AND chapter.author_id=?', [chapterOrder, bookId, userId]) as ContentQueryResult | null;
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT content.content
|
||||||
if (e instanceof Error) {
|
FROM book_chapters as chapter
|
||||||
console.error(`DB Error: ${e.message}`);
|
INNER JOIN book_chapter_content AS content ON chapter.chapter_id=content.chapter_id
|
||||||
|
WHERE chapter.chapter_order=? AND content.version=2 AND chapter.book_id=? AND chapter.author_id=?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [chapterOrder, bookId, userId];
|
||||||
|
chapterContent = db.get(query, params) as ContentQueryResult | 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 contenu du chapitre.` : `Unable to retrieve chapter content.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu du chapitre.` : `Unable to retrieve chapter content.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!chapterContent) {
|
||||||
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cet ordre.` : `No chapter found with this order.`);
|
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cet ordre.` : `No chapter found with this order.`);
|
||||||
}
|
}
|
||||||
return result;
|
return chapterContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fetchChapterContentByVersion(userId: string, chapterid: string, version: number, lang: 'fr' | 'en' = 'fr'): ContentQueryResult {
|
/**
|
||||||
let result: ContentQueryResult | null;
|
* Fetches chapter content by chapter ID and version number.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param version - The version number to fetch.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns The content query result for the specified version.
|
||||||
|
* @throws Error if no chapter is found with the specified version.
|
||||||
|
*/
|
||||||
|
static fetchChapterContentByVersion(userId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): ContentQueryResult {
|
||||||
|
let chapterContent: ContentQueryResult | null;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.get('SELECT content FROM book_chapter_content WHERE author_id=? AND chapter_id=? AND version=?', [userId, chapterid, version]) as ContentQueryResult | null;
|
const query: string = 'SELECT content FROM book_chapter_content WHERE author_id=? AND chapter_id=? AND version=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, chapterId, version];
|
||||||
if (e instanceof Error) {
|
chapterContent = db.get(query, params) as ContentQueryResult | null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu du chapitre.` : `Unable to retrieve chapter content.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu du chapitre.` : `Unable to retrieve chapter content.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!chapterContent) {
|
||||||
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cette version.` : `No chapter found with this version.`);
|
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cette version.` : `No chapter found with this version.`);
|
||||||
}
|
}
|
||||||
return result;
|
return chapterContent;
|
||||||
}
|
}
|
||||||
static isChapterContentExist(userId: string, content_id: string, lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks whether chapter content exists for a given content ID and user.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param contentId - The ID of the content to check.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the chapter content exists, false otherwise.
|
||||||
|
*/
|
||||||
|
static isChapterContentExist(userId: string, contentId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_chapter_content` WHERE `content_id`=? AND `author_id`=?', [content_id, userId]) || null;
|
const query: string = 'SELECT 1 FROM `book_chapter_content` WHERE `content_id`=? AND `author_id`=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [contentId, userId];
|
||||||
} catch (e: unknown) {
|
const existenceCheck: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existenceCheck !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du contenu du chapitre.` : `Unable to check chapter content existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du contenu du chapitre.` : `Unable to check chapter content existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -143,26 +231,47 @@ export default class ChapterContentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchBookChapterContents(userId: string,chapterId:string, lang: 'fr' | 'en'): Promise<BookChapterContentTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches all chapter contents for a specific chapter belonging to a user.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns A promise resolving to an array of book chapter content records.
|
||||||
|
*/
|
||||||
|
static async fetchBookChapterContents(userId: string, chapterId: string, lang: 'fr' | 'en'): Promise<BookChapterContentTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update FROM book_chapter_content WHERE author_id=? AND chapter_id=?', [userId, chapterId]) as BookChapterContentTable[];
|
const query: string = 'SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update FROM book_chapter_content WHERE author_id=? AND chapter_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, chapterId];
|
||||||
if (e instanceof Error) {
|
const bookChapterContents: BookChapterContentTable[] = db.all(query, params) as BookChapterContentTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return bookChapterContents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres.` : `Unable to retrieve chapter contents.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres.` : `Unable to retrieve chapter contents.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced chapter contents for a user (content ID, chapter ID, and last update timestamp).
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns An array of synced chapter content results.
|
||||||
|
*/
|
||||||
static fetchSyncedChapterContents(userId: string, lang: 'fr' | 'en'): SyncedChapterContentResult[] {
|
static fetchSyncedChapterContents(userId: string, lang: 'fr' | 'en'): SyncedChapterContentResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT content_id, chapter_id, last_update FROM book_chapter_content WHERE author_id = ?', [userId]) as SyncedChapterContentResult[];
|
const query: string = 'SELECT content_id, chapter_id, last_update FROM book_chapter_content WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedChapterContents: SyncedChapterContentResult[] = db.all(query, params) as SyncedChapterContentResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedChapterContents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres synchronisés.` : `Unable to retrieve synced chapter contents.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres synchronisés.` : `Unable to retrieve synced chapter contents.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -170,54 +279,101 @@ export default class ChapterContentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new chapter content record during synchronization.
|
||||||
|
* @param contentId - The unique ID for the content.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param authorId - The ID of the author.
|
||||||
|
* @param version - The version number of the content.
|
||||||
|
* @param content - The content string (can be null).
|
||||||
|
* @param wordsCount - The word count of the content.
|
||||||
|
* @param timeOnIt - The time spent on this content.
|
||||||
|
* @param lastUpdate - The timestamp of the last update.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the insert was successful.
|
||||||
|
*/
|
||||||
static insertSyncChapterContent(contentId: string, chapterId: string, authorId: string, version: number, content: string | null, wordsCount: number, timeOnIt: number, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncChapterContent(contentId: string, chapterId: string, authorId: string, version: number, content: string | null, wordsCount: number, timeOnIt: number, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `
|
||||||
`INSERT INTO book_chapter_content (content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update)
|
INSERT INTO book_chapter_content (content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
[contentId, chapterId, authorId, version, content, wordsCount, timeOnIt, lastUpdate]
|
`;
|
||||||
);
|
const params: SQLiteValue[] = [contentId, chapterId, authorId, version, content, wordsCount, timeOnIt, lastUpdate];
|
||||||
return result.changes > 0;
|
const insertResult: RunResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
return insertResult.changes > 0;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le contenu du chapitre.` : `Unable to insert chapter content.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le contenu du chapitre.` : `Unable to insert chapter content.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteChapterContentById(id: string, lang: "fr" | "en"):Promise<BookChapterContentTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches the complete chapter content record by its content ID.
|
||||||
|
* @param contentId - The ID of the content to fetch.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns A promise resolving to an array of book chapter content records.
|
||||||
|
*/
|
||||||
|
static async fetchCompleteChapterContentById(contentId: string, lang: "fr" | "en"): Promise<BookChapterContentTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(`SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update FROM book_chapter_content WHERE content_id = ?`, [id]) as BookChapterContentTable[];
|
const query: string = 'SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update FROM book_chapter_content WHERE content_id = ?';
|
||||||
} catch (e:unknown){
|
const params: SQLiteValue[] = [contentId];
|
||||||
if (e instanceof Error) {
|
const completeChapterContent: BookChapterContentTable[] = db.all(query, params) as BookChapterContentTable[];
|
||||||
|
return completeChapterContent;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu de chapitre complet.` : `Unable to retrieve complete chapter content.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu de chapitre complet.` : `Unable to retrieve complete chapter content.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a complete chapter with its content by joining chapters and chapter content tables.
|
||||||
|
* @param userId - The ID of the user/author.
|
||||||
|
* @param chapterId - The ID of the chapter.
|
||||||
|
* @param version - The version number of the content to fetch.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns The chapter content query result with chapter metadata.
|
||||||
|
* @throws Error if no chapter is found with the specified ID.
|
||||||
|
*/
|
||||||
public static fetchWholeChapter(userId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): ChapterContentQueryResult {
|
public static fetchWholeChapter(userId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): ChapterContentQueryResult {
|
||||||
let result: ChapterContentQueryResult | null;
|
let wholeChapter: ChapterContentQueryResult | null;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query: string = 'SELECT chapter.chapter_id as chapter_id, chapter.title as title, chapter.chapter_order, chapter.words_count, content.content AS content, content.version as version FROM book_chapters AS chapter LEFT JOIN book_chapter_content AS content ON content.chapter_id = chapter.chapter_id AND content.version = ? WHERE chapter.chapter_id = ? AND chapter.author_id = ?';
|
const query: string = `
|
||||||
result = db.get(query, [version, chapterId, userId]) as ChapterContentQueryResult | null;
|
SELECT
|
||||||
} catch (e: unknown) {
|
chapter.chapter_id as chapter_id,
|
||||||
if (e instanceof Error) {
|
chapter.title as title,
|
||||||
console.error(`DB Error: ${e.message}`);
|
chapter.chapter_order,
|
||||||
|
chapter.words_count,
|
||||||
|
content.content AS content,
|
||||||
|
content.version as version
|
||||||
|
FROM book_chapters AS chapter
|
||||||
|
LEFT JOIN book_chapter_content AS content ON content.chapter_id = chapter.chapter_id AND content.version = ?
|
||||||
|
WHERE chapter.chapter_id = ? AND chapter.author_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [version, chapterId, userId];
|
||||||
|
wholeChapter = db.get(query, params) as ChapterContentQueryResult | 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 chapitre.` : `Unable to retrieve chapter.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le chapitre.` : `Unable to retrieve chapter.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!wholeChapter) {
|
||||||
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cet ID.` : `No chapter found with this ID.`);
|
throw new Error(lang === 'fr' ? `Aucun chapitre trouvé avec cet ID.` : `No chapter found with this ID.`);
|
||||||
}
|
}
|
||||||
return result;
|
return wholeChapter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
import { Database, QueryResult, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||||
import System from "../System.js";
|
import System from "../System.js";
|
||||||
|
|
||||||
export interface BookCharactersTable extends Record<string, SQLiteValue> {
|
export interface BookCharactersTable extends Record<string, SQLiteValue> {
|
||||||
@@ -71,71 +71,125 @@ export interface CompleteCharacterResult extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class CharacterRepo {
|
export default class CharacterRepo {
|
||||||
|
/**
|
||||||
|
* Fetches all characters for a specific book and 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 character results
|
||||||
|
*/
|
||||||
public static fetchCharacters(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): CharacterResult[] {
|
public static fetchCharacters(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): CharacterResult[] {
|
||||||
let result: CharacterResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.all('SELECT character_id, first_name, last_name, title, category, image, role, biography, history FROM book_characters WHERE book_id=? AND user_id=?', [bookId, userId]) as CharacterResult[];
|
const query: string = 'SELECT character_id, first_name, last_name, title, category, image, role, biography, history FROM book_characters WHERE book_id=? AND user_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (e instanceof Error) {
|
const characters: CharacterResult[] = db.all(query, params) as CharacterResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return characters;
|
||||||
|
} 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.` : `Unable to retrieve characters.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages.` : `Unable to retrieve characters.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new character to the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param characterId - The unique identifier for the new character
|
||||||
|
* @param encryptedName - The encrypted first name of the character
|
||||||
|
* @param encryptedLastName - The encrypted last name of the character
|
||||||
|
* @param encryptedTitle - The encrypted title of the character
|
||||||
|
* @param encryptedCategory - The encrypted category of the character
|
||||||
|
* @param encryptedImage - The encrypted image path of the character
|
||||||
|
* @param encryptedRole - The encrypted role of the character
|
||||||
|
* @param encryptedBiography - The encrypted biography of the character
|
||||||
|
* @param encryptedHistory - The encrypted history of the character
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The character ID if successful
|
||||||
|
*/
|
||||||
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, lang: 'fr' | 'en' = 'fr'): string {
|
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, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
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, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [characterId, bookId, userId, encryptedName, encryptedLastName, encryptedCategory, encryptedTitle, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO `book_characters` (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [characterId, bookId, userId, encryptedName, encryptedLastName, encryptedCategory, encryptedTitle, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
const insertResult: RunResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du personnage.` : `Error adding character.`);
|
||||||
|
}
|
||||||
|
return characterId;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le personnage.` : `Unable to add character.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le personnage.` : `Unable to add character.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du personnage.` : `Error adding character.`);
|
|
||||||
}
|
|
||||||
return characterId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new attribute for a character.
|
||||||
|
* @param attributeId - The unique identifier for the new attribute
|
||||||
|
* @param characterId - The unique identifier of the character
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param type - The attribute name/type
|
||||||
|
* @param name - The attribute value
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The attribute ID if successful
|
||||||
|
*/
|
||||||
static insertAttribute(attributeId: string, characterId: string, userId: string, type: string, name: string, lang: 'fr' | 'en' = 'fr'): string {
|
static insertAttribute(attributeId: string, characterId: string, userId: string, type: string, name: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO `book_characters_attributes` (attr_id, character_id, user_id, attribute_name, attribute_value, last_update) VALUES (?,?,?,?,?,?)', [attributeId, characterId, userId, type, name, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO `book_characters_attributes` (attr_id, character_id, user_id, attribute_name, attribute_value, last_update) VALUES (?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [attributeId, characterId, userId, type, name, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
const insertResult: RunResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'attribut.` : `Error adding attribute.`);
|
||||||
|
}
|
||||||
|
return attributeId;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'attribut.` : `Unable to add attribute.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'attribut.` : `Unable to add attribute.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'attribut.` : `Error adding attribute.`);
|
|
||||||
}
|
|
||||||
return attributeId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing character's information.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param id - The unique identifier of the character to update
|
||||||
|
* @param encryptedName - The encrypted first name of the character
|
||||||
|
* @param encryptedLastName - The encrypted last name of the character
|
||||||
|
* @param encryptedTitle - The encrypted title of the character
|
||||||
|
* @param encryptedCategory - The encrypted category of the character
|
||||||
|
* @param encryptedImage - The encrypted image path of the character
|
||||||
|
* @param encryptedRole - The encrypted role of the character
|
||||||
|
* @param encryptedBiography - The encrypted biography of the character
|
||||||
|
* @param encryptedHistory - The encrypted history of the character
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
static updateCharacter(userId: string, id: string, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
static updateCharacter(userId: string, id: string, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE `book_characters` SET `first_name`=?,`last_name`=?,`title`=?,`category`=?,`image`=?,`role`=?,`biography`=?,`history`=?,`last_update`=? WHERE `character_id`=? AND `user_id`=?', [encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, lastUpdate, id, userId]);
|
const query: string = 'UPDATE `book_characters` SET `first_name`=?,`last_name`=?,`title`=?,`category`=?,`image`=?,`role`=?,`biography`=?,`history`=?,`last_update`=? WHERE `character_id`=? AND `user_id`=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, lastUpdate, id, userId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le personnage.` : `Unable to update character.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le personnage.` : `Unable to update character.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -144,14 +198,23 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a character attribute from the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param attributeId - The unique identifier of the attribute to delete
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the deletion was successful, false otherwise
|
||||||
|
*/
|
||||||
static deleteAttribute(userId: string, attributeId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
static deleteAttribute(userId: string, attributeId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM `book_characters_attributes` WHERE `attr_id`=? AND `user_id`=?', [attributeId, userId]);
|
const query: string = 'DELETE FROM `book_characters_attributes` WHERE `attr_id`=? AND `user_id`=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [attributeId, userId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer l'attribut.` : `Unable to delete attribute.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer l'attribut.` : `Unable to delete attribute.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -160,57 +223,85 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all attributes for a specific character.
|
||||||
|
* @param characterId - The unique identifier of the character
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of attribute results
|
||||||
|
*/
|
||||||
static fetchAttributes(characterId: string, userId: string, lang: 'fr' | 'en' = 'fr'): AttributeResult[] {
|
static fetchAttributes(characterId: string, userId: string, lang: 'fr' | 'en' = 'fr'): AttributeResult[] {
|
||||||
let result: AttributeResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.all('SELECT attr_id, attribute_name, attribute_value FROM book_characters_attributes WHERE character_id=? AND user_id=?', [characterId, userId]) as AttributeResult[];
|
const query: string = 'SELECT attr_id, attribute_name, attribute_value FROM book_characters_attributes WHERE character_id=? AND user_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [characterId, userId];
|
||||||
if (e instanceof Error) {
|
const attributes: AttributeResult[] = db.all(query, params) as AttributeResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return attributes;
|
||||||
|
} 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.` : `Unable to retrieve attributes.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs.` : `Unable to retrieve attributes.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches complete character information including attributes, optionally filtered by character IDs.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param tags - An optional array of character IDs to filter by
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of complete character results with attributes
|
||||||
|
*/
|
||||||
static fetchCompleteCharacters(userId: string, bookId: string, tags: string[], lang: 'fr' | 'en' = 'fr'): CompleteCharacterResult[] {
|
static fetchCompleteCharacters(userId: string, bookId: string, tags: string[], lang: 'fr' | 'en' = 'fr'): CompleteCharacterResult[] {
|
||||||
let result: CompleteCharacterResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
let query: string = 'SELECT charac.character_id, first_name, last_name, category, title, role, biography, history, attribute_name, attribute_value 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 query: string = 'SELECT charac.character_id, first_name, last_name, category, title, role, biography, history, attribute_name, attribute_value 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];
|
let params: SQLiteValue[] = [userId, bookId];
|
||||||
if (tags && tags.length > 0) {
|
if (tags && tags.length > 0) {
|
||||||
const placeholders: string = tags.map((): string => '?').join(',');
|
const placeholders: string = tags.map((): string => '?').join(',');
|
||||||
query += ` AND charac.character_id IN (${placeholders})`;
|
query += ` AND charac.character_id IN (${placeholders})`;
|
||||||
values.push(...tags);
|
params.push(...tags);
|
||||||
}
|
}
|
||||||
result = db.all(query, values) as CompleteCharacterResult[];
|
const characters: CompleteCharacterResult[] = db.all(query, params) as CompleteCharacterResult[];
|
||||||
} catch (e: unknown) {
|
if (characters.length === 0) {
|
||||||
if (e instanceof Error) {
|
throw new Error(lang === 'fr' ? `Aucun personnage complet trouvé.` : `No complete characters found.`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
}
|
||||||
|
return characters;
|
||||||
|
} 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 complets.` : `Unable to retrieve complete characters.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages complets.` : `Unable to retrieve complete characters.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "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;
|
|
||||||
}
|
/**
|
||||||
static updateCharacterAttribute(userId: string, characterAttributeId: string, attributeName: string, attributeValue: string, lastUpdate: number,lang: "fr" | "en"):boolean {
|
* Updates an existing character attribute.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param characterAttributeId - The unique identifier of the attribute to update
|
||||||
|
* @param attributeName - The new attribute name
|
||||||
|
* @param attributeValue - The new attribute value
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
|
static updateCharacterAttribute(userId: string, characterAttributeId: string, attributeName: string, attributeValue: string, lastUpdate: number, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result:RunResult = db.run('UPDATE `book_characters_attributes` SET `attribute_name`=?,`attribute_value`=?, last_update=FROM_UNIXTIME(?) WHERE `attr_id`=UUID_TO_BIN(?) AND `user_id`=UUID_TO_BIN(?)', [attributeName, attributeValue, lastUpdate, characterAttributeId, userId]);
|
const query: string = 'UPDATE `book_characters_attributes` SET `attribute_name`=?,`attribute_value`=?, last_update=FROM_UNIXTIME(?) WHERE `attr_id`=UUID_TO_BIN(?) AND `user_id`=UUID_TO_BIN(?)';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [attributeName, attributeValue, lastUpdate, characterAttributeId, userId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'attribut du personnage.` : `Unable to update character attribute.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'attribut du personnage.` : `Unable to update character attribute.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -218,14 +309,24 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static isCharacterExist(userId: string, characterId: string,lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks if a character exists in the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param characterId - The unique identifier of the character to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the character exists, false otherwise
|
||||||
|
*/
|
||||||
|
static isCharacterExist(userId: string, characterId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_characters` WHERE `character_id`=? AND `user_id`=?', [characterId, userId]) || null;
|
const query: string = 'SELECT 1 FROM `book_characters` WHERE `character_id`=? AND `user_id`=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [characterId, userId];
|
||||||
} catch (e: unknown) {
|
const character: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return character !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du personnage.` : `Unable to check character existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du personnage.` : `Unable to check character existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -234,14 +335,23 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static isCharacterAttributeExist(userId: string, characterAttributeId: string,lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a character attribute exists in the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param characterAttributeId - The unique identifier of the attribute to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the attribute exists, false otherwise
|
||||||
|
*/
|
||||||
|
static isCharacterAttributeExist(userId: string, characterAttributeId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_characters_attributes` WHERE `attr_id`=? AND `user_id`=?', [characterAttributeId, userId]) || null;
|
const query: string = 'SELECT 1 FROM `book_characters_attributes` WHERE `attr_id`=? AND `user_id`=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [characterAttributeId, userId];
|
||||||
} catch (e: unknown) {
|
const attribute: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return attribute !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'attribut du personnage.` : `Unable to check character attribute existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'attribut du personnage.` : `Unable to check character attribute existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -249,13 +359,24 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all characters for a specific book asynchronously.
|
||||||
|
* @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 A promise resolving to an array of book characters
|
||||||
|
*/
|
||||||
static async fetchBookCharacters(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookCharactersTable[]> {
|
static async fetchBookCharacters(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookCharactersTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update FROM book_characters WHERE user_id=? AND book_id=?', [userId, bookId]) as BookCharactersTable[];
|
const query: string = 'SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update FROM book_characters WHERE user_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const characters: BookCharactersTable[] = db.all(query, params) as BookCharactersTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return characters;
|
||||||
|
} 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.` : `Unable to retrieve characters.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages.` : `Unable to retrieve characters.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -263,13 +384,23 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchBookCharactersAttributes(userId: string, characterId:string, lang: 'fr' | 'en'): Promise<BookCharactersAttributesTable[]> {
|
/**
|
||||||
|
* Fetches all attributes for a specific character asynchronously.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param characterId - The unique identifier of the character
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of character attributes
|
||||||
|
*/
|
||||||
|
static async fetchBookCharactersAttributes(userId: string, characterId: string, lang: 'fr' | 'en'): Promise<BookCharactersAttributesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update FROM book_characters_attributes WHERE user_id=? AND character_id=?', [userId, characterId]) as BookCharactersAttributesTable[];
|
const query: string = 'SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update FROM book_characters_attributes WHERE user_id=? AND character_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, characterId];
|
||||||
if (e instanceof Error) {
|
const attributes: BookCharactersAttributesTable[] = db.all(query, params) as BookCharactersAttributesTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return attributes;
|
||||||
|
} 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 des personnages.` : `Unable to retrieve character attributes.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs des personnages.` : `Unable to retrieve character attributes.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -277,13 +408,22 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced characters 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 character results
|
||||||
|
*/
|
||||||
static fetchSyncedCharacters(userId: string, lang: 'fr' | 'en'): SyncedCharacterResult[] {
|
static fetchSyncedCharacters(userId: string, lang: 'fr' | 'en'): SyncedCharacterResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT character_id, book_id, first_name, last_update FROM book_characters WHERE user_id = ?', [userId]) as SyncedCharacterResult[];
|
const query: string = 'SELECT character_id, book_id, first_name, last_update FROM book_characters WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedCharacters: SyncedCharacterResult[] = db.all(query, params) as SyncedCharacterResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedCharacters;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced characters.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages synchronisés.` : `Unable to retrieve synced characters.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -292,13 +432,22 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced character attributes 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 character attribute results
|
||||||
|
*/
|
||||||
static fetchSyncedCharacterAttributes(userId: string, lang: 'fr' | 'en'): SyncedCharacterAttributeResult[] {
|
static fetchSyncedCharacterAttributes(userId: string, lang: 'fr' | 'en'): SyncedCharacterAttributeResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT attr_id, character_id, attribute_name, last_update FROM book_characters_attributes WHERE user_id = ?', [userId]) as SyncedCharacterAttributeResult[];
|
const query: string = 'SELECT attr_id, character_id, attribute_name, last_update FROM book_characters_attributes WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedAttributes: SyncedCharacterAttributeResult[] = db.all(query, params) as SyncedCharacterAttributeResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedAttributes;
|
||||||
|
} 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 des personnages synchronisés.` : `Unable to retrieve synced character attributes.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs des personnages synchronisés.` : `Unable to retrieve synced character attributes.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -307,18 +456,34 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced character into the database.
|
||||||
|
* @param characterId - The unique identifier of the character
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param firstName - The first name of the character
|
||||||
|
* @param lastName - The last name of the character (nullable)
|
||||||
|
* @param category - The category of the character
|
||||||
|
* @param title - The title of the character (nullable)
|
||||||
|
* @param image - The image path of the character (nullable)
|
||||||
|
* @param role - The role of the character (nullable)
|
||||||
|
* @param biography - The biography of the character (nullable)
|
||||||
|
* @param history - The history of the character (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, false otherwise
|
||||||
|
*/
|
||||||
static insertSyncCharacter(characterId: string, bookId: string, userId: string, firstName: string, lastName: string | null, category: string, title: string | null, image: string | null, role: string | null, biography: string | null, history: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncCharacter(characterId: string, bookId: string, userId: string, firstName: string, lastName: string | null, category: string, title: string | null, image: string | null, role: string | null, biography: string | null, history: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_characters (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update)
|
||||||
`INSERT INTO book_characters (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [characterId, bookId, userId, firstName, lastName, category, title, image, role, biography, history, lastUpdate];
|
||||||
[characterId, bookId, userId, firstName, lastName, category, title, image, role, biography, history, lastUpdate]
|
const insertResult: RunResult = db.run(query, params);
|
||||||
);
|
return insertResult.changes > 0;
|
||||||
return result.changes > 0;
|
} catch (error: unknown) {
|
||||||
} catch (e: unknown) {
|
if (error instanceof Error) {
|
||||||
if (e instanceof Error) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le personnage.` : `Unable to insert character.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le personnage.` : `Unable to insert character.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -326,35 +491,52 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced character attribute into the database.
|
||||||
|
* @param attrId - The unique identifier of the attribute
|
||||||
|
* @param characterId - The unique identifier of the character
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param attributeName - The name of the attribute
|
||||||
|
* @param attributeValue - The value of the attribute
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
static insertSyncCharacterAttribute(attrId: string, characterId: string, userId: string, attributeName: string, attributeValue: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncCharacterAttribute(attrId: string, characterId: string, userId: string, attributeName: string, attributeValue: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_characters_attributes (attr_id, character_id, user_id, attribute_name, attribute_value, last_update)
|
||||||
`INSERT INTO book_characters_attributes (attr_id, character_id, user_id, attribute_name, attribute_value, last_update)
|
VALUES (?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [attrId, characterId, userId, attributeName, attributeValue, lastUpdate];
|
||||||
[attrId, characterId, userId, attributeName, attributeValue, lastUpdate]
|
const insertResult: RunResult = db.run(query, params);
|
||||||
);
|
return insertResult.changes > 0;
|
||||||
return result.changes > 0;
|
} catch (error: unknown) {
|
||||||
} catch (e: unknown) {
|
if (error instanceof Error) {
|
||||||
if (e instanceof Error) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer l'attribut du personnage.` : `Unable to insert character attribute.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer l'attribut du personnage.` : `Unable to insert character attribute.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteCharacterById(id: string, lang: "fr" | "en"):Promise<BookCharactersTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches a complete character by its ID.
|
||||||
|
* @param id - The unique identifier of the character
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book characters (typically one)
|
||||||
|
*/
|
||||||
|
static async fetchCompleteCharacterById(id: string, lang: "fr" | "en"): Promise<BookCharactersTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update
|
||||||
`SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update
|
|
||||||
FROM book_characters
|
FROM book_characters
|
||||||
WHERE character_id = ?`,
|
WHERE character_id = ?`;
|
||||||
[id]
|
const params: SQLiteValue[] = [id];
|
||||||
) as BookCharactersTable[];
|
const character: BookCharactersTable[] = db.all(query, params) as BookCharactersTable[];
|
||||||
} catch (e:unknown){
|
return character;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le personnage complet.` : `Unable to retrieve complete character.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le personnage complet.` : `Unable to retrieve complete character.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -362,17 +544,23 @@ export default class CharacterRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteCharacterAttributeById(id: string, lang: "fr" | "en"):Promise<BookCharactersAttributesTable[]> {
|
/**
|
||||||
|
* Fetches a complete character attribute by its ID.
|
||||||
|
* @param id - The unique identifier of the attribute
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of character attributes (typically one)
|
||||||
|
*/
|
||||||
|
static async fetchCompleteCharacterAttributeById(id: string, lang: "fr" | "en"): Promise<BookCharactersAttributesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update
|
||||||
`SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update
|
|
||||||
FROM book_characters_attributes
|
FROM book_characters_attributes
|
||||||
WHERE attr_id = ?`,
|
WHERE attr_id = ?`;
|
||||||
[id]
|
const params: SQLiteValue[] = [id];
|
||||||
) as BookCharactersAttributesTable[];
|
const attribute: BookCharactersAttributesTable[] = db.all(query, params) as BookCharactersAttributesTable[];
|
||||||
} catch (e:unknown){
|
return attribute;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer l'attribut de personnage complet.` : `Unable to retrieve complete character attribute.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer l'attribut de personnage complet.` : `Unable to retrieve complete character attribute.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {Database, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
import {ChapterBookResult, EritBooksTable} from "@/electron/database/repositories/book.repository";
|
|
||||||
|
|
||||||
export interface BookAIGuideLineTable extends Record<string, SQLiteValue> {
|
export interface BookAIGuideLineTable extends Record<string, SQLiteValue> {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
@@ -72,35 +71,111 @@ export interface GuideLineAIQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class GuidelineRepo {
|
export default class GuidelineRepo {
|
||||||
|
/**
|
||||||
|
* Fetches the guideline for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of guideline query results
|
||||||
|
* @throws Error if the guideline cannot be retrieved
|
||||||
|
*/
|
||||||
public static fetchGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineQuery[] {
|
public static fetchGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineQuery[] {
|
||||||
let result: GuideLineQuery[];
|
let guidelines: GuideLineQuery[];
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.all('SELECT * FROM book_guide_line WHERE book_id=? AND user_id=?', [bookId, userId]) as GuideLineQuery[];
|
const query: string = 'SELECT * FROM book_guide_line WHERE book_id=? AND user_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
if (e instanceof Error) {
|
guidelines = db.all(query, params) as GuideLineQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return guidelines;
|
||||||
}
|
}
|
||||||
static updateGuideLine(userId: string, bookId: string, encryptedTone: string, encryptedAtmosphere: string, encryptedWritingStyle: string, encryptedThemes: string, encryptedSymbolism: string, encryptedMotifs: string, encryptedNarrativeVoice: string, encryptedPacing: string, encryptedKeyMessages: string, encryptedIntendedAudience: string, lang: 'fr' | 'en'): boolean {
|
|
||||||
|
/**
|
||||||
|
* Updates or inserts a guideline for a specific book.
|
||||||
|
* If the guideline exists, it updates it; otherwise, it inserts a new one.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param encryptedTone - The encrypted tone value
|
||||||
|
* @param encryptedAtmosphere - The encrypted atmosphere value
|
||||||
|
* @param encryptedWritingStyle - The encrypted writing style value
|
||||||
|
* @param encryptedThemes - The encrypted themes value
|
||||||
|
* @param encryptedSymbolism - The encrypted symbolism value
|
||||||
|
* @param encryptedMotifs - The encrypted motifs value
|
||||||
|
* @param encryptedNarrativeVoice - The encrypted narrative voice value
|
||||||
|
* @param encryptedPacing - The encrypted pacing value
|
||||||
|
* @param encryptedKeyMessages - The encrypted key messages value
|
||||||
|
* @param encryptedIntendedAudience - The encrypted intended audience value
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the operation was successful
|
||||||
|
* @throws Error if the guideline cannot be updated or inserted
|
||||||
|
*/
|
||||||
|
static updateGuideLine(
|
||||||
|
userId: string,
|
||||||
|
bookId: string,
|
||||||
|
encryptedTone: string,
|
||||||
|
encryptedAtmosphere: string,
|
||||||
|
encryptedWritingStyle: string,
|
||||||
|
encryptedThemes: string,
|
||||||
|
encryptedSymbolism: string,
|
||||||
|
encryptedMotifs: string,
|
||||||
|
encryptedNarrativeVoice: string,
|
||||||
|
encryptedPacing: string,
|
||||||
|
encryptedKeyMessages: string,
|
||||||
|
encryptedIntendedAudience: string,
|
||||||
|
lang: 'fr' | 'en'
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_guide_line SET tone=?, atmosphere=?, writing_style=?, themes=?, symbolism=?, motifs=?, narrative_voice=?, pacing=?, key_messages=?, last_update=? WHERE user_id=? AND book_id=?', [encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedKeyMessages, System.timeStampInSeconds(), userId, bookId]);
|
const updateQuery: string = 'UPDATE book_guide_line SET tone=?, atmosphere=?, writing_style=?, themes=?, symbolism=?, motifs=?, narrative_voice=?, pacing=?, key_messages=?, last_update=? WHERE user_id=? AND book_id=?';
|
||||||
if (result.changes > 0) {
|
const updateParams: SQLiteValue[] = [
|
||||||
|
encryptedTone,
|
||||||
|
encryptedAtmosphere,
|
||||||
|
encryptedWritingStyle,
|
||||||
|
encryptedThemes,
|
||||||
|
encryptedSymbolism,
|
||||||
|
encryptedMotifs,
|
||||||
|
encryptedNarrativeVoice,
|
||||||
|
encryptedPacing,
|
||||||
|
encryptedKeyMessages,
|
||||||
|
System.timeStampInSeconds(),
|
||||||
|
userId,
|
||||||
|
bookId
|
||||||
|
];
|
||||||
|
const updateResult: RunResult = db.run(updateQuery, updateParams);
|
||||||
|
|
||||||
|
if (updateResult.changes > 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
const insert:RunResult = db.run('INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedIntendedAudience, encryptedKeyMessages, System.timeStampInSeconds()]);
|
const insertQuery: string = 'INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
return insert.changes > 0;
|
const insertParams: SQLiteValue[] = [
|
||||||
|
userId,
|
||||||
|
bookId,
|
||||||
|
encryptedTone,
|
||||||
|
encryptedAtmosphere,
|
||||||
|
encryptedWritingStyle,
|
||||||
|
encryptedThemes,
|
||||||
|
encryptedSymbolism,
|
||||||
|
encryptedMotifs,
|
||||||
|
encryptedNarrativeVoice,
|
||||||
|
encryptedPacing,
|
||||||
|
encryptedIntendedAudience,
|
||||||
|
encryptedKeyMessages,
|
||||||
|
System.timeStampInSeconds()
|
||||||
|
];
|
||||||
|
const insertResult: RunResult = db.run(insertQuery, insertParams);
|
||||||
|
return insertResult.changes > 0;
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la ligne directrice.` : `Unable to update guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la ligne directrice.` : `Unable to update guideline.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -108,19 +183,76 @@ export default class GuidelineRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static insertAIGuideLine(userId: string, bookId: string, narrativeType: number, dialogueType: number, encryptedPlotSummary: string, encryptedToneAtmosphere: string, verbTense: number, language: number, encryptedThemes: string, lang: 'fr' | 'en'): boolean {
|
|
||||||
|
/**
|
||||||
|
* Inserts or updates an AI guideline for a specific book.
|
||||||
|
* If the AI guideline exists, it updates it; otherwise, it inserts a new one.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param narrativeType - The narrative type identifier
|
||||||
|
* @param dialogueType - The dialogue type identifier
|
||||||
|
* @param encryptedPlotSummary - The encrypted plot summary
|
||||||
|
* @param encryptedToneAtmosphere - The encrypted tone and atmosphere value
|
||||||
|
* @param verbTense - The verb tense identifier
|
||||||
|
* @param language - The language identifier
|
||||||
|
* @param encryptedThemes - The encrypted themes value
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the operation was successful
|
||||||
|
* @throws Error if the AI guideline cannot be inserted or updated
|
||||||
|
*/
|
||||||
|
static insertAIGuideLine(
|
||||||
|
userId: string,
|
||||||
|
bookId: string,
|
||||||
|
narrativeType: number,
|
||||||
|
dialogueType: number,
|
||||||
|
encryptedPlotSummary: string,
|
||||||
|
encryptedToneAtmosphere: string,
|
||||||
|
verbTense: number,
|
||||||
|
language: number,
|
||||||
|
encryptedThemes: string,
|
||||||
|
lang: 'fr' | 'en'
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
let result: RunResult = db.run('UPDATE book_ai_guide_line SET narrative_type=?, dialogue_type=?, global_resume=?, atmosphere=?, verbe_tense=?, langue=?, themes=?, last_update=? WHERE user_id=? AND book_id=?', [narrativeType ? narrativeType : null, dialogueType ? dialogueType : null, encryptedPlotSummary, encryptedToneAtmosphere, verbTense ? verbTense : null, language ? language : null, encryptedThemes, System.timeStampInSeconds(), userId, bookId]);
|
const updateQuery: string = 'UPDATE book_ai_guide_line SET narrative_type=?, dialogue_type=?, global_resume=?, atmosphere=?, verbe_tense=?, langue=?, themes=?, last_update=? WHERE user_id=? AND book_id=?';
|
||||||
if (result.changes > 0) {
|
const updateParams: SQLiteValue[] = [
|
||||||
|
narrativeType ? narrativeType : null,
|
||||||
|
dialogueType ? dialogueType : null,
|
||||||
|
encryptedPlotSummary,
|
||||||
|
encryptedToneAtmosphere,
|
||||||
|
verbTense ? verbTense : null,
|
||||||
|
language ? language : null,
|
||||||
|
encryptedThemes,
|
||||||
|
System.timeStampInSeconds(),
|
||||||
|
userId,
|
||||||
|
bookId
|
||||||
|
];
|
||||||
|
const updateResult: RunResult = db.run(updateQuery, updateParams);
|
||||||
|
|
||||||
|
if (updateResult.changes > 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
result = db.run('INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedPlotSummary, encryptedThemes, verbTense ? verbTense : null, narrativeType ? narrativeType : null, language ? language : null, dialogueType ? dialogueType : null, encryptedToneAtmosphere, encryptedToneAtmosphere, encryptedPlotSummary, System.timeStampInSeconds()]);
|
const insertQuery: string = 'INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)';
|
||||||
return result.changes > 0;
|
const insertParams: SQLiteValue[] = [
|
||||||
|
userId,
|
||||||
|
bookId,
|
||||||
|
encryptedPlotSummary,
|
||||||
|
encryptedThemes,
|
||||||
|
verbTense ? verbTense : null,
|
||||||
|
narrativeType ? narrativeType : null,
|
||||||
|
language ? language : null,
|
||||||
|
dialogueType ? dialogueType : null,
|
||||||
|
encryptedToneAtmosphere,
|
||||||
|
encryptedToneAtmosphere,
|
||||||
|
encryptedPlotSummary,
|
||||||
|
System.timeStampInSeconds()
|
||||||
|
];
|
||||||
|
const insertResult: RunResult = db.run(insertQuery, insertParams);
|
||||||
|
return insertResult.changes > 0;
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -129,58 +261,103 @@ export default class GuidelineRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the AI guideline for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The AI guideline query result
|
||||||
|
* @throws Error if the AI guideline cannot be retrieved or is not found
|
||||||
|
*/
|
||||||
static fetchGuideLineAI(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineAIQuery {
|
static fetchGuideLineAI(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineAIQuery {
|
||||||
let result: GuideLineAIQuery | null;
|
let aiGuideline: GuideLineAIQuery | null;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.get('SELECT narrative_type, dialogue_type, global_resume, atmosphere, verbe_tense, langue, themes, current_resume FROM book_ai_guide_line WHERE user_id=? AND book_id=?', [userId, bookId]) as GuideLineAIQuery | null;
|
const query: string = 'SELECT narrative_type, dialogue_type, global_resume, atmosphere, verbe_tense, langue, themes, current_resume FROM book_ai_guide_line WHERE user_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
aiGuideline = db.get(query, params) as GuideLineAIQuery | null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!aiGuideline) {
|
||||||
throw new Error(lang === 'fr' ? `Ligne directrice IA non trouvée.` : `AI guideline not found.`);
|
throw new Error(lang === 'fr' ? `Ligne directrice IA non trouvée.` : `AI guideline not found.`);
|
||||||
}
|
}
|
||||||
return result;
|
return aiGuideline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the book AI guideline table data for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book AI guideline table entries
|
||||||
|
* @throws Error if the AI guideline cannot be retrieved
|
||||||
|
*/
|
||||||
static async fetchBookAIGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookAIGuideLineTable[]> {
|
static async fetchBookAIGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookAIGuideLineTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update FROM book_ai_guide_line WHERE user_id=? AND book_id=?', [userId, bookId]) as BookAIGuideLineTable[];
|
const query: string = 'SELECT user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update FROM book_ai_guide_line WHERE user_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const aiGuidelines: BookAIGuideLineTable[] = db.all(query, params) as BookAIGuideLineTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return aiGuidelines;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the book guideline table data for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book guideline table entries
|
||||||
|
* @throws Error if the guideline cannot be retrieved
|
||||||
|
*/
|
||||||
static async fetchBookGuideLineTable(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookGuideLineTable[]> {
|
static async fetchBookGuideLineTable(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookGuideLineTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update FROM book_guide_line WHERE user_id=? AND book_id=?', [userId, bookId]) as BookGuideLineTable[];
|
const query: string = 'SELECT user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update FROM book_guide_line WHERE user_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const guidelines: BookGuideLineTable[] = db.all(query, params) as BookGuideLineTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return guidelines;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced guidelines for a specific user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced guideline results containing book_id and last_update
|
||||||
|
* @throws Error if the synced guidelines cannot be retrieved
|
||||||
|
*/
|
||||||
static fetchSyncedGuideLine(userId: string, lang: 'fr' | 'en'): SyncedGuideLineResult[] {
|
static fetchSyncedGuideLine(userId: string, lang: 'fr' | 'en'): SyncedGuideLineResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT book_id, last_update FROM book_guide_line WHERE user_id = ?', [userId]) as SyncedGuideLineResult[];
|
const query: string = 'SELECT book_id, last_update FROM book_guide_line WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedGuidelines: SyncedGuideLineResult[] = db.all(query, params) as SyncedGuideLineResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedGuidelines;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices synchronisées.` : `Unable to retrieve synced guidelines.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices synchronisées.` : `Unable to retrieve synced guidelines.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -189,13 +366,23 @@ export default class GuidelineRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced AI guidelines for a specific user.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced AI guideline results containing book_id and last_update
|
||||||
|
* @throws Error if the synced AI guidelines cannot be retrieved
|
||||||
|
*/
|
||||||
static fetchSyncedAIGuideLine(userId: string, lang: 'fr' | 'en'): SyncedAIGuideLineResult[] {
|
static fetchSyncedAIGuideLine(userId: string, lang: 'fr' | 'en'): SyncedAIGuideLineResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT book_id, last_update FROM book_ai_guide_line WHERE user_id = ?', [userId]) as SyncedAIGuideLineResult[];
|
const query: string = 'SELECT book_id, last_update FROM book_ai_guide_line WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedAIGuidelines: SyncedAIGuideLineResult[] = db.all(query, params) as SyncedAIGuideLineResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedAIGuidelines;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices IA synchronisées.` : `Unable to retrieve synced AI guidelines.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices IA synchronisées.` : `Unable to retrieve synced AI guidelines.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -203,36 +390,129 @@ export default class GuidelineRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static insertSyncAIGuideLine(userId: string, bookId: string, globalResume: string | null, themes: string | null, verbeTense: number | null, narrativeType: number | null, langue: number | null, dialogueType: number | null, tone: string | null, atmosphere: string | null, currentResume: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced AI guideline for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param globalResume - The global resume value (nullable)
|
||||||
|
* @param themes - The themes value (nullable)
|
||||||
|
* @param verbeTense - The verb tense identifier (nullable)
|
||||||
|
* @param narrativeType - The narrative type identifier (nullable)
|
||||||
|
* @param langue - The language identifier (nullable)
|
||||||
|
* @param dialogueType - The dialogue type identifier (nullable)
|
||||||
|
* @param tone - The tone value (nullable)
|
||||||
|
* @param atmosphere - The atmosphere value (nullable)
|
||||||
|
* @param currentResume - The current resume value (nullable)
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the insertion was successful
|
||||||
|
* @throws Error if the AI guideline cannot be inserted
|
||||||
|
*/
|
||||||
|
static insertSyncAIGuideLine(
|
||||||
|
userId: string,
|
||||||
|
bookId: string,
|
||||||
|
globalResume: string | null,
|
||||||
|
themes: string | null,
|
||||||
|
verbeTense: number | null,
|
||||||
|
narrativeType: number | null,
|
||||||
|
langue: number | null,
|
||||||
|
dialogueType: number | null,
|
||||||
|
tone: string | null,
|
||||||
|
atmosphere: string | null,
|
||||||
|
currentResume: string | null,
|
||||||
|
lastUpdate: number,
|
||||||
|
lang: 'fr' | 'en'
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update)
|
||||||
`INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [
|
||||||
[userId, bookId, globalResume, themes, verbeTense, narrativeType, langue, dialogueType, tone, atmosphere, currentResume, lastUpdate]
|
userId,
|
||||||
);
|
bookId,
|
||||||
return result.changes > 0;
|
globalResume,
|
||||||
} catch (e: unknown) {
|
themes,
|
||||||
if (e instanceof Error) {
|
verbeTense,
|
||||||
console.error(`DB Error: ${e.message}`);
|
narrativeType,
|
||||||
|
langue,
|
||||||
|
dialogueType,
|
||||||
|
tone,
|
||||||
|
atmosphere,
|
||||||
|
currentResume,
|
||||||
|
lastUpdate
|
||||||
|
];
|
||||||
|
const insertResult: RunResult = db.run(query, params);
|
||||||
|
return insertResult.changes > 0;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static insertSyncGuideLine(userId: string, bookId: string, tone: string | null, atmosphere: string | null, writingStyle: string | null, themes: string | null, symbolism: string | null, motifs: string | null, narrativeVoice: string | null, pacing: string | null, intendedAudience: string | null, keyMessages: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced guideline for a specific book.
|
||||||
|
* @param userId - The user identifier
|
||||||
|
* @param bookId - The book identifier
|
||||||
|
* @param tone - The tone value (nullable)
|
||||||
|
* @param atmosphere - The atmosphere value (nullable)
|
||||||
|
* @param writingStyle - The writing style value (nullable)
|
||||||
|
* @param themes - The themes value (nullable)
|
||||||
|
* @param symbolism - The symbolism value (nullable)
|
||||||
|
* @param motifs - The motifs value (nullable)
|
||||||
|
* @param narrativeVoice - The narrative voice value (nullable)
|
||||||
|
* @param pacing - The pacing value (nullable)
|
||||||
|
* @param intendedAudience - The intended audience value (nullable)
|
||||||
|
* @param keyMessages - The key messages value (nullable)
|
||||||
|
* @param lastUpdate - The last update timestamp
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the insertion was successful
|
||||||
|
* @throws Error if the guideline cannot be inserted
|
||||||
|
*/
|
||||||
|
static insertSyncGuideLine(
|
||||||
|
userId: string,
|
||||||
|
bookId: string,
|
||||||
|
tone: string | null,
|
||||||
|
atmosphere: string | null,
|
||||||
|
writingStyle: string | null,
|
||||||
|
themes: string | null,
|
||||||
|
symbolism: string | null,
|
||||||
|
motifs: string | null,
|
||||||
|
narrativeVoice: string | null,
|
||||||
|
pacing: string | null,
|
||||||
|
intendedAudience: string | null,
|
||||||
|
keyMessages: string | null,
|
||||||
|
lastUpdate: number,
|
||||||
|
lang: 'fr' | 'en'
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update)
|
||||||
`INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [
|
||||||
[userId, bookId, tone, atmosphere, writingStyle, themes, symbolism, motifs, narrativeVoice, pacing, intendedAudience, keyMessages, lastUpdate]
|
userId,
|
||||||
);
|
bookId,
|
||||||
return result.changes > 0;
|
tone,
|
||||||
} catch (e: unknown) {
|
atmosphere,
|
||||||
if (e instanceof Error) {
|
writingStyle,
|
||||||
console.error(`DB Error: ${e.message}`);
|
themes,
|
||||||
|
symbolism,
|
||||||
|
motifs,
|
||||||
|
narrativeVoice,
|
||||||
|
pacing,
|
||||||
|
intendedAudience,
|
||||||
|
keyMessages,
|
||||||
|
lastUpdate
|
||||||
|
];
|
||||||
|
const insertResult: RunResult = db.run(query, params);
|
||||||
|
return insertResult.changes > 0;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice.` : `Unable to insert guideline.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice.` : `Unable to insert guideline.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, QueryResult, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
|
|
||||||
export interface BookIncidentsTable extends Record<string, SQLiteValue> {
|
export interface BookIncidentsTable extends Record<string, SQLiteValue> {
|
||||||
@@ -25,13 +25,24 @@ export interface IncidentQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class IncidentRepository {
|
export default class IncidentRepository {
|
||||||
public static fetchAllIncitentIncidents(userId:string,bookId:string, lang: 'fr' | 'en'):IncidentQuery[]{
|
/**
|
||||||
|
* Fetches all incidents for a specific book belonging to a user.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of incidents with their ID, title, and summary
|
||||||
|
* @throws Error if the database query fails
|
||||||
|
*/
|
||||||
|
public static fetchAllIncidents(userId: string, bookId: string, lang: 'fr' | 'en'): IncidentQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT incident_id, title, summary FROM book_incidents WHERE author_id=? AND book_id=?', [userId, bookId]) as IncidentQuery[];
|
const query: string = 'SELECT incident_id, title, summary FROM book_incidents WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const incidents: IncidentQuery[] = db.all(query, params) as IncidentQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return incidents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -40,34 +51,58 @@ export default class IncidentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new incident into the database.
|
||||||
|
* @param incidentId - The unique ID for the new incident
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param encryptedName - The encrypted title of the incident
|
||||||
|
* @param hashedName - The hashed title of the incident
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The incident ID if insertion was successful
|
||||||
|
* @throws Error if the database insertion fails
|
||||||
|
*/
|
||||||
public static insertNewIncident(incidentId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
public static insertNewIncident(incidentId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
||||||
let result: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_incidents (incident_id,author_id, book_id, title, hashed_title, last_update) VALUES (?,?,?,?,?,?)', [incidentId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_incidents (incident_id,author_id, book_id, title, hashed_title, last_update) VALUES (?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [incidentId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément déclencheur.` : `Unable to add incident.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément déclencheur.` : `Unable to add incident.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément déclencheur.` : `Error adding incident.`);
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément déclencheur.` : `Error adding incident.`);
|
||||||
}
|
}
|
||||||
return incidentId;
|
return incidentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an incident from the database.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param incidentId - The ID of the incident to delete
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the incident was deleted, false otherwise
|
||||||
|
* @throws Error if the database deletion fails
|
||||||
|
*/
|
||||||
public static deleteIncident(userId: string, bookId: string, incidentId: string, lang: 'fr' | 'en'): boolean {
|
public static deleteIncident(userId: string, bookId: string, incidentId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_incidents WHERE author_id=? AND book_id=? AND incident_id=?', [userId, bookId, incidentId]);
|
const query: string = 'DELETE FROM book_incidents WHERE author_id=? AND book_id=? AND incident_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, bookId, incidentId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément déclencheur.` : `Unable to delete incident.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément déclencheur.` : `Unable to delete incident.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -75,14 +110,30 @@ export default class IncidentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing incident in the database.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param incidentId - The ID of the incident to update
|
||||||
|
* @param encryptedIncidentName - The new encrypted title
|
||||||
|
* @param incidentHashedName - The new hashed title
|
||||||
|
* @param incidentSummary - The new summary
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the incident was updated, false otherwise
|
||||||
|
* @throws Error if the database update fails
|
||||||
|
*/
|
||||||
public static updateIncident(userId: string, bookId: string, incidentId: string, encryptedIncidentName: string, incidentHashedName: string, incidentSummary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
public static updateIncident(userId: string, bookId: string, incidentId: string, encryptedIncidentName: string, incidentHashedName: string, incidentSummary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_incidents SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND incident_id=?', [encryptedIncidentName, incidentHashedName, incidentSummary, lastUpdate, userId, bookId, incidentId]);
|
const query: string = 'UPDATE book_incidents SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND incident_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [encryptedIncidentName, incidentHashedName, incidentSummary, lastUpdate, userId, bookId, incidentId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'incident.` : `Unable to update incident.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'incident.` : `Unable to update incident.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -90,26 +141,49 @@ export default class IncidentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all incidents for a book with complete information.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of complete incident records
|
||||||
|
* @throws Error if the database query fails
|
||||||
|
*/
|
||||||
static async fetchBookIncidents(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookIncidentsTable[]> {
|
static async fetchBookIncidents(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookIncidentsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update FROM book_incidents WHERE author_id=? AND book_id=?', [userId, bookId]) as BookIncidentsTable[];
|
const query: string = 'SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update FROM book_incidents WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const incidents: BookIncidentsTable[] = db.all(query, params) as BookIncidentsTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return incidents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced incidents for a user across all books.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced incident records with minimal information
|
||||||
|
* @throws Error if the database query fails
|
||||||
|
*/
|
||||||
static fetchSyncedIncidents(userId: string, lang: 'fr' | 'en'): SyncedIncidentResult[] {
|
static fetchSyncedIncidents(userId: string, lang: 'fr' | 'en'): SyncedIncidentResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT incident_id, book_id, title, last_update FROM book_incidents WHERE author_id = ?', [userId]) as SyncedIncidentResult[];
|
const query: string = 'SELECT incident_id, book_id, title, last_update FROM book_incidents WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedIncidents: SyncedIncidentResult[] = db.all(query, params) as SyncedIncidentResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedIncidents;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents synchronisés.` : `Unable to retrieve synced incidents.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents synchronisés.` : `Unable to retrieve synced incidents.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -117,49 +191,82 @@ export default class IncidentRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced incident into the database.
|
||||||
|
* @param incidentId - The unique ID for the incident
|
||||||
|
* @param authorId - The ID of the author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param title - The encrypted title
|
||||||
|
* @param hashedTitle - The hashed title
|
||||||
|
* @param summary - The encrypted summary (can be null)
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the incident was inserted, false otherwise
|
||||||
|
* @throws Error if the database insertion fails
|
||||||
|
*/
|
||||||
static insertSyncIncident(incidentId: string, authorId: string, bookId: string, title: string, hashedTitle: string, summary: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncIncident(incidentId: string, authorId: string, bookId: string, title: string, hashedTitle: string, summary: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update)
|
||||||
`INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update)
|
VALUES (?, ?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [incidentId, authorId, bookId, title, hashedTitle, summary, lastUpdate];
|
||||||
[incidentId, authorId, bookId, title, hashedTitle, summary, lastUpdate]
|
const insertResult: RunResult = db.run(query, params);
|
||||||
);
|
return insertResult.changes > 0;
|
||||||
return result.changes > 0;
|
} catch (error: unknown) {
|
||||||
} catch (e: unknown) {
|
if (error instanceof Error) {
|
||||||
if (e instanceof Error) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer l'incident.` : `Unable to insert incident.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer l'incident.` : `Unable to insert incident.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteIncidentById(id: string, lang: "fr" | "en"):Promise<BookIncidentsTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches complete incident information by its ID.
|
||||||
|
* @param id - The ID of the incident to fetch
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array containing the incident record (empty if not found)
|
||||||
|
* @throws Error if the database query fails
|
||||||
|
*/
|
||||||
|
static async fetchCompleteIncidentById(id: string, lang: "fr" | "en"): Promise<BookIncidentsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update
|
||||||
`SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update
|
|
||||||
FROM book_incidents
|
FROM book_incidents
|
||||||
WHERE incident_id = ?`,
|
WHERE incident_id = ?`;
|
||||||
[id]
|
const params: SQLiteValue[] = [id];
|
||||||
) as BookIncidentsTable[];
|
const incident: BookIncidentsTable[] = db.all(query, params) as BookIncidentsTable[];
|
||||||
} catch (e:unknown){
|
return incident;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer l'incident complet.` : `Unable to retrieve complete incident.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer l'incident complet.` : `Unable to retrieve complete incident.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static incidentExist(userId: string, bookId: string, incident_id: string,lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks if an incident exists in the database.
|
||||||
|
* @param userId - The ID of the user (author)
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param incidentId - The ID of the incident to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the incident exists, false otherwise
|
||||||
|
* @throws Error if the database query fails
|
||||||
|
*/
|
||||||
|
static incidentExist(userId: string, bookId: string, incidentId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM book_incidents WHERE book_id=? AND incident_id=? AND author_id=?', [bookId, incident_id, userId]) || null;
|
const query: string = 'SELECT 1 FROM book_incidents WHERE book_id=? AND incident_id=? AND author_id=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [bookId, incidentId, userId];
|
||||||
} catch (e: unknown) {
|
const existingIncident: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingIncident !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'incident.` : `Unable to check incident existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'incident.` : `Unable to check incident existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, QueryResult, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
|
|
||||||
export interface BookIssuesTable extends Record<string, SQLiteValue> {
|
export interface BookIssuesTable extends Record<string, SQLiteValue> {
|
||||||
@@ -23,13 +23,23 @@ export interface IssueQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class IssueRepository {
|
export default class IssueRepository {
|
||||||
public static fetchIssuesFromBook(userId:string,bookId:string, lang: 'fr' | 'en'):IssueQuery[]{
|
/**
|
||||||
|
* Fetches all issues associated with a specific book.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns An array of issues with their IDs and names.
|
||||||
|
*/
|
||||||
|
public static fetchIssuesFromBook(userId: string, bookId: string, lang: 'fr' | 'en'): IssueQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT issue_id, name FROM book_issues WHERE author_id=? AND book_id=?', [userId, bookId]) as IssueQuery[];
|
const query: string = 'SELECT issue_id, name FROM book_issues WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const issues: IssueQuery[] = db.all(query, params) as IssueQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return issues;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -37,30 +47,45 @@ export default class IssueRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new issue into the database after verifying it doesn't already exist.
|
||||||
|
* @param issueId - The unique identifier for the new issue.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param encryptedName - The encrypted name of the issue.
|
||||||
|
* @param hashedName - The hashed name of the issue for duplicate checking.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns The issue ID if successfully inserted.
|
||||||
|
*/
|
||||||
public static insertNewIssue(issueId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
public static insertNewIssue(issueId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
||||||
let existingResult: QueryResult | null;
|
let existingIssue: QueryResult | null;
|
||||||
let insertResult: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
existingResult = db.get('SELECT issue_id FROM book_issues WHERE hashed_issue_name=? AND book_id=? AND author_id=?', [hashedName, bookId, userId]);
|
const checkQuery: string = 'SELECT issue_id FROM book_issues WHERE hashed_issue_name=? AND book_id=? AND author_id=?';
|
||||||
} catch (e: unknown) {
|
const checkParams: SQLiteValue[] = [hashedName, bookId, userId];
|
||||||
if (e instanceof Error) {
|
existingIssue = db.get(checkQuery, checkParams);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de la problématique.` : `Unable to verify issue existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de la problématique.` : `Unable to verify issue existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (existingResult !== null) {
|
if (existingIssue !== null) {
|
||||||
throw new Error(lang === 'fr' ? `La problématique existe déjà.` : `This issue already exists.`);
|
throw new Error(lang === 'fr' ? `La problématique existe déjà.` : `This issue already exists.`);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
insertResult = db.run('INSERT INTO book_issues (issue_id,author_id, book_id, name, hashed_issue_name, last_update) VALUES (?,?,?,?,?,?)', [issueId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
|
const insertQuery: string = 'INSERT INTO book_issues (issue_id, author_id, book_id, name, hashed_issue_name, last_update) VALUES (?, ?, ?, ?, ?, ?)';
|
||||||
} catch (e: unknown) {
|
const insertParams: SQLiteValue[] = [issueId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(insertQuery, insertParams);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter la problématique.` : `Unable to add issue.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter la problématique.` : `Unable to add issue.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -73,14 +98,23 @@ export default class IssueRepository {
|
|||||||
return issueId;
|
return issueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an issue from the database.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param issueId - The unique identifier of the issue to delete.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the issue was successfully deleted, false otherwise.
|
||||||
|
*/
|
||||||
public static deleteIssue(userId: string, issueId: string, lang: 'fr' | 'en'): boolean {
|
public static deleteIssue(userId: string, issueId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_issues WHERE author_id=? AND issue_id=?', [userId, issueId]);
|
const query: string = 'DELETE FROM book_issues WHERE author_id=? AND issue_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, issueId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer la problématique.` : `Unable to delete issue.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer la problématique.` : `Unable to delete issue.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -88,26 +122,47 @@ export default class IssueRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all complete issue records for a specific book.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns A promise resolving to an array of complete issue records.
|
||||||
|
*/
|
||||||
static async fetchBookIssues(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookIssuesTable[]> {
|
static async fetchBookIssues(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookIssuesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update FROM book_issues WHERE author_id=? AND book_id=?', [userId, bookId]) as BookIssuesTable[];
|
const query: string = 'SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update FROM book_issues WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const issues: BookIssuesTable[] = db.all(query, params) as BookIssuesTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return issues;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced issues for a specific user.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns An array of synced issue records.
|
||||||
|
*/
|
||||||
static fetchSyncedIssues(userId: string, lang: 'fr' | 'en'): SyncedIssueResult[] {
|
static fetchSyncedIssues(userId: string, lang: 'fr' | 'en'): SyncedIssueResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT issue_id, book_id, name, last_update FROM book_issues WHERE author_id = ?', [userId]) as SyncedIssueResult[];
|
const query: string = 'SELECT issue_id, book_id, name, last_update FROM book_issues WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedIssues: SyncedIssueResult[] = db.all(query, params) as SyncedIssueResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedIssues;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques synchronisées.` : `Unable to retrieve synced issues.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques synchronisées.` : `Unable to retrieve synced issues.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -116,51 +171,77 @@ export default class IssueRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced issue from remote into the local database.
|
||||||
|
* @param issueId - The unique identifier of the issue.
|
||||||
|
* @param authorId - The unique identifier of the author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param name - The encrypted name of the issue.
|
||||||
|
* @param hashedIssueName - The hashed name of the issue.
|
||||||
|
* @param lastUpdate - The timestamp of the last update.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the issue was successfully inserted, false otherwise.
|
||||||
|
*/
|
||||||
static insertSyncIssue(issueId: string, authorId: string, bookId: string, name: string, hashedIssueName: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncIssue(issueId: string, authorId: string, bookId: string, name: string, hashedIssueName: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_issues (issue_id, author_id, book_id, name, hashed_issue_name, last_update) VALUES (?, ?, ?, ?, ?, ?)`;
|
||||||
`INSERT INTO book_issues (issue_id, author_id, book_id, name, hashed_issue_name, last_update)
|
const params: SQLiteValue[] = [issueId, authorId, bookId, name, hashedIssueName, lastUpdate];
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
const insertResult: RunResult = db.run(query, params);
|
||||||
[issueId, authorId, bookId, name, hashedIssueName, lastUpdate]
|
return insertResult.changes > 0;
|
||||||
);
|
} catch (error: unknown) {
|
||||||
return result.changes > 0;
|
if (error instanceof Error) {
|
||||||
} catch (e: unknown) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
if (e instanceof Error) {
|
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer la problématique.` : `Unable to insert issue.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer la problématique.` : `Unable to insert issue.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteIssueById(id: string, lang: "fr" | "en"):Promise<BookIssuesTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches a complete issue record by its ID.
|
||||||
|
* @param id - The unique identifier of the issue.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns A promise resolving to an array of complete issue records.
|
||||||
|
*/
|
||||||
|
static async fetchCompleteIssueById(id: string, lang: "fr" | "en"): Promise<BookIssuesTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update FROM book_issues WHERE issue_id = ?`;
|
||||||
`SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update
|
const params: SQLiteValue[] = [id];
|
||||||
FROM book_issues
|
const issues: BookIssuesTable[] = db.all(query, params) as BookIssuesTable[];
|
||||||
WHERE issue_id = ?`,
|
return issues;
|
||||||
[id]
|
} catch (error: unknown) {
|
||||||
) as BookIssuesTable[];
|
if (error instanceof Error) {
|
||||||
} catch (e:unknown){
|
|
||||||
if (e instanceof Error) {
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le problème complet.` : `Unable to retrieve complete issue.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le problème complet.` : `Unable to retrieve complete issue.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static updateIssue(userId: string, bookId: string, issueId: string, name: string, hashedName: string, lastUpdate: number, lang: "fr" | "en"):boolean {
|
|
||||||
|
/**
|
||||||
|
* Updates an existing issue in the database.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param issueId - The unique identifier of the issue to update.
|
||||||
|
* @param name - The new encrypted name of the issue.
|
||||||
|
* @param hashedName - The new hashed name of the issue.
|
||||||
|
* @param lastUpdate - The timestamp of the update.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the issue was successfully updated, false otherwise.
|
||||||
|
*/
|
||||||
|
static updateIssue(userId: string, bookId: string, issueId: string, name: string, hashedName: string, lastUpdate: number, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query:string = `UPDATE book_issues SET name = ?, hashed_issue_name = ?, last_update = FROM_UNIXTIME(?) WHERE issue_id = UUID_TO_BIN(?) AND author_id = UUID_TO_BIN(?) AND book_id = UUID_TO_BIN(?)`;
|
const query: string = `UPDATE book_issues SET name = ?, hashed_issue_name = ?, last_update = ? WHERE issue_id = ? AND author_id = ? AND book_id = ?`;
|
||||||
const params:(string|number)[] = [name, hashedName, lastUpdate, issueId, userId, bookId];
|
const params: SQLiteValue[] = [name, hashedName, lastUpdate, issueId, userId, bookId];
|
||||||
const result:RunResult = db.run(query, params);
|
const updateResult: RunResult = db.run(query, params);
|
||||||
return result.changes > 0;
|
return updateResult.changes > 0;
|
||||||
} catch (e:unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la problématique.` : `Unable to update issue.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la problématique.` : `Unable to update issue.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -168,14 +249,25 @@ export default class IssueRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static issueExist(userId: string, bookId: string, issue_id: string,lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks if an issue exists in the database.
|
||||||
|
* @param userId - The unique identifier of the user/author.
|
||||||
|
* @param bookId - The unique identifier of the book.
|
||||||
|
* @param issueId - The unique identifier of the issue to check.
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en').
|
||||||
|
* @returns True if the issue exists, false otherwise.
|
||||||
|
*/
|
||||||
|
static issueExist(userId: string, bookId: string, issueId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_issues` WHERE `issue_id`=? AND `author_id`=? AND `book_id`=?', [issue_id, userId, bookId]) || null;
|
const query: string = 'SELECT 1 FROM book_issues WHERE issue_id=? AND author_id=? AND book_id=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [issueId, userId, bookId];
|
||||||
} catch (e: unknown) {
|
const existingIssue: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingIssue !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du problème.` : `Unable to check issue existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du problème.` : `Unable to check issue existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
import { Database, QueryResult, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||||
import System from "../System.js";
|
import System from "../System.js";
|
||||||
|
|
||||||
export interface LocationQueryResult extends Record<string, SQLiteValue> {
|
export interface LocationQueryResult extends Record<string, SQLiteValue> {
|
||||||
@@ -79,92 +79,166 @@ export interface SyncedLocationSubElementResult extends Record<string, SQLiteVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class LocationRepo {
|
export default class LocationRepo {
|
||||||
|
/**
|
||||||
|
* Retrieves all locations with their elements and sub-elements for a specific book.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param bookId - The book's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of location query results with nested elements
|
||||||
|
*/
|
||||||
static getLocation(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LocationQueryResult[] {
|
static getLocation(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LocationQueryResult[] {
|
||||||
let result: LocationQueryResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query = 'SELECT loc_id, loc_name, element.element_id AS element_id, element.element_name, element.element_description, sub_elem.sub_element_id AS sub_element_id, sub_elem.sub_elem_name, sub_elem.sub_elem_description FROM book_location AS location LEFT JOIN location_element AS element ON location.loc_id=element.location LEFT JOIN location_sub_element AS sub_elem ON element.element_id=sub_elem.element_id WHERE location.user_id=? AND location.book_id=?';
|
const query: string = `
|
||||||
result = db.all(query, [userId, bookId]) as LocationQueryResult[];
|
SELECT loc_id, loc_name, element.element_id AS element_id, element.element_name,
|
||||||
} catch (e: unknown) {
|
element.element_description, sub_elem.sub_element_id AS sub_element_id,
|
||||||
if (e instanceof Error) {
|
sub_elem.sub_elem_name, sub_elem.sub_elem_description
|
||||||
console.error(`DB Error: ${e.message}`);
|
FROM book_location AS location
|
||||||
|
LEFT JOIN location_element AS element ON location.loc_id = element.location
|
||||||
|
LEFT JOIN location_sub_element AS sub_elem ON element.element_id = sub_elem.element_id
|
||||||
|
WHERE location.user_id = ? AND location.book_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
|
const locations: LocationQueryResult[] = db.all(query, params) as LocationQueryResult[];
|
||||||
|
return locations;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les emplacements.` : `Unable to retrieve locations.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les emplacements.` : `Unable to retrieve locations.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new location section for a book.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locationId - The new location's unique identifier
|
||||||
|
* @param bookId - The book's unique identifier
|
||||||
|
* @param encryptedName - The encrypted location name
|
||||||
|
* @param originalName - The original (unencrypted) location name
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The location ID if insertion was successful
|
||||||
|
*/
|
||||||
static insertLocation(userId: string, locationId: string, bookId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
static insertLocation(userId: string, locationId: string, bookId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update) VALUES (?, ?, ?, ?, ?, ?)', [locationId, bookId, userId, encryptedName, originalName, System.timeStampInSeconds()]);
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update)
|
||||||
if (e instanceof Error) {
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [locationId, bookId, userId, encryptedName, originalName, System.timeStampInSeconds()];
|
||||||
|
const insertResult: RunResult = db.run(query, params);
|
||||||
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de la section d'emplacement.` : `Error adding location section.`);
|
||||||
|
}
|
||||||
|
return locationId;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter la section d'emplacement.` : `Unable to add location section.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter la section d'emplacement.` : `Unable to add location section.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de la section d'emplacement.` : `Error adding location section.`);
|
|
||||||
}
|
|
||||||
return locationId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new location element within a location section.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param elementId - The new element's unique identifier
|
||||||
|
* @param locationId - The parent location's unique identifier
|
||||||
|
* @param encryptedName - The encrypted element name
|
||||||
|
* @param originalName - The original (unencrypted) element name
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The element ID if insertion was successful
|
||||||
|
*/
|
||||||
static insertLocationElement(userId: string, elementId: string, locationId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
static insertLocationElement(userId: string, elementId: string, locationId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update) VALUES (?,?,?,?,?,?,?)', [elementId, locationId, userId, encryptedName, originalName, '', System.timeStampInSeconds()]);
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update)
|
||||||
if (e instanceof Error) {
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [elementId, locationId, userId, encryptedName, originalName, '', System.timeStampInSeconds()];
|
||||||
|
const insertResult: RunResult = db.run(query, params);
|
||||||
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément d'emplacement.` : `Error adding location element.`);
|
||||||
|
}
|
||||||
|
return elementId;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément d'emplacement.` : `Unable to add location element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément d'emplacement.` : `Unable to add location element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément d'emplacement.` : `Error adding location element.`);
|
|
||||||
}
|
|
||||||
return elementId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new sub-element within a location element.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param subElementId - The new sub-element's unique identifier
|
||||||
|
* @param elementId - The parent element's unique identifier
|
||||||
|
* @param encryptedName - The encrypted sub-element name
|
||||||
|
* @param originalName - The original (unencrypted) sub-element name
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The sub-element ID if insertion was successful
|
||||||
|
*/
|
||||||
static insertLocationSubElement(userId: string, subElementId: string, elementId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
static insertLocationSubElement(userId: string, subElementId: string, elementId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||||
let result: RunResult;
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update) VALUES (?,?,?,?,?,?,?)', [subElementId, elementId, userId, encryptedName, originalName, '', System.timeStampInSeconds()]);
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update)
|
||||||
if (e instanceof Error) {
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [subElementId, elementId, userId, encryptedName, originalName, '', System.timeStampInSeconds()];
|
||||||
|
const insertResult: RunResult = db.run(query, params);
|
||||||
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du sous-élément d'emplacement.` : `Error adding location sub-element.`);
|
||||||
|
}
|
||||||
|
return subElementId;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le sous-élément d'emplacement.` : `Unable to add location sub-element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le sous-élément d'emplacement.` : `Unable to add location sub-element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du sous-élément d'emplacement.` : `Error adding location sub-element.`);
|
|
||||||
}
|
|
||||||
return subElementId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing location sub-element's name and description.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param id - The sub-element's unique identifier
|
||||||
|
* @param encryptedName - The new encrypted sub-element name
|
||||||
|
* @param originalName - The new original (unencrypted) sub-element name
|
||||||
|
* @param encryptDescription - The new encrypted description
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the update affected at least one row
|
||||||
|
*/
|
||||||
static updateLocationSubElement(userId: string, id: string, encryptedName: string, originalName: string, encryptDescription: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
static updateLocationSubElement(userId: string, id: string, encryptedName: string, originalName: string, encryptDescription: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE location_sub_element SET sub_elem_name=?, original_name=?, sub_elem_description=?, last_update=? WHERE sub_element_id=? AND user_id=?', [encryptedName, originalName, encryptDescription, lastUpdate, id, userId]);
|
const query: string = `
|
||||||
return result.changes > 0;
|
UPDATE location_sub_element
|
||||||
} catch (e: unknown) {
|
SET sub_elem_name = ?, original_name = ?, sub_elem_description = ?, last_update = ?
|
||||||
if (e instanceof Error) {
|
WHERE sub_element_id = ? AND user_id = ?
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [encryptedName, originalName, encryptDescription, lastUpdate, id, 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 d'emplacement.` : `Unable to update location sub-element.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le sous-élément d'emplacement.` : `Unable to update location sub-element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -173,14 +247,31 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing location element's name and description.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param id - The element's unique identifier
|
||||||
|
* @param encryptedName - The new encrypted element name
|
||||||
|
* @param originalName - The new original (unencrypted) element name
|
||||||
|
* @param encryptedDescription - The new encrypted description
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the update affected at least one row
|
||||||
|
*/
|
||||||
static updateLocationElement(userId: string, id: string, encryptedName: string, originalName: string, encryptedDescription: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
static updateLocationElement(userId: string, id: string, encryptedName: string, originalName: string, encryptedDescription: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE location_element SET element_name=?, original_name=?, element_description=?, last_update=? WHERE element_id=? AND user_id=?', [encryptedName, originalName, encryptedDescription, lastUpdate, id, userId]);
|
const query: string = `
|
||||||
return result.changes > 0;
|
UPDATE location_element
|
||||||
} catch (e: unknown) {
|
SET element_name = ?, original_name = ?, element_description = ?, last_update = ?
|
||||||
if (e instanceof Error) {
|
WHERE element_id = ? AND user_id = ?
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [encryptedName, originalName, encryptedDescription, lastUpdate, id, 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 d'emplacement.` : `Unable to update location element.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément d'emplacement.` : `Unable to update location element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -189,14 +280,30 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing location section's name.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param id - The location section's unique identifier
|
||||||
|
* @param encryptedName - The new encrypted location name
|
||||||
|
* @param originalName - The new original (unencrypted) location name
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the update affected at least one row
|
||||||
|
*/
|
||||||
static updateLocationSection(userId: string, id: string, encryptedName: string, originalName: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
static updateLocationSection(userId: string, id: string, encryptedName: string, originalName: string, lastUpdate: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_location SET loc_name=?, loc_original_name=?, last_update=? WHERE loc_id=? AND user_id=?', [encryptedName, originalName, lastUpdate, id, userId]);
|
const query: string = `
|
||||||
return result.changes > 0;
|
UPDATE book_location
|
||||||
} catch (e: unknown) {
|
SET loc_name = ?, loc_original_name = ?, last_update = ?
|
||||||
if (e instanceof Error) {
|
WHERE loc_id = ? AND user_id = ?
|
||||||
console.error(`DB Error: ${e.message}`);
|
`;
|
||||||
|
const params: SQLiteValue[] = [encryptedName, originalName, lastUpdate, id, 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 la section d'emplacement.` : `Unable to update location section.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour la section d'emplacement.` : `Unable to update location section.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -205,14 +312,23 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a location section by its ID.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locationId - The location section's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the deletion affected at least one row
|
||||||
|
*/
|
||||||
static deleteLocationSection(userId: string, locationId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
static deleteLocationSection(userId: string, locationId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_location WHERE loc_id=? AND user_id=?', [locationId, userId]);
|
const query: string = 'DELETE FROM book_location WHERE loc_id = ? AND user_id = ?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [locationId, userId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer la section d'emplacement.` : `Unable to delete location section.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer la section d'emplacement.` : `Unable to delete location section.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -221,14 +337,23 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a location element by its ID.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param elementId - The element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the deletion affected at least one row
|
||||||
|
*/
|
||||||
static deleteLocationElement(userId: string, elementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
static deleteLocationElement(userId: string, elementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM location_element WHERE element_id=? AND user_id=?', [elementId, userId]);
|
const query: string = 'DELETE FROM location_element WHERE element_id = ? AND user_id = ?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [elementId, userId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément d'emplacement.` : `Unable to delete location element.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément d'emplacement.` : `Unable to delete location element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -237,14 +362,23 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a location sub-element by its ID.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param subElementId - The sub-element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the deletion affected at least one row
|
||||||
|
*/
|
||||||
static deleteLocationSubElement(userId: string, subElementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
static deleteLocationSubElement(userId: string, subElementId: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM location_sub_element WHERE sub_element_id=? AND user_id=?', [subElementId, userId]);
|
const query: string = 'DELETE FROM location_sub_element WHERE sub_element_id = ? AND user_id = ?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [subElementId, userId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le sous-élément d'emplacement.` : `Unable to delete location sub-element.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer le sous-élément d'emplacement.` : `Unable to delete location sub-element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -253,32 +387,53 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all location elements and sub-elements for tagging purposes.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param bookId - The book's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of location elements with their sub-elements
|
||||||
|
*/
|
||||||
static fetchLocationTags(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LocationElementQueryResult[] {
|
static fetchLocationTags(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): LocationElementQueryResult[] {
|
||||||
let result: LocationElementQueryResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query = 'SELECT se.sub_element_id AS sub_element_id, se.sub_elem_name, se.sub_elem_description, el.element_id AS element_id, el.element_name, el.element_description FROM location_sub_element AS se RIGHT JOIN location_element AS el ON se.element_id = el.element_id LEFT JOIN book_location AS lo ON el.location = lo.loc_id WHERE lo.book_id = ? AND lo.user_id = ?';
|
const query: string = `
|
||||||
result = db.all(query, [bookId, userId]) as LocationElementQueryResult[];
|
SELECT se.sub_element_id AS sub_element_id, se.sub_elem_name, se.sub_elem_description,
|
||||||
} catch (e: unknown) {
|
el.element_id AS element_id, el.element_name, el.element_description
|
||||||
if (e instanceof Error) {
|
FROM location_sub_element AS se
|
||||||
console.error(`DB Error: ${e.message}`);
|
RIGHT JOIN location_element AS el ON se.element_id = el.element_id
|
||||||
|
LEFT JOIN book_location AS lo ON el.location = lo.loc_id
|
||||||
|
WHERE lo.book_id = ? AND lo.user_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [bookId, userId];
|
||||||
|
const locationTags: LocationElementQueryResult[] = db.all(query, params) as LocationElementQueryResult[];
|
||||||
|
return locationTags;
|
||||||
|
} 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 d'emplacement.` : `Unable to retrieve location tags.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les tags d'emplacement.` : `Unable to retrieve location tags.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches locations by their tag IDs (element or sub-element IDs).
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locations - An array of location tag IDs to search for
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of locations matching the provided tags
|
||||||
|
* @throws Error if no tags are provided or no locations are found
|
||||||
|
*/
|
||||||
static fetchLocationsByTags(userId: string, locations: string[], lang: 'fr' | 'en' = 'fr'): LocationByTagResult[] {
|
static fetchLocationsByTags(userId: string, locations: string[], lang: 'fr' | 'en' = 'fr'): LocationByTagResult[] {
|
||||||
if (locations.length === 0) {
|
if (locations.length === 0) {
|
||||||
throw new Error(lang === 'fr' ? `Aucun tag fourni.` : `No tags provided.`);
|
throw new Error(lang === 'fr' ? `Aucun tag fourni.` : `No tags provided.`);
|
||||||
}
|
}
|
||||||
let result: LocationByTagResult[];
|
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const locationIds: string = locations.map((): string => '?').join(',');
|
const locationPlaceholders: string = locations.map((): string => '?').join(',');
|
||||||
const query: string = `
|
const query: string = `
|
||||||
SELECT el.element_name,
|
SELECT el.element_name,
|
||||||
el.element_description,
|
el.element_description,
|
||||||
@@ -287,32 +442,42 @@ export default class LocationRepo {
|
|||||||
FROM location_element AS el
|
FROM location_element AS el
|
||||||
LEFT JOIN location_sub_element AS se ON el.element_id = se.element_id
|
LEFT JOIN location_sub_element AS se ON el.element_id = se.element_id
|
||||||
WHERE el.user_id = ?
|
WHERE el.user_id = ?
|
||||||
AND (el.element_id IN (${locationIds}) OR se.sub_element_id IN (${locationIds}))
|
AND (el.element_id IN (${locationPlaceholders}) OR se.sub_element_id IN (${locationPlaceholders}))
|
||||||
`;
|
`;
|
||||||
const values: any[] = [userId, ...locations, ...locations];
|
const params: SQLiteValue[] = [userId, ...locations, ...locations];
|
||||||
result = db.all(query, values) as LocationByTagResult[];
|
const locationsByTags: LocationByTagResult[] = db.all(query, params) as LocationByTagResult[];
|
||||||
} catch (e: unknown) {
|
if (locationsByTags.length === 0) {
|
||||||
if (e instanceof Error) {
|
throw new Error(lang === 'fr' ? `Aucun emplacement trouvé avec ces tags.` : `No locations found with these tags.`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
}
|
||||||
|
return locationsByTags;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les emplacements par tags.` : `Unable to retrieve locations by tags.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les emplacements par tags.` : `Unable to retrieve locations by tags.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "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 emplacement trouvé avec ces tags.` : `No locations found with these tags.`);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
/**
|
||||||
static isLocationExist(userId: string, locId: string,lang: "fr" | "en"): boolean {
|
* Checks if a location exists in the database.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locId - The location's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the location exists, false otherwise
|
||||||
|
*/
|
||||||
|
static isLocationExist(userId: string, locId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_location` WHERE `loc_id`=? AND `user_id`=?', [locId, userId]) || null;
|
const query: string = 'SELECT 1 FROM `book_location` WHERE `loc_id` = ? AND `user_id` = ?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [locId, userId];
|
||||||
} catch (e: unknown) {
|
const existingLocation: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingLocation !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'emplacement.` : `Unable to check location existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'emplacement.` : `Unable to check location existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -321,14 +486,23 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static isLocationElementExist(userId: string, elementId: string,lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a location element exists in the database.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param elementId - The element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the location element exists, false otherwise
|
||||||
|
*/
|
||||||
|
static isLocationElementExist(userId: string, elementId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `location_element` WHERE `element_id`=? AND `user_id`=?', [elementId, userId]) || null;
|
const query: string = 'SELECT 1 FROM `location_element` WHERE `element_id` = ? AND `user_id` = ?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [elementId, userId];
|
||||||
} catch (e: unknown) {
|
const existingElement: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingElement !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément d'emplacement.` : `Unable to check location element existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément d'emplacement.` : `Unable to check location element existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -337,14 +511,23 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static isLocationSubElementExist(userId: string, subElementId: string,lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a location sub-element exists in the database.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param subElementId - The sub-element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the location sub-element exists, false otherwise
|
||||||
|
*/
|
||||||
|
static isLocationSubElementExist(userId: string, subElementId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `location_sub_element` WHERE `sub_element_id`=? AND `user_id`=?', [subElementId, userId]) || null;
|
const query: string = 'SELECT 1 FROM `location_sub_element` WHERE `sub_element_id` = ? AND `user_id` = ?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [subElementId, userId];
|
||||||
} catch (e: unknown) {
|
const existingSubElement: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingSubElement !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du sous-élément d'emplacement.` : `Unable to check location sub-element existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du sous-élément d'emplacement.` : `Unable to check location sub-element existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -352,26 +535,56 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all locations for a specific book.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param bookId - The book's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book location records
|
||||||
|
*/
|
||||||
static async fetchBookLocations(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookLocationTable[]> {
|
static async fetchBookLocations(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookLocationTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update FROM book_location WHERE user_id=? AND book_id=?', [userId, bookId]) as BookLocationTable[];
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update
|
||||||
if (e instanceof Error) {
|
FROM book_location
|
||||||
console.error(`DB Error: ${e.message}`);
|
WHERE user_id = ? AND book_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
|
const bookLocations: BookLocationTable[] = db.all(query, params) as BookLocationTable[];
|
||||||
|
return bookLocations;
|
||||||
|
} 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.` : `Unable to retrieve locations.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les lieux.` : `Unable to retrieve locations.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchLocationElements(userId: string,locationId:string, lang: 'fr' | 'en'): Promise<LocationElementTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches all elements for a specific location.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locationId - The location's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of location element records
|
||||||
|
*/
|
||||||
|
static async fetchLocationElements(userId: string, locationId: string, lang: 'fr' | 'en'): Promise<LocationElementTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT element_id, location, user_id, element_name, original_name, element_description, last_update FROM location_element WHERE user_id=? AND location=?', [userId, locationId]) as LocationElementTable[];
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT element_id, location, user_id, element_name, original_name, element_description, last_update
|
||||||
if (e instanceof Error) {
|
FROM location_element
|
||||||
console.error(`DB Error: ${e.message}`);
|
WHERE user_id = ? AND location = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId, locationId];
|
||||||
|
const locationElements: LocationElementTable[] = db.all(query, params) as LocationElementTable[];
|
||||||
|
return locationElements;
|
||||||
|
} 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.` : `Unable to retrieve location elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu.` : `Unable to retrieve location elements.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -379,26 +592,50 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchLocationSubElements(userId: string,elementId:string, lang: 'fr' | 'en'): Promise<LocationSubElementTable[]> {
|
/**
|
||||||
|
* Fetches all sub-elements for a specific location element.
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param elementId - The element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of location sub-element records
|
||||||
|
*/
|
||||||
|
static async fetchLocationSubElements(userId: string, elementId: string, lang: 'fr' | 'en'): Promise<LocationSubElementTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update FROM location_sub_element WHERE user_id=? AND element_id=?', [userId, elementId]) as LocationSubElementTable[];
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update
|
||||||
if (e instanceof Error) {
|
FROM location_sub_element
|
||||||
console.error(`DB Error: ${e.message}`);
|
WHERE user_id = ? AND element_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId, elementId];
|
||||||
|
const locationSubElements: LocationSubElementTable[] = db.all(query, params) as LocationSubElementTable[];
|
||||||
|
return locationSubElements;
|
||||||
|
} 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.` : `Unable to retrieve location sub-elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu.` : `Unable to retrieve location sub-elements.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced locations for a user (used for synchronization).
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced location records
|
||||||
|
*/
|
||||||
static fetchSyncedLocations(userId: string, lang: 'fr' | 'en'): SyncedLocationResult[] {
|
static fetchSyncedLocations(userId: string, lang: 'fr' | 'en'): SyncedLocationResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT loc_id, book_id, loc_name, last_update FROM book_location WHERE user_id = ?', [userId]) as SyncedLocationResult[];
|
const query: string = 'SELECT loc_id, book_id, loc_name, last_update FROM book_location WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedLocations: SyncedLocationResult[] = db.all(query, params) as SyncedLocationResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedLocations;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced locations.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les lieux synchronisés.` : `Unable to retrieve synced locations.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -407,13 +644,22 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced location elements for a user (used for synchronization).
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced location element records
|
||||||
|
*/
|
||||||
static fetchSyncedLocationElements(userId: string, lang: 'fr' | 'en'): SyncedLocationElementResult[] {
|
static fetchSyncedLocationElements(userId: string, lang: 'fr' | 'en'): SyncedLocationElementResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT element_id, location, element_name, last_update FROM location_element WHERE user_id = ?', [userId]) as SyncedLocationElementResult[];
|
const query: string = 'SELECT element_id, location, element_name, last_update FROM location_element WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedLocationElements: SyncedLocationElementResult[] = db.all(query, params) as SyncedLocationElementResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedLocationElements;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced location elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu synchronisés.` : `Unable to retrieve synced location elements.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -422,13 +668,22 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced location sub-elements for a user (used for synchronization).
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced location sub-element records
|
||||||
|
*/
|
||||||
static fetchSyncedLocationSubElements(userId: string, lang: 'fr' | 'en'): SyncedLocationSubElementResult[] {
|
static fetchSyncedLocationSubElements(userId: string, lang: 'fr' | 'en'): SyncedLocationSubElementResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT sub_element_id, element_id, sub_elem_name, last_update FROM location_sub_element WHERE user_id = ?', [userId]) as SyncedLocationSubElementResult[];
|
const query: string = 'SELECT sub_element_id, element_id, sub_elem_name, last_update FROM location_sub_element WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedLocationSubElements: SyncedLocationSubElementResult[] = db.all(query, params) as SyncedLocationSubElementResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedLocationSubElements;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced location sub-elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu synchronisés.` : `Unable to retrieve synced location sub-elements.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -436,36 +691,63 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced location from the remote server.
|
||||||
|
* @param locId - The location's unique identifier
|
||||||
|
* @param bookId - The book's unique identifier
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param locName - The encrypted location name
|
||||||
|
* @param locOriginalName - The original (unencrypted) location name
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the insertion affected at least one row
|
||||||
|
*/
|
||||||
static insertSyncLocation(locId: string, bookId: string, userId: string, locName: string, locOriginalName: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncLocation(locId: string, bookId: string, userId: string, locName: string, locOriginalName: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `
|
||||||
`INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update)
|
INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
[locId, bookId, userId, locName, locOriginalName, lastUpdate]
|
`;
|
||||||
);
|
const params: SQLiteValue[] = [locId, bookId, userId, locName, locOriginalName, lastUpdate];
|
||||||
return result.changes > 0;
|
const insertResult: RunResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
return insertResult.changes > 0;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le lieu.` : `Unable to insert location.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le lieu.` : `Unable to insert location.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced location element from the remote server.
|
||||||
|
* @param elementId - The element's unique identifier
|
||||||
|
* @param location - The parent location's unique identifier
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param elementName - The encrypted element name
|
||||||
|
* @param originalName - The original (unencrypted) element name
|
||||||
|
* @param elementDescription - The encrypted element description (can be null)
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the insertion affected at least one row
|
||||||
|
*/
|
||||||
static insertSyncLocationElement(elementId: string, location: string, userId: string, elementName: string, originalName: string, elementDescription: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncLocationElement(elementId: string, location: string, userId: string, elementName: string, originalName: string, elementDescription: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `
|
||||||
`INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update)
|
INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
[elementId, location, userId, elementName, originalName, elementDescription, lastUpdate]
|
`;
|
||||||
);
|
const params: SQLiteValue[] = [elementId, location, userId, elementName, originalName, elementDescription, lastUpdate];
|
||||||
return result.changes > 0;
|
const insertResult: RunResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
return insertResult.changes > 0;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du lieu.` : `Unable to insert location element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du lieu.` : `Unable to insert location element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -473,35 +755,57 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced location sub-element from the remote server.
|
||||||
|
* @param subElementId - The sub-element's unique identifier
|
||||||
|
* @param elementId - The parent element's unique identifier
|
||||||
|
* @param userId - The user's unique identifier
|
||||||
|
* @param subElemName - The encrypted sub-element name
|
||||||
|
* @param originalName - The original (unencrypted) sub-element name
|
||||||
|
* @param subElemDescription - The encrypted sub-element description (can be null)
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the insertion affected at least one row
|
||||||
|
*/
|
||||||
static insertSyncLocationSubElement(subElementId: string, elementId: string, userId: string, subElemName: string, originalName: string, subElemDescription: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncLocationSubElement(subElementId: string, elementId: string, userId: string, subElemName: string, originalName: string, subElemDescription: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `
|
||||||
`INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update)
|
INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
[subElementId, elementId, userId, subElemName, originalName, subElemDescription, lastUpdate]
|
`;
|
||||||
);
|
const params: SQLiteValue[] = [subElementId, elementId, userId, subElemName, originalName, subElemDescription, lastUpdate];
|
||||||
return result.changes > 0;
|
const insertResult: RunResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
return insertResult.changes > 0;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le sous-élément du lieu.` : `Unable to insert location sub-element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le sous-élément du lieu.` : `Unable to insert location sub-element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompleteLocationById(id: string, lang: "fr" | "en"):Promise<BookLocationTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches complete location data by its ID (without user filtering).
|
||||||
|
* @param id - The location's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book location records
|
||||||
|
*/
|
||||||
|
static async fetchCompleteLocationById(id: string, lang: "fr" | "en"): Promise<BookLocationTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `
|
||||||
`SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update
|
SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update
|
||||||
FROM book_location
|
FROM book_location
|
||||||
WHERE loc_id = ?`,
|
WHERE loc_id = ?
|
||||||
[id]
|
`;
|
||||||
) as BookLocationTable[];
|
const params: SQLiteValue[] = [id];
|
||||||
} catch (e:unknown){
|
const completeLocation: BookLocationTable[] = db.all(query, params) as BookLocationTable[];
|
||||||
if (e instanceof Error) {
|
return completeLocation;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le lieu complet.` : `Unable to retrieve complete location.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le lieu complet.` : `Unable to retrieve complete location.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -509,17 +813,25 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteLocationElementById(id: string, lang: "fr" | "en"):Promise<LocationElementTable[]> {
|
/**
|
||||||
|
* Fetches complete location element data by its ID (without user filtering).
|
||||||
|
* @param id - The element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of location element records
|
||||||
|
*/
|
||||||
|
static async fetchCompleteLocationElementById(id: string, lang: "fr" | "en"): Promise<LocationElementTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `
|
||||||
`SELECT element_id, location, user_id, element_name, original_name, element_description, last_update
|
SELECT element_id, location, user_id, element_name, original_name, element_description, last_update
|
||||||
FROM location_element
|
FROM location_element
|
||||||
WHERE element_id = ?`,
|
WHERE element_id = ?
|
||||||
[id]
|
`;
|
||||||
) as LocationElementTable[];
|
const params: SQLiteValue[] = [id];
|
||||||
} catch (e:unknown){
|
const completeLocationElement: LocationElementTable[] = db.all(query, params) as LocationElementTable[];
|
||||||
if (e instanceof Error) {
|
return completeLocationElement;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de lieu complet.` : `Unable to retrieve complete location element.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de lieu complet.` : `Unable to retrieve complete location element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -527,17 +839,25 @@ export default class LocationRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteLocationSubElementById(id: string, lang: "fr" | "en"):Promise<LocationSubElementTable[]> {
|
/**
|
||||||
|
* Fetches complete location sub-element data by its ID (without user filtering).
|
||||||
|
* @param id - The sub-element's unique identifier
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of location sub-element records
|
||||||
|
*/
|
||||||
|
static async fetchCompleteLocationSubElementById(id: string, lang: "fr" | "en"): Promise<LocationSubElementTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `
|
||||||
`SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update
|
SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update
|
||||||
FROM location_sub_element
|
FROM location_sub_element
|
||||||
WHERE sub_element_id = ?`,
|
WHERE sub_element_id = ?
|
||||||
[id]
|
`;
|
||||||
) as LocationSubElementTable[];
|
const params: SQLiteValue[] = [id];
|
||||||
} catch (e:unknown){
|
const completeLocationSubElement: LocationSubElementTable[] = db.all(query, params) as LocationSubElementTable[];
|
||||||
if (e instanceof Error) {
|
return completeLocationSubElement;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le sous-élément de lieu complet.` : `Unable to retrieve complete location sub-element.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le sous-élément de lieu complet.` : `Unable to retrieve complete location sub-element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, QueryResult, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
|
|
||||||
export interface BookPlotPointsTable extends Record<string, SQLiteValue> {
|
export interface BookPlotPointsTable extends Record<string, SQLiteValue> {
|
||||||
@@ -27,13 +27,23 @@ export interface PlotPointQuery extends Record<string, SQLiteValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class PlotPointRepository {
|
export default class PlotPointRepository {
|
||||||
public static fetchAllPlotPoints(userId:string,bookId:string, lang: 'fr' | 'en'):PlotPointQuery[]{
|
/**
|
||||||
|
* Fetches all plot points for a specific book.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of plot points with their basic information
|
||||||
|
*/
|
||||||
|
public static fetchAllPlotPoints(userId: string, bookId: string, lang: 'fr' | 'en'): PlotPointQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT plot_point_id, title, summary, linked_incident_id FROM book_plot_points WHERE author_id=? AND book_id=?', [userId, bookId]) as PlotPointQuery[];
|
const query: string = 'SELECT plot_point_id, title, summary, linked_incident_id FROM book_plot_points WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const plotPoints: PlotPointQuery[] = db.all(query, params) as PlotPointQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return plotPoints;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -41,30 +51,46 @@ export default class PlotPointRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new plot point into the database.
|
||||||
|
* @param plotPointId - The unique ID for the new plot point
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param encryptedName - The encrypted title of the plot point
|
||||||
|
* @param hashedName - The hashed title for duplicate checking
|
||||||
|
* @param incidentId - The ID of the linked incident (can be empty string)
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The ID of the newly created plot point
|
||||||
|
*/
|
||||||
static insertNewPlotPoint(plotPointId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, incidentId: string, lang: 'fr' | 'en'): string {
|
static insertNewPlotPoint(plotPointId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, incidentId: string, lang: 'fr' | 'en'): string {
|
||||||
let existingResult: QueryResult | null;
|
let existingPlotPoint: QueryResult | null;
|
||||||
let insertResult: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
existingResult = db.get('SELECT plot_point_id FROM book_plot_points WHERE author_id=? AND book_id=? AND hashed_title=?', [userId, bookId, hashedName]);
|
const checkQuery: string = 'SELECT plot_point_id FROM book_plot_points WHERE author_id=? AND book_id=? AND hashed_title=?';
|
||||||
} catch (e: unknown) {
|
const checkParams: SQLiteValue[] = [userId, bookId, hashedName];
|
||||||
if (e instanceof Error) {
|
existingPlotPoint = db.get(checkQuery, checkParams);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point d'intrigue.` : `Unable to verify plot point existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point d'intrigue.` : `Unable to verify plot point existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (existingResult !== null) {
|
if (existingPlotPoint !== null) {
|
||||||
throw new Error(lang === 'fr' ? `Ce point de l'intrigue existe déjà.` : `This plot point already exists.`);
|
throw new Error(lang === 'fr' ? `Ce point de l'intrigue existe déjà.` : `This plot point already exists.`);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
insertResult = db.run('INSERT INTO book_plot_points (plot_point_id,title,hashed_title,author_id,book_id,linked_incident_id,last_update) VALUES (?,?,?,?,?,?,?)', [plotPointId, encryptedName, hashedName, userId, bookId, incidentId, System.timeStampInSeconds()]);
|
const insertQuery: string = 'INSERT INTO book_plot_points (plot_point_id,title,hashed_title,author_id,book_id,linked_incident_id,last_update) VALUES (?,?,?,?,?,?,?)';
|
||||||
} catch (e: unknown) {
|
const insertParams: SQLiteValue[] = [plotPointId, encryptedName, hashedName, userId, bookId, incidentId, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(insertQuery, insertParams);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le point d'intrigue.` : `Unable to add plot point.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le point d'intrigue.` : `Unable to add plot point.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -77,14 +103,23 @@ export default class PlotPointRepository {
|
|||||||
return plotPointId;
|
return plotPointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static deletePlotPoint(userId: string, plotNumId: string, lang: 'fr' | 'en'): boolean {
|
/**
|
||||||
|
* Deletes a plot point from the database.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param plotPointId - The ID of the plot point to delete
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the plot point was deleted, false otherwise
|
||||||
|
*/
|
||||||
|
static deletePlotPoint(userId: string, plotPointId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_plot_points WHERE author_id=? AND plot_point_id=?', [userId, plotNumId]);
|
const query: string = 'DELETE FROM book_plot_points WHERE author_id=? AND plot_point_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, plotPointId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer le point d'intrigue.` : `Unable to delete plot point.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer le point d'intrigue.` : `Unable to delete plot point.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -92,14 +127,29 @@ export default class PlotPointRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static updatePlotPoint(userId: string, bookId: string, plotPointId: string, encryptedPlotPointName: string, plotPointHashedName: string, plotPointSummary: string, lastUpdate:number, lang: 'fr' | 'en'): boolean {
|
|
||||||
|
/**
|
||||||
|
* Updates an existing plot point in the database.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param plotPointId - The ID of the plot point to update
|
||||||
|
* @param encryptedPlotPointName - The new encrypted title
|
||||||
|
* @param plotPointHashedName - The new hashed title
|
||||||
|
* @param plotPointSummary - The new summary
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the plot point was updated, false otherwise
|
||||||
|
*/
|
||||||
|
public static updatePlotPoint(userId: string, bookId: string, plotPointId: string, encryptedPlotPointName: string, plotPointHashedName: string, plotPointSummary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_plot_points SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND plot_point_id=?', [encryptedPlotPointName, plotPointHashedName, plotPointSummary, lastUpdate, userId, bookId, plotPointId]);
|
const query: string = 'UPDATE book_plot_points SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND plot_point_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [encryptedPlotPointName, plotPointHashedName, plotPointSummary, lastUpdate, userId, bookId, plotPointId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le point d'intrigue.` : `Unable to update plot point.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le point d'intrigue.` : `Unable to update plot point.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -107,26 +157,47 @@ export default class PlotPointRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all plot points for a book with complete information for synchronization.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of complete plot point records
|
||||||
|
*/
|
||||||
static async fetchBookPlotPoints(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookPlotPointsTable[]> {
|
static async fetchBookPlotPoints(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookPlotPointsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update FROM book_plot_points WHERE author_id=? AND book_id=?', [userId, bookId]) as BookPlotPointsTable[];
|
const query: string = 'SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update FROM book_plot_points WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const plotPoints: BookPlotPointsTable[] = db.all(query, params) as BookPlotPointsTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return plotPoints;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced plot points for a user across all books.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced plot point records with minimal information
|
||||||
|
*/
|
||||||
static fetchSyncedPlotPoints(userId: string, lang: 'fr' | 'en'): SyncedPlotPointResult[] {
|
static fetchSyncedPlotPoints(userId: string, lang: 'fr' | 'en'): SyncedPlotPointResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT plot_point_id, book_id, title, last_update FROM book_plot_points WHERE author_id = ?', [userId]) as SyncedPlotPointResult[];
|
const query: string = 'SELECT plot_point_id, book_id, title, last_update FROM book_plot_points WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedPlotPoints: SyncedPlotPointResult[] = db.all(query, params) as SyncedPlotPointResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedPlotPoints;
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue synchronisés.` : `Unable to retrieve synced plot points.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue synchronisés.` : `Unable to retrieve synced plot points.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -134,49 +205,80 @@ export default class PlotPointRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a plot point during synchronization from remote data.
|
||||||
|
* @param plotPointId - The unique ID of the plot point
|
||||||
|
* @param title - The encrypted title
|
||||||
|
* @param hashedTitle - The hashed title for duplicate checking
|
||||||
|
* @param summary - The encrypted summary (can be null)
|
||||||
|
* @param linkedIncidentId - The ID of the linked incident (can be null)
|
||||||
|
* @param authorId - The ID of the author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param lastUpdate - The timestamp of the last update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the plot point was inserted, false otherwise
|
||||||
|
*/
|
||||||
static insertSyncPlotPoint(plotPointId: string, title: string, hashedTitle: string, summary: string | null, linkedIncidentId: string | null, authorId: string, bookId: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncPlotPoint(plotPointId: string, title: string, hashedTitle: string, summary: string | null, linkedIncidentId: string | null, authorId: string, bookId: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_plot_points (plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update)
|
||||||
`INSERT INTO book_plot_points (plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
const params: SQLiteValue[] = [plotPointId, title, hashedTitle, summary, linkedIncidentId, authorId, bookId, lastUpdate];
|
||||||
[plotPointId, title, hashedTitle, summary, linkedIncidentId, authorId, bookId, lastUpdate]
|
const insertResult: RunResult = db.run(query, params);
|
||||||
);
|
return insertResult.changes > 0;
|
||||||
return result.changes > 0;
|
} catch (error: unknown) {
|
||||||
} catch (e: unknown) {
|
if (error instanceof Error) {
|
||||||
if (e instanceof Error) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le point d'intrigue.` : `Unable to insert plot point.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le point d'intrigue.` : `Unable to insert plot point.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static async fetchCompletePlotPointById(id: string, lang: "fr" | "en"):Promise<BookPlotPointsTable[]> {
|
|
||||||
|
/**
|
||||||
|
* Fetches complete plot point data by its ID.
|
||||||
|
* @param plotPointId - The ID of the plot point to retrieve
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array containing the plot point data (empty if not found)
|
||||||
|
*/
|
||||||
|
static async fetchCompletePlotPointById(plotPointId: string, lang: "fr" | "en"): Promise<BookPlotPointsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update
|
||||||
`SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update
|
|
||||||
FROM book_plot_points
|
FROM book_plot_points
|
||||||
WHERE plot_point_id = ?`,
|
WHERE plot_point_id = ?`;
|
||||||
[id]
|
const params: SQLiteValue[] = [plotPointId];
|
||||||
) as BookPlotPointsTable[];
|
const plotPoint: BookPlotPointsTable[] = db.all(query, params) as BookPlotPointsTable[];
|
||||||
} catch (e:unknown){
|
return plotPoint;
|
||||||
if (e instanceof Error) {
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le point d'intrigue complet.` : `Unable to retrieve complete plot point.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le point d'intrigue complet.` : `Unable to retrieve complete plot point.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static plotPointExist(userId: string, bookId: string, plot_point_id: string,lang: "fr" | "en"): boolean {
|
|
||||||
|
/**
|
||||||
|
* Checks if a plot point exists in the database.
|
||||||
|
* @param userId - The ID of the user/author
|
||||||
|
* @param bookId - The ID of the book
|
||||||
|
* @param plotPointId - The ID of the plot point to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the plot point exists, false otherwise
|
||||||
|
*/
|
||||||
|
static plotPointExist(userId: string, bookId: string, plotPointId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result:QueryResult|null = db.get('SELECT 1 FROM book_plot_points WHERE author_id =? AND book_id =? AND plot_point_id =?', [userId, bookId, plot_point_id]) || null;
|
const query: string = 'SELECT 1 FROM book_plot_points WHERE author_id =? AND book_id =? AND plot_point_id =?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [userId, bookId, plotPointId];
|
||||||
} catch (e: unknown) {
|
const existingPlotPoint: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return existingPlotPoint !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point de intrigue.` : `Unable to check plot point existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point de intrigue.` : `Unable to check plot point existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
|
import { Database, RunResult, SQLiteValue } from 'node-sqlite3-wasm';
|
||||||
import System from "../System.js";
|
import System from "../System.js";
|
||||||
|
|
||||||
export interface UserInfosQueryResponse extends Record<string, SQLiteValue> {
|
export interface UserInfosQueryResponse extends Record<string, SQLiteValue> {
|
||||||
@@ -45,15 +45,39 @@ export interface GuideTourResult extends Record<string, SQLiteValue> {
|
|||||||
|
|
||||||
export default class UserRepo {
|
export default class UserRepo {
|
||||||
|
|
||||||
public static insertUser(uuId: string, firstName: string, lastName: string, username: string, originUsername: string, email: string, originEmail: string, lang: 'fr' | 'en' = 'fr'): string {
|
/**
|
||||||
let result: RunResult;
|
* Inserts a new user into the database.
|
||||||
|
* @param uuId - The unique identifier for the user
|
||||||
|
* @param firstName - The user's first name
|
||||||
|
* @param lastName - The user's last name
|
||||||
|
* @param username - The user's username
|
||||||
|
* @param originUsername - The original username from the source platform
|
||||||
|
* @param email - The user's email address
|
||||||
|
* @param originEmail - The original email from the source platform
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The user's UUID if insertion was successful
|
||||||
|
* @throws Error if the user cannot be registered
|
||||||
|
*/
|
||||||
|
public static insertUser(
|
||||||
|
uuId: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string,
|
||||||
|
username: string,
|
||||||
|
originUsername: string,
|
||||||
|
email: string,
|
||||||
|
originEmail: string,
|
||||||
|
lang: 'fr' | 'en' = 'fr'
|
||||||
|
): string {
|
||||||
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query = `INSERT INTO erit_users (user_id, first_name, last_name, username, email, origin_email,
|
const query: string = `
|
||||||
origin_username, plateform, term_accepted,
|
INSERT INTO erit_users (
|
||||||
account_verified, reg_date)
|
user_id, first_name, last_name, username, email, origin_email,
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
origin_username, plateform, term_accepted, account_verified, reg_date
|
||||||
const values: (string | null | number)[] = [
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [
|
||||||
uuId,
|
uuId,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
@@ -61,56 +85,113 @@ export default class UserRepo {
|
|||||||
email,
|
email,
|
||||||
originEmail,
|
originEmail,
|
||||||
originUsername,
|
originUsername,
|
||||||
'desktop', // plateform
|
'desktop',
|
||||||
0, // term_accepted
|
0,
|
||||||
1, // account_verified
|
1,
|
||||||
Date.now() // reg_date (current timestamp)
|
Date.now()
|
||||||
];
|
];
|
||||||
result = db.run(query, values);
|
insertResult = db.run(query, params);
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'enregistrer l'utilisateur.` : `Unable to register user.`);
|
throw new Error(lang === 'fr' ? `Impossible d'enregistrer l'utilisateur.` : `Unable to register user.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result.changes > 0) {
|
if (insertResult.changes > 0) {
|
||||||
return uuId;
|
return uuId;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'enregistrement de l'utilisateur.` : `Error registering user.`);
|
throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'enregistrement de l'utilisateur.` : `Error registering user.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches user information from the database.
|
||||||
|
* @param userId - The unique identifier of the user to fetch
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The user information object
|
||||||
|
* @throws Error if the user is not found or cannot be retrieved
|
||||||
|
*/
|
||||||
public static fetchUserInfos(userId: string, lang: 'fr' | 'en' = 'fr'): UserInfosQueryResponse {
|
public static fetchUserInfos(userId: string, lang: 'fr' | 'en' = 'fr'): UserInfosQueryResponse {
|
||||||
let result;
|
let userInfo: Record<string, SQLiteValue> | undefined;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.get('SELECT first_name, last_name, username, email, plateform, term_accepted, account_verified, author_name, erite_points AS rite_points, user_group FROM erit_users WHERE user_id=?', [userId]);
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT first_name, last_name, username, email, plateform, term_accepted,
|
||||||
if (e instanceof Error) {
|
account_verified, author_name, erite_points AS rite_points, user_group
|
||||||
console.error(`DB Error: ${e.message}`);
|
FROM erit_users
|
||||||
|
WHERE user_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId];
|
||||||
|
userInfo = db.get(query, params);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations utilisateur.` : `Unable to retrieve user information.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations utilisateur.` : `Unable to retrieve user information.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!userInfo) {
|
||||||
throw new Error(lang === 'fr' ? `Utilisateur non trouvé.` : `User not found.`);
|
throw new Error(lang === 'fr' ? `Utilisateur non trouvé.` : `User not found.`);
|
||||||
}
|
}
|
||||||
return result as UserInfosQueryResponse;
|
return userInfo as UserInfosQueryResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static updateUserInfos(userId: string, firstName: string, lastName: string, username: string, originUsername: string, email: string, originEmail: string, originalAuthorName: string, authorName: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
/**
|
||||||
|
* Updates user information in the database.
|
||||||
|
* @param userId - The unique identifier of the user to update
|
||||||
|
* @param firstName - The new first name
|
||||||
|
* @param lastName - The new last name
|
||||||
|
* @param username - The new username
|
||||||
|
* @param originUsername - The original username from the source platform
|
||||||
|
* @param email - The new email address
|
||||||
|
* @param originEmail - The original email from the source platform
|
||||||
|
* @param originalAuthorName - The original author name
|
||||||
|
* @param authorName - The new author name
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the update was successful, false otherwise
|
||||||
|
* @throws Error if the update fails
|
||||||
|
*/
|
||||||
|
public static updateUserInfos(
|
||||||
|
userId: string,
|
||||||
|
firstName: string,
|
||||||
|
lastName: string,
|
||||||
|
username: string,
|
||||||
|
originUsername: string,
|
||||||
|
email: string,
|
||||||
|
originEmail: string,
|
||||||
|
originalAuthorName: string,
|
||||||
|
authorName: string,
|
||||||
|
lang: 'fr' | 'en' = 'fr'
|
||||||
|
): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE `erit_users` SET `first_name`=?, `last_name`=?, `username`=?, email=?,`origin_username`=?, origin_author_name=? ,author_name=? WHERE user_id=? AND `origin_email`=?', [firstName, lastName, username, email, originUsername, originalAuthorName, authorName, userId, originEmail]);
|
const query: string = `
|
||||||
return result.changes > 0;
|
UPDATE erit_users
|
||||||
} catch (e: unknown) {
|
SET first_name = ?, last_name = ?, username = ?, email = ?,
|
||||||
if (e instanceof Error) {
|
origin_username = ?, origin_author_name = ?, author_name = ?
|
||||||
console.error(`DB Error: ${e.message}`);
|
WHERE user_id = ? AND origin_email = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
originUsername,
|
||||||
|
originalAuthorName,
|
||||||
|
authorName,
|
||||||
|
userId,
|
||||||
|
originEmail
|
||||||
|
];
|
||||||
|
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 les informations utilisateur.` : `Unable to update user information.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les informations utilisateur.` : `Unable to update user information.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -119,23 +200,36 @@ export default class UserRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches account information for a user.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The user account information object
|
||||||
|
* @throws Error if the account is not found or cannot be retrieved
|
||||||
|
*/
|
||||||
public static fetchAccountInformation(userId: string, lang: 'fr' | 'en' = 'fr'): UserAccountQuery {
|
public static fetchAccountInformation(userId: string, lang: 'fr' | 'en' = 'fr'): UserAccountQuery {
|
||||||
let result;
|
let accountInfo: Record<string, SQLiteValue> | undefined;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.get('SELECT first_name, last_name, username, author_name, email FROM erit_users WHERE user_id=?', [userId]);
|
const query: string = `
|
||||||
} catch (e: unknown) {
|
SELECT first_name, last_name, username, author_name, email
|
||||||
if (e instanceof Error) {
|
FROM erit_users
|
||||||
console.error(`DB Error: ${e.message}`);
|
WHERE user_id = ?
|
||||||
|
`;
|
||||||
|
const params: SQLiteValue[] = [userId];
|
||||||
|
accountInfo = db.get(query, params);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du compte.` : `Unable to retrieve account information.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du compte.` : `Unable to retrieve account information.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!accountInfo) {
|
||||||
throw new Error(lang === 'fr' ? `Compte non trouvé.` : `Account not found.`);
|
throw new Error(lang === 'fr' ? `Compte non trouvé.` : `Account not found.`);
|
||||||
}
|
}
|
||||||
return result as UserAccountQuery;
|
return accountInfo as UserAccountQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Database, QueryResult, RunResult, SQLiteValue} from "node-sqlite3-wasm";
|
import { Database, QueryResult, RunResult, SQLiteValue } from "node-sqlite3-wasm";
|
||||||
import System from "@/electron/database/System";
|
import System from "@/electron/database/System";
|
||||||
|
|
||||||
export interface BookWorldTable extends Record<string, SQLiteValue> {
|
export interface BookWorldTable extends Record<string, SQLiteValue> {
|
||||||
@@ -62,14 +62,24 @@ export interface WorldElementValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class WorldRepository {
|
export default class WorldRepository {
|
||||||
public static checkWorldExist(userId:string,bookId:string,worldName:string, lang: 'fr' | 'en'):boolean{
|
/**
|
||||||
|
* Checks if a world with the given name exists for a specific user and book.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param worldName - The hashed name of the world to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the world exists, false otherwise
|
||||||
|
*/
|
||||||
|
public static checkWorldExist(userId: string, bookId: string, worldName: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result = db.get('SELECT world_id FROM book_world WHERE author_id=? AND book_id=? AND hashed_name=?', [userId,bookId,worldName]);
|
const query: string = 'SELECT world_id FROM book_world WHERE author_id=? AND book_id=? AND hashed_name=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [userId, bookId, worldName];
|
||||||
} catch (e: unknown) {
|
const world: QueryResult | null = db.get(query, params);
|
||||||
if (e instanceof Error) {
|
return world !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to verify world existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to verify world existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -78,32 +88,55 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new world into the database.
|
||||||
|
* @param worldId - The unique identifier for the new world
|
||||||
|
* @param userId - The unique identifier of the author
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param encryptedName - The encrypted name of the world
|
||||||
|
* @param hashedName - The hashed name of the world for uniqueness checks
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The world ID if insertion was successful
|
||||||
|
*/
|
||||||
public static insertNewWorld(worldId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
public static insertNewWorld(worldId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
||||||
let result: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_world (world_id,author_id, book_id, name, hashed_name, last_update) VALUES (?,?,?,?,?,?)', [worldId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_world (world_id, author_id, book_id, name, hashed_name, last_update) VALUES (?, ?, ?, ?, ?, ?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [worldId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter le monde.` : `Unable to add world.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter le monde.` : `Unable to add world.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du monde.` : `Error adding world.`);
|
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du monde.` : `Error adding world.`);
|
||||||
}
|
}
|
||||||
return worldId;
|
return worldId;
|
||||||
}
|
}
|
||||||
public static fetchWorlds(userId: string, bookId: string, lang: 'fr' | 'en'):WorldQuery[] {
|
|
||||||
|
/**
|
||||||
|
* Fetches all worlds and their elements for a specific user and book.
|
||||||
|
* @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 world query results with joined element data
|
||||||
|
*/
|
||||||
|
public static fetchWorlds(userId: string, bookId: string, lang: 'fr' | 'en'): WorldQuery[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT world.world_id AS world_id, world.name AS world_name, world.history, world.politics, world.economy, world.religion, world.languages, element.element_id AS element_id, element.name AS element_name, element.description AS element_description, element.element_type FROM book_world AS world LEFT JOIN book_world_elements AS element ON world.world_id=element.world_id WHERE world.author_id=? AND world.book_id=?', [userId, bookId]) as WorldQuery[];
|
const query: string = `SELECT world.world_id AS world_id, world.name AS world_name, world.history, world.politics, world.economy, world.religion, world.languages, element.element_id AS element_id, element.name AS element_name, element.description AS element_description, element.element_type FROM book_world AS world LEFT JOIN book_world_elements AS element ON world.world_id=element.world_id WHERE world.author_id=? AND world.book_id=?`;
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const worlds: WorldQuery[] = db.all(query, params) as WorldQuery[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return worlds;
|
||||||
|
} 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.` : `Unable to retrieve worlds.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes.` : `Unable to retrieve worlds.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -112,14 +145,31 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a world's data in the database.
|
||||||
|
* @param userId - The unique identifier of the author
|
||||||
|
* @param worldId - The unique identifier of the world to update
|
||||||
|
* @param encryptName - The new encrypted name
|
||||||
|
* @param hashedName - The new hashed name
|
||||||
|
* @param encryptHistory - The new encrypted history
|
||||||
|
* @param encryptPolitics - The new encrypted politics
|
||||||
|
* @param encryptEconomy - The new encrypted economy
|
||||||
|
* @param encryptReligion - The new encrypted religion
|
||||||
|
* @param encryptLanguages - The new encrypted languages
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
public static updateWorld(userId: string, worldId: string, encryptName: string, hashedName: string, encryptHistory: string, encryptPolitics: string, encryptEconomy: string, encryptReligion: string, encryptLanguages: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
public static updateWorld(userId: string, worldId: string, encryptName: string, hashedName: string, encryptHistory: string, encryptPolitics: string, encryptEconomy: string, encryptReligion: string, encryptLanguages: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('UPDATE book_world SET name=?, hashed_name=?, history=?, politics=?, economy=?, religion=?, languages=?, last_update=? WHERE author_id=? AND world_id=?', [encryptName, hashedName, encryptHistory, encryptPolitics, encryptEconomy, encryptReligion, encryptLanguages, lastUpdate, userId, worldId]);
|
const query: string = 'UPDATE book_world SET name=?, hashed_name=?, history=?, politics=?, economy=?, religion=?, languages=?, last_update=? WHERE author_id=? AND world_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [encryptName, hashedName, encryptHistory, encryptPolitics, encryptEconomy, encryptReligion, encryptLanguages, lastUpdate, userId, worldId];
|
||||||
} catch (e: unknown) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return updateResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le monde.` : `Unable to update world.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour le monde.` : `Unable to update world.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -128,19 +178,28 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates multiple world elements in the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param elements - An array of world element values to update
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if all updates were successful, false otherwise
|
||||||
|
*/
|
||||||
public static updateWorldElements(userId: string, elements: WorldElementValue[], lang: 'fr' | 'en'): boolean {
|
public static updateWorldElements(userId: string, elements: WorldElementValue[], lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
|
const query: string = 'UPDATE book_world_elements SET name=?, description=?, element_type=?, last_update=? WHERE user_id=? AND element_id=?';
|
||||||
for (const element of elements) {
|
for (const element of elements) {
|
||||||
const result: RunResult = db.run('UPDATE book_world_elements SET name=?, description=?, element_type=?, last_update=? WHERE user_id=? AND element_id=?', [element.name, element.description, element.type, System.timeStampInSeconds(), userId, element.id]);
|
const params: SQLiteValue[] = [element.name, element.description, element.type, System.timeStampInSeconds(), userId, element.id];
|
||||||
if (result.changes <= 0) {
|
const updateResult: RunResult = db.run(query, params);
|
||||||
|
if (updateResult.changes <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (e: unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les éléments du monde.` : `Unable to update world elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour les éléments du monde.` : `Unable to update world elements.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -149,14 +208,23 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a world element with the given hashed name exists.
|
||||||
|
* @param worldNumId - The unique identifier of the world
|
||||||
|
* @param hashedName - The hashed name of the element to check
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the element exists, false otherwise
|
||||||
|
*/
|
||||||
public static checkElementExist(worldNumId: string, hashedName: string, lang: 'fr' | 'en'): boolean {
|
public static checkElementExist(worldNumId: string, hashedName: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result = db.get('SELECT element_id FROM book_world_elements WHERE world_id=? AND original_name=?', [worldNumId, hashedName]);
|
const query: string = 'SELECT element_id FROM book_world_elements WHERE world_id=? AND original_name=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [worldNumId, hashedName];
|
||||||
} catch (e: unknown) {
|
const element: QueryResult | null = db.get(query, params);
|
||||||
if (e instanceof Error) {
|
return element !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément.` : `Unable to verify element existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément.` : `Unable to verify element existence.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -165,34 +233,56 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new world element into the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param elementId - The unique identifier for the new element
|
||||||
|
* @param elementType - The type of the element
|
||||||
|
* @param worldId - The unique identifier of the parent world
|
||||||
|
* @param encryptedName - The encrypted name of the element
|
||||||
|
* @param hashedName - The hashed name of the element for uniqueness checks
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns The element ID if insertion was successful
|
||||||
|
*/
|
||||||
public static insertNewElement(userId: string, elementId: string, elementType: number, worldId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
public static insertNewElement(userId: string, elementId: string, elementType: number, worldId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
|
||||||
let result: RunResult;
|
let insertResult: RunResult;
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
result = db.run('INSERT INTO book_world_elements (element_id,world_id,user_id, name, original_name, element_type, last_update) VALUES (?,?,?,?,?,?,?)', [elementId, worldId, userId, encryptedName, hashedName, elementType, System.timeStampInSeconds()]);
|
const query: string = 'INSERT INTO book_world_elements (element_id, world_id, user_id, name, original_name, element_type, last_update) VALUES (?, ?, ?, ?, ?, ?, ?)';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [elementId, worldId, userId, encryptedName, hashedName, elementType, System.timeStampInSeconds()];
|
||||||
if (e instanceof Error) {
|
insertResult = db.run(query, params);
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément.` : `Unable to add element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément.` : `Unable to add element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!result || result.changes === 0) {
|
if (!insertResult || insertResult.changes === 0) {
|
||||||
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout de l'élément.` : `Error adding element.`);
|
throw new Error(lang === 'fr' ? `Erreur lors de l'ajout de l'élément.` : `Error adding element.`);
|
||||||
}
|
}
|
||||||
return elementId;
|
return elementId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a world element from the database.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param elementId - The unique identifier of the element to delete
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the deletion was successful, false otherwise
|
||||||
|
*/
|
||||||
public static deleteElement(userId: string, elementId: string, lang: 'fr' | 'en'): boolean {
|
public static deleteElement(userId: string, elementId: string, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run('DELETE FROM book_world_elements WHERE user_id=? AND element_id=?', [userId, elementId]);
|
const query: string = 'DELETE FROM book_world_elements WHERE user_id=? AND element_id=?';
|
||||||
return result.changes > 0;
|
const params: SQLiteValue[] = [userId, elementId];
|
||||||
} catch (e: unknown) {
|
const deleteResult: RunResult = db.run(query, params);
|
||||||
if (e instanceof Error) {
|
return deleteResult.changes > 0;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément.` : `Unable to delete element.`);
|
throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément.` : `Unable to delete element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -201,13 +291,23 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all worlds for a specific user and book.
|
||||||
|
* @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 A promise resolving to an array of book world table records
|
||||||
|
*/
|
||||||
static async fetchBookWorlds(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookWorldTable[]> {
|
static async fetchBookWorlds(userId: string, bookId: string, lang: 'fr' | 'en'): Promise<BookWorldTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update FROM book_world WHERE author_id=? AND book_id=?', [userId, bookId]) as BookWorldTable[];
|
const query: string = 'SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update FROM book_world WHERE author_id=? AND book_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, bookId];
|
||||||
if (e instanceof Error) {
|
const worlds: BookWorldTable[] = db.all(query, params) as BookWorldTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return worlds;
|
||||||
|
} 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.` : `Unable to retrieve worlds.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes.` : `Unable to retrieve worlds.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -215,13 +315,23 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchBookWorldElements(userId: string,worldId:string, lang: 'fr' | 'en'): Promise<BookWorldElementsTable[]> {
|
/**
|
||||||
|
* Fetches all elements for a specific world.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param worldId - The unique identifier of the world
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book world elements table records
|
||||||
|
*/
|
||||||
|
static async fetchBookWorldElements(userId: string, worldId: string, lang: 'fr' | 'en'): Promise<BookWorldElementsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update FROM book_world_elements WHERE user_id=? AND world_id=?', [userId, worldId]) as BookWorldElementsTable[];
|
const query: string = 'SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update FROM book_world_elements WHERE user_id=? AND world_id=?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId, worldId];
|
||||||
if (e instanceof Error) {
|
const elements: BookWorldElementsTable[] = db.all(query, params) as BookWorldElementsTable[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return elements;
|
||||||
|
} 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 du monde.` : `Unable to retrieve world elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments du monde.` : `Unable to retrieve world elements.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -229,13 +339,22 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced worlds for a specific user.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced world results
|
||||||
|
*/
|
||||||
static fetchSyncedWorlds(userId: string, lang: 'fr' | 'en'): SyncedWorldResult[] {
|
static fetchSyncedWorlds(userId: string, lang: 'fr' | 'en'): SyncedWorldResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT world_id, book_id, name, last_update FROM book_world WHERE author_id = ?', [userId]) as SyncedWorldResult[];
|
const query: string = 'SELECT world_id, book_id, name, last_update FROM book_world WHERE author_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedWorlds: SyncedWorldResult[] = db.all(query, params) as SyncedWorldResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedWorlds;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced worlds.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes synchronisés.` : `Unable to retrieve synced worlds.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -244,13 +363,22 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all synced world elements for a specific user.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns An array of synced world element results
|
||||||
|
*/
|
||||||
static fetchSyncedWorldElements(userId: string, lang: 'fr' | 'en'): SyncedWorldElementResult[] {
|
static fetchSyncedWorldElements(userId: string, lang: 'fr' | 'en'): SyncedWorldElementResult[] {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all('SELECT element_id, world_id, name, last_update FROM book_world_elements WHERE user_id = ?', [userId]) as SyncedWorldElementResult[];
|
const query: string = 'SELECT element_id, world_id, name, last_update FROM book_world_elements WHERE user_id = ?';
|
||||||
} catch (e: unknown) {
|
const params: SQLiteValue[] = [userId];
|
||||||
if (e instanceof Error) {
|
const syncedElements: SyncedWorldElementResult[] = db.all(query, params) as SyncedWorldElementResult[];
|
||||||
console.error(`DB Error: ${e.message}`);
|
return syncedElements;
|
||||||
|
} 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 synchronisés.` : `Unable to retrieve synced world elements.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de monde synchronisés.` : `Unable to retrieve synced world elements.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -259,18 +387,32 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced world into the database.
|
||||||
|
* @param worldId - The unique identifier for the world
|
||||||
|
* @param name - The encrypted name of the world
|
||||||
|
* @param hashedName - The hashed name of the world
|
||||||
|
* @param authorId - The unique identifier of the author
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param history - The encrypted history (optional)
|
||||||
|
* @param politics - The encrypted politics (optional)
|
||||||
|
* @param economy - The encrypted economy (optional)
|
||||||
|
* @param religion - The encrypted religion (optional)
|
||||||
|
* @param languages - The encrypted languages (optional)
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
static insertSyncWorld(worldId: string, name: string, hashedName: string, authorId: string, bookId: string, history: string | null, politics: string | null, economy: string | null, religion: string | null, languages: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncWorld(worldId: string, name: string, hashedName: string, authorId: string, bookId: string, history: string | null, politics: string | null, economy: string | null, religion: string | null, languages: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_world (world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
`INSERT INTO book_world (world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update)
|
const params: SQLiteValue[] = [worldId, name, hashedName, authorId, bookId, history, politics, economy, religion, languages, lastUpdate];
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
const insertResult: RunResult = db.run(query, params);
|
||||||
[worldId, name, hashedName, authorId, bookId, history, politics, economy, religion, languages, lastUpdate]
|
return insertResult.changes > 0;
|
||||||
);
|
} catch (error: unknown) {
|
||||||
return result.changes > 0;
|
if (error instanceof Error) {
|
||||||
} catch (e: unknown) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
if (e instanceof Error) {
|
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer le monde.` : `Unable to insert world.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer le monde.` : `Unable to insert world.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -278,18 +420,29 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a synced world element into the database.
|
||||||
|
* @param elementId - The unique identifier for the element
|
||||||
|
* @param worldId - The unique identifier of the parent world
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param elementType - The type of the element
|
||||||
|
* @param name - The encrypted name of the element
|
||||||
|
* @param originalName - The original hashed name
|
||||||
|
* @param description - The encrypted description (optional)
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
static insertSyncWorldElement(elementId: string, worldId: string, userId: string, elementType: number, name: string, originalName: string, description: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
static insertSyncWorldElement(elementId: string, worldId: string, userId: string, elementType: number, name: string, originalName: string, description: string | null, lastUpdate: number, lang: 'fr' | 'en'): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: RunResult = db.run(
|
const query: string = `INSERT INTO book_world_elements (element_id, world_id, user_id, element_type, name, original_name, description, last_update) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
`INSERT INTO book_world_elements (element_id, world_id, user_id, element_type, name, original_name, description, last_update)
|
const params: SQLiteValue[] = [elementId, worldId, userId, elementType, name, originalName, description, lastUpdate];
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
const insertResult: RunResult = db.run(query, params);
|
||||||
[elementId, worldId, userId, elementType, name, originalName, description, lastUpdate]
|
return insertResult.changes > 0;
|
||||||
);
|
} catch (error: unknown) {
|
||||||
return result.changes > 0;
|
if (error instanceof Error) {
|
||||||
} catch (e: unknown) {
|
console.error(`DB Error: ${error.message}`);
|
||||||
if (e instanceof Error) {
|
|
||||||
console.error(`DB Error: ${e.message}`);
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du monde.` : `Unable to insert world element.`);
|
throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du monde.` : `Unable to insert world element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -297,17 +450,21 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteWorldById(id: string, lang: "fr" | "en"):Promise<BookWorldTable[]> {
|
/**
|
||||||
|
* Fetches a complete world by its ID.
|
||||||
|
* @param id - The unique identifier of the world
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book world table records
|
||||||
|
*/
|
||||||
|
static async fetchCompleteWorldById(id: string, lang: "fr" | "en"): Promise<BookWorldTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update FROM book_world WHERE world_id = ?`;
|
||||||
`SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update
|
const params: SQLiteValue[] = [id];
|
||||||
FROM book_world
|
const worlds: BookWorldTable[] = db.all(query, params) as BookWorldTable[];
|
||||||
WHERE world_id = ?`,
|
return worlds;
|
||||||
[id]
|
} catch (error: unknown) {
|
||||||
) as BookWorldTable[];
|
if (error instanceof Error) {
|
||||||
} catch (e:unknown){
|
|
||||||
if (e instanceof Error) {
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer le monde complet.` : `Unable to retrieve complete world.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer le monde complet.` : `Unable to retrieve complete world.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -315,33 +472,48 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fetchCompleteWorldElementById(id: string, lang: "fr" | "en"):Promise<BookWorldElementsTable[]> {
|
/**
|
||||||
|
* Fetches a complete world element by its ID.
|
||||||
|
* @param id - The unique identifier of the element
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns A promise resolving to an array of book world elements table records
|
||||||
|
*/
|
||||||
|
static async fetchCompleteWorldElementById(id: string, lang: "fr" | "en"): Promise<BookWorldElementsTable[]> {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
return db.all(
|
const query: string = `SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update FROM book_world_elements WHERE element_id = ?`;
|
||||||
`SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update
|
const params: SQLiteValue[] = [id];
|
||||||
FROM book_world_elements
|
const elements: BookWorldElementsTable[] = db.all(query, params) as BookWorldElementsTable[];
|
||||||
WHERE element_id = ?`,
|
return elements;
|
||||||
[id]
|
} catch (error: unknown) {
|
||||||
) as BookWorldElementsTable[];
|
if (error instanceof Error) {
|
||||||
} catch (e:unknown){
|
|
||||||
if (e instanceof Error) {
|
|
||||||
throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de monde complet.` : `Unable to retrieve complete world element.`);
|
throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de monde complet.` : `Unable to retrieve complete world element.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static updateWorldElement(userId: string, elementId: string, name: string, description: string, lastUpdate: number,lang: "fr" | "en"):boolean {
|
|
||||||
|
/**
|
||||||
|
* Updates a single world element's name and description.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param elementId - The unique identifier of the element to update
|
||||||
|
* @param name - The new encrypted name
|
||||||
|
* @param description - The new encrypted description
|
||||||
|
* @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, false otherwise
|
||||||
|
*/
|
||||||
|
static updateWorldElement(userId: string, elementId: string, name: string, description: string, lastUpdate: number, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const query:string = `UPDATE book_world_elements SET name = ?, description = ?, last_update = FROM_UNIXTIME(?) WHERE element_id = UUID_TO_BIN(?) AND user_id = UUID_TO_BIN(?)`;
|
const query: string = `UPDATE book_world_elements SET name = ?, description = ?, last_update = ? WHERE element_id = ? AND user_id = ?`;
|
||||||
const params:(string|number)[] = [name, description, lastUpdate, elementId, userId];
|
const params: SQLiteValue[] = [name, description, lastUpdate, elementId, userId];
|
||||||
const result:RunResult = db.run(query, params);
|
const updateResult: RunResult = db.run(query, params);
|
||||||
return result.changes > 0;
|
return updateResult.changes > 0;
|
||||||
} catch (e:unknown) {
|
} catch (error: unknown) {
|
||||||
if (e instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error(`DB Error: ${e.message}`);
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément du monde.` : `Unable to update world element.`);
|
throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément du monde.` : `Unable to update world element.`);
|
||||||
} else {
|
} else {
|
||||||
console.error("An unknown error occurred.");
|
console.error("An unknown error occurred.");
|
||||||
@@ -350,14 +522,24 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static worldExist(userId: string, bookId: string, world_id: string,lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a world exists for a specific user and book.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param bookId - The unique identifier of the book
|
||||||
|
* @param worldId - The unique identifier of the world
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the world exists, false otherwise
|
||||||
|
*/
|
||||||
|
static worldExist(userId: string, bookId: string, worldId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_world` WHERE `world_id`=? AND `author_id`=? AND `book_id`=?', [world_id, userId, bookId]) || null;
|
const query: string = 'SELECT 1 FROM book_world WHERE world_id=? AND author_id=? AND book_id=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [worldId, userId, bookId];
|
||||||
} catch (e: unknown) {
|
const world: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return world !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to check world existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to check world existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||||
@@ -365,14 +547,24 @@ export default class WorldRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static worldElementExist(userId: string, world_id: string, element_id: string, lang: "fr" | "en"): boolean {
|
/**
|
||||||
|
* Checks if a world element exists for a specific user and world.
|
||||||
|
* @param userId - The unique identifier of the user
|
||||||
|
* @param worldId - The unique identifier of the world
|
||||||
|
* @param elementId - The unique identifier of the element
|
||||||
|
* @param lang - The language for error messages ('fr' or 'en')
|
||||||
|
* @returns True if the element exists, false otherwise
|
||||||
|
*/
|
||||||
|
static worldElementExist(userId: string, worldId: string, elementId: string, lang: "fr" | "en"): boolean {
|
||||||
try {
|
try {
|
||||||
const db: Database = System.getDb();
|
const db: Database = System.getDb();
|
||||||
const result: QueryResult | null = db.get('SELECT 1 FROM `book_world_elements` WHERE `element_id`=? AND `world_id`=? AND `user_id`=?', [element_id, world_id, userId]) || null;
|
const query: string = 'SELECT 1 FROM book_world_elements WHERE element_id=? AND world_id=? AND user_id=?';
|
||||||
return result !== null;
|
const params: SQLiteValue[] = [elementId, worldId, userId];
|
||||||
} catch (e: unknown) {
|
const element: QueryResult | null = db.get(query, params) || null;
|
||||||
if (e instanceof Error) {
|
return element !== null;
|
||||||
console.error(`DB Error: ${e.message}`);
|
} catch (error: unknown) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
console.error(`DB Error: ${error.message}`);
|
||||||
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément du monde.` : `Unable to check world element existence.`);
|
throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément du monde.` : `Unable to check world element existence.`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "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