mirror of https://github.com/AMT-Cheif/drift.git
Simple test for new query analyzer
This commit is contained in:
parent
b33ef8a220
commit
dcdbcb7156
|
@ -19,6 +19,19 @@ class FileState {
|
||||||
|
|
||||||
String get extension => url.extension(ownUri.path);
|
String get extension => url.extension(ownUri.path);
|
||||||
|
|
||||||
|
Iterable<DriftAnalysisError> get allErrors sync* {
|
||||||
|
yield* errorsDuringDiscovery;
|
||||||
|
|
||||||
|
for (final entry in analysis.values) {
|
||||||
|
yield* entry.errorsDuringAnalysis;
|
||||||
|
}
|
||||||
|
|
||||||
|
final fileResults = fileAnalysis;
|
||||||
|
if (fileResults != null) {
|
||||||
|
yield* fileResults.analysisErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool get isFullyAnalyzed {
|
bool get isFullyAnalyzed {
|
||||||
return discovery != null &&
|
return discovery != null &&
|
||||||
discovery!.locallyDefinedElements
|
discovery!.locallyDefinedElements
|
||||||
|
|
|
@ -44,7 +44,7 @@ class FileAnalyzer {
|
||||||
final genericEngineForParsing = driver.newSqlEngine();
|
final genericEngineForParsing = driver.newSqlEngine();
|
||||||
final source = await driver.backend.readAsString(state.ownUri);
|
final source = await driver.backend.readAsString(state.ownUri);
|
||||||
final parsedFile =
|
final parsedFile =
|
||||||
genericEngineForParsing.parse(source).rootNode as DriftFile;
|
genericEngineForParsing.parseDriftFile(source).rootNode as DriftFile;
|
||||||
|
|
||||||
for (final elementAnalysis in state.analysis.values) {
|
for (final elementAnalysis in state.analysis.values) {
|
||||||
final element = elementAnalysis.result;
|
final element = elementAnalysis.result;
|
||||||
|
@ -52,12 +52,13 @@ class FileAnalyzer {
|
||||||
final engine =
|
final engine =
|
||||||
driver.typeMapping.newEngineWithTables(element.references);
|
driver.typeMapping.newEngineWithTables(element.references);
|
||||||
final stmt = parsedFile.statements
|
final stmt = parsedFile.statements
|
||||||
.firstWhere((e) => e.firstPosition == element.sqlOffset)
|
.whereType<DeclaredStatement>()
|
||||||
as DeclaredStatement;
|
.firstWhere(
|
||||||
|
(e) => e.statement.firstPosition == element.sqlOffset);
|
||||||
final options = _createOptionsAndVars(engine, stmt);
|
final options = _createOptionsAndVars(engine, stmt);
|
||||||
|
|
||||||
final analysisResult =
|
final analysisResult = engine.analyzeNode(stmt.statement, source,
|
||||||
engine.analyzeNode(stmt, source, stmtOptions: options.options);
|
stmtOptions: options.options);
|
||||||
|
|
||||||
final analyzer = QueryAnalyzer(analysisResult, driver,
|
final analyzer = QueryAnalyzer(analysisResult, driver,
|
||||||
references: element.references,
|
references: element.references,
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../../test_utils.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('select from view', () async {
|
||||||
|
final backend = TestBackend.inTest({
|
||||||
|
'foo|lib/a.drift': '''
|
||||||
|
CREATE TABLE artists (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE albums (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
artist INTEGER NOT NULL REFERENCES artists (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tracks (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
album INTEGER NOT NULL REFERENCES albums (id),
|
||||||
|
duration_seconds INTEGER NOT NULL,
|
||||||
|
was_single BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE VIEW total_duration_by_artist_view AS
|
||||||
|
SELECT a.*, SUM(tracks.duration_seconds) AS duration
|
||||||
|
FROM artists a
|
||||||
|
INNER JOIN albums ON albums.artist = a.id
|
||||||
|
INNER JOIN tracks ON tracks.album = albums.id
|
||||||
|
GROUP BY a.id;
|
||||||
|
|
||||||
|
totalDurationByArtist:
|
||||||
|
SELECT * FROM total_duration_by_artist_view;
|
||||||
|
''',
|
||||||
|
});
|
||||||
|
|
||||||
|
final file =
|
||||||
|
await backend.driver.fullyAnalyze(Uri.parse('package:foo/a.drift'));
|
||||||
|
|
||||||
|
expect(file.allErrors, isEmpty);
|
||||||
|
|
||||||
|
final results = file.fileAnalysis!;
|
||||||
|
final query = results.resolvedQueries.values
|
||||||
|
.singleWhere((q) => q.name == 'totalDurationByArtist');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
query,
|
||||||
|
returnsColumns({
|
||||||
|
'id': DriftSqlType.int,
|
||||||
|
'name': DriftSqlType.string,
|
||||||
|
'duration': DriftSqlType.int,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
|
@ -9,10 +9,12 @@ import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/file_system/overlay_file_system.dart';
|
import 'package:analyzer/file_system/overlay_file_system.dart';
|
||||||
import 'package:analyzer/file_system/physical_file_system.dart';
|
import 'package:analyzer/file_system/physical_file_system.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_dev/src/analysis/backend.dart';
|
import 'package:drift_dev/src/analysis/backend.dart';
|
||||||
import 'package:drift_dev/src/analysis/driver/driver.dart';
|
import 'package:drift_dev/src/analysis/driver/driver.dart';
|
||||||
import 'package:drift_dev/src/analysis/driver/error.dart';
|
import 'package:drift_dev/src/analysis/driver/error.dart';
|
||||||
import 'package:drift_dev/src/analysis/driver/state.dart';
|
import 'package:drift_dev/src/analysis/driver/state.dart';
|
||||||
|
import 'package:drift_dev/src/analysis/results/results.dart';
|
||||||
import 'package:drift_dev/src/analyzer/options.dart';
|
import 'package:drift_dev/src/analyzer/options.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:package_config/package_config.dart';
|
import 'package:package_config/package_config.dart';
|
||||||
|
@ -133,10 +135,29 @@ class TestBackend extends DriftBackend {
|
||||||
Future<void> dispose() async {}
|
Future<void> dispose() async {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Matcher get hasNoErrors => isA<FileState>()
|
Matcher get hasNoErrors =>
|
||||||
.having((e) => e.errorsDuringDiscovery, 'errorsDuringDiscovery', isEmpty)
|
isA<FileState>().having((e) => e.allErrors, 'allErrors', isEmpty);
|
||||||
.having((e) => e.analysis.values.expand((e) => e.errorsDuringAnalysis),
|
|
||||||
'(errors in analyzed elements)', isEmpty);
|
Matcher returnsColumns(Map<String, DriftSqlType> columns) {
|
||||||
|
return _HasInferredColumnTypes(columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HasInferredColumnTypes extends CustomMatcher {
|
||||||
|
_HasInferredColumnTypes(dynamic expected)
|
||||||
|
: super('Select query with inferred columns', 'columns', expected);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object? featureValueOf(dynamic actual) {
|
||||||
|
if (actual is! SqlSelectQuery) {
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
final resultSet = actual.resultSet;
|
||||||
|
return {
|
||||||
|
for (final column in resultSet.columns) column.name: column.sqlType
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TypeMatcher<DriftAnalysisError> isDriftError(dynamic message) {
|
TypeMatcher<DriftAnalysisError> isDriftError(dynamic message) {
|
||||||
return isA<DriftAnalysisError>().having((e) => e.message, 'message', message);
|
return isA<DriftAnalysisError>().having((e) => e.message, 'message', message);
|
||||||
|
|
|
@ -33,7 +33,7 @@ CREATE VIEW total_duration_by_artist_view AS
|
||||||
FROM artists a
|
FROM artists a
|
||||||
INNER JOIN albums ON albums.artist = a.id
|
INNER JOIN albums ON albums.artist = a.id
|
||||||
INNER JOIN tracks ON tracks.album = albums.id
|
INNER JOIN tracks ON tracks.album = albums.id
|
||||||
GROUP BY artists.id;
|
GROUP BY a.id;
|
||||||
|
|
||||||
totalDurationByArtist:
|
totalDurationByArtist:
|
||||||
SELECT * FROM total_duration_by_artist_view;
|
SELECT * FROM total_duration_by_artist_view;
|
||||||
|
|
Loading…
Reference in New Issue