-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathsqlite_database.dart
106 lines (95 loc) · 4.35 KB
/
sqlite_database.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import 'dart:async';
import 'package:meta/meta.dart';
import 'package:sqlite_async/src/common/abstract_open_factory.dart';
import 'package:sqlite_async/src/common/isolate_connection_factory.dart';
import 'package:sqlite_async/src/impl/single_connection_database.dart';
import 'package:sqlite_async/src/impl/sqlite_database_impl.dart';
import 'package:sqlite_async/src/sqlite_options.dart';
import 'package:sqlite_async/src/sqlite_queries.dart';
import 'package:sqlite_async/src/update_notification.dart';
import 'package:sqlite_async/src/sqlite_connection.dart';
mixin SqliteDatabaseMixin implements SqliteConnection, SqliteQueries {
/// Maximum number of concurrent read transactions.
int get maxReaders;
/// Factory that opens a raw database connection in each isolate.
///
/// This must be safe to pass to different isolates.
///
/// Use a custom class for this to customize the open process.
AbstractDefaultSqliteOpenFactory get openFactory;
/// Use this stream to subscribe to notifications of updates to tables.
@override
Stream<UpdateNotification> get updates;
@protected
Future<void> get isInitialized;
/// Wait for initialization to complete.
///
/// While initializing is automatic, this helps to catch and report initialization errors.
Future<void> initialize() async {
await isInitialized;
}
/// A connection factory that can be passed to different isolates.
///
/// Use this to access the database in background isolates.
IsolateConnectionFactory isolateConnectionFactory();
}
/// A SQLite database instance.
///
/// Use one instance per database file. If multiple instances are used, update
/// notifications may not trigger, and calls may fail with "SQLITE_BUSY" errors.
abstract class SqliteDatabase
with SqliteQueries, SqliteDatabaseMixin
implements SqliteConnection {
/// The maximum number of concurrent read transactions if not explicitly specified.
static const int defaultMaxReaders = 5;
/// Open a SqliteDatabase.
///
/// Only a single SqliteDatabase per [path] should be opened at a time.
///
/// A connection pool is used by default, allowing multiple concurrent read
/// transactions, and a single concurrent write transaction. Write transactions
/// do not block read transactions, and read transactions will see the state
/// from the last committed write transaction.
///
/// A maximum of [maxReaders] concurrent read transactions are allowed.
factory SqliteDatabase(
{required path,
int maxReaders = SqliteDatabase.defaultMaxReaders,
SqliteOptions options = const SqliteOptions.defaults()}) {
return SqliteDatabaseImpl(
path: path, maxReaders: maxReaders, options: options);
}
/// Advanced: Open a database with a specified factory.
///
/// The factory is used to open each database connection in background isolates.
///
/// Use when control is required over the opening process. Examples include:
/// 1. Specifying the path to `libsqlite.so` on Linux.
/// 2. Running additional per-connection PRAGMA statements on each connection.
/// 3. Creating custom SQLite functions.
/// 4. Creating temporary views or triggers.
factory SqliteDatabase.withFactory(
AbstractDefaultSqliteOpenFactory openFactory,
{int maxReaders = SqliteDatabase.defaultMaxReaders}) {
return SqliteDatabaseImpl.withFactory(openFactory, maxReaders: maxReaders);
}
/// Opens a [SqliteDatabase] that only wraps an underlying connection.
///
/// This function may be useful in some instances like tests, but should not
/// typically be used by applications. Compared to the other ways to open
/// databases, it has the following downsides:
///
/// 1. No connection pool / concurrent readers for native databases.
/// 2. No reliable update notifications on the web.
/// 3. There is no reliable transaction management in Dart, and opening the
/// same database with [SqliteDatabase.singleConnection] multiple times
/// may cause "database is locked" errors.
///
/// Together with [SqliteConnection.synchronousWrapper], this can be used to
/// open in-memory databases (e.g. via [SqliteOpenFactory.open]). That
/// bypasses most convenience features, but may still be useful for
/// short-lived databases used in tests.
factory SqliteDatabase.singleConnection(SqliteConnection connection) {
return SingleConnectionDatabase(connection);
}
}