mirror of https://github.com/AMT-Cheif/drift.git
Avoid analyzing unfinished views
This commit is contained in:
parent
c0fc691a94
commit
c0865e51fb
|
@ -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/errors.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/results.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/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/analyzer/sql_queries/query_analyzer.dart';
|
||||||
import 'package:moor_generator/src/model/view.dart';
|
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
import 'package:sqlparser/utils/find_referenced_tables.dart';
|
import 'package:sqlparser/utils/find_referenced_tables.dart';
|
||||||
|
|
||||||
|
@ -20,15 +18,16 @@ class EntityHandler extends BaseAnalyzer {
|
||||||
AnalyzeMoorStep step,
|
AnalyzeMoorStep step,
|
||||||
this.file,
|
this.file,
|
||||||
List<MoorTable> availableTables,
|
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);
|
_referenceResolver = _ReferenceResolvingVisitor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<CreateTriggerStatement, MoorTrigger> _triggers = {};
|
final Map<CreateTriggerStatement, MoorTrigger> _triggers = {};
|
||||||
final Map<TableInducingStatement, MoorTable> _tables = {};
|
final Map<TableInducingStatement, MoorTable> _tables = {};
|
||||||
final Map<CreateIndexStatement, MoorIndex> _indexes = {};
|
final Map<CreateIndexStatement, MoorIndex> _indexes = {};
|
||||||
final Map<CreateViewStatement, MoorView> _views = {};
|
|
||||||
|
|
||||||
_ReferenceResolvingVisitor _referenceResolver;
|
_ReferenceResolvingVisitor _referenceResolver;
|
||||||
|
|
||||||
|
@ -61,23 +60,13 @@ class EntityHandler extends BaseAnalyzer {
|
||||||
|
|
||||||
_lint(node, 'special @create table');
|
_lint(node, 'special @create table');
|
||||||
entity.references.addAll(_findTables(node.statement));
|
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) {
|
void _lint(AstNode node, String displayName) {
|
||||||
final context = engine.analyzeNode(node, file.parseResult.sql);
|
final context = engine.analyzeNode(node, file.parseResult.sql);
|
||||||
context.errors.forEach(report);
|
lintContext(context, displayName);
|
||||||
|
|
||||||
final linter = Linter(context, mapper);
|
|
||||||
linter.reportLints();
|
|
||||||
reportLints(linter.lints, name: displayName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<MoorTable> _findTables(AstNode node) {
|
Iterable<MoorTable> _findTables(AstNode node) {
|
||||||
|
@ -86,12 +75,6 @@ class EntityHandler extends BaseAnalyzer {
|
||||||
return tablesFinder.foundTables.map(mapper.tableToMoor);
|
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) {
|
Iterable<WrittenMoorTable> _findUpdatedTables(AstNode node) {
|
||||||
final finder = UpdatedTablesVisitor();
|
final finder = UpdatedTablesVisitor();
|
||||||
node.acceptWithoutArg(finder);
|
node.acceptWithoutArg(finder);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class AnalyzeMoorStep extends AnalyzingStep {
|
||||||
.followedBy(parseResult.declaredViews)
|
.followedBy(parseResult.declaredViews)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
EntityHandler(this, parseResult, availableTables, availableViews).handle();
|
EntityHandler(this, parseResult, availableTables).handle();
|
||||||
|
|
||||||
ViewAnalyzer(this, availableTables, availableViews).resolve();
|
ViewAnalyzer(this, availableTables, availableViews).resolve();
|
||||||
|
|
||||||
|
|
|
@ -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/errors.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/file_graph.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/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/model/sql_query.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/query_handler.dart';
|
import 'package:moor_generator/src/analyzer/sql_queries/query_handler.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
||||||
|
@ -35,6 +36,16 @@ abstract class BaseAnalyzer {
|
||||||
return _engine;
|
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
|
@protected
|
||||||
void report(AnalysisError error, {String Function() msg, Severity severity}) {
|
void report(AnalysisError error, {String Function() msg, Severity severity}) {
|
||||||
if (step.file.type == FileType.moor) {
|
if (step.file.type == FileType.moor) {
|
||||||
|
|
|
@ -5,8 +5,12 @@ import 'package:moor_generator/src/model/view.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
class ViewAnalyzer extends BaseAnalyzer {
|
class ViewAnalyzer extends BaseAnalyzer {
|
||||||
ViewAnalyzer(Step step, List<MoorTable> tables, List<MoorView> views)
|
final List<MoorView> viewsToAnalyze;
|
||||||
: super(tables, views, step);
|
|
||||||
|
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;
|
List<MoorView> _viewsOrder;
|
||||||
Set<MoorView> _resolvedViews;
|
Set<MoorView> _resolvedViews;
|
||||||
|
@ -16,7 +20,7 @@ class ViewAnalyzer extends BaseAnalyzer {
|
||||||
_viewsOrder = [];
|
_viewsOrder = [];
|
||||||
_resolvedViews = {};
|
_resolvedViews = {};
|
||||||
// Topologically sorting all the views.
|
// Topologically sorting all the views.
|
||||||
for (final view in views) {
|
for (final view in viewsToAnalyze) {
|
||||||
if (!_resolvedViews.contains(view)) {
|
if (!_resolvedViews.contains(view)) {
|
||||||
_topologicalSort(view);
|
_topologicalSort(view);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +36,8 @@ class ViewAnalyzer extends BaseAnalyzer {
|
||||||
}
|
}
|
||||||
final ctx =
|
final ctx =
|
||||||
engine.analyzeNode(view.declaration.node, view.file.parseResult.sql);
|
engine.analyzeNode(view.declaration.node, view.file.parseResult.sql);
|
||||||
|
lintContext(ctx, view.name);
|
||||||
|
|
||||||
view.parserView = const SchemaFromCreateTable(moorExtensions: true)
|
view.parserView = const SchemaFromCreateTable(moorExtensions: true)
|
||||||
.readView(ctx, view.declaration.creatingStatement);
|
.readView(ctx, view.declaration.creatingStatement);
|
||||||
engine.registerView(mapper.extractView(view));
|
engine.registerView(mapper.extractView(view));
|
||||||
|
|
|
@ -57,8 +57,6 @@ void main() {
|
||||||
|
|
||||||
state.close();
|
state.close();
|
||||||
|
|
||||||
// Currently failing:
|
|
||||||
// is it a problem with sqlparser?
|
|
||||||
expect(file.errors.errors, isEmpty);
|
expect(file.errors.errors, isEmpty);
|
||||||
expect(column.type.type, BasicType.text);
|
expect(column.type.type, BasicType.text);
|
||||||
});
|
});
|
||||||
|
@ -83,4 +81,27 @@ void main() {
|
||||||
contains('Could not find t.'),
|
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.'),
|
||||||
|
)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue