ARTICLE AD BOX
I am refactoring code and implementing repositories. Database access is handled via this singleton:
class SQLiteConnectorV2 { private static instance: SQLiteConnectorV2 | null = null; public db: ExpoSQLiteDatabase; private nativeDb: ReturnType<typeof SQLite.openDatabaseSync> | null = null; private constructor() { const sqliteDb = SQLite.openDatabaseSync(DB_NAME); this.nativeDb = sqliteDb; this.db = drizzle(sqliteDb); } public static getInstance(): SQLiteConnectorV2 { if (!SQLiteConnectorV2.instance) { SQLiteConnectorV2.instance = new SQLiteConnectorV2(); } return SQLiteConnectorV2.instance; } }This works until a change in the code triggers a fast refresh/full reload (whenever I change something that triggers the app to reload on the emulator). This happens both on a phone and on the emulator. After a reload, accessing the database throws:
Error: [Error: Call to function 'NativeStatement.runSync' has been rejected. → Caused by: Error code : database is locked]
I suspect the connection remains open and the new one conflicts. I tried globalThis to persist the connection but this reload resets the globalThis object. This probably only happens in development but while developing I don't want to have to restart every time or have to ignore errors.
Leaving the connection open and using a singleton are standard practices. Am I doing something wrong? With OP SQLite the error doesn't happen, so either my analysis is wrong or the thing being locked is not the .db file but something in Expo SQLite.
