Skip to content

Commit 2ebac2e

Browse files
committed
feat: Allow profiling queries
1 parent 6d85217 commit 2ebac2e

File tree

10 files changed

+293
-114
lines changed

10 files changed

+293
-114
lines changed

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

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import 'dart:developer';
2+
13
import 'package:sqlite3/common.dart';
24
import 'package:sqlite_async/src/common/mutex.dart';
35
import 'package:sqlite_async/src/sqlite_connection.dart';
46
import 'package:sqlite_async/src/sqlite_queries.dart';
57
import 'package:sqlite_async/src/update_notification.dart';
8+
import 'package:sqlite_async/src/utils/profiler.dart';
69

710
/// A simple "synchronous" connection which provides the async SqliteConnection
811
/// implementation using a synchronous SQLite connection
@@ -14,7 +17,12 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
1417

1518
bool _closed = false;
1619

17-
SyncSqliteConnection(this.db, Mutex m) {
20+
/// Whether queries should be added to the `dart:developer` timeline.
21+
///
22+
/// This is disabled by default.
23+
final bool profileQueries;
24+
25+
SyncSqliteConnection(this.db, Mutex m, {this.profileQueries = false}) {
1826
mutex = m.open();
1927
updates = db.updates.map(
2028
(event) {
@@ -26,15 +34,31 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
2634
@override
2735
Future<T> readLock<T>(Future<T> Function(SqliteReadContext tx) callback,
2836
{Duration? lockTimeout, String? debugContext}) {
29-
return mutex.lock(() => callback(SyncReadContext(db)),
30-
timeout: lockTimeout);
37+
final task = profileQueries ? TimelineTask() : null;
38+
task?.start('mutex_lock');
39+
40+
return mutex.lock(
41+
() {
42+
task?.finish();
43+
return callback(SyncReadContext(db, parent: task));
44+
},
45+
timeout: lockTimeout,
46+
);
3147
}
3248

3349
@override
3450
Future<T> writeLock<T>(Future<T> Function(SqliteWriteContext tx) callback,
3551
{Duration? lockTimeout, String? debugContext}) {
36-
return mutex.lock(() => callback(SyncWriteContext(db)),
37-
timeout: lockTimeout);
52+
final task = profileQueries ? TimelineTask() : null;
53+
task?.start('mutex_lock');
54+
55+
return mutex.lock(
56+
() {
57+
task?.finish();
58+
return callback(SyncWriteContext(db));
59+
},
60+
timeout: lockTimeout,
61+
);
3862
}
3963

4064
@override
@@ -53,9 +77,12 @@ class SyncSqliteConnection extends SqliteConnection with SqliteQueries {
5377
}
5478

5579
class SyncReadContext implements SqliteReadContext {
80+
final TimelineTask? task;
81+
5682
CommonDatabase db;
5783

58-
SyncReadContext(this.db);
84+
SyncReadContext(this.db, {TimelineTask? parent})
85+
: task = TimelineTask(parent: parent);
5986

6087
@override
6188
Future<T> computeWithDatabase<T>(
@@ -65,13 +92,21 @@ class SyncReadContext implements SqliteReadContext {
6592

6693
@override
6794
Future<Row> get(String sql, [List<Object?> parameters = const []]) async {
68-
return db.select(sql, parameters).first;
95+
return task.timeSync(
96+
'get',
97+
() => db.select(sql, parameters).first,
98+
arguments: timelineArgs(sql, parameters),
99+
);
69100
}
70101

71102
@override
72103
Future<ResultSet> getAll(String sql,
73104
[List<Object?> parameters = const []]) async {
74-
return db.select(sql, parameters);
105+
return task.timeSync(
106+
'getAll',
107+
() => db.select(sql, parameters),
108+
arguments: timelineArgs(sql, parameters),
109+
);
75110
}
76111

77112
@override
@@ -91,26 +126,31 @@ class SyncReadContext implements SqliteReadContext {
91126
}
92127

93128
class SyncWriteContext extends SyncReadContext implements SqliteWriteContext {
94-
SyncWriteContext(super.db);
129+
SyncWriteContext(super.db, {super.parent});
95130

96131
@override
97132
Future<ResultSet> execute(String sql,
98133
[List<Object?> parameters = const []]) async {
99-
return db.select(sql, parameters);
134+
return task.timeSync(
135+
'execute',
136+
() => db.select(sql, parameters),
137+
arguments: timelineArgs(sql, parameters),
138+
);
100139
}
101140

102141
@override
103142
Future<void> executeBatch(
104143
String sql, List<List<Object?>> parameterSets) async {
105-
return computeWithDatabase((db) async {
144+
task.timeSync('executeBatch', () {
106145
final statement = db.prepare(sql, checkNoTail: true);
107146
try {
108147
for (var parameters in parameterSets) {
109-
statement.execute(parameters);
148+
task.timeSync('iteration', () => statement.execute(parameters),
149+
arguments: parameterArgs(parameters));
110150
}
111151
} finally {
112152
statement.dispose();
113153
}
114-
});
154+
}, arguments: {'sql': sql});
115155
}
116156
}

0 commit comments

Comments
 (0)