Skip to content

Commit

Permalink
Add interceptor example to docs
Browse files Browse the repository at this point in the history
  • Loading branch information
simolus3 committed Nov 7, 2023
1 parent 446832c commit b096e84
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
92 changes: 92 additions & 0 deletions docs/lib/snippets/log_interceptor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'dart:async';
import 'dart:io';

import 'package:drift/drift.dart';
import 'package:drift/native.dart';

// #docregion class
class LogInterceptor extends QueryInterceptor {
Future<T> _run<T>(
String description, FutureOr<T> Function() operation) async {
final stopwatch = Stopwatch()..start();
print('Running $description');

try {
final result = await operation();
print(' => succeeded after ${stopwatch.elapsedMilliseconds}ms');
return result;
} on Object catch (e) {
print(' => failed after ${stopwatch.elapsedMilliseconds}ms ($e)');
rethrow;
}
}

@override
TransactionExecutor beginTransaction(QueryExecutor parent) {
print('begin');
return super.beginTransaction(parent);
}

@override
Future<void> commitTransaction(TransactionExecutor inner) {
return _run('commit', () => inner.send());
}

@override
Future<void> rollbackTransaction(TransactionExecutor inner) {
return _run('rollback', () => inner.rollback());
}

@override
Future<void> runBatched(
QueryExecutor executor, BatchedStatements statements) {
return _run(
'batch with $statements', () => executor.runBatched(statements));
}

@override
Future<int> runInsert(
QueryExecutor executor, String statement, List<Object?> args) {
return _run(
'$statement with $args', () => executor.runInsert(statement, args));
}

@override
Future<int> runUpdate(
QueryExecutor executor, String statement, List<Object?> args) {
return _run(
'$statement with $args', () => executor.runUpdate(statement, args));
}

@override
Future<int> runDelete(
QueryExecutor executor, String statement, List<Object?> args) {
return _run(
'$statement with $args', () => executor.runDelete(statement, args));
}

@override
Future<void> runCustom(
QueryExecutor executor, String statement, List<Object?> args) {
return _run(
'$statement with $args', () => executor.runCustom(statement, args));
}

@override
Future<List<Map<String, Object?>>> runSelect(
QueryExecutor executor, String statement, List<Object?> args) {
return _run(
'$statement with $args', () => executor.runSelect(statement, args));
}
}
// #enddocregion class

void use() {
final myDatabaseFile = File('/dev/null');

// #docregion use
NativeDatabase.createInBackground(
myDatabaseFile,
).interceptWith(LogInterceptor());
// #enddocregion use
}
24 changes: 24 additions & 0 deletions docs/pages/docs/Examples/tracing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
data:
title: "Tracing database operations"
description: Using the `QueryInterceptor` API to log details about database operations.
template: layouts/docs/single
---

{% assign snippets = 'package:drift_docs/snippets/log_interceptor.dart.excerpt.json' | readString | json_decode %}

Drift provides the relatively simple `logStatements` option to print the statements it
executes.
The `QueryInterceptor` API can be used to extend this logging to provide more information,
which this example will show.

{% include "blocks/snippet" snippets=snippets name="class" %}

Interceptors can be applied with the `interceptWith` extension on `QueryExecutor` and
`DatabaseConnection`:

{% include "blocks/snippet" snippets=snippets name="use" %}

The `QueryInterceptor` class is pretty powerful, as it allows you to fully control the underlying
database connection. You could also use it to retry some failing statements or to aggregate
statistics about query times to an external monitoring service.
31 changes: 31 additions & 0 deletions docs/test/snippet_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:drift_docs/snippets/dart_api/datetime_conversion.dart';
import 'package:drift_docs/snippets/log_interceptor.dart';
import 'package:drift_docs/snippets/modular/schema_inspection.dart';
import 'package:test/test.dart';

Expand Down Expand Up @@ -117,4 +118,34 @@ void main() {
expect(row.name, 'bar');
});
});

test('interceptor', () {
expect(
() async {
final db =
Database(NativeDatabase.memory().interceptWith(LogInterceptor()));

await db.batch((batch) {
batch.insert(db.users, UsersCompanion.insert(name: 'foo'));
});

await db.users.all().get();
},
prints(
allOf(
stringContainsInOrder(
[
'begin',
'Running batch with BatchedStatements',
' => succeeded after ',
'Running commit',
' => succeeded after ',
'Running SELECT * FROM "users"; with []',
' => succeeded after'
],
),
),
),
);
});
}

0 comments on commit b096e84

Please sign in to comment.