diff --git a/floor_generator/lib/model/query_method.dart b/floor_generator/lib/model/query_method.dart index 1d3367e7..73c8a8e8 100644 --- a/floor_generator/lib/model/query_method.dart +++ b/floor_generator/lib/model/query_method.dart @@ -5,7 +5,7 @@ import 'package:floor_generator/misc/constants.dart'; import 'package:floor_generator/model/entity.dart'; import 'package:source_gen/source_gen.dart'; -/// Raps a method annotated with Query +/// Wraps a method annotated with Query /// to enable easy access to code generation relevant data. class QueryMethod { final MethodElement method; @@ -13,7 +13,7 @@ class QueryMethod { QueryMethod(final this.method); /// Query as defined in by user in Dart code. - String get rawQuery { + String get _rawQuery { final query = method.metadata .firstWhere(isQueryAnnotation) .computeConstantValue() @@ -21,15 +21,24 @@ class QueryMethod { .toStringValue(); if (query.isEmpty || query == null) { - throw InvalidGenerationSourceError("You didn't define a query.", - element: method); + throw InvalidGenerationSourceError( + "You didn't define a query.", + element: method, + ); } return query; } /// Query where ':' got replaced with '$'. - String get query => rawQuery.replaceAll(RegExp(':'), '\$'); + String get query => _rawQuery.replaceAll(RegExp(':'), r'$'); + + List get queryParameterNames { + return RegExp(r'\$.[^\s]+') + .allMatches(query) + .map((match) => match.group(0).replaceFirst(RegExp(r'\$'), '')) + .toList(); + } String get name => method.displayName; diff --git a/floor_generator/lib/writer/query_method_writer.dart b/floor_generator/lib/writer/query_method_writer.dart index 7dffa00b..3f05ddcb 100644 --- a/floor_generator/lib/writer/query_method_writer.dart +++ b/floor_generator/lib/writer/query_method_writer.dart @@ -15,12 +15,13 @@ class QueryMethodWriter implements Writer { @override Method write() { - return _generateQueryMethod(queryMethod); + return _generateQueryMethod(); } - Method _generateQueryMethod(final QueryMethod queryMethod) { + Method _generateQueryMethod() { _assertReturnsFuture(); _assertReturnsEntity(); + _assertQueryParameters(); return Method((builder) => builder ..annotations.add(overrideAnnotationExpression) @@ -113,17 +114,41 @@ class QueryMethodWriter implements Writer { '''; } + void _assertQueryParameters() { + final queryParameterNames = queryMethod.queryParameterNames; + final methodSignatureParameterNames = + queryMethod.parameters.map((parameter) => parameter.name).toList(); + + final sameAmountParameters = + queryParameterNames.length == methodSignatureParameterNames.length; + + final allParametersAreAvailable = queryParameterNames.every( + (parameterName) => + methodSignatureParameterNames.any((name) => name == parameterName)); + + if (!allParametersAreAvailable || !sameAmountParameters) { + throw InvalidGenerationSourceError( + "Parameters of method signature don't match with parameters in the query.", + element: queryMethod.method, + ); + } + } + void _assertReturnsFuture() { if (!queryMethod.rawReturnType.isDartAsyncFuture) { - throw InvalidGenerationSourceError('All queries have to return a Future.', - element: queryMethod.method); + throw InvalidGenerationSourceError( + 'All queries have to return a Future.', + element: queryMethod.method, + ); } } void _assertReturnsEntity() { if (!queryMethod.returnsEntity(library)) { - throw InvalidGenerationSourceError('The return type is not an entity.', - element: queryMethod.method); + throw InvalidGenerationSourceError( + 'The return type is not an entity.', + element: queryMethod.method, + ); } } } diff --git a/floor_test/test/database.dart b/floor_test/test/database.dart index 7f9baf89..db72d605 100644 --- a/floor_test/test/database.dart +++ b/floor_test/test/database.dart @@ -14,7 +14,7 @@ abstract class TestDatabase extends FloorDatabase { @Query('SELECT * FROM person WHERE id = :id') Future findPersonById(int id); - @Query('SELECT * FROM person WHERE id = :id AND name = :name') + @Query('SELECT * FROM person WHERE id = :id AND custom_name = :name') Future findPersonByIdAndName(int id, String name); @insert