Skip to content

Commit e72d8d1

Browse files
remove requirement for checking SQL statements when checking autocommit
1 parent 7b6b555 commit e72d8d1

File tree

2 files changed

+56
-54
lines changed

2 files changed

+56
-54
lines changed

lib/src/web/database.dart

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'dart:js_interop';
44
import 'package:sqlite3/common.dart';
55
import 'package:sqlite3_web/sqlite3_web.dart';
66
import 'package:sqlite_async/mutex.dart';
7+
import 'package:sqlite_async/sqlite_async.dart';
78
import 'package:sqlite_async/src/common/sqlite_database.dart';
89
import 'package:sqlite_async/src/sqlite_connection.dart';
910
import 'package:sqlite_async/src/sqlite_queries.dart';
@@ -84,33 +85,29 @@ class WebDatabase
8485
Stream<UpdateNotification> get updates =>
8586
_database.updates.map((event) => UpdateNotification({event.tableName}));
8687

87-
@override
88-
Future<T> writeLock<T>(Future<T> Function(SqliteWriteContext tx) callback,
89-
{Duration? lockTimeout, String? debugContext}) async {
90-
return _writeLock(callback,
91-
lockTimeout: lockTimeout, debugContext: debugContext);
92-
}
93-
9488
@override
9589
Future<T> writeTransaction<T>(
9690
Future<T> Function(SqliteWriteContext tx) callback,
9791
{Duration? lockTimeout}) {
98-
return _writeLock((ctx) => internalWriteTransaction(ctx, callback),
92+
return writeLock(
93+
(writeContext) =>
94+
internalWriteTransaction(writeContext, (context) async {
95+
// All execute calls done in the callback will be checked for the
96+
// autocommit state
97+
return callback(_ExclusiveTransactionContext(this, writeContext));
98+
}),
9999
debugContext: 'writeTransaction()',
100-
isTransaction: true,
101100
lockTimeout: lockTimeout);
102101
}
103102

103+
@override
104+
104105
/// Internal writeLock which intercepts transaction context's to verify auto commit is not active
105-
Future<T> _writeLock<T>(Future<T> Function(SqliteWriteContext tx) callback,
106-
{Duration? lockTimeout,
107-
String? debugContext,
108-
bool isTransaction = false}) async {
106+
Future<T> writeLock<T>(Future<T> Function(SqliteWriteContext tx) callback,
107+
{Duration? lockTimeout, String? debugContext}) async {
109108
if (_mutex case var mutex?) {
110109
return await mutex.lock(() async {
111-
final context = isTransaction
112-
? _ExclusiveTransactionContext(this)
113-
: _ExclusiveContext(this);
110+
final context = _ExclusiveContext(this);
114111
try {
115112
return await callback(context);
116113
} finally {
@@ -121,11 +118,7 @@ class WebDatabase
121118
// No custom mutex, coordinate locks through shared worker.
122119
await _database.customRequest(CustomDatabaseMessage(
123120
CustomDatabaseMessageKind.requestExclusiveLock));
124-
final context = isTransaction
125-
? _ExclusiveTransactionContext(this)
126-
: _ExclusiveContext(this);
127-
;
128-
121+
final context = _ExclusiveContext(this);
129122
try {
130123
return await callback(context);
131124
} finally {
@@ -207,47 +200,56 @@ class _ExclusiveContext extends _SharedContext implements SqliteWriteContext {
207200
}
208201

209202
class _ExclusiveTransactionContext extends _ExclusiveContext {
210-
_ExclusiveTransactionContext(super.database);
203+
SqliteWriteContext baseContext;
204+
_ExclusiveTransactionContext(super.database, this.baseContext);
205+
206+
@override
207+
bool get closed => baseContext.closed;
211208

212209
@override
213210
Future<ResultSet> execute(String sql,
214211
[List<Object?> parameters = const []]) async {
215-
var res = await _database._database.customRequest(CustomDatabaseMessage(
216-
CustomDatabaseMessageKind.executeInTransaction, sql, parameters));
217-
var result = Map<String, dynamic>.from((res as JSObject).dartify() as Map);
218-
final columnNames = [
219-
for (final entry in result['columnNames']) entry as String
220-
];
221-
final rawTableNames = result['tableNames'];
222-
final tableNames = rawTableNames != null
223-
? [
224-
for (final entry in (rawTableNames as List<Object?>))
225-
entry as String
226-
]
227-
: null;
228-
229-
final rows = <List<Object?>>[];
230-
for (final row in (result['rows'] as List<Object?>)) {
231-
final dartRow = <Object?>[];
232-
233-
for (final column in (row as List<Object?>)) {
234-
dartRow.add(column);
235-
}
212+
return await wrapSqliteException(() async {
213+
var res = await _database._database.customRequest(CustomDatabaseMessage(
214+
CustomDatabaseMessageKind.executeInTransaction, sql, parameters));
215+
var result =
216+
Map<String, dynamic>.from((res as JSObject).dartify() as Map);
217+
final columnNames = [
218+
for (final entry in result['columnNames']) entry as String
219+
];
220+
final rawTableNames = result['tableNames'];
221+
final tableNames = rawTableNames != null
222+
? [
223+
for (final entry in (rawTableNames as List<Object?>))
224+
entry as String
225+
]
226+
: null;
227+
228+
final rows = <List<Object?>>[];
229+
for (final row in (result['rows'] as List<Object?>)) {
230+
final dartRow = <Object?>[];
231+
232+
for (final column in (row as List<Object?>)) {
233+
dartRow.add(column);
234+
}
236235

237-
rows.add(dartRow);
238-
}
239-
final resultSet = ResultSet(columnNames, tableNames, rows);
240-
return resultSet;
236+
rows.add(dartRow);
237+
}
238+
final resultSet = ResultSet(columnNames, tableNames, rows);
239+
return resultSet;
240+
});
241241
}
242242

243243
@override
244244
Future<void> executeBatch(
245245
String sql, List<List<Object?>> parameterSets) async {
246-
for (final set in parameterSets) {
247-
await _database._database.customRequest(CustomDatabaseMessage(
248-
CustomDatabaseMessageKind.executeBatchInTransaction, sql, set));
249-
}
250-
return;
246+
return await wrapSqliteException(() async {
247+
for (final set in parameterSets) {
248+
await _database._database.customRequest(CustomDatabaseMessage(
249+
CustomDatabaseMessageKind.executeBatchInTransaction, sql, set));
250+
}
251+
return;
252+
});
251253
}
252254
}
253255

lib/src/web/worker/worker_utils.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class AsyncSqliteDatabase extends WorkerDatabase {
5858
final parameters = [
5959
for (final raw in (message.rawParameters).toDart) raw.dartify()
6060
];
61-
if (database.autocommit && !sql.toLowerCase().contains('begin')) {
61+
if (database.autocommit) {
6262
throw SqliteException(0,
6363
"Transaction rolled back by earlier statement. Cannot execute: $sql");
6464
}
@@ -74,7 +74,7 @@ class AsyncSqliteDatabase extends WorkerDatabase {
7474
final parameters = [
7575
for (final raw in (message.rawParameters).toDart) raw.dartify()
7676
];
77-
if (database.autocommit && !sql.toLowerCase().contains('begin')) {
77+
if (database.autocommit) {
7878
throw SqliteException(0,
7979
"Transaction rolled back by earlier statement. Cannot execute: $sql");
8080
}

0 commit comments

Comments
 (0)