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:
@@ -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";
|
||||
|
||||
export interface BookIncidentsTable extends Record<string, SQLiteValue> {
|
||||
@@ -25,13 +25,24 @@ export interface IncidentQuery extends Record<string, SQLiteValue> {
|
||||
}
|
||||
|
||||
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 {
|
||||
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[];
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'SELECT incident_id, title, summary FROM book_incidents WHERE author_id=? AND book_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
const incidents: IncidentQuery[] = db.all(query, params) as IncidentQuery[];
|
||||
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.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
@@ -39,35 +50,59 @@ 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 {
|
||||
let result: RunResult;
|
||||
let insertResult: RunResult;
|
||||
try {
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'INSERT INTO book_incidents (incident_id,author_id, book_id, title, hashed_title, last_update) VALUES (?,?,?,?,?,?)';
|
||||
const params: SQLiteValue[] = [incidentId, userId, bookId, encryptedName, hashedName, 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 l'élément déclencheur.` : `Unable to add incident.`);
|
||||
} else {
|
||||
console.error("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.`);
|
||||
}
|
||||
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 {
|
||||
try {
|
||||
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]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'DELETE FROM book_incidents WHERE author_id=? AND book_id=? AND incident_id=?';
|
||||
const params: SQLiteValue[] = [userId, bookId, incidentId];
|
||||
const deleteResult: RunResult = db.run(query, params);
|
||||
return deleteResult.changes > 0;
|
||||
} 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.`);
|
||||
} else {
|
||||
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 {
|
||||
try {
|
||||
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]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'UPDATE book_incidents SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND incident_id=?';
|
||||
const params: SQLiteValue[] = [encryptedIncidentName, incidentHashedName, incidentSummary, lastUpdate, userId, bookId, incidentId];
|
||||
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'incident.` : `Unable to update incident.`);
|
||||
} else {
|
||||
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[]> {
|
||||
try {
|
||||
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[];
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
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=?';
|
||||
const params: SQLiteValue[] = [userId, bookId];
|
||||
const incidents: BookIncidentsTable[] = db.all(query, params) as BookIncidentsTable[];
|
||||
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.`);
|
||||
} else {
|
||||
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[] {
|
||||
try {
|
||||
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[];
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'SELECT incident_id, book_id, title, last_update FROM book_incidents WHERE author_id = ?';
|
||||
const params: SQLiteValue[] = [userId];
|
||||
const syncedIncidents: SyncedIncidentResult[] = db.all(query, params) as SyncedIncidentResult[];
|
||||
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.`);
|
||||
} else {
|
||||
console.error("An unknown error occurred.");
|
||||
@@ -117,53 +191,86 @@ 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 {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run(
|
||||
`INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
[incidentId, authorId, bookId, title, hashedTitle, summary, lastUpdate]
|
||||
);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = `INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`;
|
||||
const params: SQLiteValue[] = [incidentId, authorId, bookId, title, hashedTitle, summary, 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 l'incident.` : `Unable to insert incident.`);
|
||||
} else {
|
||||
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 {
|
||||
const db: Database = System.getDb();
|
||||
return db.all(
|
||||
`SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update
|
||||
const query: string = `SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update
|
||||
FROM book_incidents
|
||||
WHERE incident_id = ?`,
|
||||
[id]
|
||||
) as BookIncidentsTable[];
|
||||
} catch (e:unknown){
|
||||
if (e instanceof Error) {
|
||||
WHERE incident_id = ?`;
|
||||
const params: SQLiteValue[] = [id];
|
||||
const incident: BookIncidentsTable[] = db.all(query, params) as BookIncidentsTable[];
|
||||
return incident;
|
||||
} 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.`);
|
||||
} else {
|
||||
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 {
|
||||
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;
|
||||
return result !== null;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
const query: string = 'SELECT 1 FROM book_incidents WHERE book_id=? AND incident_id=? AND author_id=?';
|
||||
const params: SQLiteValue[] = [bookId, incidentId, userId];
|
||||
const existingIncident: QueryResult | null = db.get(query, params) || null;
|
||||
return existingIncident !== 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 de l'incident.` : `Unable to check incident existence.`);
|
||||
} else {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user