mirror of https://github.com/AMT-Cheif/drift.git
Use sqlparser for drift snippets
This commit is contained in:
parent
99172c1216
commit
48041512cb
|
@ -12,15 +12,18 @@ jobs:
|
|||
- name: Get dependencies
|
||||
run: dart pub get
|
||||
working-directory: docs
|
||||
- name: Analyze Dart sources
|
||||
working-directory: docs
|
||||
run: dart analyze --fatal-infos --fatal-warnings
|
||||
- name: Run build
|
||||
env:
|
||||
IS_RELEASE: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/latest-release' }}
|
||||
run: dart run tool/ci_build.dart
|
||||
working-directory: docs
|
||||
|
||||
- name: Analyze Dart sources
|
||||
working-directory: docs
|
||||
run: >
|
||||
dart analyze --fatal-infos --fatal-warnings
|
||||
dart run drift_dev analyze
|
||||
|
||||
- name: Deploy to netlify (Branch)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: nwtgck/actions-netlify@v1.2
|
||||
|
|
|
@ -4,16 +4,23 @@ builders:
|
|||
build_to: cache
|
||||
builder_factories: ["writeVersions"]
|
||||
build_extensions: {"$package$": ["lib/versions.json"]}
|
||||
code_snippets:
|
||||
import: 'tool/snippets.dart'
|
||||
build_to: cache
|
||||
builder_factories: ["SnippetsBuilder.new"]
|
||||
build_extensions: {"": [".excerpt.json"]}
|
||||
auto_apply: none
|
||||
|
||||
targets:
|
||||
prepare:
|
||||
builders:
|
||||
"|versions":
|
||||
enabled: true
|
||||
code_snippets:
|
||||
"|code_snippets":
|
||||
enabled: true
|
||||
generate_for:
|
||||
- "lib/snippets/**/*.dart"
|
||||
- "lib/snippets/*/*.drift"
|
||||
- "lib/snippets/*.dart"
|
||||
auto_apply_builders: false
|
||||
sources:
|
||||
|
@ -21,6 +28,7 @@ targets:
|
|||
- "lib/versions.json"
|
||||
- "lib/snippets/**"
|
||||
- "tool/write_versions.dart"
|
||||
- "tool/snippets.dart"
|
||||
|
||||
$default:
|
||||
dependencies: [":prepare"]
|
||||
|
@ -38,8 +46,6 @@ targets:
|
|||
- "--csp"
|
||||
moor_generator:
|
||||
enabled: false
|
||||
code_snippets:
|
||||
enabled: false
|
||||
sources:
|
||||
- "lib/**"
|
||||
- "pages/**"
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// #docregion overview
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@DriftDatabase(
|
||||
include: {'tables.drift'},
|
||||
)
|
||||
class MyDb extends _$MyDb {
|
||||
// This example creates a simple in-memory database (without actual
|
||||
// persistence).
|
||||
// To store data, see the database setups from other "Getting started" guides.
|
||||
MyDb() : super(NativeDatabase.memory());
|
||||
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
}
|
||||
// #enddocregion overview
|
||||
|
||||
extension MoreSnippets on MyDb {
|
||||
// #docregion dart_interop_insert
|
||||
Future<void> insert(TodosCompanion companion) async {
|
||||
await into(todos).insert(companion);
|
||||
}
|
||||
// #enddocregion dart_interop_insert
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* #docregion overview */
|
||||
CREATE TABLE coordinates (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
lat REAL NOT NULL,
|
||||
long REAL NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE saved_routes (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
"from" INTEGER NOT NULL REFERENCES coordinates (id),
|
||||
"to" INTEGER NOT NULL REFERENCES coordinates (id)
|
||||
);
|
||||
|
||||
/* #enddocregion overview */
|
||||
/* #docregion route_points*/
|
||||
CREATE TABLE route_points (
|
||||
route INTEGER NOT NULL REFERENCES saved_routes (id),
|
||||
point INTEGER NOT NULL REFERENCES coordinates (id),
|
||||
index_on_route INTEGER,
|
||||
PRIMARY KEY (route, point)
|
||||
);
|
||||
/* #enddocregion route_points */
|
||||
|
||||
/* #docregion overview */
|
||||
routesWithPoints: SELECT r.id, r.name, f.*, t.* FROM routes r
|
||||
INNER JOIN coordinates f ON f.id = r."from"
|
||||
INNER JOIN coordinates t ON t.id = r."to";
|
||||
/* #enddocregion overview */
|
||||
/* #docregion nested */
|
||||
routesWithNestedPoints: SELECT r.id, r.name, f.** AS "from", t.** AS "to" FROM routes r
|
||||
INNER JOIN coordinates f ON f.id = r."from"
|
||||
INNER JOIN coordinates t ON t.id = r."to";
|
||||
/* #enddocregion nested */
|
||||
/* #docregion list */
|
||||
routeWithPoints: SELECT
|
||||
route.**,
|
||||
LIST(SELECT coordinates.* FROM route_points
|
||||
INNER JOIN coordinates ON id = point
|
||||
WHERE route = route.id
|
||||
ORDER BY index_on_route
|
||||
) AS points
|
||||
FROM saved_routes route;
|
||||
/* #enddocregion list */
|
|
@ -0,0 +1,19 @@
|
|||
/* #docregion import */
|
||||
import 'tables.drift'; -- single quotes are required for imports
|
||||
/* #enddocregion import */
|
||||
|
||||
/* #docregion q1 */
|
||||
myQuery(:variable AS TEXT): SELECT :variable;
|
||||
/* #enddocregion q1 */
|
||||
/* #docregion q2 */
|
||||
myNullableQuery(:variable AS TEXT OR NULL): SELECT :variable;
|
||||
/* #enddocregion q2 */
|
||||
/* #docregion q3 */
|
||||
myRequiredQuery(REQUIRED :variable AS TEXT OR NULL): SELECT :variable;
|
||||
/* #enddocregion q3 */
|
||||
/* #docregion entries */
|
||||
entriesWithId: SELECT * FROM todos WHERE id IN ?;
|
||||
/* #enddocregion entries */
|
||||
/* #docregion filter */
|
||||
_filterTodos: SELECT * FROM todos WHERE $predicate;
|
||||
/* #enddocregion filter */
|
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE todos (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
category INTEGER REFERENCES categories(id)
|
||||
);
|
||||
|
||||
CREATE TABLE categories (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
description TEXT NOT NULL
|
||||
) AS Category; -- the AS xyz after the table defines the data class name
|
||||
|
||||
-- You can also create an index or triggers with drift files
|
||||
CREATE INDEX categories_description ON categories(description);
|
||||
|
||||
-- we can put named sql queries in here as well:
|
||||
createEntry: INSERT INTO todos (title, content) VALUES (:title, :content);
|
||||
deleteById: DELETE FROM todos WHERE id = :id;
|
||||
allTodos: SELECT * FROM todos;
|
|
@ -1,4 +1,3 @@
|
|||
// #docregion
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'package:sqlite3/open.dart';
|
||||
|
@ -15,4 +14,3 @@ DynamicLibrary _openOnLinux() {
|
|||
return DynamicLibrary.open(libraryNextToScript.path);
|
||||
}
|
||||
// _openOnWindows could be implemented similarly by opening `sqlite3.dll`
|
||||
// #enddocregion
|
||||
|
|
|
@ -11,52 +11,21 @@ aliases:
|
|||
template: layouts/docs/single
|
||||
---
|
||||
|
||||
{% assign dart_snippets = "package:moor_documentation/snippets/drift_files/database.dart.excerpt.json" | readString | json_decode %}
|
||||
{% assign drift_tables = "package:moor_documentation/snippets/drift_files/tables.drift.excerpt.json" | readString | json_decode %}
|
||||
{% assign small = "package:moor_documentation/snippets/drift_files/small_snippets.drift.excerpt.json" | readString | json_decode %}
|
||||
|
||||
Drift files are a new feature that lets you write all your database code in SQL - drift will generate typesafe APIs for them.
|
||||
|
||||
## Getting started
|
||||
To use this feature, lets create two files: `database.dart` and `tables.drift`. The Dart file only contains the minimum code
|
||||
to setup the database:
|
||||
```dart
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift/native.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@DriftDatabase(
|
||||
include: {'tables.drift'},
|
||||
)
|
||||
class MyDb extends _$MyDb {
|
||||
// This example creates a simple in-memory database (without actual persistence).
|
||||
// To actually store data, see the database setups from other "Getting started" guides.
|
||||
MyDb() : super(NativeDatabase.memory());
|
||||
|
||||
@override
|
||||
int get schemaVersion => 1;
|
||||
}
|
||||
```
|
||||
{% include "blocks/snippet" snippets = dart_snippets name = "overview" %}
|
||||
|
||||
We can now declare tables and queries in the drift file:
|
||||
```sql
|
||||
CREATE TABLE todos (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
category INTEGER REFERENCES categories(id)
|
||||
);
|
||||
|
||||
CREATE TABLE categories (
|
||||
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
description TEXT NOT NULL
|
||||
) AS Category; -- the AS xyz after the table defines the data class name
|
||||
|
||||
-- You can also create an index or triggers with drift files
|
||||
CREATE INDEX categories_description ON categories(description);
|
||||
|
||||
-- we can put named sql queries in here as well:
|
||||
createEntry: INSERT INTO todos (title, content) VALUES (:title, :content);
|
||||
deleteById: DELETE FROM todos WHERE id = :id;
|
||||
allTodos: SELECT * FROM todos;
|
||||
```
|
||||
{% include "blocks/snippet" snippets = drift_tables %}
|
||||
|
||||
After running the build runner with `flutter pub run build_runner build`,
|
||||
drift will write the `database.g.dart`
|
||||
|
@ -92,22 +61,17 @@ queries, the variables will be written as parameters to your method.
|
|||
When it's ambiguous, the analyzer might be unable to resolve the type of
|
||||
a variable. For those scenarios, you can also denote the explicit type
|
||||
of a variable:
|
||||
```sql
|
||||
myQuery(:variable AS TEXT): SELECT :variable;
|
||||
```
|
||||
|
||||
{% include "blocks/snippet" snippets = small name = "q1" %}
|
||||
|
||||
In addition to the base type, you can also declare that the type is nullable:
|
||||
|
||||
```sql
|
||||
myQuery(:variable AS TEXT OR NULL): SELECT :variable;
|
||||
```
|
||||
{% include "blocks/snippet" snippets = small name = "q2" %}
|
||||
|
||||
Finally, you can declare that a variable should be required in Dart when using
|
||||
named parameters. To do so, add a `REQUIRED` keyword:
|
||||
|
||||
```sql
|
||||
myQuery(REQUIRED :variable AS TEXT OR NULL): SELECT :variable;
|
||||
```
|
||||
{% include "blocks/snippet" snippets = small name = "q3" %}
|
||||
|
||||
Note that this only has an effect when the `named_parameters`
|
||||
[build option]({{ '../Advanced Features/builder_options.md' | pageUrl }}) is
|
||||
|
@ -116,9 +80,9 @@ enabled. Further, non-nullable variables are required by default.
|
|||
### Arrays
|
||||
If you want to check whether a value is in an array of values, you can
|
||||
use `IN ?`. That's not valid sql, but drift will desugar that at runtime. So, for this query:
|
||||
```sql
|
||||
entriesWithId: SELECT * FROM todos WHERE id IN ?;
|
||||
```
|
||||
|
||||
{% include "blocks/snippet" snippets = small name = "entries" %}
|
||||
|
||||
Drift will generate a `Selectable<Todo> entriesWithId(List<int> ids)` method.
|
||||
Running `entriesWithId([1,2])` would generate `SELECT * ... id IN (?1, ?2)` and
|
||||
bind the arguments accordingly. To make sure this works as expected, drift
|
||||
|
@ -142,9 +106,9 @@ written as an `INTEGER` column when the table gets created.
|
|||
|
||||
## Imports
|
||||
You can put import statements at the top of a `drift` file:
|
||||
```sql
|
||||
import 'other.drift'; -- single quotes are required for imports
|
||||
```
|
||||
|
||||
{% include "blocks/snippet" snippets = small name = "import" %}
|
||||
|
||||
All tables reachable from the other file will then also be visible in
|
||||
the current file and to the database that `includes` it. If you want
|
||||
to declare queries on tables that were defined in another drift
|
||||
|
@ -161,28 +125,13 @@ know from Dart.
|
|||
|
||||
## Nested results
|
||||
|
||||
{% assign nested = "package:moor_documentation/snippets/drift_files/nested.drift.excerpt.json" | readString | json_decode %}
|
||||
|
||||
Many queries fetch all columns from some table, typically by using the
|
||||
`SELECT table.*` syntax. That approach can become a bit tedious when applied
|
||||
over multiple tables from a join, as shown in this example:
|
||||
|
||||
```sql
|
||||
CREATE TABLE coordinates (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
lat REAL NOT NULL,
|
||||
long REAL NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE saved_routes (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
"from" INTEGER NOT NULL REFERENCES coordinates (id),
|
||||
"to" INTEGER NOT NULL REFERENCES coordinates (id)
|
||||
);
|
||||
|
||||
routesWithPoints: SELECT r.id, r.name, f.*, t.* FROM routes r
|
||||
INNER JOIN coordinates f ON f.id = r."from"
|
||||
INNER JOIN coordinates t ON t.id = r."to";
|
||||
```
|
||||
{% include "blocks/snippet" snippets = nested name = "overview" %}
|
||||
|
||||
To match the returned column names while avoiding name clashes in Dart, drift
|
||||
will generate a class having an `id`, `name`, `id1`, `lat`, `long`, `lat1` and
|
||||
|
@ -190,11 +139,7 @@ a `long1` field.
|
|||
Of course, that's not helpful at all - was `lat1` coming from `from` or `to`
|
||||
again? Let's rewrite the query, this time using nested results:
|
||||
|
||||
```sql
|
||||
routesWithNestedPoints: SELECT r.id, r.name, f.**, t.** FROM routes r
|
||||
INNER JOIN coordinates f ON f.id = r."from"
|
||||
INNER JOIN coordinates t ON t.id = r."to";
|
||||
```
|
||||
{% include "blocks/snippet" snippets = nested name = "nested" %}
|
||||
|
||||
As you can see, we can nest a result simply by using the drift-specific
|
||||
`table.**` syntax.
|
||||
|
@ -235,29 +180,13 @@ Re-using the `coordinates` and `saved_routes` tables introduced in the example
|
|||
for [nested results](#nested-results), we add a new table storing coordinates
|
||||
along a route:
|
||||
|
||||
```sql
|
||||
CREATE TABLE route_points (
|
||||
route INTEGER NOT NULL REFERENCES saved_routes (id),
|
||||
point INTEGER NOT NULL REFERENCES coordinates (id),
|
||||
index_on_route INTEGER,
|
||||
PRIMARY KEY (route, point)
|
||||
);
|
||||
```
|
||||
{% include "blocks/snippet" snippets = nested name = "route_points" %}
|
||||
|
||||
Now, assume we wanted to query a route with information about all points
|
||||
along the way. While this requires two SQL statements, we can write this as a
|
||||
single drift query that is then split into the two statements automatically:
|
||||
|
||||
```sql
|
||||
routeWithPoints: SELECT
|
||||
route.**
|
||||
LIST(SELECT coordinates.* FROM route_points
|
||||
INNER JOIN coordinates ON id = point
|
||||
WHERE route = route.id
|
||||
ORDER BY index_on_route
|
||||
) AS points
|
||||
FROM saved_routes route;
|
||||
```
|
||||
{% include "blocks/snippet" snippets = nested name = "list" %}
|
||||
|
||||
This will generate a result set containing a `SavedRoute route` field along with a
|
||||
`List<Point> points` list of all points along the route.
|
||||
|
@ -279,11 +208,9 @@ supported with the `new_sql_code_generation` [build option]({{ '../Advanced Feat
|
|||
Drift files work perfectly together with drift's existing Dart API:
|
||||
|
||||
- you can write Dart queries for tables declared in a drift file:
|
||||
```dart
|
||||
Future<void> insert(TodosCompanion companion) async {
|
||||
await into(todos).insert(companion);
|
||||
}
|
||||
```
|
||||
|
||||
{% include "blocks/snippet" snippets = dart_snippets name = "dart_interop_insert" %}
|
||||
|
||||
- by importing Dart files into a drift file, you can write sql queries for
|
||||
tables declared in Dart.
|
||||
- generated methods for queries can be used in transactions, they work
|
||||
|
|
|
@ -22,7 +22,7 @@ dev_dependencies:
|
|||
shelf_static: ^1.1.0
|
||||
code_snippets:
|
||||
hosted: https://simonbinder.eu
|
||||
version: ^0.0.2
|
||||
version: ^0.0.3
|
||||
|
||||
# Fake path_provider for snippets
|
||||
path_provider:
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
import 'package:build/build.dart';
|
||||
import 'package:code_snippets/builder.dart';
|
||||
import 'package:code_snippets/highlight.dart';
|
||||
import 'package:source_span/source_span.dart';
|
||||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
class SnippetsBuilder extends CodeExcerptBuilder {
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
SnippetsBuilder([BuilderOptions? options]);
|
||||
|
||||
@override
|
||||
bool shouldEmitFor(AssetId input, Excerpter excerpts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Highlighter?> highlighterFor(
|
||||
AssetId assetId, String content, BuildStep buildStep) async {
|
||||
switch (assetId.extension) {
|
||||
case '.drift':
|
||||
return _DriftHighlighter(
|
||||
SourceFile.fromString(content, url: assetId.uri));
|
||||
default:
|
||||
return super.highlighterFor(assetId, content, buildStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _DriftHighlighter extends Highlighter {
|
||||
_DriftHighlighter(SourceFile file) : super(file);
|
||||
|
||||
@override
|
||||
void highlight() {
|
||||
final engine = SqlEngine(
|
||||
EngineOptions(
|
||||
useMoorExtensions: true,
|
||||
version: SqliteVersion.current,
|
||||
),
|
||||
);
|
||||
|
||||
final result = engine.parseMoorFile(file.span(0).text);
|
||||
_HighlightingVisitor().visit(result.rootNode, this);
|
||||
|
||||
for (final token in result.tokens) {
|
||||
const ignoredKeyword = [
|
||||
TokenType.$null,
|
||||
TokenType.$true,
|
||||
TokenType.$false
|
||||
];
|
||||
|
||||
if (token is KeywordToken &&
|
||||
!ignoredKeyword.contains(token.type) &&
|
||||
!token.isIdentifier) {
|
||||
reportSql(token, RegionType.keyword);
|
||||
} else if (token is CommentToken) {
|
||||
reportSql(token, RegionType.comment);
|
||||
} else if (token is StringLiteralToken) {
|
||||
reportSql(token, RegionType.string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reportSql(SyntacticEntity? entity, RegionType type) {
|
||||
if (entity != null) {
|
||||
report(HighlightRegion(
|
||||
type, file.span(entity.firstPosition, entity.lastPosition)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _HighlightingVisitor extends RecursiveVisitor<_DriftHighlighter, void> {
|
||||
@override
|
||||
void visitCreateTriggerStatement(
|
||||
CreateTriggerStatement e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e.triggerNameToken, RegionType.classTitle);
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitCreateViewStatement(CreateViewStatement e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e.viewNameToken, RegionType.classTitle);
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitColumnDefinition(ColumnDefinition e, _DriftHighlighter arg) {
|
||||
arg
|
||||
..reportSql(e.nameToken, RegionType.variable)
|
||||
..reportSql(e.typeNames?.toSingleEntity, RegionType.type);
|
||||
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitColumnConstraint(ColumnConstraint e, _DriftHighlighter arg) {
|
||||
if (e is NotNull) {
|
||||
arg.reportSql(e.$null, RegionType.keyword);
|
||||
} else if (e is NullColumnConstraint) {
|
||||
arg.reportSql(e.$null, RegionType.keyword);
|
||||
}
|
||||
super.visitColumnConstraint(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullLiteral(NullLiteral e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e, RegionType.builtIn);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNumericLiteral(Literal e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e, RegionType.number);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitMoorSpecificNode(MoorSpecificNode e, _DriftHighlighter arg) {
|
||||
if (e is DeclaredStatement) {
|
||||
final name = e.identifier;
|
||||
if (name is SimpleName) {
|
||||
arg.reportSql(name.identifier, RegionType.functionTitle);
|
||||
}
|
||||
}
|
||||
super.visitMoorSpecificNode(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitBooleanLiteral(BooleanLiteral e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e, RegionType.literal);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitReference(Reference e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e, RegionType.variable);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTableReference(TableReference e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e.tableNameToken, RegionType.type);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTableInducingStatement(
|
||||
TableInducingStatement e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e.tableNameToken, RegionType.classTitle);
|
||||
|
||||
if (e is CreateVirtualTableStatement) {
|
||||
arg.reportSql(e.moduleNameToken, RegionType.invokedFunctionTitle);
|
||||
}
|
||||
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitVariable(Variable e, _DriftHighlighter arg) {
|
||||
arg.reportSql(e, RegionType.variable);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
//@dart=2.9
|
||||
import 'package:drift_dev/src/analyzer/runner/file_graph.dart';
|
||||
import 'package:drift_dev/src/analyzer/runner/results.dart';
|
||||
|
||||
extension CurrentResults on FoundFile {
|
||||
ParsedMoorFile get parsedMoorOrNull {
|
||||
ParsedMoorFile? get parsedMoorOrNull {
|
||||
final result = currentResult;
|
||||
if (result is ParsedMoorFile && isParsed) {
|
||||
return result;
|
||||
|
|
Loading…
Reference in New Issue