Skip to content

Commit

Permalink
Add support for running queries that return void (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitusortner authored Feb 24, 2019
1 parent b337055 commit 85566fa
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 8 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ For further examples take a look at the [example](https://github.com/vitusortner
## Querying
Method signatures turn into query methods by adding the `@Query()` annotation with the query in parenthesis to them.
Be patient about the correctness of your SQL statements.
The are only partly validated while generating the code.
These queries have to return an entity.
They are only partly validated while generating the code.
These queries have to return either a `Future` of an entity or `void`.
Returning `Future<void>` comes in handy whenever you want to delete the full content of a table.

````dart
@Query('SELECT * FROM Person WHERE id = :id')
Expand All @@ -138,6 +139,9 @@ Future<Person> findPersonByIdAndName(int id, String name);

@Query('SELECT * FROM Person')
Future<List<Person>> findAllPersons(); // select multiple items

@Query('DELETE FROM person')
Future<void> deleteAllPersons(); // query without returning an entity
````

## Persisting Data Changes
Expand Down Expand Up @@ -186,8 +190,7 @@ It's also required to add the `async` modifier. These methods can only return `F
```dart
@transaction
Future<void> replacePersons(List<Person> persons) async {
// execute SQL without automatically generated code
await database.execute('DELETE FROM Person');
await deleteAllPersons();
await insertPersons(persons);
}
```
Expand Down
4 changes: 4 additions & 0 deletions floor_generator/lib/model/query_method.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ class QueryMethod {
return isList(type);
}

bool get returnsVoid {
return method.returnType.flattenFutures(method.context.typeSystem).isVoid;
}

Entity getEntity(final LibraryReader library) {
final entity = _getEntities(library).firstWhere(
(entity) => entity.displayName == flattenedReturnType.displayName,
Expand Down
8 changes: 5 additions & 3 deletions floor_generator/lib/writer/query_method_writer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class QueryMethodWriter implements Writer {

Method _generateQueryMethod() {
_assertReturnsFuture();
_assertReturnsEntity();
_assertQueryParameters();

return Method((builder) => builder
Expand Down Expand Up @@ -106,11 +105,14 @@ class QueryMethodWriter implements Writer {
}

String _generateMethodBody() {
final mapping = _generateMapping();
if (queryMethod.returnsVoid) {
return "await database.rawQuery('${queryMethod.query}');";
}

_assertReturnsEntity();
return '''
final rows = await database.rawQuery('${queryMethod.query}');
$mapping
${_generateMapping()}
''';
}

Expand Down
31 changes: 30 additions & 1 deletion floor_test/test/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ abstract class TestDatabase extends FloorDatabase {

@transaction
Future<void> replacePersons(List<Person> persons) async {
await database.execute('DELETE FROM person');
await deleteAllPersons();
await insertPersons(persons);
}

Expand All @@ -67,6 +67,9 @@ abstract class TestDatabase extends FloorDatabase {

@Query('SELECT * FROM dog')
Future<List<Dog>> findAllDogs();

@Query('DELETE FROM person')
Future<void> deleteAllPersons();
}

@Entity(tableName: 'person')
Expand All @@ -77,6 +80,9 @@ class Person {
@ColumnInfo(name: 'custom_name', nullable: false)
final String name;

// @embedded
// final Address address;

Person(this.id, this.name);

@override
Expand Down Expand Up @@ -135,3 +141,26 @@ class Dog {
return 'Dog{id: $id, name: $name, ownerId: $ownerId}';
}
}

class Address {
final String street;
final String city;

Address(this.street, this.city);

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Address &&
runtimeType == other.runtimeType &&
street == other.street &&
city == other.city;

@override
int get hashCode => street.hashCode ^ city.hashCode;

@override
String toString() {
return 'Address{street: $street, city: $city}';
}
}
12 changes: 12 additions & 0 deletions floor_test/test/database_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ void main() {
expect(actual, isEmpty);
});
});

group('query with void return', () {
test('delete all persons', () async {
final persons = [Person(1, 'Simon'), Person(2, 'Frank')];
await database.insertPersons(persons);

await database.deleteAllPersons();
final actual = await database.findAllPersons();

expect(actual, isEmpty);
});
});
});
}

Expand Down

0 comments on commit 85566fa

Please sign in to comment.