Skip to content

Commit c5c0eac

Browse files
committed
Add common prefix
1 parent 73776f6 commit c5c0eac

File tree

6 files changed

+104
-63
lines changed

6 files changed

+104
-63
lines changed

packages/sqlite_async/lib/src/common/connection/sync_sqlite_connection.dart

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:developer';
33
import 'package:sqlite3/common.dart';
44
import 'package:sqlite_async/src/common/mutex.dart';
55
import 'package:sqlite_async/src/sqlite_connection.dart';
6+
import 'package:sqlite_async/src/sqlite_options.dart';
67
import 'package:sqlite_async/src/sqlite_queries.dart';
78
import 'package:sqlite_async/src/update_notification.dart';
89
import 'package:sqlite_async/src/utils/profiler.dart';
@@ -19,10 +20,13 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
1920

2021
/// Whether queries should be added to the `dart:developer` timeline.
2122
///
22-
/// This is disabled by default.
23+
/// This is enabled by default outside of release builds, see
24+
/// [SqliteOptions.profileQueries] for details.
2325
final bool profileQueries;
2426

25-
SyncSqliteConnection(this.db, Mutex m, {this.profileQueries = false}) {
27+
SyncSqliteConnection(this.db, Mutex m, {bool? profileQueries})
28+
: profileQueries =
29+
profileQueries ?? const SqliteOptions().profileQueries {
2630
mutex = m.open();
2731
updates = db.updates.map(
2832
(event) {
@@ -35,7 +39,7 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
3539
Future<T> readLock<T>(Future<T> Function(SqliteReadContext tx) callback,
3640
{Duration? lockTimeout, String? debugContext}) {
3741
final task = profileQueries ? TimelineTask() : null;
38-
task?.start('mutex_lock');
42+
task?.start('${profilerPrefix}mutex_lock');
3943

4044
return mutex.lock(
4145
() {
@@ -50,7 +54,7 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
5054
Future<T> writeLock<T>(Future<T> Function(SqliteWriteContext tx) callback,
5155
{Duration? lockTimeout, String? debugContext}) {
5256
final task = profileQueries ? TimelineTask() : null;
53-
task?.start('mutex_lock');
57+
task?.start('${profilerPrefix}mutex_lock');
5458

5559
return mutex.lock(
5660
() {
@@ -95,7 +99,8 @@ class SyncReadContext implements SqliteReadContext {
9599
return task.timeSync(
96100
'get',
97101
() => db.select(sql, parameters).first,
98-
arguments: timelineArgs(sql, parameters),
102+
sql: sql,
103+
parameters: parameters,
99104
);
100105
}
101106

@@ -105,7 +110,8 @@ class SyncReadContext implements SqliteReadContext {
105110
return task.timeSync(
106111
'getAll',
107112
() => db.select(sql, parameters),
108-
arguments: timelineArgs(sql, parameters),
113+
sql: sql,
114+
parameters: parameters,
109115
);
110116
}
111117

@@ -134,7 +140,8 @@ class SyncWriteContext extends SyncReadContext implements SqliteWriteContext {
134140
return task.timeSync(
135141
'execute',
136142
() => db.select(sql, parameters),
137-
arguments: timelineArgs(sql, parameters),
143+
sql: sql,
144+
parameters: parameters,
138145
);
139146
}
140147

@@ -146,11 +153,11 @@ class SyncWriteContext extends SyncReadContext implements SqliteWriteContext {
146153
try {
147154
for (var parameters in parameterSets) {
148155
task.timeSync('iteration', () => statement.execute(parameters),
149-
arguments: parameterArgs(parameters));
156+
parameters: parameters);
150157
}
151158
} finally {
152159
statement.dispose();
153160
}
154-
}, arguments: {'sql': sql});
161+
}, sql: sql);
155162
}
156163
}

packages/sqlite_async/lib/src/native/database/native_sqlite_connection_impl.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,12 @@ Future<void> _sqliteConnectionIsolateInner(_SqliteConnectionParams params,
386386
maybeFireUpdates();
387387
return null;
388388
case _SqliteIsolateStatement():
389-
return task.timeSync('execute_remote', () => runStatement(data),
390-
arguments: timelineArgs(data.sql, data.args));
389+
return task.timeSync(
390+
'execute_remote',
391+
() => runStatement(data),
392+
sql: data.sql,
393+
parameters: data.args,
394+
);
391395
case _SqliteIsolateClosure():
392396
try {
393397
return await data.cb(db);

packages/sqlite_async/lib/src/sqlite_connection.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ abstract class SqliteConnection extends SqliteWriteContext {
9494
/// may be used as an escape hatch for the asynchronous wrappers provided by
9595
/// this package.
9696
///
97-
/// When [profileQueries] is enabled (it's disabled by default, queries are
98-
/// posted to the `dart:developer` timeline).
97+
/// When [profileQueries] is enabled (it's enabled by default outside of
98+
/// release builds, queries are posted to the `dart:developer` timeline).
9999
factory SqliteConnection.synchronousWrapper(CommonDatabase raw,
100-
{Mutex? mutex, bool profileQueries = false}) {
100+
{Mutex? mutex, bool? profileQueries}) {
101101
return SyncSqliteConnection(raw, mutex ?? Mutex(),
102102
profileQueries: profileQueries);
103103
}
Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,64 @@
11
import 'dart:developer';
22

3-
/// Turns the [parameters] for an SQL query into a [Map] that can be serialized
4-
/// to JSON (as a requirement for using it as a timeline argument).
5-
Map parameterArgs(List<Object?> parameters) {
6-
return {
7-
'parameters': [
8-
for (final parameter in parameters)
9-
if (parameter is List) '<blob>' else parameter
10-
],
11-
};
12-
}
13-
14-
Map timelineArgs(String sql, List<Object?> parameters) {
15-
return parameterArgs(parameters)..['sql'] = sql;
16-
}
17-
183
extension TimeSync on TimelineTask? {
194
T timeSync<T>(String name, TimelineSyncFunction<T> function,
20-
{Map? arguments}) {
5+
{String? sql, List<Object?>? parameters}) {
216
final currentTask = this;
227
if (currentTask == null) {
238
return function();
249
}
2510

11+
final (resolvedName, args) =
12+
profilerNameAndArgs(name, sql: sql, parameters: parameters);
13+
currentTask.start(resolvedName, arguments: args);
14+
2615
try {
27-
currentTask.start(name, arguments: arguments);
2816
return function();
2917
} finally {
3018
currentTask.finish();
3119
}
3220
}
21+
22+
Future<T> timeAsync<T>(String name, TimelineSyncFunction<Future<T>> function,
23+
{String? sql, List<Object?>? parameters}) {
24+
final currentTask = this;
25+
if (currentTask == null) {
26+
return function();
27+
}
28+
29+
final (resolvedName, args) =
30+
profilerNameAndArgs(name, sql: sql, parameters: parameters);
31+
currentTask.start(resolvedName, arguments: args);
32+
33+
return Future.sync(function).whenComplete(() {
34+
currentTask.finish();
35+
});
36+
}
37+
}
38+
39+
(String, Map) profilerNameAndArgs(String name,
40+
{String? sql, List<Object?>? parameters}) {
41+
// On native platforms, we want static names for tasks because every
42+
// unique key here shows up in a separate line in Perfetto: https://github.com/dart-lang/sdk/issues/56274
43+
// On the web however, the names are embedded in the timeline slices and
44+
// it's convenient to include the SQL there.
45+
const isWeb = bool.fromEnvironment('dart.library.js_interop');
46+
var resolvedName = '$profilerPrefix$name';
47+
if (isWeb && sql != null) {
48+
resolvedName = ' $sql';
49+
}
50+
51+
return (
52+
resolvedName,
53+
{
54+
if (sql != null) 'sql': sql,
55+
if (parameters != null)
56+
'parameters': [
57+
for (final parameter in parameters)
58+
if (parameter is List) '<blob>' else parameter
59+
],
60+
}
61+
);
3362
}
63+
64+
const profilerPrefix = 'sqlite_async:';

packages/sqlite_async/lib/src/web/database.dart

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,15 @@ class _SharedContext implements SqliteReadContext {
207207
@override
208208
Future<ResultSet> getAll(String sql,
209209
[List<Object?> parameters = const []]) async {
210-
try {
211-
_task?.start('getAll', arguments: timelineArgs(sql, parameters));
212-
return await wrapSqliteException(
213-
() => _database._database.select(sql, parameters));
214-
} finally {
215-
_task?.finish();
216-
}
210+
return _task.timeAsync(
211+
'getAll',
212+
sql: sql,
213+
parameters: parameters,
214+
() async {
215+
return await wrapSqliteException(
216+
() => _database._database.select(sql, parameters));
217+
},
218+
);
217219
}
218220

219221
@override
@@ -237,21 +239,23 @@ class _ExclusiveContext extends _SharedContext implements SqliteWriteContext {
237239
_ExclusiveContext(super.database);
238240

239241
@override
240-
Future<ResultSet> execute(String sql,
241-
[List<Object?> parameters = const []]) async {
242-
return wrapSqliteException(
243-
() => _database._database.select(sql, parameters));
242+
Future<ResultSet> execute(String sql, [List<Object?> parameters = const []]) {
243+
return _task.timeAsync('execute', sql: sql, parameters: parameters, () {
244+
return wrapSqliteException(
245+
() => _database._database.select(sql, parameters));
246+
});
244247
}
245248

246249
@override
247-
Future<void> executeBatch(
248-
String sql, List<List<Object?>> parameterSets) async {
249-
return wrapSqliteException(() async {
250-
for (final set in parameterSets) {
251-
// use execute instead of select to avoid transferring rows from the
252-
// worker to this context.
253-
await _database._database.execute(sql, set);
254-
}
250+
Future<void> executeBatch(String sql, List<List<Object?>> parameterSets) {
251+
return _task.timeAsync('executeBatch', sql: sql, () {
252+
return wrapSqliteException(() async {
253+
for (final set in parameterSets) {
254+
// use execute instead of select to avoid transferring rows from the
255+
// worker to this context.
256+
await _database._database.execute(sql, set);
257+
}
258+
});
255259
});
256260
}
257261
}
@@ -312,23 +316,19 @@ class _ExclusiveTransactionContext extends _ExclusiveContext {
312316
@override
313317
Future<ResultSet> execute(String sql,
314318
[List<Object?> parameters = const []]) async {
315-
try {
316-
_task?.start('execute', arguments: timelineArgs(sql, parameters));
317-
return await _executeInternal(sql, parameters);
318-
} finally {
319-
_task?.finish();
320-
}
319+
return _task.timeAsync('execute', sql: sql, parameters: parameters, () {
320+
return _executeInternal(sql, parameters);
321+
});
321322
}
322323

323324
@override
324325
Future<void> executeBatch(
325326
String sql, List<List<Object?>> parameterSets) async {
326-
return await wrapSqliteException(() async {
327+
return _task.timeAsync('executeBatch', sql: sql, () async {
327328
for (final set in parameterSets) {
328329
await _database._database.customRequest(CustomDatabaseMessage(
329330
CustomDatabaseMessageKind.executeBatchInTransaction, sql, set));
330331
}
331-
return;
332332
});
333333
}
334334
}

packages/sqlite_async/lib/src/web/worker/throttled_common_database.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ class ThrottledCommonDatabase extends CommonDatabase {
2424
required List<Object?> parameters,
2525
}) {
2626
if (profileQueries) {
27-
return Timeline.timeSync(
28-
name,
29-
function,
30-
arguments: timelineArgs(sql, parameters),
31-
);
27+
final (resolvedName, args) =
28+
profilerNameAndArgs(name, sql: sql, parameters: parameters);
29+
30+
return Timeline.timeSync(resolvedName, function, arguments: args);
3231
} else {
3332
return function();
3433
}

0 commit comments

Comments
 (0)