fix: better rebuilding of database
This commit is contained in:
@@ -542,9 +542,12 @@ export class MediaEngine extends EventEmitter {
|
||||
name: 'Rebuild database from media files',
|
||||
execute: async (onProgress) => {
|
||||
const db = getDatabase().getLocal();
|
||||
|
||||
|
||||
onProgress(0, 'Deleting existing media for project...');
|
||||
|
||||
// Notify UI that rebuild is starting so it can clear the list
|
||||
this.emit('rebuildStarted');
|
||||
|
||||
// Delete all media for the current project - clean slate rebuild
|
||||
const existingMedia = await db.select({ id: media.id }).from(media).where(eq(media.projectId, this.currentProjectId)).all();
|
||||
if (existingMedia.length > 0) {
|
||||
@@ -553,7 +556,7 @@ export class MediaEngine extends EventEmitter {
|
||||
}
|
||||
|
||||
onProgress(5, 'Scanning media directory...');
|
||||
|
||||
|
||||
// Recursively find all .meta files in the media directory tree
|
||||
const metaFiles: string[] = [];
|
||||
const scanDir = async (dir: string) => {
|
||||
@@ -578,18 +581,18 @@ export class MediaEngine extends EventEmitter {
|
||||
// Already exists
|
||||
}
|
||||
await scanDir(mediaBaseDir);
|
||||
|
||||
|
||||
onProgress(10, `Found ${metaFiles.length} media sidecar files`);
|
||||
|
||||
|
||||
for (let i = 0; i < metaFiles.length; i++) {
|
||||
const sidecarPath = metaFiles[i];
|
||||
const mediaFilePath = sidecarPath.replace('.meta', '');
|
||||
const metaFileName = path.basename(sidecarPath);
|
||||
|
||||
onProgress(10 + (80 * (i / metaFiles.length)), `Processing ${metaFileName}...`);
|
||||
|
||||
|
||||
onProgress(10 + (80 * (i / metaFiles.length)), `Processing ${i + 1}/${metaFiles.length}: ${metaFileName}`);
|
||||
|
||||
const metadata = await this.readSidecarFile(sidecarPath);
|
||||
|
||||
|
||||
if (metadata) {
|
||||
try {
|
||||
const stats = await fs.stat(mediaFilePath);
|
||||
@@ -621,13 +624,18 @@ export class MediaEngine extends EventEmitter {
|
||||
console.error(`Media file not found for sidecar: ${sidecarPath}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Yield to event loop periodically so the window stays responsive
|
||||
if (i % 10 === 0) {
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onProgress(100, 'Database rebuild complete');
|
||||
this.emit('databaseRebuilt');
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
await taskManager.runTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,6 +897,9 @@ export class PostEngine extends EventEmitter {
|
||||
|
||||
onProgress(0, 'Deleting existing posts for project...');
|
||||
|
||||
// Notify UI that rebuild is starting so it can clear the list
|
||||
this.emit('rebuildStarted');
|
||||
|
||||
// Delete all posts for the current project - clean slate rebuild
|
||||
const existingPosts = await db.select({ id: posts.id }).from(posts).where(eq(posts.projectId, this.currentProjectId)).all();
|
||||
if (existingPosts.length > 0) {
|
||||
@@ -951,7 +954,7 @@ export class PostEngine extends EventEmitter {
|
||||
const filePath = mdFiles[i];
|
||||
const fileName = path.basename(filePath);
|
||||
|
||||
onProgress(10 + (80 * (i / mdFiles.length)), `Processing ${fileName}...`);
|
||||
onProgress(10 + (80 * (i / mdFiles.length)), `Processing ${i + 1}/${mdFiles.length}: ${fileName}`);
|
||||
|
||||
const postData = await this.readPostFile(filePath);
|
||||
|
||||
@@ -1007,6 +1010,11 @@ export class PostEngine extends EventEmitter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Yield to event loop periodically so the window stays responsive
|
||||
if (i % 10 === 0) {
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
}
|
||||
}
|
||||
|
||||
onProgress(100, 'Database rebuild complete');
|
||||
|
||||
@@ -83,13 +83,20 @@ export class TaskManager extends EventEmitter {
|
||||
this.emit('taskStarted', progress);
|
||||
|
||||
try {
|
||||
let lastEmitTime = 0;
|
||||
const THROTTLE_MS = 250; // Only emit progress to renderer every 250ms
|
||||
|
||||
const result = await task.execute((progressValue, message) => {
|
||||
if (abortController.signal.aborted) {
|
||||
throw new Error('Task cancelled');
|
||||
}
|
||||
progress.progress = progressValue;
|
||||
progress.message = message;
|
||||
this.emit('taskProgress', progress);
|
||||
const now = Date.now();
|
||||
if (now - lastEmitTime >= THROTTLE_MS || progressValue >= 100) {
|
||||
lastEmitTime = now;
|
||||
this.emit('taskProgress', { ...progress });
|
||||
}
|
||||
});
|
||||
|
||||
progress.status = 'completed';
|
||||
|
||||
@@ -137,7 +137,10 @@ export function registerIpcHandlers(): void {
|
||||
if (project) {
|
||||
engine.setProjectContext(project.id);
|
||||
}
|
||||
return engine.rebuildDatabaseFromFiles();
|
||||
// Fire and forget - don't await, let it run in background
|
||||
engine.rebuildDatabaseFromFiles().catch(err => {
|
||||
console.error('Post rebuild failed:', err);
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle('posts:search', async (_, query: string) => {
|
||||
@@ -256,7 +259,10 @@ export function registerIpcHandlers(): void {
|
||||
if (project) {
|
||||
engine.setProjectContext(project.id);
|
||||
}
|
||||
return engine.rebuildDatabaseFromFiles();
|
||||
// Fire and forget - don't await, let it run in background
|
||||
engine.rebuildDatabaseFromFiles().catch(err => {
|
||||
console.error('Media rebuild failed:', err);
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle('media:getThumbnail', async (_, id: string, size?: 'small' | 'medium' | 'large') => {
|
||||
@@ -440,11 +446,13 @@ export function registerIpcHandlers(): void {
|
||||
postEngine.on('postCreated', forwardEvent('post:created'));
|
||||
postEngine.on('postUpdated', forwardEvent('post:updated'));
|
||||
postEngine.on('postDeleted', forwardEvent('post:deleted'));
|
||||
postEngine.on('rebuildStarted', forwardEvent('posts:rebuildStarted'));
|
||||
postEngine.on('databaseRebuilt', forwardEvent('posts:databaseRebuilt'));
|
||||
|
||||
mediaEngine.on('mediaImported', forwardEvent('media:imported'));
|
||||
mediaEngine.on('mediaUpdated', forwardEvent('media:updated'));
|
||||
mediaEngine.on('mediaDeleted', forwardEvent('media:deleted'));
|
||||
mediaEngine.on('rebuildStarted', forwardEvent('media:rebuildStarted'));
|
||||
mediaEngine.on('databaseRebuilt', forwardEvent('media:databaseRebuilt'));
|
||||
|
||||
syncEngine.on('syncStarted', forwardEvent('sync:started'));
|
||||
|
||||
Reference in New Issue
Block a user