Avoid analyzing unfinished views

This commit is contained in:
Simon Binder 2021-02-11 22:03:25 +01:00
parent c0fc691a94
commit c0865e51fb
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
5 changed files with 49 additions and 28 deletions

View File

@ -2,9 +2,7 @@ import 'package:moor_generator/moor_generator.dart';
import 'package:moor_generator/src/analyzer/errors.dart';
import 'package:moor_generator/src/analyzer/runner/results.dart';
import 'package:moor_generator/src/analyzer/runner/steps.dart';
import 'package:moor_generator/src/analyzer/sql_queries/lints/linter.dart';
import 'package:moor_generator/src/analyzer/sql_queries/query_analyzer.dart';
import 'package:moor_generator/src/model/view.dart';
import 'package:sqlparser/sqlparser.dart';
import 'package:sqlparser/utils/find_referenced_tables.dart';
@ -20,15 +18,16 @@ class EntityHandler extends BaseAnalyzer {
AnalyzeMoorStep step,
this.file,
List<MoorTable> availableTables,
List<MoorView> availableViews,
) : super(availableTables, availableViews, step) {
) :
// we'll analyze views later, so pass an empty list for now. Otherwise
// the incomplete views would be added to the engine.
super(availableTables, const [], step) {
_referenceResolver = _ReferenceResolvingVisitor(this);
}
final Map<CreateTriggerStatement, MoorTrigger> _triggers = {};
final Map<TableInducingStatement, MoorTable> _tables = {};
final Map<CreateIndexStatement, MoorIndex> _indexes = {};
final Map<CreateViewStatement, MoorView> _views = {};
_ReferenceResolvingVisitor _referenceResolver;
@ -61,23 +60,13 @@ class EntityHandler extends BaseAnalyzer {
_lint(node, 'special @create table');
entity.references.addAll(_findTables(node.statement));
} else if (entity is MoorView) {
final node =
_handleMoorDeclaration(entity, _views) as CreateViewStatement;
_lint(node, node.viewName);
entity.references.addAll(_findTables(node.query));
entity.references.addAll(_findViews(node.query));
}
}
}
void _lint(AstNode node, String displayName) {
final context = engine.analyzeNode(node, file.parseResult.sql);
context.errors.forEach(report);
final linter = Linter(context, mapper);
linter.reportLints();
reportLints(linter.lints, name: displayName);
lintContext(context, displayName);
}
Iterable<MoorTable> _findTables(AstNode node) {
@ -86,12 +75,6 @@ class EntityHandler extends BaseAnalyzer {
return tablesFinder.foundTables.map(mapper.tableToMoor);
}
Iterable<MoorView> _findViews(AstNode node) {
final tablesFinder = ReferencedTablesVisitor();
node.acceptWithoutArg(tablesFinder);
return tablesFinder.foundViews.map(mapper.viewToMoor);
}
Iterable<WrittenMoorTable> _findUpdatedTables(AstNode node) {
final finder = UpdatedTablesVisitor();
node.acceptWithoutArg(finder);

View File

@ -22,7 +22,7 @@ class AnalyzeMoorStep extends AnalyzingStep {
.followedBy(parseResult.declaredViews)
.toList();
EntityHandler(this, parseResult, availableTables, availableViews).handle();
EntityHandler(this, parseResult, availableTables).handle();
ViewAnalyzer(this, availableTables, availableViews).resolve();

View File

@ -4,6 +4,7 @@ import 'package:moor_generator/moor_generator.dart';
import 'package:moor_generator/src/analyzer/errors.dart';
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
import 'package:moor_generator/src/analyzer/runner/steps.dart';
import 'package:moor_generator/src/analyzer/sql_queries/lints/linter.dart';
import 'package:moor_generator/src/model/sql_query.dart';
import 'package:moor_generator/src/analyzer/sql_queries/query_handler.dart';
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
@ -35,6 +36,16 @@ abstract class BaseAnalyzer {
return _engine;
}
@protected
void lintContext(AnalysisContext context, String displayName) {
context.errors.forEach(report);
// Additional, moor-specific analysis
final linter = Linter(context, mapper);
linter.reportLints();
reportLints(linter.lints, name: displayName);
}
@protected
void report(AnalysisError error, {String Function() msg, Severity severity}) {
if (step.file.type == FileType.moor) {

View File

@ -5,8 +5,12 @@ import 'package:moor_generator/src/model/view.dart';
import 'package:sqlparser/sqlparser.dart';
class ViewAnalyzer extends BaseAnalyzer {
ViewAnalyzer(Step step, List<MoorTable> tables, List<MoorView> views)
: super(tables, views, step);
final List<MoorView> viewsToAnalyze;
ViewAnalyzer(Step step, List<MoorTable> tables, this.viewsToAnalyze)
: // We're about to analyze views and add them to the engine, but don't
// add the unfinished views right away
super(tables, const [], step);
List<MoorView> _viewsOrder;
Set<MoorView> _resolvedViews;
@ -16,7 +20,7 @@ class ViewAnalyzer extends BaseAnalyzer {
_viewsOrder = [];
_resolvedViews = {};
// Topologically sorting all the views.
for (final view in views) {
for (final view in viewsToAnalyze) {
if (!_resolvedViews.contains(view)) {
_topologicalSort(view);
}
@ -32,6 +36,8 @@ class ViewAnalyzer extends BaseAnalyzer {
}
final ctx =
engine.analyzeNode(view.declaration.node, view.file.parseResult.sql);
lintContext(ctx, view.name);
view.parserView = const SchemaFromCreateTable(moorExtensions: true)
.readView(ctx, view.declaration.creatingStatement);
engine.registerView(mapper.extractView(view));

View File

@ -57,8 +57,6 @@ void main() {
state.close();
// Currently failing:
// is it a problem with sqlparser?
expect(file.errors.errors, isEmpty);
expect(column.type.type, BasicType.text);
});
@ -83,4 +81,27 @@ void main() {
contains('Could not find t.'),
)));
});
test('does not allow nested columns', () async {
final state = TestState.withContent({
'foo|lib/a.moor': '''
CREATE TABLE foo (bar INTEGER NOT NULL PRIMARY KEY);
CREATE VIEW v AS SELECT foo.** FROM foo;
''',
});
final file = await state.analyze('package:foo/a.moor');
state.close();
expect(
file.errors.errors,
contains(isA<MoorError>().having(
(e) => e.message,
'message',
contains('Nested star columns may only appear in a top-level select '
'query.'),
)));
});
}