Skip to content

Commit 4c66487

Browse files
fix: capacitor readTransaction not allowed errors (#768)
1 parent 66218b2 commit 4c66487

File tree

3 files changed

+27
-28
lines changed

3 files changed

+27
-28
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@powersync/common': patch
3+
---
4+
5+
Fixed readTransaction method throwing "not allowed in read-only mode" errors

packages/capacitor/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const db = new PowerSyncDatabase({
8282

8383
- Encryption for native mobile platforms is not yet supported.
8484
- `PowerSyncDatabase.executeRaw` does not support results where multiple columns would have the same name in SQLite
85-
- `PowerSyncDatabase.execute` has limited support on Android. The SQLCipher Android driver exposes queries and executions as separate APIs, so there is no single method that handles both. While `PowerSyncDatabase.execute` accepts both, on Android we treat a statement as a query only when the SQL starts with `select` (case-insensitive).
85+
- `PowerSyncDatabase.execute` has limited support on Android. The SQLCipher Android driver exposes queries and executions as separate APIs, so there is no single method that handles both. While `PowerSyncDatabase.execute` accepts both, on Android we treat a statement as a query only when the SQL starts with `select` (case-insensitive). Queries such as `INSERT into customers (id, name) VALUES (uuid(), 'name') RETURNING *` do not work on Android.
8686
- Multiple tab support is not available for native Android and iOS targets. If you're not opening a second webview in your native app using something like `@jackobo/capacitor-webview`, you are unaffected by this.
8787

8888
## Examples

packages/capacitor/src/adapter/CapacitorSQLiteAdapter.ts

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -118,22 +118,31 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
118118
}
119119

120120
protected generateLockContext(db: SQLiteDBConnection): LockContext {
121+
const _query = async (query: string, params: any[] = []) => {
122+
const result = await db.query(query, params);
123+
const arrayResult = result.values ?? [];
124+
return {
125+
rowsAffected: 0,
126+
rows: {
127+
_array: arrayResult,
128+
length: arrayResult.length,
129+
item: (idx: number) => arrayResult[idx]
130+
}
131+
};
132+
};
133+
121134
const _execute = async (query: string, params: any[] = []): Promise<QueryResult> => {
122135
const platform = Capacitor.getPlatform();
136+
137+
if (db.getConnectionReadOnly()) {
138+
return _query(query, params);
139+
}
140+
123141
if (platform == 'android') {
124142
// Android: use query for SELECT and executeSet for mutations
125143
// We cannot use `run` here for both cases.
126144
if (query.toLowerCase().trim().startsWith('select')) {
127-
const result = await db.query(query, params);
128-
const arrayResult = result.values ?? [];
129-
return {
130-
rowsAffected: 0,
131-
rows: {
132-
_array: arrayResult,
133-
length: arrayResult.length,
134-
item: (idx: number) => arrayResult[idx]
135-
}
136-
};
145+
return _query(query, params);
137146
} else {
138147
const result = await db.executeSet([{ statement: query, values: params }], false);
139148
return {
@@ -166,24 +175,9 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
166175
? (sql: string, params?: any[]) => monitorQuery(sql, () => _execute(sql, params))
167176
: _execute;
168177

169-
const _executeQuery = async (query: string, params?: any[]): Promise<QueryResult> => {
170-
let result = await db.query(query, params);
171-
172-
let arrayResult = result.values ?? [];
173-
174-
return {
175-
rowsAffected: 0,
176-
rows: {
177-
_array: arrayResult,
178-
length: arrayResult.length,
179-
item: (idx: number) => arrayResult[idx]
180-
}
181-
};
182-
};
183-
184178
const executeQuery = this.options.debugMode
185-
? (sql: string, params?: any[]) => monitorQuery(sql, () => _executeQuery(sql, params))
186-
: _executeQuery;
179+
? (sql: string, params?: any[]) => monitorQuery(sql, () => _query(sql, params))
180+
: _query;
187181

188182
const getAll = async <T>(query: string, params?: any[]): Promise<T[]> => {
189183
const result = await executeQuery(query, params);

0 commit comments

Comments
 (0)