Browse Source

fix: resolve migration 004 transaction and executeSet errors

- Remove explicit transaction wrapping in migration service that caused
  "cannot start a transaction within a transaction" errors
- Fix executeSet method call format to include both statement and values
  properties as required by Capacitor SQLite plugin
- Update CapacitorPlatformService to properly handle multi-statement SQL
  using executeSet for migration SQL blocks
- Ensure migration 004 (active_identity_management) executes atomically
  without nested transaction conflicts
- Remove unnecessary try/catch wrapper

Fixes iOS simulator migration failures where:
- Migration 004 would fail with transaction errors
- executeSet would fail with "Must provide a set as Array of {statement,values}"
- Database initialization would fail after migration errors

Tested on iOS simulator with successful migration completion and
active_identity table creation with proper data migration.
pull/188/head
Jose Olarte III 1 day ago
parent
commit
1790a6c5d6
  1. 16
      src/services/migrationService.ts
  2. 19
      src/services/platforms/CapacitorPlatformService.ts

16
src/services/migrationService.ts

@ -687,16 +687,14 @@ export async function runMigrations<T>(
}
try {
// Execute the migration SQL as single atomic operation with transaction
// Execute the migration SQL as single atomic operation
if (isDevelopment) {
migrationLog(`🔧 [Migration] Executing SQL for: ${migration.name}`);
migrationLog(`🔧 [Migration] SQL content: ${migration.sql}`);
}
// Begin transaction for atomic execution
await sqlExec("BEGIN IMMEDIATE");
try {
// Execute the migration SQL directly - it should be atomic
// The SQL itself should handle any necessary transactions
const execResult = await sqlExec(migration.sql);
if (isDevelopment) {
@ -724,9 +722,6 @@ export async function runMigrations<T>(
migration.name,
]);
// Commit transaction
await sqlExec("COMMIT");
// Only log success in development
if (isDevelopment) {
migrationLog(
@ -734,11 +729,6 @@ export async function runMigrations<T>(
);
}
appliedCount++;
} catch (error) {
// Rollback transaction on any error
await sqlExec("ROLLBACK");
throw error;
}
} catch (error) {
logger.error(`❌ [Migration] Error applying ${migration.name}:`, error);

19
src/services/platforms/CapacitorPlatformService.ts

@ -508,10 +508,25 @@ export class CapacitorPlatformService implements PlatformService {
// This is essential for proper parameter binding and SQL injection prevention
await this.db!.run(sql, params);
} else {
// Use execute method for non-parameterized queries
// This is more efficient for simple DDL statements
// For multi-statement SQL (like migrations), use executeSet method
// This handles multiple statements properly
if (
sql.includes(";") &&
sql.split(";").filter((s) => s.trim()).length > 1
) {
// Multi-statement SQL - use executeSet for proper handling
const statements = sql.split(";").filter((s) => s.trim());
await this.db!.executeSet(
statements.map((stmt) => ({
statement: stmt.trim(),
values: [], // Empty values array for non-parameterized statements
})),
);
} else {
// Single statement - use execute method
await this.db!.execute(sql);
}
}
};
/**

Loading…
Cancel
Save