Skip to content

Commit 3aad5a4

Browse files
committed
Use proper read-only connections with op-sqlite (#1012)
1 parent 1a644f9 commit 3aad5a4

18 files changed

Lines changed: 60 additions & 144 deletions

File tree

demos/react-native-barebones-opsqlite/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"dependencies": {
1212
"@azure/core-asynciterator-polyfill": "^1.0.2",
13-
"@op-engineering/op-sqlite": "^17.0.0",
13+
"@op-engineering/op-sqlite": "^17.1.0",
1414
"@powersync/react": "^1.10.0",
1515
"@powersync/react-native": "^1.35.7",
1616
"react": "19.1.0",

demos/react-native-supabase-background-sync/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"dependencies": {
1212
"@expo/vector-icons": "^15.1.1",
13-
"@op-engineering/op-sqlite": "^17.0.0",
13+
"@op-engineering/op-sqlite": "^17.1.0",
1414
"@powersync/react-native": "^1.35.7",
1515
"@react-navigation/bottom-tabs": "^7.3.10",
1616
"@react-navigation/elements": "^2.3.8",

demos/react-native-supabase-todolist/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@azure/core-asynciterator-polyfill": "^1.0.2",
1313
"@dr.pogodin/react-native-fs": "2.37.0",
1414
"@expo/vector-icons": "^15.1.1",
15-
"@op-engineering/op-sqlite": "^17.0.0",
15+
"@op-engineering/op-sqlite": "^17.1.0",
1616
"@powersync/attachments-storage-react-native": "^0.0.2",
1717
"@powersync/common": "^1.57.0",
1818
"@powersync/react": "^1.10.0",

packages/adapter-sql-js/src/SQLJSAdapter.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,6 @@ class SqlJsLockContext extends LockContext {
173173
super();
174174
}
175175

176-
get connectionType(): 'readWrite' {
177-
return 'readWrite';
178-
}
179-
180176
async executeRaw(query: string, params?: any[]): Promise<RawQueryResult> {
181177
const db = this.db;
182178
const statement = db.prepare(query);

packages/capacitor/src/adapter/CapacitorSQLiteAdapter.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,6 @@ export class CapacitorSQLiteAdapter extends DBAdapter {
264264
};
265265

266266
class CapacitorLockContext extends LockContext {
267-
get connectionType(): 'readWrite' {
268-
return 'readWrite';
269-
}
270-
271267
getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
272268
return getAll(sql, parameters);
273269
}

packages/common/etc/common.api.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ export interface LocalStorageAdapter {
658658

659659
// @public (undocumented)
660660
export abstract class LockContext implements SqlExecutor, DBGetUtils {
661-
abstract get connectionType(): 'readWrite' | 'queryOnly' | 'readOnly';
662661
// (undocumented)
663662
execute<T = SqliteRecord>(query: string, params?: any[] | undefined): Promise<QueryResult<T>>;
664663
// (undocumented)

packages/common/src/db/DBAdapter.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,6 @@ export interface SqlExecutor {
8787
* @public
8888
*/
8989
export abstract class LockContext implements SqlExecutor, DBGetUtils {
90-
/**
91-
* How the connection has been opened.
92-
*
93-
* `readWrite` indicates that the lock context is capable of writing to the database.
94-
* `queryOnly` indicates that the lock context has been opened in a readwrite mode, but a `PRAGMA query_only = TRUE`
95-
* disabled writes.
96-
* `readOnly` indicates that the lock context has been opened by passing `SQLITE_OPEN_READONLY` to `sqlite3_open_v2`.
97-
*/
98-
abstract get connectionType(): 'readWrite' | 'queryOnly' | 'readOnly';
99-
10090
abstract executeRaw<T>(query: string, params?: any[] | undefined): Promise<RawQueryResult>;
10191

10292
async getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
@@ -237,10 +227,6 @@ class TransactionImplementation extends LockContext {
237227
super();
238228
}
239229

240-
get connectionType() {
241-
return this.inner.connectionType;
242-
}
243-
244230
async commit(): Promise<void> {
245231
if (this.finalized) {
246232
return;
@@ -272,16 +258,8 @@ class TransactionImplementation extends LockContext {
272258
static async runWith<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T> {
273259
let tx = new TransactionImplementation(ctx);
274260

275-
// For write transactions, use BEGIN IMMEDIATE to immediately obtain a write lock on the database (instead of doing
276-
// that on the first statement). If we have a genuine read-only connection, we also use BEGIN IMMEDIATE there: In
277-
// WAL mode, that ensures we pin the current state of the database (instead of the state at the first statement in
278-
// the transaction). But if we have a "fake" read-only connection implemented through `pragma query_only = true`, we
279-
// can't use this trick because it would attempt to lock the connection. So there, we use a regular `BEGIN`
280-
// statement.
281-
const useBeginImmediate = ctx.connectionType != 'queryOnly';
282-
283261
try {
284-
await ctx.execute(useBeginImmediate ? 'BEGIN IMMEDIATE' : 'BEGIN');
262+
await ctx.execute('BEGIN IMMEDIATE');
285263

286264
const result = await fn(tx);
287265
await tx.commit();

packages/node/src/db/RemoteConnection.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ export class RemoteConnection extends LockContext {
1414

1515
private readonly notifyWorkerClosed = new AbortController();
1616

17-
constructor(
18-
worker: Worker,
19-
comlink: Remote<AsyncDatabaseOpener>,
20-
database: Remote<AsyncDatabase>,
21-
private readonly readonly: boolean
22-
) {
17+
constructor(worker: Worker, comlink: Remote<AsyncDatabaseOpener>, database: Remote<AsyncDatabase>) {
2318
super();
2419
this.worker = worker;
2520
this.comlink = comlink;
@@ -30,10 +25,6 @@ export class RemoteConnection extends LockContext {
3025
});
3126
}
3227

33-
public get connectionType() {
34-
return this.readonly ? 'readOnly' : 'readWrite';
35-
}
36-
3728
/**
3829
* Runs the inner function, but appends the stack trace where this function was called. This is useful for workers
3930
* because stack traces from worker errors are otherwise unrelated to the application issue that has caused them.

packages/node/src/db/WorkerConnectionPool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class WorkerConnectionPool extends DBAdapter {
119119
await database.executeRaw("SELECT powersync_update_hooks('install');", []);
120120
}
121121

122-
const connection = new RemoteConnection(worker, comlink, database, !isWriter);
122+
const connection = new RemoteConnection(worker, comlink, database);
123123
if (this.options.initializeConnection) {
124124
await this.options.initializeConnection(connection, isWriter);
125125
}

packages/react-native/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
},
3636
"homepage": "https://docs.powersync.com/",
3737
"peerDependencies": {
38-
"@op-engineering/op-sqlite": "^17.0.0",
38+
"@op-engineering/op-sqlite": "^17.1.0",
3939
"@powersync/common": "workspace:^1.57.0",
4040
"react": "*",
4141
"react-native": "*"

0 commit comments

Comments
 (0)