Browse Source
Add robust SQLite migration system with initial schema for TimeSafari desktop app. Includes comprehensive error handling, transaction safety, and detailed logging. Key Changes: - Add migration system with version tracking and rollback support - Implement initial schema with accounts, secret, settings, contacts tables - Configure SQLite PRAGMAs for optimal performance and reliability - Add detailed logging and state verification - Set up WAL journal mode and connection pooling Technical Details: - Use @capacitor-community/sqlite for native SQLite integration - Implement atomic transactions per migration - Add SQL validation and parsing utilities - Configure PRAGMAs: * foreign_keys = ON * journal_mode = WAL * synchronous = NORMAL * temp_store = MEMORY * page_size = 4096 * cache_size = 2000 * busy_timeout = 15000 * wal_autocheckpoint = 1000 Note: Current version has duplicate migration v1 entries that need to be addressed in a follow-up commit to ensure proper versioning. Testing: - Verified migrations run successfully - Confirmed table creation and index setup - Validated transaction safety and rollback - Checked logging and error handlingpull/136/head
2 changed files with 371 additions and 2 deletions
@ -0,0 +1,270 @@ |
|||
# Electron App Migration Strategy |
|||
|
|||
## Overview |
|||
|
|||
This document outlines the migration strategy for the TimeSafari Electron app, focusing on the transition from web-based storage to native SQLite implementation while maintaining cross-platform compatibility. |
|||
|
|||
## Current Architecture |
|||
|
|||
### 1. Platform Services |
|||
- `ElectronPlatformService`: Implements platform-specific features for desktop |
|||
- Uses `@capacitor-community/sqlite` for database operations |
|||
- Maintains compatibility with web/mobile platforms through shared interfaces |
|||
|
|||
### 2. Database Implementation |
|||
- SQLite with native Node.js backend |
|||
- WAL journal mode for better concurrency |
|||
- Connection pooling for performance |
|||
- Migration system for schema updates |
|||
- Secure file permissions (0o755) |
|||
|
|||
### 3. Build Process |
|||
```bash |
|||
# Development |
|||
npm run dev:electron |
|||
|
|||
# Production Build |
|||
npm run build:web |
|||
npm run build:electron |
|||
npm run electron:build-linux # or electron:build-mac |
|||
``` |
|||
|
|||
## Migration Goals |
|||
|
|||
1. **Data Integrity** |
|||
- Preserve existing data during migration |
|||
- Maintain data relationships |
|||
- Ensure ACID compliance |
|||
- Implement proper backup/restore |
|||
|
|||
2. **Performance** |
|||
- Optimize SQLite configuration |
|||
- Implement connection pooling |
|||
- Use WAL journal mode |
|||
- Configure optimal PRAGMA settings |
|||
|
|||
3. **Security** |
|||
- Secure file permissions |
|||
- Proper IPC communication |
|||
- Context isolation |
|||
- Safe preload scripts |
|||
|
|||
4. **User Experience** |
|||
- Zero data loss |
|||
- Automatic migration |
|||
- Progress indicators |
|||
- Error recovery |
|||
|
|||
## Implementation Details |
|||
|
|||
### 1. Database Initialization |
|||
```typescript |
|||
// electron/src/rt/sqlite-init.ts |
|||
export async function initializeSQLite() { |
|||
// Set up database path with proper permissions |
|||
const dbPath = path.join(app.getPath('userData'), 'timesafari.db'); |
|||
|
|||
// Initialize SQLite plugin |
|||
const sqlite = new CapacitorSQLite(); |
|||
|
|||
// Configure database |
|||
await sqlite.createConnection({ |
|||
database: 'timesafari', |
|||
path: dbPath, |
|||
encrypted: false, |
|||
mode: 'no-encryption' |
|||
}); |
|||
|
|||
// Set optimal PRAGMA settings |
|||
await sqlite.execute({ |
|||
database: 'timesafari', |
|||
statements: [ |
|||
'PRAGMA journal_mode = WAL;', |
|||
'PRAGMA synchronous = NORMAL;', |
|||
'PRAGMA foreign_keys = ON;' |
|||
] |
|||
}); |
|||
} |
|||
``` |
|||
|
|||
### 2. Migration System |
|||
```typescript |
|||
// electron/src/rt/sqlite-migrations.ts |
|||
interface Migration { |
|||
version: number; |
|||
name: string; |
|||
description: string; |
|||
sql: string; |
|||
rollback?: string; |
|||
} |
|||
|
|||
async function runMigrations(plugin: any, database: string) { |
|||
// Track migration state |
|||
const state = await getMigrationState(plugin, database); |
|||
|
|||
// Execute migrations in transaction |
|||
for (const migration of pendingMigrations) { |
|||
await executeMigration(plugin, database, migration); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### 3. Platform Service Implementation |
|||
```typescript |
|||
// src/services/platforms/ElectronPlatformService.ts |
|||
export class ElectronPlatformService implements PlatformService { |
|||
private sqlite: any; |
|||
|
|||
async dbQuery(sql: string, params: any[]): Promise<QueryExecResult> { |
|||
return await this.sqlite.execute({ |
|||
database: 'timesafari', |
|||
statements: [{ statement: sql, values: params }] |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### 4. Preload Script |
|||
```typescript |
|||
// electron/preload.ts |
|||
contextBridge.exposeInMainWorld('electron', { |
|||
sqlite: { |
|||
isAvailable: () => ipcRenderer.invoke('sqlite:isAvailable'), |
|||
execute: (method: string, ...args: unknown[]) => |
|||
ipcRenderer.invoke('sqlite:execute', method, ...args) |
|||
}, |
|||
getPath: (pathType: string) => ipcRenderer.invoke('get-path', pathType), |
|||
env: { |
|||
platform: 'electron' |
|||
} |
|||
}); |
|||
``` |
|||
|
|||
## Build Configuration |
|||
|
|||
### 1. Vite Configuration |
|||
```typescript |
|||
// vite.config.app.electron.mts |
|||
export default defineConfig({ |
|||
build: { |
|||
outDir: 'dist', |
|||
emptyOutDir: true |
|||
}, |
|||
define: { |
|||
'process.env.VITE_PLATFORM': JSON.stringify('electron'), |
|||
'process.env.VITE_PWA_ENABLED': JSON.stringify(false) |
|||
} |
|||
}); |
|||
``` |
|||
|
|||
### 2. Package Scripts |
|||
```json |
|||
{ |
|||
"scripts": { |
|||
"dev:electron": "vite build --watch --config vite.config.app.electron.mts", |
|||
"build:electron": "vite build --config vite.config.app.electron.mts", |
|||
"electron:build-linux": "electron-builder --linux", |
|||
"electron:build-mac": "electron-builder --mac" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## Testing Strategy |
|||
|
|||
1. **Unit Tests** |
|||
- Database operations |
|||
- Migration system |
|||
- Platform service methods |
|||
- IPC communication |
|||
|
|||
2. **Integration Tests** |
|||
- Full migration process |
|||
- Data integrity verification |
|||
- Cross-platform compatibility |
|||
- Error recovery |
|||
|
|||
3. **End-to-End Tests** |
|||
- User workflows |
|||
- Data persistence |
|||
- UI interactions |
|||
- Platform-specific features |
|||
|
|||
## Error Handling |
|||
|
|||
1. **Database Errors** |
|||
- Connection failures |
|||
- Migration errors |
|||
- Query execution errors |
|||
- Transaction failures |
|||
|
|||
2. **Platform Errors** |
|||
- File system errors |
|||
- IPC communication errors |
|||
- Permission issues |
|||
- Resource constraints |
|||
|
|||
3. **Recovery Mechanisms** |
|||
- Automatic retry logic |
|||
- Transaction rollback |
|||
- State verification |
|||
- User notifications |
|||
|
|||
## Security Considerations |
|||
|
|||
1. **File System** |
|||
- Secure file permissions |
|||
- Path validation |
|||
- Access control |
|||
- Data encryption |
|||
|
|||
2. **IPC Communication** |
|||
- Context isolation |
|||
- Channel validation |
|||
- Data sanitization |
|||
- Error handling |
|||
|
|||
3. **Preload Scripts** |
|||
- Minimal API exposure |
|||
- Type safety |
|||
- Input validation |
|||
- Error boundaries |
|||
|
|||
## Future Improvements |
|||
|
|||
1. **Performance** |
|||
- Query optimization |
|||
- Index tuning |
|||
- Connection management |
|||
- Cache implementation |
|||
|
|||
2. **Features** |
|||
- Offline support |
|||
- Sync capabilities |
|||
- Backup/restore |
|||
- Data export/import |
|||
|
|||
3. **Security** |
|||
- Database encryption |
|||
- Secure storage |
|||
- Access control |
|||
- Audit logging |
|||
|
|||
## Maintenance |
|||
|
|||
1. **Regular Tasks** |
|||
- Database optimization |
|||
- Log rotation |
|||
- Error monitoring |
|||
- Performance tracking |
|||
|
|||
2. **Updates** |
|||
- Dependency updates |
|||
- Security patches |
|||
- Feature additions |
|||
- Bug fixes |
|||
|
|||
3. **Documentation** |
|||
- API documentation |
|||
- Migration guides |
|||
- Troubleshooting |
|||
- Best practices |
Loading…
Reference in new issue