mirror of https://github.com/AMT-Cheif/drift.git
Add more tests in moor_ffi subproject
This commit is contained in:
parent
0d56594933
commit
b99bc820da
|
@ -96,7 +96,9 @@ dev_dependencies:
|
|||
|
||||
In the file where you created a `FlutterQueryExecutor`, replace the `moor_flutter` import
|
||||
with both `package:moor/moor.dart` and `package:moor_ffi/moor_ffi.dart`.
|
||||
|
||||
In all other project files that use moor apis (e.g. a `Value` class for companions), just import `package:moor/moor.dart`.
|
||||
|
||||
Finally, replace usages of `FlutterQueryExecutor` with `VmDatabase`.
|
||||
Finally, replace usages of `FlutterQueryExecutor` with `VmDatabase`.
|
||||
|
||||
Note that, at the moment, there is no counterpart for `FlutterQueryExecutor.inDatabasePath` and that the async API using
|
||||
a background isolate is not available yet. Both shortcomings with be fixed by the upcoming moor 2.0 release.
|
|
@ -44,6 +44,7 @@ class Database implements BaseDatabase {
|
|||
if (resultCode == Errors.SQLITE_OK) {
|
||||
return Database._(dbPointer);
|
||||
} else {
|
||||
bindings.sqlite3_close_v2(dbPointer);
|
||||
throw SqliteException._fromErrorCode(dbPointer, resultCode);
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +57,12 @@ class Database implements BaseDatabase {
|
|||
|
||||
@override
|
||||
void close() {
|
||||
// close all prepared statements first
|
||||
_isClosed = true;
|
||||
for (var stmt in _preparedStmt) {
|
||||
stmt.close();
|
||||
}
|
||||
|
||||
final code = bindings.sqlite3_close_v2(_db);
|
||||
SqliteException exception;
|
||||
if (code != Errors.SQLITE_OK) {
|
||||
|
@ -63,10 +70,7 @@ class Database implements BaseDatabase {
|
|||
}
|
||||
_isClosed = true;
|
||||
|
||||
for (var stmt in _preparedStmt) {
|
||||
stmt.close();
|
||||
}
|
||||
_db.free();
|
||||
// we don't need to deallocate the _db pointer, sqlite takes care of that
|
||||
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
|
@ -82,6 +86,7 @@ class Database implements BaseDatabase {
|
|||
@override
|
||||
void execute(String sql) {
|
||||
_ensureOpen();
|
||||
|
||||
final sqlPtr = CBlob.allocateString(sql);
|
||||
final errorOut = Pointer<Pointer<CBlob>>.allocate();
|
||||
|
||||
|
@ -125,7 +130,10 @@ class Database implements BaseDatabase {
|
|||
throw SqliteException._fromErrorCode(_db, resultCode);
|
||||
}
|
||||
|
||||
return PreparedStatement._(stmt, this);
|
||||
final prepared = PreparedStatement._(stmt, this);
|
||||
_preparedStmt.add(prepared);
|
||||
|
||||
return prepared;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -48,6 +48,8 @@ class DbOperationProxy {
|
|||
final SendPort send;
|
||||
final Isolate isolate;
|
||||
|
||||
var closed = false;
|
||||
|
||||
int _currentRequestId = 0;
|
||||
|
||||
DbOperationProxy(
|
||||
|
@ -57,6 +59,10 @@ class DbOperationProxy {
|
|||
|
||||
Future<dynamic> sendRequest(IsolateCommandType type, dynamic data,
|
||||
{int preparedStmtId}) {
|
||||
if (closed) {
|
||||
throw StateError('Tried to call a database method after .close()');
|
||||
}
|
||||
|
||||
final id = _currentRequestId++;
|
||||
final cmd = IsolateCommand(id, type, data)
|
||||
..preparedStatementId = preparedStmtId;
|
||||
|
@ -80,6 +86,7 @@ class DbOperationProxy {
|
|||
}
|
||||
|
||||
void close() {
|
||||
closed = true;
|
||||
_receivePort.close();
|
||||
backgroundMsgs.close();
|
||||
isolate.kill();
|
||||
|
@ -128,7 +135,15 @@ class BackgroundIsolateRunner {
|
|||
final response = _handleCommand(data);
|
||||
send.send(IsolateResponse(data.requestId, response, null));
|
||||
} catch (e) {
|
||||
send.send(IsolateResponse(data.requestId, null, e));
|
||||
if (e is Error) {
|
||||
// errors contain a StackTrace, which cannot be sent. So we just
|
||||
// send the description of that stacktrace.
|
||||
final exception =
|
||||
Exception('Error in background isolate: $e\n${e.stackTrace}');
|
||||
send.send(IsolateResponse(data.requestId, null, exception));
|
||||
} else {
|
||||
send.send(IsolateResponse(data.requestId, null, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -22,7 +22,7 @@ class PreparedStatement implements BasePreparedStatement {
|
|||
|
||||
void _ensureNotFinalized() {
|
||||
if (_closed) {
|
||||
throw Exception('Tried to operate on a released prepared statement');
|
||||
throw StateError('Tried to operate on a released prepared statement');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
name: moor_ffi
|
||||
description: "Experimental moor implementation that uses dart:ffi"
|
||||
description: "Experimental sqlite bindings using dart:ffi"
|
||||
version: 0.0.1
|
||||
author:
|
||||
homepage:
|
||||
author: Simon Binder <oss@simonbinder.eu>
|
||||
homepage: https://github.com/simolus3/moor/tree/develop/moor_ffi
|
||||
issue_tracker: https://github.com/simolus3/moor/issues
|
||||
|
||||
environment:
|
||||
sdk: ">=2.5.0-dev <2.6.0"
|
||||
|
||||
dependencies:
|
||||
moor: ">=1.7.0 <2.1.0"
|
||||
# flutter:
|
||||
# sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.6.0
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:moor/moor.dart';
|
||||
import 'package:moor_ffi/src/ffi/blob.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test('utf8 store and load test', () {
|
||||
final content = 'Hasta Mañana';
|
||||
final blob = CBlob.allocateString(content);
|
||||
|
||||
expect(blob.load<CBlob>().readString(), content);
|
||||
blob.free();
|
||||
});
|
||||
|
||||
test('blob load and store test', () {
|
||||
final data = List.generate(256, (x) => x);
|
||||
final blob = CBlob.allocate(Uint8List.fromList(data));
|
||||
|
||||
expect(blob.load<CBlob>().read(256), data);
|
||||
blob.free();
|
||||
});
|
||||
}
|
|
@ -5,6 +5,8 @@ import 'package:path/path.dart' as p;
|
|||
import 'package:test/test.dart';
|
||||
import 'package:moor_ffi/database.dart';
|
||||
|
||||
import 'suite/insert.dart' as insert;
|
||||
import 'suite/prepared_statements.dart' as prepared_statements;
|
||||
import 'suite/select.dart' as select;
|
||||
import 'suite/user_version.dart' as user_version;
|
||||
|
||||
|
@ -59,6 +61,8 @@ void main() {
|
|||
}
|
||||
|
||||
void _declareAll(TestedDatabase db) {
|
||||
insert.main(db);
|
||||
prepared_statements.main(db);
|
||||
select.main(db);
|
||||
user_version.main(db);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:test/test.dart';
|
||||
|
||||
import '../runners.dart';
|
||||
|
||||
void main(TestedDatabase db) {
|
||||
test('insert statements report their id', () async {
|
||||
final opened = await db.openMemory();
|
||||
await opened
|
||||
.execute('CREATE TABLE tbl(a INTEGER PRIMARY KEY AUTOINCREMENT)');
|
||||
|
||||
for (var i = 0; i < 5; i++) {
|
||||
await opened.execute('INSERT INTO tbl DEFAULT VALUES');
|
||||
expect(await opened.getLastInsertId(), i + 1);
|
||||
}
|
||||
|
||||
await opened.close();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import 'package:test/test.dart';
|
||||
|
||||
import '../runners.dart';
|
||||
|
||||
void main(TestedDatabase db) {
|
||||
test('prepared statements can be used multiple times', () async {
|
||||
final opened = await db.openMemory();
|
||||
await opened.execute('CREATE TABLE tbl (a TEXT);');
|
||||
|
||||
final stmt = await opened.prepare('INSERT INTO tbl(a) VALUES(?)');
|
||||
await stmt.execute(['a']);
|
||||
await stmt.execute(['b']);
|
||||
await stmt.close();
|
||||
|
||||
final select = await opened.prepare('SELECT * FROM tbl ORDER BY a');
|
||||
final result = await select.select();
|
||||
|
||||
expect(result, hasLength(2));
|
||||
expect(result.map((row) => row['a']), ['a', 'b']);
|
||||
|
||||
await select.close();
|
||||
|
||||
await opened.close();
|
||||
});
|
||||
|
||||
test('prepared statements cannot be used after close', () async {
|
||||
final opened = await db.openMemory();
|
||||
|
||||
final stmt = await opened.prepare('SELECT ?');
|
||||
await stmt.close();
|
||||
|
||||
expect(stmt.select, throwsA(anything));
|
||||
|
||||
await opened.close();
|
||||
});
|
||||
|
||||
test('prepared statements cannot be used after db is closed', () async {
|
||||
final opened = await db.openMemory();
|
||||
final stmt = await opened.prepare('SELECT 1');
|
||||
await opened.close();
|
||||
|
||||
expect(stmt.select, throwsA(anything));
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue