@ -4,11 +4,10 @@ import {
PlatformCapabilities ,
} from "../PlatformService" ;
import { logger } from "../../utils/logger" ;
import { QueryExecResult , SqlValue } from "@/interfaces/database" ;
import { QueryExecResult } from "@/interfaces/database" ;
import {
SQLiteConnection ,
SQLiteDBConnection ,
Changes ,
} from "@capacitor-community/sqlite" ;
import { DEFAULT_ENDORSER_API_SERVER } from "@/constants/app" ;
@ -30,6 +29,7 @@ export class ElectronPlatformService implements PlatformService {
private db : SQLiteDBConnection | null = null ;
private dbName = "timesafari.db" ;
private initialized = false ;
private initializationPromise : Promise < void > | null = null ;
constructor ( ) {
// Use the IPC bridge for SQLite operations
@ -40,40 +40,53 @@ export class ElectronPlatformService implements PlatformService {
}
private async initializeDatabase ( ) : Promise < void > {
// If already initialized, return
if ( this . initialized ) {
return ;
}
try {
// Check if SQLite is available through IPC
const isAvailable = await window . electron . sqlite . isAvailable ( ) ;
if ( ! isAvailable ) {
throw new Error ( "SQLite is not available in the main process" ) ;
}
// Create/Open database with native implementation
this . db = await this . sqlite . createConnection (
this . dbName ,
false ,
"no-encryption" ,
1 ,
true , // Use native implementation
) ;
await this . db . open ( ) ;
// Set journal mode to WAL for better performance
await this . db . execute ( "PRAGMA journal_mode=WAL;" ) ;
// If initialization is in progress, wait for it
if ( this . initializationPromise ) {
return this . initializationPromise ;
}
// Run migrations
await this . runMigrations ( ) ;
// Start initialization
this . initializationPromise = ( async ( ) = > {
try {
// Check if SQLite is available through IPC
const isAvailable = await window . electron . sqlite . isAvailable ( ) ;
if ( ! isAvailable ) {
throw new Error ( "SQLite is not available in the main process" ) ;
}
// Create/Open database with native implementation
this . db = await this . sqlite . createConnection (
this . dbName ,
false ,
"no-encryption" ,
1 ,
true , // Use native implementation
) ;
await this . db . open ( ) ;
// Set journal mode to WAL for better performance
await this . db . execute ( "PRAGMA journal_mode=WAL;" ) ;
// Run migrations
await this . runMigrations ( ) ;
this . initialized = true ;
logger . log ( "[Electron] SQLite database initialized successfully" ) ;
} catch ( error ) {
logger . error ( "[Electron] Error initializing SQLite database:" , error ) ;
this . initialized = false ;
this . initializationPromise = null ;
throw error ;
}
} ) ( ) ;
this . initialized = true ;
logger . log ( "SQLite database initialized successfully" ) ;
} catch ( error ) {
logger . error ( "Error initializing SQLite database:" , error ) ;
throw new Error ( "Failed to initialize database" ) ;
}
return this . initializationPromise ;
}
private async runMigrations ( ) : Promise < void > {
@ -300,24 +313,24 @@ export class ElectronPlatformService implements PlatformService {
/ * *
* @see PlatformService . dbQuery
* /
async dbQuery ( sql : string , params? : unknown [ ] ) : Promise < QueryExecResult > {
await this . initializeDatabase ( ) ;
if ( ! this . db ) {
throw new Error ( "Database not initialized" ) ;
}
async dbQuery (
sql : string ,
params? : unknown [ ] ,
) : Promise < QueryExecResult | undefined > {
try {
const result = await this . db . query ( sql , params || [ ] ) ;
const values = result . values || [ ] ;
await this . initializeDatabase ( ) ;
if ( ! this . db ) {
throw new Error ( "Database not initialized" ) ;
}
const result = await this . db . query ( sql , params ) ;
// Convert SQLite plugin result to QueryExecResult format
return {
columns : [ ] , // SQLite plugin doesn't provide column names in query result
values : values as SqlValue [ ] [ ] ,
columns : [ ] , // SQLite plugin doesn't provide column names
values : result.values || [ ] ,
} ;
} catch ( error ) {
logger . error ( "Error executing query:" , error ) ;
throw new Error (
` Database query failed: ${ error instanceof Error ? error.message : String ( error ) } ` ,
) ;
logger . error ( "[Electron] Database query error:" , error ) ;
throw error ;
}
}
@ -328,23 +341,20 @@ export class ElectronPlatformService implements PlatformService {
sql : string ,
params? : unknown [ ] ,
) : Promise < { changes : number ; lastId? : number } > {
await this . initializeDatabase ( ) ;
if ( ! this . db ) {
throw new Error ( "Database not initialized" ) ;
}
try {
const result = await this . db . run ( sql , params || [ ] ) ;
const changes = result . changes as Changes ;
await this . initializeDatabase ( ) ;
if ( ! this . db ) {
throw new Error ( "Database not initialized" ) ;
}
const result = await this . db . run ( sql , params ) ;
// Convert SQLite plugin result to expected format
return {
changes : changes?.changes || 0 ,
lastId : changes?.lastId ,
changes : result. changes?.changes || 0 ,
lastId : result. changes?.lastId,
} ;
} catch ( error ) {
logger . error ( "Error executing statement:" , error ) ;
throw new Error (
` Database execution failed: ${ error instanceof Error ? error.message : String ( error ) } ` ,
) ;
logger . error ( "[Electron] Database execution error:" , error ) ;
throw error ;
}
}
}