Rename customSelectQuery to just customSelect

Also fix a crash in the builder
This commit is contained in:
Simon Binder 2020-02-17 20:43:42 +01:00
parent 8c4c6cd8cd
commit e2b65e968a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
19 changed files with 88 additions and 124 deletions

View File

@ -548,7 +548,7 @@ abstract class _$Database extends GeneratedDatabase {
}
Selectable<User> mostPopularUsersQuery(int amount) {
return customSelectQuery(
return customSelect(
'SELECT * FROM users u ORDER BY (SELECT COUNT(*) FROM friendships WHERE first_user = u.id OR second_user = u.id) DESC LIMIT :amount',
variables: [Variable.withInt(amount)],
readsFrom: {users, friendships}).map(_rowToUser);
@ -563,7 +563,7 @@ abstract class _$Database extends GeneratedDatabase {
}
Selectable<int> amountOfGoodFriendsQuery(int user) {
return customSelectQuery(
return customSelect(
'SELECT COUNT(*) FROM friendships f WHERE f.really_good_friends AND (f.first_user = :user OR f.second_user = :user)',
variables: [
Variable.withInt(user)
@ -582,7 +582,7 @@ abstract class _$Database extends GeneratedDatabase {
}
Selectable<User> friendsOfQuery(int user) {
return customSelectQuery(
return customSelect(
'SELECT u.* FROM friendships f\n INNER JOIN users u ON u.id IN (f.first_user, f.second_user) AND\n u.id != :user\n WHERE (f.first_user = :user OR f.second_user = :user)',
variables: [Variable.withInt(user)],
readsFrom: {friendships, users}).map(_rowToUser);
@ -597,7 +597,7 @@ abstract class _$Database extends GeneratedDatabase {
}
Selectable<int> userCountQuery() {
return customSelectQuery('SELECT COUNT(id) FROM users',
return customSelect('SELECT COUNT(id) FROM users',
variables: [],
readsFrom: {users}).map((QueryRow row) => row.readInt('COUNT(id)'));
}
@ -611,7 +611,7 @@ abstract class _$Database extends GeneratedDatabase {
}
Selectable<Preferences> settingsForQuery(int user) {
return customSelectQuery('SELECT preferences FROM users WHERE id = :user',
return customSelect('SELECT preferences FROM users WHERE id = :user',
variables: [Variable.withInt(user)], readsFrom: {users})
.map((QueryRow row) =>
$UsersTable.$converter0.mapToDart(row.readString('preferences')));
@ -629,7 +629,7 @@ abstract class _$Database extends GeneratedDatabase {
var $arrayStartIndex = 1;
final expandedvar1 = $expandVar($arrayStartIndex, var1.length);
$arrayStartIndex += var1.length;
return customSelectQuery('SELECT * FROM users WHERE id IN ($expandedvar1)',
return customSelect('SELECT * FROM users WHERE id IN ($expandedvar1)',
variables: [for (var $ in var1) Variable.withInt($)],
readsFrom: {users}).map(_rowToUser);
}

View File

@ -47,7 +47,7 @@ void main() {
test('saves the database after creating it', () async {
var db = _FakeDb(WebDatabase('foo'), 1);
// ensure the database is opened
await db.customSelectQuery('SELECT 1').get();
await db.customSelect('SELECT 1').get();
await db.close();
db = _FakeDb(WebDatabase('foo'), 1);
@ -58,12 +58,12 @@ void main() {
test('saves the database after an update', () async {
var db = _FakeDb(WebDatabase('foo'), 1);
await db.customSelectQuery('SELECT 1').get();
await db.customSelect('SELECT 1').get();
await db.close();
// run a migration to version 2
db = _FakeDb(WebDatabase('foo'), 2);
await db.customSelectQuery('SELECT 1').get();
await db.customSelect('SELECT 1').get();
await db.close();
db = _FakeDb(WebDatabase('foo'), 2);

View File

@ -8,6 +8,8 @@
- __Breaking__: Remove the second type variable on `Expression` and subclasses.
- __Breaking__: Remove `InsertStatement.insertAll` (use batches instead) and `insert(orReplace: true)`
(use `mode: InsertMode.orReplace` instead).
- __Breaking__: Remove `customSelectStream` from `QueryEngine`. The `customSelect`
method now returns an `Selectable` (like `customSelectQuery`, which in turn has been deprecated).
- Experimentally support IndexedDB to store sqlite data on the web
## 2.4.0

View File

@ -6,6 +6,7 @@ targets:
override_hash_and_equals_in_result_sets: true
use_column_name_as_json_key_when_defined_in_moor_file: true
generate_connect_constructor: true
compact_query_methods: true
write_from_json_string_constructor: true
use_experimental_inference: true
sqlite_modules:

View File

@ -862,21 +862,13 @@ abstract class _$Database extends GeneratedDatabase {
);
}
Selectable<TotalWeightResult> _totalWeightQuery() {
return customSelectQuery(
Selectable<TotalWeightResult> _totalWeight() {
return customSelect(
'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',
variables: [],
readsFrom: {recipes, ingredientInRecipes}).map(_rowToTotalWeightResult);
}
Future<List<TotalWeightResult>> _totalWeight() {
return _totalWeightQuery().get();
}
Stream<List<TotalWeightResult>> _watchTotalWeight() {
return _totalWeightQuery().watch();
}
@override
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
@override

View File

@ -204,31 +204,6 @@ mixin QueryEngine on DatabaseConnectionUser {
return result;
}
/// Executes a custom select statement once. To use the variables, mark them
/// with a "?" in your [query]. They will then be changed to the appropriate
/// value.
@protected
@visibleForTesting
@Deprecated('use customSelectQuery(...).get() instead')
Future<List<QueryRow>> customSelect(String query,
{List<Variable> variables = const []}) async {
return customSelectQuery(query, variables: variables).get();
}
/// Creates a stream from a custom select statement.To use the variables, mark
/// them with a "?" in your [query]. They will then be changed to the
/// appropriate value. The stream will re-emit items when any table in
/// [readsFrom] changes, so be sure to set it to the set of tables your query
/// reads data from.
@protected
@visibleForTesting
@Deprecated('use customSelectQuery(...).watch() instead')
Stream<List<QueryRow>> customSelectStream(String query,
{List<Variable> variables = const [], Set<TableInfo> readsFrom}) {
return customSelectQuery(query, variables: variables, readsFrom: readsFrom)
.watch();
}
/// Creates a custom select statement from the given sql [query]. To run the
/// query once, use [Selectable.get]. For an auto-updating streams, set the
/// set of tables the ready [readsFrom] and use [Selectable.watch]. If you
@ -240,13 +215,29 @@ mixin QueryEngine on DatabaseConnectionUser {
/// bound to the [variables] you specify on this query.
@protected
@visibleForTesting
Selectable<QueryRow> customSelectQuery(String query,
Selectable<QueryRow> customSelect(String query,
{List<Variable> variables = const [],
Set<TableInfo> readsFrom = const {}}) {
readsFrom ??= {};
return CustomSelectStatement(query, variables, readsFrom, _resolvedEngine);
}
/// Creates a custom select statement from the given sql [query]. To run the
/// query once, use [Selectable.get]. For an auto-updating streams, set the
/// set of tables the ready [readsFrom] and use [Selectable.watch]. If you
/// know the query will never emit more than one row, you can also use
/// [Selectable.getSingle] and [Selectable.watchSingle] which return the item
/// directly or wrapping it into a list.
///
/// If you use variables in your query (for instance with "?"), they will be
/// bound to the [variables] you specify on this query.
@Deprecated('Renamed to customSelect')
Selectable<QueryRow> customSelectQuery(String query,
{List<Variable> variables = const [],
Set<TableInfo> readsFrom = const {}}) {
return customSelect(query, variables: variables, readsFrom: readsFrom);
}
/// Executes the custom sql [statement] on the database.
@protected
@visibleForTesting

View File

@ -22,7 +22,6 @@ dev_dependencies:
path: ../moor_ffi
path: ^1.6.4
build_runner: '>=1.3.0 <2.0.0'
build_test: ^0.10.8
test: ^1.9.0
mockito: ^4.1.0

View File

@ -49,7 +49,7 @@ void main() {
]);
});
final rows = await db.customSelectQuery('').get();
final rows = await db.customSelect('').get();
final row = rows.single;
expect(row.readBool('bool'), isTrue);

View File

@ -1149,7 +1149,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<Config> readConfig(String var1) {
return customSelectQuery('SELECT * FROM config WHERE config_key = ?',
return customSelect('SELECT * FROM config WHERE config_key = ?',
variables: [Variable.withString(var1)],
readsFrom: {config}).map(_rowToConfig);
}
@ -1160,7 +1160,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
$arrayStartIndex += var1.length;
final generatedclause = $write(clause);
$arrayStartIndex += generatedclause.amountOfVariables;
return customSelectQuery(
return customSelect(
'SELECT * FROM config WHERE config_key IN ($expandedvar1) ORDER BY ${generatedclause.sql}',
variables: [
for (var $ in var1) Variable.withString($),
@ -1173,8 +1173,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
Selectable<Config> readDynamic(Expression<bool> predicate) {
final generatedpredicate = $write(predicate);
return customSelectQuery(
'SELECT * FROM config WHERE ${generatedpredicate.sql}',
return customSelect('SELECT * FROM config WHERE ${generatedpredicate.sql}',
variables: [...generatedpredicate.introducedVariables],
readsFrom: {config}).map(_rowToConfig);
}
@ -1187,7 +1186,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<TableValuedResult> tableValued() {
return customSelectQuery(
return customSelect(
'SELECT "key", "value"\n FROM config, json_each(config.config_value)\n WHERE json_valid(config_value)',
variables: [],
readsFrom: {config}).map(_rowToTableValuedResult);
@ -1205,7 +1204,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
Selectable<MultipleResult> multiple(Expression<bool> predicate) {
final generatedpredicate = $write(predicate, hasMultipleTables: true);
return customSelectQuery(
return customSelect(
'SELECT * FROM with_constraints c\n INNER JOIN with_defaults d\n ON d.a = c.a AND d.b = c.b\n WHERE ${generatedpredicate.sql}',
variables: [...generatedpredicate.introducedVariables],
readsFrom: {withConstraints, withDefaults}).map(_rowToMultipleResult);
@ -1220,7 +1219,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<EMail> searchEmails(String term) {
return customSelectQuery(
return customSelect(
'SELECT * FROM email WHERE email MATCH :term ORDER BY rank',
variables: [Variable.withString(term)],
readsFrom: {email}).map(_rowToEMail);
@ -1237,14 +1236,14 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
Selectable<ReadRowIdResult> readRowId(Expression<int> expr) {
final generatedexpr = $write(expr);
return customSelectQuery(
return customSelect(
'SELECT oid, * FROM config WHERE _rowid_ = ${generatedexpr.sql}',
variables: [...generatedexpr.introducedVariables],
readsFrom: {config}).map(_rowToReadRowIdResult);
}
Selectable<int> cfeTest() {
return customSelectQuery(
return customSelect(
'WITH RECURSIVE\n cnt(x) AS (\n SELECT 1\n UNION ALL\n SELECT x+1 FROM cnt\n LIMIT 1000000\n )\n SELECT x FROM cnt',
variables: [],
readsFrom: {}).map((QueryRow row) => row.readInt('x'));

View File

@ -1328,8 +1328,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
);
}
Selectable<AllTodosWithCategoryResult> allTodosWithCategoryQuery() {
return customSelectQuery(
Selectable<AllTodosWithCategoryResult> allTodosWithCategory() {
return customSelect(
'SELECT t.*, c.id as catId, c."desc" as catDesc FROM todos t INNER JOIN categories c ON c.id = t.category',
variables: [],
readsFrom: {
@ -1338,14 +1338,6 @@ abstract class _$TodoDb extends GeneratedDatabase {
}).map(_rowToAllTodosWithCategoryResult);
}
Future<List<AllTodosWithCategoryResult>> allTodosWithCategory() {
return allTodosWithCategoryQuery().get();
}
Stream<List<AllTodosWithCategoryResult>> watchAllTodosWithCategory() {
return allTodosWithCategoryQuery().watch();
}
Future<int> deleteTodoById(int var1) {
return customUpdate(
'DELETE FROM todos WHERE id = ?',
@ -1364,11 +1356,11 @@ abstract class _$TodoDb extends GeneratedDatabase {
);
}
Selectable<TodoEntry> withInQuery(String var1, String var2, List<int> var3) {
Selectable<TodoEntry> withIn(String var1, String var2, List<int> var3) {
var $arrayStartIndex = 3;
final expandedvar3 = $expandVar($arrayStartIndex, var3.length);
$arrayStartIndex += var3.length;
return customSelectQuery(
return customSelect(
'SELECT * FROM todos WHERE title = ?2 OR id IN ($expandedvar3) OR title = ?1',
variables: [
Variable.withString(var1),
@ -1380,32 +1372,15 @@ abstract class _$TodoDb extends GeneratedDatabase {
}).map(_rowToTodoEntry);
}
Future<List<TodoEntry>> withIn(String var1, String var2, List<int> var3) {
return withInQuery(var1, var2, var3).get();
}
Stream<List<TodoEntry>> watchWithIn(
String var1, String var2, List<int> var3) {
return withInQuery(var1, var2, var3).watch();
}
Selectable<TodoEntry> searchQuery(int id) {
return customSelectQuery(
Selectable<TodoEntry> search(int id) {
return customSelect(
'SELECT * FROM todos WHERE CASE WHEN -1 = :id THEN 1 ELSE id = :id END',
variables: [Variable.withInt(id)],
readsFrom: {todosTable}).map(_rowToTodoEntry);
}
Future<List<TodoEntry>> search(int id) {
return searchQuery(id).get();
}
Stream<List<TodoEntry>> watchSearch(int id) {
return searchQuery(id).watch();
}
Selectable<MyCustomObject> findCustomQuery() {
return customSelectQuery(
Selectable<MyCustomObject> findCustom() {
return customSelect(
'SELECT custom FROM table_without_p_k WHERE some_float < 10',
variables: [],
readsFrom: {tableWithoutPK})
@ -1413,14 +1388,6 @@ abstract class _$TodoDb extends GeneratedDatabase {
.mapToDart(row.readString('custom')));
}
Future<List<MyCustomObject>> findCustom() {
return findCustomQuery().get();
}
Stream<List<MyCustomObject>> watchFindCustom() {
return findCustomQuery().watch();
}
@override
Iterable<TableInfo> get allTables => allSchemaEntities.whereType<TableInfo>();
@override
@ -1493,18 +1460,10 @@ mixin _$SomeDaoMixin on DatabaseAccessor<TodoDb> {
);
}
Selectable<TodoEntry> todosForUserQuery(int user) {
return customSelectQuery(
Selectable<TodoEntry> todosForUser(int user) {
return customSelect(
'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: [Variable.withInt(user)],
readsFrom: {todosTable, sharedTodos, users}).map(_rowToTodoEntry);
}
Future<List<TodoEntry>> todosForUser(int user) {
return todosForUserQuery(user).get();
}
Stream<List<TodoEntry>> watchTodosForUser(int user) {
return todosForUserQuery(user).watch();
}
}

View File

@ -18,7 +18,7 @@ class _FakeDb extends GeneratedDatabase {
},
beforeOpen: (details) async {
// this fake select query is verified via mocks
await customSelectQuery(
await customSelect(
'opened: ${details.versionBefore} to ${details.versionNow}')
.get();
},

View File

@ -130,7 +130,7 @@ void _runTests(
.customStatement('create table tbl (id integer primary key not null)');
Future<void> expectRowCount(TodoDb db, int count) async {
final rows = await db.customSelectQuery('select * from tbl').get();
final rows = await db.customSelect('select * from tbl').get();
expect(rows, hasLength(count));
}
@ -155,12 +155,12 @@ void _runTests(
test("can't run queries on a closed database", () async {
final db = TodoDb.connect(isolateConnection);
await db.customSelectQuery('SELECT 1;').getSingle();
await db.customSelect('SELECT 1;').getSingle();
await db.close();
await expectLater(
() => db.customSelectQuery('SELECT 1;').getSingle(), throwsStateError);
() => db.customSelect('SELECT 1;').getSingle(), throwsStateError);
});
}

View File

@ -158,7 +158,7 @@ void main() {
when(executor.runSelect(any, any))
.thenAnswer((_) => Future.error(exception));
final result = db.customSelectQuery('select 1').watch().first;
final result = db.customSelect('select 1').watch().first;
expectLater(result, throwsA(exception));
});

View File

@ -49,7 +49,7 @@ void main() {
final transaction = db.transaction(() async {
stream = db
.customSelectQuery(
.customSelect(
'SELECT _mocked_',
readsFrom: {db.users},
)

View File

@ -52,7 +52,7 @@ void main() {
final db = TodoDb(LazyDatabase(() => inner));
// run a statement to make sure the database has been opened
await db.customSelectQuery('custom_select').get();
await db.customSelect('custom_select').get();
verify(inner.databaseInfo = db);
});

View File

@ -56,12 +56,8 @@ class MoorDartParser {
return (method.body as ExpressionFunctionBody).expression;
}
Future<ElementDeclarationResult> loadElementDeclaration(
Element element) async {
final resolvedLibrary = await element.library.session
.getResolvedLibraryByElement(element.library);
return resolvedLibrary.getElementDeclaration(element);
Future<ElementDeclarationResult> loadElementDeclaration(Element element) {
return step.task.backend.loadElementDeclaration(element);
}
String readStringLiteral(Expression expression, void Function() onError) {

View File

@ -1,3 +1,4 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:logging/logging.dart';
@ -32,6 +33,14 @@ abstract class BackendTask {
throw UnsupportedError('Resolving dart expressions not supported');
}
Future<ElementDeclarationResult> loadElementDeclaration(
Element element) async {
final resolvedLibrary = await element.library.session
.getResolvedLibraryByElement(element.library);
return resolvedLibrary.getElementDeclaration(element);
}
/// Checks whether a file at [uri] exists.
Future<bool> exists(Uri uri);

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:build/build.dart' hide log;
@ -24,6 +25,8 @@ class BuildBackendTask extends BackendTask {
final BuildBackend backend;
final TypeDeserializer typeDeserializer;
final Map<AssetId, ResolvedLibraryResult> _cachedResults = {};
BuildBackendTask(this.step, this.backend)
: typeDeserializer = TypeDeserializer(step);
@ -42,15 +45,28 @@ class BuildBackendTask extends BackendTask {
@override
Future<LibraryElement> resolveDart(Uri uri) async {
try {
final library = await step.resolver.libraryFor(_resolve(uri));
// older versions of the resolver used to return null instead of throwing
if (library == null) throw NotALibraryException(uri);
final asset = _resolve(uri);
final library = await step.resolver.libraryFor(asset);
_cachedResults[asset] =
await library.session.getResolvedLibraryByElement(library);
return library;
} on NonLibraryAssetException catch (_) {
throw NotALibraryException(uri);
}
}
@override
Future<ElementDeclarationResult> loadElementDeclaration(
Element element) async {
// prefer to use a cached value in case the session changed because another
// dart file was read...
final assetId = await step.resolver.assetIdForElement(element);
final result = _cachedResults[assetId];
return result.getElementDeclaration(element) ??
await super.loadElementDeclaration(element);
}
@override
Logger get log => build.log;

View File

@ -142,7 +142,7 @@ class QueryWriter {
_buffer.write(') {\n');
_writeExpandedDeclarations();
_buffer.write('return customSelectQuery(${_queryCode()}, ');
_buffer.write('return customSelect(${_queryCode()}, ');
_writeVariables();
_buffer.write(', ');
_writeReadsFrom();