Provide hint on join that includes same table twice

This commit is contained in:
Simon Binder 2019-06-25 22:09:56 +02:00
parent 12e8c31b71
commit 178df7ab1e
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
2 changed files with 44 additions and 1 deletions

View File

@ -9,3 +9,21 @@ class InvalidDataException implements Exception {
return 'InvalidDataException: $message';
}
}
/// A wrapper class for internal exceptions thrown by the underlying database
/// engine when moor can give additional context or help.
///
/// For instance, when we know that an invalid statement has been constructed,
/// we catch the database exception and try to explain why that has happened.
class MoorWrappedException implements Exception {
final String message;
final dynamic cause;
final StackTrace trace;
MoorWrappedException({this.message, this.cause, this.trace});
@override
String toString() {
return '$cause at \n$trace\nMoor detected a possible cause for this: $message';
}
}

View File

@ -118,7 +118,18 @@ class JoinedSelectStatement<FirstT extends Table, FirstD extends DataClass>
Future<List<TypedResult>> _getWithQuery(GenerationContext ctx) async {
final results = await ctx.executor.doWhenOpened((e) async {
return await e.runSelect(ctx.sql, ctx.boundVariables);
try {
return await e.runSelect(ctx.sql, ctx.boundVariables);
} catch (e, s) {
final foundTables = <String>{};
for (var table in _tables) {
if (!foundTables.add(table.$tableName)) {
_warnAboutDuplicate(e, s, table);
}
}
rethrow;
}
});
final tables = _tables;
@ -139,6 +150,20 @@ class JoinedSelectStatement<FirstT extends Table, FirstD extends DataClass>
return TypedResult(map, QueryRow(row, database));
}).toList();
}
@alwaysThrows
void _warnAboutDuplicate(dynamic cause, StackTrace trace, TableInfo table) {
throw MoorWrappedException(
message:
'This query contained the table ${table.actualTableName} more than '
'once. Is this a typo? \n'
'If you need a join that includes the same table more than once, you '
'need to alias() at least one table. See https://moor.simonbinder.eu/queries/joins#aliases '
'for an example.',
cause: cause,
trace: trace,
);
}
}
/// A select statement that doesn't use joins