Add BooksSyncContext, refine database schema, and enhance synchronization support
- Introduce `BooksSyncContext` for managing book synchronization states (server-only, local-only, to-sync, etc.). - Remove `UserContext` and related dependencies. - Refine localization strings (`en.json`) with sync-related updates (e.g., "toSyncFromServer", "toSyncToServer"). - Extend database schema with additional tables and fields for syncing books, chapters, and related entities. - Add `last_update` fields and update corresponding repository methods to support synchronization logic. - Enhance IPC handlers with stricter typing, data validation, and sync-aware operations.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -78,7 +78,7 @@ export default class ChapterRepo{
|
||||
let result: RunResult;
|
||||
try {
|
||||
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) VALUES (?,?,?,?,?,?,?)', [chapterId, userId, bookId, title, hashedTitle, wordsCount, chapterOrder]);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -88,11 +88,10 @@ export default class ChapterRepo{
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return chapterId;
|
||||
} else {
|
||||
if (!result || result.changes === 0) {
|
||||
throw new Error(lang === 'fr' ? `Une erreur s'est passé lors de l'ajout du chapitre.` : `Error adding chapter.`);
|
||||
}
|
||||
return chapterId;
|
||||
}
|
||||
|
||||
public static fetchWholeChapter(userId: string, chapterId: string, version: number, lang: 'fr' | 'en' = 'fr'): ChapterContentQueryResult {
|
||||
@@ -197,7 +196,7 @@ export default class ChapterRepo{
|
||||
}
|
||||
try {
|
||||
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) VALUES (?,?,?,?,?,?,?,?,?)', [chapterInfoId, chapterId, actId, bookId, userId, incidentId, plotId, '', '']);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -207,17 +206,16 @@ export default class ChapterRepo{
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return chapterInfoId;
|
||||
} else {
|
||||
if (!result || result.changes === 0) {
|
||||
throw new Error(lang === 'fr' ? `Une erreur s'est produite pendant la liaison du chapitre.` : `Error linking chapter.`);
|
||||
}
|
||||
return chapterInfoId;
|
||||
}
|
||||
|
||||
public static updateChapter(userId: string, chapterId: string, encryptedTitle: string, hashTitle: string, chapterOrder: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE book_chapters SET title=?, hashed_title=?, chapter_order=? WHERE author_id=? AND chapter_id=?', [encryptedTitle, hashTitle, chapterOrder, userId, chapterId]);
|
||||
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, System.timeStampInSeconds(), userId, chapterId]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
@@ -270,12 +268,12 @@ export default class ChapterRepo{
|
||||
public static updateChapterContent(userId: string, chapterId: string, version: number, encryptContent: string, wordsCount: number, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE book_chapter_content SET content=?, words_count=? WHERE chapter_id=? AND author_id=? AND version=?', [encryptContent, wordsCount, chapterId, userId, version]);
|
||||
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, System.timeStampInSeconds(), chapterId, userId, version]);
|
||||
if (result.changes > 0) {
|
||||
return true;
|
||||
} else {
|
||||
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) VALUES (?,?,?,?,?,?)', [contentId, chapterId, userId, version, encryptContent, wordsCount]);
|
||||
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, System.timeStampInSeconds()]);
|
||||
return insertResult.changes > 0;
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
|
||||
@@ -54,7 +54,7 @@ export default class CharacterRepo {
|
||||
let result: RunResult;
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
result = db.run('INSERT INTO `book_characters` (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history) VALUES (?,?,?,?,?,?,?,?,?,?,?)', [characterId, bookId, userId, encryptedName, encryptedLastName, encryptedCategory, encryptedTitle, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory]);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -64,18 +64,17 @@ export default class CharacterRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return characterId;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
static insertAttribute(attributeId: string, characterId: string, userId: string, type: string, name: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||
let result: RunResult;
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
result = db.run('INSERT INTO `book_characters_attributes` (attr_id, character_id, user_id, attribute_name, attribute_value) VALUES (?,?,?,?,?)', [attributeId, characterId, userId, type, name]);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -85,17 +84,16 @@ export default class CharacterRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return attributeId;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
static updateCharacter(userId: string, id: number | null, encryptedName: string, encryptedLastName: string, encryptedTitle: string, encryptedCategory: string, encryptedImage: string, encryptedRole: string, encryptedBiography: string, encryptedHistory: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE `book_characters` SET `first_name`=?,`last_name`=?,`title`=?,`category`=?,`image`=?,`role`=?,`biography`=?,`history`=? WHERE `character_id`=? AND `user_id`=?', [encryptedName, encryptedLastName, encryptedTitle, encryptedCategory, encryptedImage, encryptedRole, encryptedBiography, encryptedHistory, id, userId]);
|
||||
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, System.timeStampInSeconds(), id, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
|
||||
@@ -51,7 +51,7 @@ export default class LocationRepo {
|
||||
let result: RunResult;
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
result = db.run('INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name) VALUES (?, ?, ?, ?, ?)', [locationId, bookId, userId, encryptedName, originalName]);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -61,18 +61,17 @@ export default class LocationRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return locationId;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
static insertLocationElement(userId: string, elementId: string, locationId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||
let result: RunResult;
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
result = db.run('INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description) VALUES (?,?,?,?,?,?)', [elementId, locationId, userId, encryptedName, originalName, '']);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -82,18 +81,17 @@ export default class LocationRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return elementId;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
static insertLocationSubElement(userId: string, subElementId: string, elementId: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): string {
|
||||
let result: RunResult;
|
||||
try {
|
||||
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) VALUES (?,?,?,?,?,?)', [subElementId, elementId, userId, encryptedName, originalName, '']);
|
||||
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()]);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
console.error(`DB Error: ${e.message}`);
|
||||
@@ -103,17 +101,16 @@ export default class LocationRepo {
|
||||
throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
if (result.changes > 0) {
|
||||
return subElementId;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
static updateLocationSubElement(userId: string, id: string, encryptedName: string, originalName: string, encryptDescription: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE location_sub_element SET sub_elem_name=?, original_name=?, sub_elem_description=? WHERE sub_element_id=? AND user_id=?', [encryptedName, originalName, encryptDescription, id, userId]);
|
||||
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, System.timeStampInSeconds(), id, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
@@ -129,7 +126,7 @@ export default class LocationRepo {
|
||||
static updateLocationElement(userId: string, id: string, encryptedName: string, originalName: string, encryptedDescription: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE location_element SET element_name=?, original_name=?, element_description=? WHERE element_id=? AND user_id=?', [encryptedName, originalName, encryptedDescription, id, userId]);
|
||||
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, System.timeStampInSeconds(), id, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
@@ -145,7 +142,7 @@ export default class LocationRepo {
|
||||
static updateLocationSection(userId: string, id: string, encryptedName: string, originalName: string, lang: 'fr' | 'en' = 'fr'): boolean {
|
||||
try {
|
||||
const db: Database = System.getDb();
|
||||
const result: RunResult = db.run('UPDATE book_location SET loc_name=?, loc_original_name=? WHERE loc_id=? AND user_id=?', [encryptedName, originalName, id, userId]);
|
||||
const result: RunResult = db.run('UPDATE book_location SET loc_name=?, loc_original_name=?, last_update=? WHERE loc_id=? AND user_id=?', [encryptedName, originalName, System.timeStampInSeconds(), id, userId]);
|
||||
return result.changes > 0;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
|
||||
Reference in New Issue
Block a user