mirror of https://github.com/AMT-Cheif/drift.git
Name schema exports automatically (#1721)
This commit is contained in:
parent
9c80fb047b
commit
61dc1f17b8
|
@ -271,21 +271,29 @@ To begin, let's create the first schema representation:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ mkdir drift_schemas
|
$ mkdir drift_schemas
|
||||||
$ dart run drift_dev schema dump lib/database/database.dart drift_schemas/drift_schema_v1.json
|
$ dart run drift_dev schema dump lib/database/database.dart drift_schemas/
|
||||||
```
|
```
|
||||||
|
|
||||||
This instructs the generator to look at the database defined in `lib/database/database.dart` and extract
|
This instructs the generator to look at the database defined in `lib/database/database.dart` and extract
|
||||||
its schema into the new folder.
|
its schema into the new folder.
|
||||||
|
|
||||||
After making a change to your database schema, you can run the command again. For instance, let's say we
|
After making a change to your database schema, you can run the command again. For instance, let's say we
|
||||||
made a change to our tables and increased the `schemaVersion` to `2`. We would then run:
|
made a change to our tables and increased the `schemaVersion` to `2`. To dump the new schema, just run the
|
||||||
|
command again:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ dart run drift_dev schema dump lib/database/database.dart drift_schemas/drift_schema_v2.json
|
$ dart run drift_dev schema dump lib/database/database.dart drift_schemas/
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll need to run this command every time you change the schema of your database and increment the `schemaVersion`.
|
You'll need to run this command every time you change the schema of your database and increment the `schemaVersion`.
|
||||||
Remember to name the files `drift_schema_vX.json`, where `X` is the current `schemaVersion` of your database.
|
|
||||||
|
Drift will name the files in the folder `drift_schema_vX.json`, where `X` is the current `schemaVersion` of your
|
||||||
|
database.
|
||||||
|
If drift is unable to extract the version from your `schemaVersion` getter, provide the full path explicitly:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ dart run drift_dev schema dump lib/database/database.dart drift_schemas/drift_schema_v3.json
|
||||||
|
```
|
||||||
|
|
||||||
#### Generating test code
|
#### Generating test code
|
||||||
|
|
||||||
|
|
|
@ -55,16 +55,20 @@ class MoorDartParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
Expression? returnExpressionOfMethod(MethodDeclaration method) {
|
Expression? returnExpressionOfMethod(MethodDeclaration method,
|
||||||
|
{bool reportErrorOnFailure = true}) {
|
||||||
final body = method.body;
|
final body = method.body;
|
||||||
|
|
||||||
if (body is! ExpressionFunctionBody) {
|
if (body is! ExpressionFunctionBody) {
|
||||||
step.reportError(ErrorInDartCode(
|
if (reportErrorOnFailure) {
|
||||||
affectedElement: method.declaredElement,
|
step.reportError(ErrorInDartCode(
|
||||||
severity: Severity.criticalError,
|
affectedElement: method.declaredElement,
|
||||||
message: 'This method must have an expression body '
|
severity: Severity.criticalError,
|
||||||
'(use => instead of {return ...})',
|
message: 'This method must have an expression body '
|
||||||
));
|
'(use => instead of {return ...})',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class UseMoorParser {
|
||||||
daos: daoTypes,
|
daos: daoTypes,
|
||||||
declaredIncludes: includes,
|
declaredIncludes: includes,
|
||||||
declaredQueries: parsedQueries,
|
declaredQueries: parsedQueries,
|
||||||
|
schemaVersion: await _readSchemaVersion(element),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,4 +64,30 @@ class UseMoorParser {
|
||||||
.toList() ??
|
.toList() ??
|
||||||
[];
|
[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int?> _readSchemaVersion(ClassElement dbClass) async {
|
||||||
|
final element = dbClass.thisType.getGetter('schemaVersion')?.variable;
|
||||||
|
if (element == null) return null;
|
||||||
|
|
||||||
|
final helper = MoorDartParser(step);
|
||||||
|
|
||||||
|
if (element.isSynthetic) {
|
||||||
|
// Getter, read from `=>` body if possible.
|
||||||
|
final expr = helper.returnExpressionOfMethod(
|
||||||
|
await helper.loadElementDeclaration(element.getter!)
|
||||||
|
as MethodDeclaration,
|
||||||
|
reportErrorOnFailure: false);
|
||||||
|
if (expr is IntegerLiteral) {
|
||||||
|
return expr.value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final astField =
|
||||||
|
await helper.loadElementDeclaration(element) as VariableDeclaration;
|
||||||
|
if (astField.initializer is IntegerLiteral) {
|
||||||
|
return (astField.initializer as IntegerLiteral).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
||||||
import 'package:args/command_runner.dart';
|
import 'package:args/command_runner.dart';
|
||||||
import 'package:drift_dev/src/analyzer/runner/results.dart';
|
import 'package:drift_dev/src/analyzer/runner/results.dart';
|
||||||
import 'package:drift_dev/src/services/schema/schema_files.dart';
|
import 'package:drift_dev/src/services/schema/schema_files.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
import '../../cli.dart';
|
import '../../cli.dart';
|
||||||
|
|
||||||
|
@ -51,6 +52,33 @@ class DumpSchemaCommand extends Command {
|
||||||
final db = result.declaredDatabases.single;
|
final db = result.declaredDatabases.single;
|
||||||
final writer = SchemaWriter(db);
|
final writer = SchemaWriter(db);
|
||||||
|
|
||||||
await File(rest[1]).writeAsString(json.encode(writer.createSchemaJson()));
|
var target = rest[1];
|
||||||
|
// This command is most commonly used to write into
|
||||||
|
// `<dir>/drift_schema_vx.json`. When we get a directory as a second arg,
|
||||||
|
// try to infer the file name.
|
||||||
|
if (await FileSystemEntity.isDirectory(target) ||
|
||||||
|
!target.endsWith('.json')) {
|
||||||
|
final version = db.schemaVersion;
|
||||||
|
|
||||||
|
if (version == null) {
|
||||||
|
// Couldn't read schema from database, so fail.
|
||||||
|
usageException(
|
||||||
|
'Target is a directory and the schema version could not be read from '
|
||||||
|
'the database class. Please use a full filename (e.g. '
|
||||||
|
'`$target/drift_schema_v3.json`)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
target = join(target, 'drift_schema_v$version.json');
|
||||||
|
}
|
||||||
|
|
||||||
|
final file = File(target);
|
||||||
|
final parent = file.parent;
|
||||||
|
if (!await parent.exists()) {
|
||||||
|
await parent.create(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await File(target).writeAsString(json.encode(writer.createSchemaJson()));
|
||||||
|
print('Wrote to $target');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,16 @@ abstract class BaseMoorAccessor implements HasDeclaration {
|
||||||
class Database extends BaseMoorAccessor {
|
class Database extends BaseMoorAccessor {
|
||||||
final List<DartType> daos;
|
final List<DartType> daos;
|
||||||
|
|
||||||
|
/// If the source database class overrides `schemaVersion` and returns a
|
||||||
|
/// simple integer literal, stores that version.
|
||||||
|
///
|
||||||
|
/// This is optionally used by the migration tooling to store the schema in a
|
||||||
|
/// versioned file.
|
||||||
|
int? schemaVersion;
|
||||||
|
|
||||||
Database({
|
Database({
|
||||||
this.daos = const [],
|
this.daos = const [],
|
||||||
|
this.schemaVersion,
|
||||||
DatabaseOrDaoDeclaration? declaration,
|
DatabaseOrDaoDeclaration? declaration,
|
||||||
List<MoorTable> declaredTables = const [],
|
List<MoorTable> declaredTables = const [],
|
||||||
List<MoorView> declaredViews = const [],
|
List<MoorView> declaredViews = const [],
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import 'package:drift_dev/src/analyzer/runner/results.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../utils.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('parses schema version getter', () async {
|
||||||
|
final state = TestState.withContent({
|
||||||
|
'a|lib/main.dart': r'''
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
|
||||||
|
@DriftDatabase()
|
||||||
|
class MyDatabase extends _$MyDatabase {
|
||||||
|
@override
|
||||||
|
int get schemaVersion => 13;
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
});
|
||||||
|
addTearDown(state.close);
|
||||||
|
|
||||||
|
final file = (await state.analyze('package:a/main.dart')).currentResult!;
|
||||||
|
final db = (file as ParsedDartFile).declaredDatabases.single;
|
||||||
|
|
||||||
|
expect(db.schemaVersion, 13);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('parses schema version field', () async {
|
||||||
|
final state = TestState.withContent({
|
||||||
|
'a|lib/main.dart': r'''
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
|
||||||
|
@DriftDatabase()
|
||||||
|
class MyDatabase extends _$MyDatabase {
|
||||||
|
@override
|
||||||
|
final int schemaVersion = 23;
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
});
|
||||||
|
addTearDown(state.close);
|
||||||
|
|
||||||
|
final file = (await state.analyze('package:a/main.dart')).currentResult!;
|
||||||
|
final db = (file as ParsedDartFile).declaredDatabases.single;
|
||||||
|
|
||||||
|
expect(db.schemaVersion, 23);
|
||||||
|
});
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ See `test/migration_test.dart` on how to use the generated verification code.
|
||||||
After adapting a schema and incrementing the `schemaVersion` in the database, run
|
After adapting a schema and incrementing the `schemaVersion` in the database, run
|
||||||
|
|
||||||
```
|
```
|
||||||
dart run drift_dev schema dump lib/database.dart moor_migrations/moor_schema_v2.json
|
dart run drift_dev schema dump lib/database.dart drift_migrations/
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `_v2` with the current `schemaVersion`.
|
Replace `_v2` with the current `schemaVersion`.
|
||||||
|
|
Loading…
Reference in New Issue