mirror of https://github.com/AMT-Cheif/drift.git
Breaking changes for the upcoming version
1. Removes transaction parameter in callbacks, custom queries 2. Removes MigrationStrategy.onFinished
This commit is contained in:
parent
3097bb0591
commit
c8ae99b52e
|
@ -98,7 +98,7 @@ class Database extends _$Database {
|
|||
await m.createTable(friendships);
|
||||
}
|
||||
},
|
||||
beforeOpen: (_, details) async {
|
||||
beforeOpen: (details) async {
|
||||
if (details.wasCreated) {
|
||||
await into(users)
|
||||
.insertAll([People.dash, People.duke, People.gopher]);
|
||||
|
@ -108,7 +108,7 @@ class Database extends _$Database {
|
|||
}
|
||||
|
||||
Future<void> deleteUser(User user, {bool fail = false}) {
|
||||
return transaction((_) async {
|
||||
return transaction(() async {
|
||||
final id = user.id;
|
||||
await (delete(friendships)
|
||||
..where((f) => or(f.firstUser.equals(id), f.secondUser.equals(id))))
|
||||
|
|
|
@ -9,7 +9,7 @@ void transactionTests(TestExecutor executor) {
|
|||
final db = Database(executor.createExecutor());
|
||||
|
||||
// ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
|
||||
await db.transaction((_) async {
|
||||
await db.transaction(() async {
|
||||
final florianId = await db.writeUser(People.florian);
|
||||
|
||||
final dash = await db.getUserById(People.dashId);
|
||||
|
@ -32,7 +32,7 @@ void transactionTests(TestExecutor executor) {
|
|||
|
||||
try {
|
||||
// ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
|
||||
await db.transaction((_) async {
|
||||
await db.transaction(() async {
|
||||
final florianId = await db.writeUser(People.florian);
|
||||
|
||||
final dash = await db.getUserById(People.dashId);
|
||||
|
|
|
@ -1,3 +1,36 @@
|
|||
## 2.0.0
|
||||
This is the first major update after the initial release and moor and we have a lot to cover.
|
||||
... Finally, we also removed a variety of deprecated features. See the breaking changes
|
||||
section to learn what components are affected and what alternatives are available.
|
||||
|
||||
TODO: Properly describe these additions when they're finalized:
|
||||
|
||||
- Queries and imports in `.moor` files
|
||||
- Analyzer plugin for Dart Code
|
||||
- `ffi` libraries
|
||||
|
||||
### Breaking changes
|
||||
- __THIS LIKELY AFFECTS YOUR APP:__ Removed the `transaction` parameter for callbacks
|
||||
in transactions and `beforeOpen` callbacks. So, instead of writing
|
||||
```dart
|
||||
transaction((t) async {
|
||||
await t.update(table)...;
|
||||
});
|
||||
```
|
||||
simply write
|
||||
```dart
|
||||
transaction(() async {
|
||||
await update(table)...;
|
||||
});
|
||||
```
|
||||
Similarly, instead of using `onOpen: (db, details) async {...}`, use
|
||||
`onOpen: (details) async {...}`. You don't have to worry about calling methods on
|
||||
your database instead of a transaction objects. They will be delegated automatically.
|
||||
|
||||
On a similar note, we also removed the `operateOn` parameter from compiled queries.
|
||||
|
||||
- Removed `MigrationStrategy.onFinished`. Use `beforeOpen` instead.
|
||||
|
||||
## 1.7.2
|
||||
- Fixed a race condition that caused the database to be opened multiple times on slower devices.
|
||||
This problem was introduced in `1.7.0` and was causing problems during migrations.
|
||||
|
|
|
@ -59,10 +59,9 @@ class Database extends _$Database {
|
|||
@override
|
||||
MigrationStrategy get migration {
|
||||
return MigrationStrategy(
|
||||
beforeOpen: (engine, details) async {
|
||||
beforeOpen: (details) async {
|
||||
// populate data
|
||||
await engine
|
||||
.into(categories)
|
||||
await into(categories)
|
||||
.insert(const CategoriesCompanion(description: Value('Sweets')));
|
||||
},
|
||||
);
|
||||
|
|
|
@ -847,19 +847,15 @@ abstract class _$Database extends GeneratedDatabase {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<TotalWeightResult> _totalWeightQuery(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<TotalWeightResult> _totalWeightQuery() {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
' SELECT r.title, SUM(ir.amount) AS total_weight\n FROM recipes r\n INNER JOIN recipe_ingredients ir ON ir.recipe = r.id\n GROUP BY r.id\n ',
|
||||
variables: [],
|
||||
readsFrom: {recipes, ingredientInRecipes}).map(_rowToTotalWeightResult);
|
||||
}
|
||||
|
||||
Future<List<TotalWeightResult>> _totalWeight(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return _totalWeightQuery(operateOn: operateOn).get();
|
||||
Future<List<TotalWeightResult>> _totalWeight() {
|
||||
return _totalWeightQuery().get();
|
||||
}
|
||||
|
||||
Stream<List<TotalWeightResult>> _watchTotalWeight() {
|
||||
|
|
|
@ -28,7 +28,7 @@ class Database extends _$Database {
|
|||
MigrationStrategy get migration {
|
||||
return MigrationStrategy(
|
||||
onCreate: (m) async => await m.createAllTables(),
|
||||
beforeOpen: (engine, details) async {
|
||||
beforeOpen: (details) async {
|
||||
if (details.wasCreated) {
|
||||
// populate default data
|
||||
await createTodoEntry(
|
||||
|
|
|
@ -280,10 +280,10 @@ mixin QueryEngine on DatabaseConnectionUser {
|
|||
/// inside a transaction returns the parent transaction.
|
||||
@protected
|
||||
@visibleForTesting
|
||||
Future transaction(Future Function(QueryEngine transaction) action) async {
|
||||
Future transaction(Future Function() action) async {
|
||||
final resolved = _resolvedEngine;
|
||||
if (resolved is Transaction) {
|
||||
return action(resolved);
|
||||
return action();
|
||||
}
|
||||
|
||||
final executor = resolved.executor;
|
||||
|
@ -294,7 +294,7 @@ mixin QueryEngine on DatabaseConnectionUser {
|
|||
return _runEngineZoned(transaction, () async {
|
||||
var success = false;
|
||||
try {
|
||||
await action(transaction);
|
||||
await action();
|
||||
success = true;
|
||||
} catch (e) {
|
||||
await transactionExecutor.rollback();
|
||||
|
@ -376,13 +376,11 @@ abstract class GeneratedDatabase extends DatabaseConnectionUser
|
|||
Future<void> beforeOpenCallback(
|
||||
QueryExecutor executor, OpeningDetails details) async {
|
||||
final migration = _resolvedMigration;
|
||||
if (migration.onFinished != null) {
|
||||
await migration.onFinished();
|
||||
}
|
||||
|
||||
if (migration.beforeOpen != null) {
|
||||
final engine = BeforeOpenEngine(this, executor);
|
||||
await _runEngineZoned(engine, () {
|
||||
return migration.beforeOpen(engine, details);
|
||||
return migration.beforeOpen(details);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@ typedef Future<void> OnMigrationFinished();
|
|||
/// Signature of a function that's called before a database is marked opened by
|
||||
/// moor, but after migrations took place. This is a suitable callback to to
|
||||
/// populate initial data or issue `PRAGMA` statements that you want to use.
|
||||
typedef OnBeforeOpen = Future<void> Function(
|
||||
QueryEngine db, OpeningDetails details);
|
||||
typedef OnBeforeOpen = Future<void> Function(OpeningDetails details);
|
||||
|
||||
Future<void> _defaultOnCreate(Migrator m) => m.createAllTables();
|
||||
Future<void> _defaultOnUpdate(Migrator m, int from, int to) async =>
|
||||
|
@ -33,14 +32,6 @@ class MigrationStrategy {
|
|||
/// happened at a lower [GeneratedDatabase.schemaVersion].
|
||||
final OnUpgrade onUpgrade;
|
||||
|
||||
/// Executes after the database is ready and all migrations ran, but before
|
||||
/// any other queries will be executed, making this method suitable to
|
||||
/// populate data.
|
||||
@Deprecated(
|
||||
'This callback is broken and only exists for backwards compatibility. '
|
||||
'Use beforeOpen instead')
|
||||
final OnMigrationFinished onFinished;
|
||||
|
||||
/// Executes after the database is ready to be used (ie. it has been opened
|
||||
/// and all migrations ran), but before any other queries will be sent. This
|
||||
/// makes it a suitable place to populate data after the database has been
|
||||
|
@ -51,8 +42,6 @@ class MigrationStrategy {
|
|||
this.onCreate = _defaultOnCreate,
|
||||
this.onUpgrade = _defaultOnUpdate,
|
||||
this.beforeOpen,
|
||||
@Deprecated('This callback is broken. Use beforeOpen instead')
|
||||
this.onFinished,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -819,10 +819,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<ConfigData> readConfig(
|
||||
String var1,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<ConfigData> readConfig(String var1) {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
'readConfig: SELECT * FROM config WHERE config_key = ?;',
|
||||
variables: [
|
||||
|
@ -833,11 +830,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
}).map(_rowToConfigData);
|
||||
}
|
||||
|
||||
Future<int> writeConfig(
|
||||
String key,
|
||||
String value,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Future<int> writeConfig(String key, String value) {
|
||||
return (operateOn ?? this).customInsert(
|
||||
'REPLACE INTO config VALUES (:key, :value)',
|
||||
variables: [
|
||||
|
|
|
@ -1312,9 +1312,7 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<AllTodosWithCategoryResult> allTodosWithCategoryQuery(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<AllTodosWithCategoryResult> allTodosWithCategoryQuery() {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
'SELECT t.*, c.id as catId, c."desc" as catDesc FROM todos t INNER JOIN categories c ON c.id = t.category',
|
||||
variables: [],
|
||||
|
@ -1324,20 +1322,15 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
}).map(_rowToAllTodosWithCategoryResult);
|
||||
}
|
||||
|
||||
Future<List<AllTodosWithCategoryResult>> allTodosWithCategory(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return allTodosWithCategoryQuery(operateOn: operateOn).get();
|
||||
Future<List<AllTodosWithCategoryResult>> allTodosWithCategory() {
|
||||
return allTodosWithCategoryQuery().get();
|
||||
}
|
||||
|
||||
Stream<List<AllTodosWithCategoryResult>> watchAllTodosWithCategory() {
|
||||
return allTodosWithCategoryQuery().watch();
|
||||
}
|
||||
|
||||
Future<int> deleteTodoById(
|
||||
int var1,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Future<int> deleteTodoById(int var1) {
|
||||
return (operateOn ?? this).customUpdate(
|
||||
'DELETE FROM todos WHERE id = ?',
|
||||
variables: [
|
||||
|
@ -1357,12 +1350,7 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<TodoEntry> withInQuery(
|
||||
String var1,
|
||||
String var2,
|
||||
List<int> var3,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<TodoEntry> withInQuery(String var1, String var2, List<int> var3) {
|
||||
var $highestIndex = 3;
|
||||
final expandedvar3 = $expandVar($highestIndex, var3.length);
|
||||
$highestIndex += var3.length;
|
||||
|
@ -1378,13 +1366,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
}).map(_rowToTodoEntry);
|
||||
}
|
||||
|
||||
Future<List<TodoEntry>> withIn(
|
||||
String var1,
|
||||
String var2,
|
||||
List<int> var3,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return withInQuery(var1, var2, var3, operateOn: operateOn).get();
|
||||
Future<List<TodoEntry>> withIn(String var1, String var2, List<int> var3) {
|
||||
return withInQuery(var1, var2, var3).get();
|
||||
}
|
||||
|
||||
Stream<List<TodoEntry>> watchWithIn(
|
||||
|
@ -1392,10 +1375,7 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
return withInQuery(var1, var2, var3).watch();
|
||||
}
|
||||
|
||||
Selectable<TodoEntry> searchQuery(
|
||||
int id,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<TodoEntry> searchQuery(int id) {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
'SELECT * FROM todos WHERE CASE WHEN -1 = :id THEN 1 ELSE id = :id END',
|
||||
variables: [
|
||||
|
@ -1406,11 +1386,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
}).map(_rowToTodoEntry);
|
||||
}
|
||||
|
||||
Future<List<TodoEntry>> search(
|
||||
int id,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return searchQuery(id, operateOn: operateOn).get();
|
||||
Future<List<TodoEntry>> search(int id) {
|
||||
return searchQuery(id).get();
|
||||
}
|
||||
|
||||
Stream<List<TodoEntry>> watchSearch(int id) {
|
||||
|
@ -1424,19 +1401,15 @@ abstract class _$TodoDb extends GeneratedDatabase {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<FindCustomResult> findCustomQuery(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<FindCustomResult> findCustomQuery() {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
'SELECT custom FROM table_without_p_k WHERE some_float < 10',
|
||||
variables: [],
|
||||
readsFrom: {tableWithoutPK}).map(_rowToFindCustomResult);
|
||||
}
|
||||
|
||||
Future<List<FindCustomResult>> findCustom(
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return findCustomQuery(operateOn: operateOn).get();
|
||||
Future<List<FindCustomResult>> findCustom() {
|
||||
return findCustomQuery().get();
|
||||
}
|
||||
|
||||
Stream<List<FindCustomResult>> watchFindCustom() {
|
||||
|
@ -1498,10 +1471,7 @@ mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
|
|||
);
|
||||
}
|
||||
|
||||
Selectable<TodoEntry> todosForUserQuery(
|
||||
int user,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
Selectable<TodoEntry> todosForUserQuery(int user) {
|
||||
return (operateOn ?? this).customSelectQuery(
|
||||
'SELECT t.* FROM todos t INNER JOIN shared_todos st ON st.todo = t.id INNER JOIN users u ON u.id = st.user WHERE u.id = :user',
|
||||
variables: [
|
||||
|
@ -1514,11 +1484,8 @@ mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
|
|||
}).map(_rowToTodoEntry);
|
||||
}
|
||||
|
||||
Future<List<TodoEntry>> todosForUser(
|
||||
int user,
|
||||
{@Deprecated('No longer needed with Moor 1.6 - see the changelog for details')
|
||||
QueryEngine operateOn}) {
|
||||
return todosForUserQuery(user, operateOn: operateOn).get();
|
||||
Future<List<TodoEntry>> todosForUser(int user) {
|
||||
return todosForUserQuery(user).get();
|
||||
}
|
||||
|
||||
Stream<List<TodoEntry>> watchTodosForUser(int user) {
|
||||
|
|
|
@ -15,8 +15,9 @@ class _FakeDb extends GeneratedDatabase {
|
|||
onUpgrade: (m, from, to) async {
|
||||
await m.issueCustomQuery('updated from $from to $to');
|
||||
},
|
||||
beforeOpen: (db, details) async {
|
||||
await db.customSelect(
|
||||
beforeOpen: (details) async {
|
||||
// this fake select query is verified via mocks
|
||||
await customSelect(
|
||||
'opened: ${details.versionBefore} to ${details.versionNow}');
|
||||
},
|
||||
);
|
||||
|
|
|
@ -33,16 +33,16 @@ void main() {
|
|||
|
||||
test("transactions don't allow creating streams", () {
|
||||
expect(() async {
|
||||
await db.transaction((t) async {
|
||||
t.select(db.users).watch();
|
||||
await db.transaction(() async {
|
||||
db.select(db.users).watch();
|
||||
});
|
||||
}, throwsStateError);
|
||||
});
|
||||
|
||||
test('nested transactions use the outer transaction', () async {
|
||||
await db.transaction((t) async {
|
||||
await t.transaction((t2) async {
|
||||
expect(t2, equals(t));
|
||||
await db.transaction(() async {
|
||||
await db.transaction(() async {
|
||||
// todo how can we test that these are really equal?
|
||||
});
|
||||
|
||||
// the outer callback has not completed yet, so shouldn't send
|
||||
|
@ -55,7 +55,7 @@ void main() {
|
|||
test('code in callback uses transaction', () async {
|
||||
// notice how we call .select on the database, but it should be called on
|
||||
// transaction executor.
|
||||
await db.transaction((_) async {
|
||||
await db.transaction(() async {
|
||||
await db.select(db.users).get();
|
||||
});
|
||||
|
||||
|
@ -65,7 +65,7 @@ void main() {
|
|||
|
||||
test('transactions rollback after errors', () async {
|
||||
final exception = Exception('oh no');
|
||||
final future = db.transaction((_) async {
|
||||
final future = db.transaction(() async {
|
||||
throw exception;
|
||||
});
|
||||
|
||||
|
@ -79,8 +79,8 @@ void main() {
|
|||
when(executor.transactions.runUpdate(any, any))
|
||||
.thenAnswer((_) => Future.value(2));
|
||||
|
||||
await db.transaction((t) async {
|
||||
await t
|
||||
await db.transaction(() async {
|
||||
await db
|
||||
.update(db.users)
|
||||
.write(const UsersCompanion(name: Value('Updated name')));
|
||||
|
||||
|
@ -95,7 +95,7 @@ void main() {
|
|||
});
|
||||
|
||||
test('the database is opened before starting a transaction', () async {
|
||||
await db.transaction((t) async {
|
||||
await db.transaction(() async {
|
||||
verify(executor.doWhenOpened(any));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -63,7 +63,7 @@ class Database extends _$Database {
|
|||
await m.addColumn(todos, todos.targetDate);
|
||||
}
|
||||
},
|
||||
beforeOpen: (db, details) async {
|
||||
beforeOpen: (details) async {
|
||||
if (details.wasCreated) {
|
||||
// create default categories and entries
|
||||
final workId = await into(categories)
|
||||
|
@ -154,7 +154,7 @@ class Database extends _$Database {
|
|||
}
|
||||
|
||||
Future deleteCategory(Category category) {
|
||||
return transaction((t) async {
|
||||
return transaction(() async {
|
||||
await _resetCategory(category.id);
|
||||
await delete(categories).delete(category);
|
||||
});
|
||||
|
|
|
@ -9,9 +9,6 @@ import 'package:moor_generator/src/writer/writer.dart';
|
|||
import 'package:recase/recase.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
const queryEngineWarningDesc =
|
||||
'No longer needed with Moor 1.6 - see the changelog for details';
|
||||
|
||||
const highestAssignedIndexVar = '\$highestIndex';
|
||||
|
||||
/// Writes the handling code for a query. The code emitted will be a method that
|
||||
|
@ -157,9 +154,9 @@ class QueryWriter {
|
|||
}
|
||||
|
||||
_buffer.write('Stream<List<${_select.resultClassName}>> $methodName(');
|
||||
_writeParameters(dontOverrideEngine: true);
|
||||
_writeParameters();
|
||||
_buffer..write(') {\n')..write('return ${_nameOfCreationMethod()}(');
|
||||
_writeUseParameters(dontUseEngine: true);
|
||||
_writeUseParameters();
|
||||
_buffer.write(').watch();\n}\n');
|
||||
}
|
||||
|
||||
|
@ -187,7 +184,7 @@ class QueryWriter {
|
|||
_buffer..write(',);\n}\n');
|
||||
}
|
||||
|
||||
void _writeParameters({bool dontOverrideEngine = false}) {
|
||||
void _writeParameters() {
|
||||
final paramList = query.variables.map((v) {
|
||||
var dartType = dartTypeNames[v.type];
|
||||
if (v.isArray) {
|
||||
|
@ -197,25 +194,13 @@ class QueryWriter {
|
|||
}).join(', ');
|
||||
|
||||
_buffer.write(paramList);
|
||||
|
||||
// write named optional parameter to configure the query engine used to
|
||||
// execute the statement,
|
||||
if (!dontOverrideEngine) {
|
||||
if (query.variables.isNotEmpty) _buffer.write(', ');
|
||||
_buffer.write('{@Deprecated(${asDartLiteral(queryEngineWarningDesc)}) '
|
||||
'QueryEngine operateOn}');
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes code that uses the parameters as declared by [_writeParameters],
|
||||
/// assuming that for each parameter, a variable with the same name exists
|
||||
/// in the current scope.
|
||||
void _writeUseParameters({bool dontUseEngine = false}) {
|
||||
void _writeUseParameters() {
|
||||
_buffer.write(query.variables.map((v) => v.dartParameterName).join(', '));
|
||||
if (!dontUseEngine) {
|
||||
if (query.variables.isNotEmpty) _buffer.write(', ');
|
||||
_buffer.write('operateOn: operateOn');
|
||||
}
|
||||
}
|
||||
|
||||
// Some notes on parameters and generating query code:
|
||||
|
|
Loading…
Reference in New Issue