From 178df7ab1e4f4cac7b02d2a625c49958fb669582 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 25 Jun 2019 22:09:56 +0200 Subject: [PATCH] Provide hint on join that includes same table twice --- moor/lib/src/runtime/exceptions.dart | 18 ++++++++++++++ moor/lib/src/runtime/statements/select.dart | 27 ++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/moor/lib/src/runtime/exceptions.dart b/moor/lib/src/runtime/exceptions.dart index ea8fa1ad..e084eecf 100644 --- a/moor/lib/src/runtime/exceptions.dart +++ b/moor/lib/src/runtime/exceptions.dart @@ -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'; + } +} diff --git a/moor/lib/src/runtime/statements/select.dart b/moor/lib/src/runtime/statements/select.dart index ea7bd5b0..b15c5069 100644 --- a/moor/lib/src/runtime/statements/select.dart +++ b/moor/lib/src/runtime/statements/select.dart @@ -118,7 +118,18 @@ class JoinedSelectStatement Future> _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 = {}; + for (var table in _tables) { + if (!foundTables.add(table.$tableName)) { + _warnAboutDuplicate(e, s, table); + } + } + + rethrow; + } }); final tables = _tables; @@ -139,6 +150,20 @@ class JoinedSelectStatement 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