mirror of https://github.com/AMT-Cheif/drift.git
Refactoring on the model classes in moor_generator
This commit is contained in:
parent
6b776d47d7
commit
8661e0a28a
|
@ -48,7 +48,7 @@ You can learn more about the json1 extension on [sqlite.org](https://www.sqlite.
|
||||||
|
|
||||||
## fts5
|
## fts5
|
||||||
|
|
||||||
The fts5 extensions provides full-text search capabilities in sqlite tables.
|
The fts5 extension provides full-text search capabilities in sqlite tables.
|
||||||
To enable the fts5 extension in moor files and compiled queries, modify the
|
To enable the fts5 extension in moor files and compiled queries, modify the
|
||||||
[build options]({{<relref "../Advanced Features/builder_options.md">}}) to include
|
[build options]({{<relref "../Advanced Features/builder_options.md">}}) to include
|
||||||
`fts5` in the `sqlite_module` section.
|
`fts5` in the `sqlite_module` section.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:moor_generator/src/backends/build/moor_builder.dart';
|
import 'package:moor_generator/src/backends/build/moor_builder.dart';
|
||||||
|
|
||||||
|
export 'src/model/model.dart';
|
||||||
|
|
||||||
Builder moorBuilder(BuilderOptions options) => MoorBuilder(options);
|
Builder moorBuilder(BuilderOptions options) => MoorBuilder(options);
|
||||||
|
|
|
@ -46,7 +46,7 @@ class ColumnParser {
|
||||||
|
|
||||||
ColumnParser(this.base);
|
ColumnParser(this.base);
|
||||||
|
|
||||||
SpecifiedColumn parse(MethodDeclaration getter, Element element) {
|
MoorColumn parse(MethodDeclaration getter, Element element) {
|
||||||
final expr = base.returnExpressionOfMethod(getter);
|
final expr = base.returnExpressionOfMethod(getter);
|
||||||
|
|
||||||
if (expr is! FunctionExpressionInvocation) {
|
if (expr is! FunctionExpressionInvocation) {
|
||||||
|
@ -180,20 +180,18 @@ class ColumnParser {
|
||||||
sqlType: columnType);
|
sqlType: columnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
final column = SpecifiedColumn(
|
return MoorColumn(
|
||||||
type: columnType,
|
type: columnType,
|
||||||
dartGetterName: getter.name.name,
|
dartGetterName: getter.name.name,
|
||||||
name: name,
|
name: name,
|
||||||
overriddenJsonName: _readJsonKey(element),
|
overriddenJsonName: _readJsonKey(element),
|
||||||
customConstraints: foundCustomConstraint,
|
customConstraints: foundCustomConstraint,
|
||||||
nullable: nullable,
|
nullable: nullable,
|
||||||
features: foundFeatures,
|
features: foundFeatures,
|
||||||
defaultArgument: foundDefaultExpression?.toSource(),
|
defaultArgument: foundDefaultExpression?.toSource(),
|
||||||
typeConverter: converter);
|
typeConverter: converter,
|
||||||
|
declaration: DartColumnDeclaration(element, base.step.file),
|
||||||
final declaration =
|
);
|
||||||
ColumnDeclaration(column, base.step.file, element, null);
|
|
||||||
return column..declaration = declaration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnType _startMethodToColumnType(String startMethod) {
|
ColumnType _startMethodToColumnType(String startMethod) {
|
||||||
|
|
|
@ -4,12 +4,10 @@ import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:moor/sqlite_keywords.dart';
|
import 'package:moor/sqlite_keywords.dart';
|
||||||
|
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/steps.dart';
|
import 'package:moor_generator/src/analyzer/runner/steps.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart';
|
import 'package:moor_generator/src/model/declarations/declaration.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_db_classes.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/used_type_converter.dart';
|
import 'package:moor_generator/src/model/used_type_converter.dart';
|
||||||
import 'package:moor_generator/src/utils/names.dart';
|
import 'package:moor_generator/src/utils/names.dart';
|
||||||
import 'package:moor_generator/src/utils/type_utils.dart';
|
import 'package:moor_generator/src/utils/type_utils.dart';
|
||||||
|
@ -32,11 +30,11 @@ class MoorDartParser {
|
||||||
_tableParser = TableParser(this);
|
_tableParser = TableParser(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SpecifiedTable> parseTable(ClassElement classElement) {
|
Future<MoorTable> parseTable(ClassElement classElement) {
|
||||||
return _tableParser.parseTable(classElement);
|
return _tableParser.parseTable(classElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SpecifiedColumn> parseColumn(
|
Future<MoorColumn> parseColumn(
|
||||||
MethodDeclaration declaration, Element element) {
|
MethodDeclaration declaration, Element element) {
|
||||||
return Future.value(_columnParser.parse(declaration, element));
|
return Future.value(_columnParser.parse(declaration, element));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
part of 'parser.dart';
|
part of 'parser.dart';
|
||||||
|
|
||||||
/// Parses a [SpecifiedTable] from a Dart class.
|
/// Parses a [MoorTable] from a Dart class.
|
||||||
class TableParser {
|
class TableParser {
|
||||||
final MoorDartParser base;
|
final MoorDartParser base;
|
||||||
|
|
||||||
TableParser(this.base);
|
TableParser(this.base);
|
||||||
|
|
||||||
Future<SpecifiedTable> parseTable(ClassElement element) async {
|
Future<MoorTable> parseTable(ClassElement element) async {
|
||||||
final sqlName = await _parseTableName(element);
|
final sqlName = await _parseTableName(element);
|
||||||
if (sqlName == null) return null;
|
if (sqlName == null) return null;
|
||||||
|
|
||||||
final columns = await _parseColumns(element);
|
final columns = await _parseColumns(element);
|
||||||
|
|
||||||
final table = SpecifiedTable(
|
final table = MoorTable(
|
||||||
fromClass: element,
|
fromClass: element,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
sqlName: escapeIfNeeded(sqlName),
|
sqlName: escapeIfNeeded(sqlName),
|
||||||
dartTypeName: _readDartTypeName(element),
|
dartTypeName: _readDartTypeName(element),
|
||||||
primaryKey: await _readPrimaryKey(element, columns),
|
primaryKey: await _readPrimaryKey(element, columns),
|
||||||
|
declaration: DartTableDeclaration(element, base.step.file),
|
||||||
);
|
);
|
||||||
table.declaration = TableDeclaration(table, base.step.file, element, null);
|
|
||||||
|
|
||||||
var index = 0;
|
var index = 0;
|
||||||
for (final converter in table.converters) {
|
for (final converter in table.converters) {
|
||||||
|
@ -71,8 +71,8 @@ class TableParser {
|
||||||
return tableName;
|
return tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Set<SpecifiedColumn>> _readPrimaryKey(
|
Future<Set<MoorColumn>> _readPrimaryKey(
|
||||||
ClassElement element, List<SpecifiedColumn> columns) async {
|
ClassElement element, List<MoorColumn> columns) async {
|
||||||
final primaryKeyGetter = element.getGetter('primaryKey');
|
final primaryKeyGetter = element.getGetter('primaryKey');
|
||||||
if (primaryKeyGetter == null) {
|
if (primaryKeyGetter == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -88,7 +88,7 @@ class TableParser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final expression = (body as ExpressionFunctionBody).expression;
|
final expression = (body as ExpressionFunctionBody).expression;
|
||||||
final parsedPrimaryKey = <SpecifiedColumn>{};
|
final parsedPrimaryKey = <MoorColumn>{};
|
||||||
|
|
||||||
if (expression is SetOrMapLiteral) {
|
if (expression is SetOrMapLiteral) {
|
||||||
for (final entry in expression.elements) {
|
for (final entry in expression.elements) {
|
||||||
|
@ -109,7 +109,7 @@ class TableParser {
|
||||||
return parsedPrimaryKey;
|
return parsedPrimaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SpecifiedColumn>> _parseColumns(ClassElement element) {
|
Future<List<MoorColumn>> _parseColumns(ClassElement element) {
|
||||||
final columnNames = element.allSupertypes
|
final columnNames = element.allSupertypes
|
||||||
.map((t) => t.element)
|
.map((t) => t.element)
|
||||||
.followedBy([element])
|
.followedBy([element])
|
||||||
|
|
|
@ -7,8 +7,7 @@ class UseDaoParser {
|
||||||
|
|
||||||
/// If [element] has a `@UseDao` annotation, parses the database model
|
/// If [element] has a `@UseDao` annotation, parses the database model
|
||||||
/// declared by that class and the referenced tables.
|
/// declared by that class and the referenced tables.
|
||||||
Future<SpecifiedDao> parseDao(
|
Future<Dao> parseDao(ClassElement element, ConstantReader annotation) async {
|
||||||
ClassElement element, ConstantReader annotation) async {
|
|
||||||
final dbType = element.supertype;
|
final dbType = element.supertype;
|
||||||
if (dbType.name != 'DatabaseAccessor') {
|
if (dbType.name != 'DatabaseAccessor') {
|
||||||
step.reportError(ErrorInDartCode(
|
step.reportError(ErrorInDartCode(
|
||||||
|
@ -47,6 +46,12 @@ class UseDaoParser {
|
||||||
final parsedTables = await step.parseTables(tableTypes, element);
|
final parsedTables = await step.parseTables(tableTypes, element);
|
||||||
final parsedQueries = step.readDeclaredQueries(queryStrings);
|
final parsedQueries = step.readDeclaredQueries(queryStrings);
|
||||||
|
|
||||||
return SpecifiedDao(element, dbImpl, parsedTables, includes, parsedQueries);
|
return Dao(
|
||||||
|
declaration: DatabaseOrDaoDeclaration(element, step.file),
|
||||||
|
dbClass: dbImpl,
|
||||||
|
declaredTables: parsedTables,
|
||||||
|
declaredIncludes: includes,
|
||||||
|
declaredQueries: parsedQueries,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ class UseMoorParser {
|
||||||
|
|
||||||
/// If [element] has a `@UseMoor` annotation, parses the database model
|
/// If [element] has a `@UseMoor` annotation, parses the database model
|
||||||
/// declared by that class and the referenced tables.
|
/// declared by that class and the referenced tables.
|
||||||
Future<SpecifiedDatabase> parseDatabase(
|
Future<Database> parseDatabase(
|
||||||
ClassElement element, ConstantReader annotation) async {
|
ClassElement element, ConstantReader annotation) async {
|
||||||
// the types declared in UseMoor.tables
|
// the types declared in UseMoor.tables
|
||||||
final tableTypes =
|
final tableTypes =
|
||||||
|
@ -27,8 +27,13 @@ class UseMoorParser {
|
||||||
final parsedQueries = step.readDeclaredQueries(queryStrings);
|
final parsedQueries = step.readDeclaredQueries(queryStrings);
|
||||||
final daoTypes = _readDaoTypes(annotation);
|
final daoTypes = _readDaoTypes(annotation);
|
||||||
|
|
||||||
return SpecifiedDatabase(
|
return Database(
|
||||||
element, parsedTables, daoTypes, includes, parsedQueries);
|
declaration: DatabaseOrDaoDeclaration(element, step.file),
|
||||||
|
declaredTables: parsedTables,
|
||||||
|
daos: daoTypes,
|
||||||
|
declaredIncludes: includes,
|
||||||
|
declaredQueries: parsedQueries,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DartType> _readDaoTypes(ConstantReader annotation) {
|
List<DartType> _readDaoTypes(ConstantReader annotation) {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
import 'package:moor_generator/moor_generator.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/meta/declarations.dart';
|
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
import 'package:moor_generator/src/model/declarations/declaration.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/used_type_converter.dart';
|
import 'package:moor_generator/src/model/used_type_converter.dart';
|
||||||
import 'package:moor_generator/src/utils/names.dart';
|
import 'package:moor_generator/src/utils/names.dart';
|
||||||
import 'package:moor_generator/src/utils/string_escaper.dart';
|
import 'package:moor_generator/src/utils/string_escaper.dart';
|
||||||
|
@ -16,11 +15,11 @@ class CreateTableReader {
|
||||||
|
|
||||||
CreateTableReader(this.stmt, this.step);
|
CreateTableReader(this.stmt, this.step);
|
||||||
|
|
||||||
SpecifiedTable extractTable(TypeMapper mapper) {
|
MoorTable extractTable(TypeMapper mapper) {
|
||||||
final table = SchemaFromCreateTable(moorExtensions: true).read(stmt);
|
final table = SchemaFromCreateTable(moorExtensions: true).read(stmt);
|
||||||
|
|
||||||
final foundColumns = <String, SpecifiedColumn>{};
|
final foundColumns = <String, MoorColumn>{};
|
||||||
final primaryKey = <SpecifiedColumn>{};
|
final primaryKey = <MoorColumn>{};
|
||||||
|
|
||||||
for (final column in table.resultColumns) {
|
for (final column in table.resultColumns) {
|
||||||
var isPrimaryKey = false;
|
var isPrimaryKey = false;
|
||||||
|
@ -71,7 +70,12 @@ class CreateTableReader {
|
||||||
constraintWriter.write(constraint.span.text);
|
constraintWriter.write(constraint.span.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
final parsed = SpecifiedColumn(
|
// if the column definition isn't set - which can happen for CREATE
|
||||||
|
// VIRTUAL TABLE statements - use the entire statement as declaration.
|
||||||
|
final declaration =
|
||||||
|
MoorColumnDeclaration(column.definition ?? stmt, step.file);
|
||||||
|
|
||||||
|
final parsed = MoorColumn(
|
||||||
type: moorType,
|
type: moorType,
|
||||||
nullable: column.type.nullable,
|
nullable: column.type.nullable,
|
||||||
dartGetterName: dartName,
|
dartGetterName: dartName,
|
||||||
|
@ -81,12 +85,9 @@ class CreateTableReader {
|
||||||
defaultArgument: defaultValue,
|
defaultArgument: defaultValue,
|
||||||
typeConverter: converter,
|
typeConverter: converter,
|
||||||
overriddenJsonName: overriddenJsonKey,
|
overriddenJsonName: overriddenJsonKey,
|
||||||
|
declaration: declaration,
|
||||||
);
|
);
|
||||||
|
|
||||||
final declaration =
|
|
||||||
ColumnDeclaration(parsed, step.file, null, column.definition);
|
|
||||||
parsed.declaration = declaration;
|
|
||||||
|
|
||||||
foundColumns[column.name] = parsed;
|
foundColumns[column.name] = parsed;
|
||||||
if (isPrimaryKey) {
|
if (isPrimaryKey) {
|
||||||
primaryKey.add(parsed);
|
primaryKey.add(parsed);
|
||||||
|
@ -108,7 +109,7 @@ class CreateTableReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final specifiedTable = SpecifiedTable(
|
return MoorTable(
|
||||||
fromClass: null,
|
fromClass: null,
|
||||||
columns: foundColumns.values.toList(),
|
columns: foundColumns.values.toList(),
|
||||||
sqlName: table.name,
|
sqlName: table.name,
|
||||||
|
@ -119,13 +120,8 @@ class CreateTableReader {
|
||||||
overrideTableConstraints: constraints.isNotEmpty ? constraints : null,
|
overrideTableConstraints: constraints.isNotEmpty ? constraints : null,
|
||||||
// we take care of writing the primary key ourselves
|
// we take care of writing the primary key ourselves
|
||||||
overrideDontWriteConstraints: true,
|
overrideDontWriteConstraints: true,
|
||||||
);
|
declaration: MoorTableDeclaration(stmt, step.file),
|
||||||
|
)..parserTable = table;
|
||||||
final declaration = TableDeclaration(
|
|
||||||
specifiedTable, step.file, null, table.definition,
|
|
||||||
tableFromSqlParser: table);
|
|
||||||
|
|
||||||
return specifiedTable..declaration = declaration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UsedTypeConverter _readTypeConverter(MappedBy mapper) {
|
UsedTypeConverter _readTypeConverter(MappedBy mapper) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
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/steps.dart';
|
import 'package:moor_generator/src/analyzer/runner/steps.dart';
|
||||||
import 'package:moor_generator/src/analyzer/moor/create_table_reader.dart';
|
import 'package:moor_generator/src/analyzer/moor/create_table_reader.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ class MoorParser {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
final createdTables = <SpecifiedTable>[];
|
final createdTables = <MoorTable>[];
|
||||||
final tableDeclarations = <TableInducingStatement, SpecifiedTable>{};
|
final tableDeclarations = <TableInducingStatement, MoorTable>{};
|
||||||
for (final reader in createdReaders) {
|
for (final reader in createdReaders) {
|
||||||
final table = reader.extractTable(step.mapper);
|
final table = reader.extractTable(step.mapper);
|
||||||
createdTables.add(table);
|
createdTables.add(table);
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
|
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/model/specified_table.dart';
|
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
/// Handles `REFERENCES` clauses in tables by resolving their columns and
|
/// Handles `REFERENCES` clauses in tables by resolving their columns and
|
||||||
/// reporting errors if they don't exist. Further, sets the
|
/// reporting errors if they don't exist. Further, sets the
|
||||||
/// [SpecifiedTable.references] field for tables declared in moor.
|
/// [MoorTable.references] field for tables declared in moor.
|
||||||
class TableHandler {
|
class TableHandler {
|
||||||
final AnalyzeMoorStep step;
|
final AnalyzeMoorStep step;
|
||||||
final ParsedMoorFile file;
|
final ParsedMoorFile file;
|
||||||
final List<SpecifiedTable> availableTables;
|
final List<MoorTable> availableTables;
|
||||||
|
|
||||||
TableHandler(this.step, this.file, this.availableTables);
|
TableHandler(this.step, this.file, this.availableTables);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.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/model/specified_db_classes.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
abstract class FileResult {
|
abstract class FileResult {
|
||||||
final List<SpecifiedTable> declaredTables;
|
final List<MoorTable> declaredTables;
|
||||||
|
|
||||||
FileResult(this.declaredTables);
|
FileResult(this.declaredTables);
|
||||||
}
|
}
|
||||||
|
@ -15,15 +14,15 @@ abstract class FileResult {
|
||||||
class ParsedDartFile extends FileResult {
|
class ParsedDartFile extends FileResult {
|
||||||
final LibraryElement library;
|
final LibraryElement library;
|
||||||
|
|
||||||
final List<SpecifiedDao> declaredDaos;
|
final List<Dao> declaredDaos;
|
||||||
final List<SpecifiedDatabase> declaredDatabases;
|
final List<Database> declaredDatabases;
|
||||||
|
|
||||||
Iterable<SpecifiedDbAccessor> get dbAccessors =>
|
Iterable<BaseMoorAccessor> get dbAccessors =>
|
||||||
declaredDatabases.cast<SpecifiedDbAccessor>().followedBy(declaredDaos);
|
declaredDatabases.cast<BaseMoorAccessor>().followedBy(declaredDaos);
|
||||||
|
|
||||||
ParsedDartFile(
|
ParsedDartFile(
|
||||||
{@required this.library,
|
{@required this.library,
|
||||||
List<SpecifiedTable> declaredTables = const [],
|
List<MoorTable> declaredTables = const [],
|
||||||
this.declaredDaos = const [],
|
this.declaredDaos = const [],
|
||||||
this.declaredDatabases = const []})
|
this.declaredDatabases = const []})
|
||||||
: super(declaredTables);
|
: super(declaredTables);
|
||||||
|
@ -37,11 +36,11 @@ class ParsedMoorFile extends FileResult {
|
||||||
final List<DeclaredQuery> queries;
|
final List<DeclaredQuery> queries;
|
||||||
|
|
||||||
List<SqlQuery> resolvedQueries;
|
List<SqlQuery> resolvedQueries;
|
||||||
Map<TableInducingStatement, SpecifiedTable> tableDeclarations;
|
Map<TableInducingStatement, MoorTable> tableDeclarations;
|
||||||
Map<ImportStatement, FoundFile> resolvedImports;
|
Map<ImportStatement, FoundFile> resolvedImports;
|
||||||
|
|
||||||
ParsedMoorFile(this.parseResult,
|
ParsedMoorFile(this.parseResult,
|
||||||
{List<SpecifiedTable> declaredTables = const [],
|
{List<MoorTable> declaredTables = const [],
|
||||||
this.queries = const [],
|
this.queries = const [],
|
||||||
this.imports = const [],
|
this.imports = const [],
|
||||||
this.tableDeclarations = const {}})
|
this.tableDeclarations = const {}})
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/analyzer/dart/parser.dart';
|
import 'package:moor_generator/src/analyzer/dart/parser.dart';
|
||||||
import 'package:moor_generator/src/analyzer/errors.dart';
|
import 'package:moor_generator/src/analyzer/errors.dart';
|
||||||
import 'package:moor_generator/src/analyzer/moor/table_handler.dart';
|
import 'package:moor_generator/src/analyzer/moor/table_handler.dart';
|
||||||
|
@ -12,8 +13,6 @@ import 'package:moor_generator/src/analyzer/moor/parser.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/sql_parser.dart';
|
import 'package:moor_generator/src/analyzer/sql_queries/sql_parser.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
import 'package:moor_generator/src/analyzer/sql_queries/type_mapping.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
||||||
import 'package:moor_generator/src/model/specified_db_classes.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:moor_generator/src/utils/table_reference_sorter.dart';
|
import 'package:moor_generator/src/utils/table_reference_sorter.dart';
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
@ -54,8 +53,8 @@ abstract class AnalyzingStep extends Step {
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<SpecifiedTable> _availableTables(List<FoundFile> imports) {
|
Iterable<MoorTable> _availableTables(List<FoundFile> imports) {
|
||||||
return imports.expand<SpecifiedTable>(
|
return imports.expand<MoorTable>(
|
||||||
(file) => file.currentResult?.declaredTables ?? const Iterable.empty());
|
(file) => file.currentResult?.declaredTables ?? const Iterable.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ class AnalyzeDartStep extends AnalyzingStep {
|
||||||
final parseResult = file.currentResult as ParsedDartFile;
|
final parseResult = file.currentResult as ParsedDartFile;
|
||||||
|
|
||||||
for (final accessor in parseResult.dbAccessors) {
|
for (final accessor in parseResult.dbAccessors) {
|
||||||
final transitiveImports = _transitiveImports(accessor.resolvedImports);
|
final transitiveImports = _transitiveImports(accessor.imports);
|
||||||
|
|
||||||
var availableTables = _availableTables(transitiveImports)
|
var availableTables = _availableTables(transitiveImports)
|
||||||
.followedBy(accessor.tables)
|
.followedBy(accessor.declaredTables)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -39,13 +39,12 @@ class AnalyzeDartStep extends AnalyzingStep {
|
||||||
.whereType<ParsedMoorFile>()
|
.whereType<ParsedMoorFile>()
|
||||||
.expand((f) => f.resolvedQueries);
|
.expand((f) => f.resolvedQueries);
|
||||||
|
|
||||||
final parser = SqlParser(this, availableTables, accessor.queries);
|
final parser = SqlParser(this, availableTables, accessor.declaredQueries);
|
||||||
parser.parse();
|
parser.parse();
|
||||||
|
|
||||||
accessor.allTables = availableTables;
|
accessor
|
||||||
|
..tables = availableTables
|
||||||
accessor.resolvedQueries =
|
..queries = availableQueries.followedBy(parser.foundQueries).toList();
|
||||||
availableQueries.followedBy(parser.foundQueries).toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
part of '../steps.dart';
|
part of '../steps.dart';
|
||||||
|
|
||||||
/// Extracts the following information from a Dart file:
|
/// Extracts the following information from a Dart file:
|
||||||
/// - [SpecifiedTable]s, which are read from Dart classes extending `Table`.
|
/// - [MoorTable]s, which are read from Dart classes extending `Table`.
|
||||||
/// - [SpecifiedDatabase]s, which are read from `@UseMoor`-annotated classes
|
/// - [Database]s, which are read from `@UseMoor`-annotated classes
|
||||||
/// - [SpecifiedDao]s, which are read from `@UseDao`-annotated classes.
|
/// - [Dao]s, which are read from `@UseDao`-annotated classes.
|
||||||
///
|
///
|
||||||
/// Notably, this step does not analyze defined queries.
|
/// Notably, this step does not analyze defined queries.
|
||||||
class ParseDartStep extends Step {
|
class ParseDartStep extends Step {
|
||||||
|
@ -16,7 +16,7 @@ class ParseDartStep extends Step {
|
||||||
MoorDartParser _parser;
|
MoorDartParser _parser;
|
||||||
MoorDartParser get parser => _parser;
|
MoorDartParser get parser => _parser;
|
||||||
|
|
||||||
final Map<ClassElement, SpecifiedTable> _tables = {};
|
final Map<ClassElement, MoorTable> _tables = {};
|
||||||
|
|
||||||
ParseDartStep(Task task, FoundFile file, this.library) : super(task, file) {
|
ParseDartStep(Task task, FoundFile file, this.library) : super(task, file) {
|
||||||
_parser = MoorDartParser(this);
|
_parser = MoorDartParser(this);
|
||||||
|
@ -24,8 +24,8 @@ class ParseDartStep extends Step {
|
||||||
|
|
||||||
Future<ParsedDartFile> parse() async {
|
Future<ParsedDartFile> parse() async {
|
||||||
final reader = LibraryReader(library);
|
final reader = LibraryReader(library);
|
||||||
final databases = <SpecifiedDatabase>[];
|
final databases = <Database>[];
|
||||||
final daos = <SpecifiedDao>[];
|
final daos = <Dao>[];
|
||||||
|
|
||||||
for (final declaredClass in reader.classes) {
|
for (final declaredClass in reader.classes) {
|
||||||
// check if the table inherits from the moor table class. The !isExactly
|
// check if the table inherits from the moor table class. The !isExactly
|
||||||
|
@ -55,33 +55,32 @@ class ParseDartStep extends Step {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SpecifiedTable> _parseTable(ClassElement element) async {
|
Future<MoorTable> _parseTable(ClassElement element) async {
|
||||||
if (!_tables.containsKey(element)) {
|
if (!_tables.containsKey(element)) {
|
||||||
_tables[element] = await parser.parseTable(element);
|
_tables[element] = await parser.parseTable(element);
|
||||||
}
|
}
|
||||||
return _tables[element];
|
return _tables[element];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a [SpecifiedDatabase] from the [ClassElement] which was annotated
|
/// Parses a [Database] from the [ClassElement] which was annotated
|
||||||
/// with `@UseMoor` and the [annotation] reader that reads the `@UseMoor`
|
/// with `@UseMoor` and the [annotation] reader that reads the `@UseMoor`
|
||||||
/// annotation.
|
/// annotation.
|
||||||
Future<SpecifiedDatabase> parseDatabase(
|
Future<Database> parseDatabase(
|
||||||
ClassElement element, ConstantReader annotation) {
|
ClassElement element, ConstantReader annotation) {
|
||||||
return UseMoorParser(this).parseDatabase(element, annotation);
|
return UseMoorParser(this).parseDatabase(element, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a [SpecifiedDao] from a class declaration that has a `UseDao`
|
/// Parses a [Dao] from a class declaration that has a `UseDao`
|
||||||
/// [annotation].
|
/// [annotation].
|
||||||
Future<SpecifiedDao> parseDao(
|
Future<Dao> parseDao(ClassElement element, ConstantReader annotation) {
|
||||||
ClassElement element, ConstantReader annotation) {
|
|
||||||
return UseDaoParser(this).parseDao(element, annotation);
|
return UseDaoParser(this).parseDao(element, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves a [SpecifiedTable] for the class of each [DartType] in [types].
|
/// Resolves a [MoorTable] for the class of each [DartType] in [types].
|
||||||
/// The [initializedBy] element should be the piece of code that caused the
|
/// The [initializedBy] element should be the piece of code that caused the
|
||||||
/// parsing (e.g. the database class that is annotated with `@UseMoor`). This
|
/// parsing (e.g. the database class that is annotated with `@UseMoor`). This
|
||||||
/// will allow for more descriptive error messages.
|
/// will allow for more descriptive error messages.
|
||||||
Future<List<SpecifiedTable>> parseTables(
|
Future<List<MoorTable>> parseTables(
|
||||||
Iterable<DartType> types, Element initializedBy) {
|
Iterable<DartType> types, Element initializedBy) {
|
||||||
return Future.wait(types.map((type) {
|
return Future.wait(types.map((type) {
|
||||||
if (!_tableTypeChecker.isAssignableFrom(type.element)) {
|
if (!_tableTypeChecker.isAssignableFrom(type.element)) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
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/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/session.dart';
|
import 'package:moor_generator/src/analyzer/session.dart';
|
||||||
import 'package:moor_generator/src/backends/backend.dart';
|
import 'package:moor_generator/src/backends/backend.dart';
|
||||||
import 'package:moor_generator/src/model/specified_db_classes.dart';
|
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
/// A task is used to fully parse and analyze files based on an input file. To
|
/// A task is used to fully parse and analyze files based on an input file. To
|
||||||
|
@ -109,13 +109,13 @@ class Task {
|
||||||
file.currentResult = parsed;
|
file.currentResult = parsed;
|
||||||
|
|
||||||
final daosAndDatabases = parsed.declaredDaos
|
final daosAndDatabases = parsed.declaredDaos
|
||||||
.cast<SpecifiedDbAccessor>()
|
.cast<BaseMoorAccessor>()
|
||||||
.followedBy(parsed.declaredDatabases);
|
.followedBy(parsed.declaredDatabases);
|
||||||
|
|
||||||
for (final accessor in daosAndDatabases) {
|
for (final accessor in daosAndDatabases) {
|
||||||
final resolvedForAccessor = <FoundFile>[];
|
final resolvedForAccessor = <FoundFile>[];
|
||||||
|
|
||||||
for (final import in accessor.includes) {
|
for (final import in accessor.declaredIncludes) {
|
||||||
final found = session.resolve(file, import);
|
final found = session.resolve(file, import);
|
||||||
if (!await backend.exists(found.uri)) {
|
if (!await backend.exists(found.uri)) {
|
||||||
step.reportError(ErrorInDartCode(
|
step.reportError(ErrorInDartCode(
|
||||||
|
@ -129,7 +129,7 @@ class Task {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accessor.resolvedImports = resolvedForAccessor;
|
accessor.imports = resolvedForAccessor;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
|
||||||
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
|
||||||
|
|
||||||
class BaseDeclaration {
|
|
||||||
final FoundFile declarationFile;
|
|
||||||
|
|
||||||
/// If the column was declared in Dart, contains an enclosing getter element
|
|
||||||
/// that declared the column
|
|
||||||
final Element dartDeclaration;
|
|
||||||
|
|
||||||
/// If the column was declared in a moor file, contains the ast node that
|
|
||||||
/// contains the column definition
|
|
||||||
final AstNode moorDeclaration;
|
|
||||||
|
|
||||||
BaseDeclaration(
|
|
||||||
this.declarationFile, this.dartDeclaration, this.moorDeclaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Column declaration that is used as a metadata on a [Column] so that the
|
|
||||||
/// analysis plugin can know where a referenced column was declared and provide
|
|
||||||
/// navigation hints.
|
|
||||||
class ColumnDeclaration extends BaseDeclaration {
|
|
||||||
/// The moor version of the declared column.
|
|
||||||
final SpecifiedColumn column;
|
|
||||||
|
|
||||||
/// Whether this declaration is from a moor file (e.g. inside a `CREATE TABLE`
|
|
||||||
/// statement).
|
|
||||||
bool get isDefinedInMoorFile => moorDeclaration != null;
|
|
||||||
|
|
||||||
ColumnDeclaration(this.column, FoundFile declarationFile,
|
|
||||||
Element dartDeclaration, AstNode moorDeclaration)
|
|
||||||
: super(declarationFile, dartDeclaration, moorDeclaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Meta information set on a [Table] so that the analysis plugin can know where
|
|
||||||
/// a referenced table was declared and provide navigation hints.
|
|
||||||
class TableDeclaration extends BaseDeclaration {
|
|
||||||
final SpecifiedTable table;
|
|
||||||
final Table tableFromSqlParser;
|
|
||||||
|
|
||||||
TableDeclaration(this.table, FoundFile declarationFile,
|
|
||||||
Element dartDeclaration, AstNode moorDeclaration,
|
|
||||||
{this.tableFromSqlParser})
|
|
||||||
: super(declarationFile, dartDeclaration, moorDeclaration);
|
|
||||||
}
|
|
|
@ -1,15 +1,15 @@
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
|
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/model/specified_table.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';
|
||||||
import 'package:sqlparser/sqlparser.dart' hide ResultColumn;
|
import 'package:sqlparser/sqlparser.dart' hide ResultColumn;
|
||||||
|
|
||||||
class SqlParser {
|
class SqlParser {
|
||||||
final List<SpecifiedTable> tables;
|
final List<MoorTable> tables;
|
||||||
final Step step;
|
final Step step;
|
||||||
final List<DeclaredQuery> definedQueries;
|
final List<DeclaredQuery> definedQueries;
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ class SqlParser {
|
||||||
..declaredInMoorFile = declaredInMoor;
|
..declaredInMoorFile = declaredInMoor;
|
||||||
foundQueries.add(query);
|
foundQueries.add(query);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
|
// todo remove dependency on build package here
|
||||||
log.warning('Error while generating APIs for $name', e, s);
|
log.warning('Error while generating APIs for $name', e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:moor_generator/src/utils/type_converter_hint.dart';
|
import 'package:moor_generator/src/utils/type_converter_hint.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
import 'meta/declarations.dart';
|
|
||||||
|
|
||||||
/// Converts tables and types between the moor_generator and the sqlparser
|
/// Converts tables and types between the moor_generator and the sqlparser
|
||||||
/// library.
|
/// library.
|
||||||
class TypeMapper {
|
class TypeMapper {
|
||||||
final Map<Table, SpecifiedTable> _engineTablesToSpecified = {};
|
final Map<Table, MoorTable> _engineTablesToSpecified = {};
|
||||||
|
|
||||||
/// Convert a [SpecifiedTable] from moor into something that can be understood
|
/// Convert a [MoorTable] from moor into something that can be understood
|
||||||
/// by the sqlparser library.
|
/// by the sqlparser library.
|
||||||
Table extractStructure(SpecifiedTable table) {
|
Table extractStructure(MoorTable table) {
|
||||||
final existingTable = table.declaration?.tableFromSqlParser;
|
if (table.parserTable != null) {
|
||||||
if (existingTable != null) {
|
final parserTbl = table.parserTable;
|
||||||
_engineTablesToSpecified[existingTable] = table;
|
_engineTablesToSpecified[parserTbl] = table;
|
||||||
return existingTable;
|
return parserTbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
final columns = <TableColumn>[];
|
final columns = <TableColumn>[];
|
||||||
|
@ -29,13 +26,13 @@ class TypeMapper {
|
||||||
.withNullable(specified.nullable);
|
.withNullable(specified.nullable);
|
||||||
|
|
||||||
final column = TableColumn(specified.name.name, type);
|
final column = TableColumn(specified.name.name, type);
|
||||||
column.setMeta<ColumnDeclaration>(specified.declaration);
|
column.setMeta<MoorColumn>(specified);
|
||||||
|
|
||||||
columns.add(column);
|
columns.add(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
final engineTable = Table(name: table.sqlName, resolvedColumns: columns);
|
final engineTable = Table(name: table.sqlName, resolvedColumns: columns);
|
||||||
engineTable.setMeta<TableDeclaration>(table.declaration);
|
engineTable.setMeta<MoorTable>(table);
|
||||||
_engineTablesToSpecified[engineTable] = table;
|
_engineTablesToSpecified[engineTable] = table;
|
||||||
return engineTable;
|
return engineTable;
|
||||||
}
|
}
|
||||||
|
@ -222,7 +219,7 @@ class TypeMapper {
|
||||||
return FoundDartPlaceholder(type, columnType, name)..astNode = placeholder;
|
return FoundDartPlaceholder(type, columnType, name)..astNode = placeholder;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecifiedTable tableToMoor(Table table) {
|
MoorTable tableToMoor(Table table) {
|
||||||
return _engineTablesToSpecified[table];
|
return _engineTablesToSpecified[table];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class DaoGenerator extends Generator implements BaseGenerator {
|
||||||
classScope.leaf().write('mixin _\$${daoName}Mixin on '
|
classScope.leaf().write('mixin _\$${daoName}Mixin on '
|
||||||
'DatabaseAccessor<${dao.dbClass.displayName}> {\n');
|
'DatabaseAccessor<${dao.dbClass.displayName}> {\n');
|
||||||
|
|
||||||
for (final table in dao.allTables) {
|
for (final table in dao.tables) {
|
||||||
final infoType = table.tableInfoName;
|
final infoType = table.tableInfoName;
|
||||||
final getterName = table.tableFieldName;
|
final getterName = table.tableFieldName;
|
||||||
classScope
|
classScope
|
||||||
|
@ -30,7 +30,7 @@ class DaoGenerator extends Generator implements BaseGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
final writtenMappingMethods = <String>{};
|
final writtenMappingMethods = <String>{};
|
||||||
for (final query in dao.resolvedQueries) {
|
for (final query in dao.queries) {
|
||||||
QueryWriter(query, classScope.child(), writtenMappingMethods).write();
|
QueryWriter(query, classScope.child(), writtenMappingMethods).write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||||
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
|
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
import 'package:moor_generator/src/backends/plugin/services/requests.dart';
|
||||||
import 'package:moor_generator/src/backends/plugin/utils/ast_to_location.dart';
|
import 'package:moor_generator/src/backends/plugin/utils/ast_to_location.dart';
|
||||||
import 'package:moor_generator/src/backends/plugin/utils/span_utils.dart';
|
import 'package:moor_generator/src/backends/plugin/utils/span_utils.dart';
|
||||||
|
@ -73,7 +73,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<Location> _locationOfColumn(Column column) sync* {
|
Iterable<Location> _locationOfColumn(Column column) sync* {
|
||||||
final declaration = column.meta<ColumnDeclaration>();
|
final declaration = column.meta<MoorColumn>()?.declaration;
|
||||||
if (declaration != null) {
|
if (declaration != null) {
|
||||||
// the column was declared in a table and we happen to know where the
|
// the column was declared in a table and we happen to know where the
|
||||||
// declaration is - point to that declaration.
|
// declaration is - point to that declaration.
|
||||||
|
@ -101,7 +101,7 @@ class _NavigationVisitor extends RecursiveVisitor<void> {
|
||||||
final resolved = e.resolved;
|
final resolved = e.resolved;
|
||||||
|
|
||||||
if (resolved is Table && resolved != null) {
|
if (resolved is Table && resolved != null) {
|
||||||
final declaration = resolved.meta<TableDeclaration>();
|
final declaration = resolved.meta<MoorTable>()?.declaration;
|
||||||
_reportForSpan(
|
_reportForSpan(
|
||||||
e.span, ElementKind.CLASS, locationOfDeclaration(declaration));
|
e.span, ElementKind.CLASS, locationOfDeclaration(declaration));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
import 'package:analyzer_plugin/protocol/protocol_common.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.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/sql_queries/meta/declarations.dart';
|
|
||||||
import 'package:source_gen/source_gen.dart' show spanForElement;
|
import 'package:source_gen/source_gen.dart' show spanForElement;
|
||||||
import 'package:source_span/source_span.dart';
|
import 'package:source_span/source_span.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
@ -25,13 +25,13 @@ Location locationOfNode(FoundFile file, AstNode node) {
|
||||||
return _locationForSpan(node.span, file);
|
return _locationForSpan(node.span, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Location locationOfDeclaration(BaseDeclaration declaration) {
|
Location locationOfDeclaration(Declaration declaration) {
|
||||||
if (declaration.dartDeclaration != null) {
|
final file = declaration.declaration.file;
|
||||||
final span = spanForElement(declaration.dartDeclaration);
|
if (declaration is DartDeclaration) {
|
||||||
return _locationForSpan(span, declaration.declarationFile);
|
return _locationForSpan(spanForElement(declaration.element), file);
|
||||||
} else if (declaration.moorDeclaration != null) {
|
} else if (declaration is MoorDeclaration) {
|
||||||
return locationOfNode(
|
return locationOfNode(file, declaration.node);
|
||||||
declaration.declarationFile, declaration.moorDeclaration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:moor_generator/src/analyzer/options.dart';
|
import 'package:moor_generator/src/analyzer/options.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart';
|
|
||||||
import 'package:moor_generator/src/model/used_type_converter.dart';
|
import 'declarations/declaration.dart';
|
||||||
|
import 'used_type_converter.dart';
|
||||||
|
|
||||||
/// The column types in sql.
|
/// The column types in sql.
|
||||||
enum ColumnType { integer, text, boolean, datetime, blob, real }
|
enum ColumnType { integer, text, boolean, datetime, blob, real }
|
||||||
|
@ -77,7 +78,7 @@ const Map<ColumnType, String> sqlTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A column, as specified by a getter in a table.
|
/// A column, as specified by a getter in a table.
|
||||||
class SpecifiedColumn {
|
class MoorColumn implements HasDeclaration {
|
||||||
/// The getter name of this column in the table class. It will also be used
|
/// The getter name of this column in the table class. It will also be used
|
||||||
/// as getter name in the TableInfo class (as it needs to override the field)
|
/// as getter name in the TableInfo class (as it needs to override the field)
|
||||||
/// and in the generated data class that will be generated for each table.
|
/// and in the generated data class that will be generated for each table.
|
||||||
|
@ -85,7 +86,8 @@ class SpecifiedColumn {
|
||||||
|
|
||||||
/// The declaration of this column, contains information about where this
|
/// The declaration of this column, contains information about where this
|
||||||
/// column was created in source code.
|
/// column was created in source code.
|
||||||
ColumnDeclaration declaration;
|
@override
|
||||||
|
final ColumnDeclaration declaration;
|
||||||
|
|
||||||
/// Whether this column was declared inside a moor file.
|
/// Whether this column was declared inside a moor file.
|
||||||
bool get declaredInMoorFile => declaration?.isDefinedInMoorFile ?? false;
|
bool get declaredInMoorFile => declaration?.isDefinedInMoorFile ?? false;
|
||||||
|
@ -176,7 +178,7 @@ class SpecifiedColumn {
|
||||||
/// this column.
|
/// this column.
|
||||||
String get sqlTypeName => sqlTypes[type];
|
String get sqlTypeName => sqlTypes[type];
|
||||||
|
|
||||||
SpecifiedColumn({
|
MoorColumn({
|
||||||
this.type,
|
this.type,
|
||||||
this.dartGetterName,
|
this.dartGetterName,
|
||||||
this.name,
|
this.name,
|
||||||
|
@ -186,6 +188,7 @@ class SpecifiedColumn {
|
||||||
this.features = const [],
|
this.features = const [],
|
||||||
this.defaultArgument,
|
this.defaultArgument,
|
||||||
this.typeConverter,
|
this.typeConverter,
|
||||||
|
this.declaration,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,9 +234,3 @@ class LimitingTextLength extends ColumnFeature {
|
||||||
typedOther.maxLength == maxLength;
|
typedOther.maxLength == maxLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Reference extends ColumnFeature {
|
|
||||||
final SpecifiedColumn referencedColumn;
|
|
||||||
|
|
||||||
const Reference(this.referencedColumn);
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
||||||
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
|
|
||||||
|
import 'declarations/declaration.dart';
|
||||||
|
import 'table.dart';
|
||||||
|
|
||||||
|
/// Abstract class for database and dao elements.
|
||||||
|
abstract class BaseMoorAccessor implements HasDeclaration {
|
||||||
|
@override
|
||||||
|
final DatabaseOrDaoDeclaration declaration;
|
||||||
|
|
||||||
|
/// The [ClassElement] that was annotated with `UseMoor` or `UseDao`.
|
||||||
|
ClassElement get fromClass => declaration.fromClass;
|
||||||
|
|
||||||
|
/// All tables that have been declared on this accessor directly.
|
||||||
|
///
|
||||||
|
/// This contains the `tables` field from a `UseMoor` or `UseDao` annotation,
|
||||||
|
/// but not tables that are declared in imported moor files. Use
|
||||||
|
final List<MoorTable> declaredTables;
|
||||||
|
|
||||||
|
/// The `includes` field from the `UseMoor` or `UseDao` annotation.
|
||||||
|
final List<String> declaredIncludes;
|
||||||
|
|
||||||
|
/// All queries declared directly in the `UseMoor` or `UseDao` annotation.
|
||||||
|
final List<DeclaredQuery> declaredQueries;
|
||||||
|
|
||||||
|
/// All tables for this database accessor. This contains the [declaredTables]
|
||||||
|
/// and all tables that are reachable through
|
||||||
|
List<MoorTable> tables = [];
|
||||||
|
|
||||||
|
/// All resolved queries.
|
||||||
|
///
|
||||||
|
/// This includes the resolve result for queries that were declared in the
|
||||||
|
/// same annotation, and queries that were in declared files.
|
||||||
|
List<SqlQuery> queries = [];
|
||||||
|
|
||||||
|
/// Resolved imports from this file.
|
||||||
|
List<FoundFile> imports = [];
|
||||||
|
|
||||||
|
BaseMoorAccessor._(this.declaration, this.declaredTables,
|
||||||
|
this.declaredIncludes, this.declaredQueries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A database, declared via a `UseMoor` annotation on a Dart class.
|
||||||
|
class Database extends BaseMoorAccessor {
|
||||||
|
final List<DartType> daos;
|
||||||
|
|
||||||
|
Database({
|
||||||
|
this.daos = const [],
|
||||||
|
DatabaseOrDaoDeclaration declaration,
|
||||||
|
List<MoorTable> declaredTables,
|
||||||
|
List<String> declaredIncludes,
|
||||||
|
List<DeclaredQuery> declaredQueries,
|
||||||
|
}) : super._(declaration, declaredTables, declaredIncludes, declaredQueries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A dao, declared via an `UseDao` annotation on a Dart class.
|
||||||
|
class Dao extends BaseMoorAccessor {
|
||||||
|
/// The database class this dao belongs to.
|
||||||
|
final DartType dbClass;
|
||||||
|
|
||||||
|
Dao({
|
||||||
|
@required this.dbClass,
|
||||||
|
DatabaseOrDaoDeclaration declaration,
|
||||||
|
List<MoorTable> declaredTables,
|
||||||
|
List<String> declaredIncludes,
|
||||||
|
List<DeclaredQuery> declaredQueries,
|
||||||
|
}) : super._(declaration, declaredTables, declaredIncludes, declaredQueries);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
part of 'declaration.dart';
|
||||||
|
|
||||||
|
abstract class ColumnDeclaration extends Declaration {
|
||||||
|
/// Whether this column was declared in a moor file (e.g. in a `CREATE TABLE`
|
||||||
|
/// statement).
|
||||||
|
bool get isDefinedInMoorFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DartColumnDeclaration implements DartDeclaration, ColumnDeclaration {
|
||||||
|
@override
|
||||||
|
final SourceRange declaration;
|
||||||
|
|
||||||
|
/// In the Dart api, columns declared via getters.
|
||||||
|
@override
|
||||||
|
final Element element;
|
||||||
|
|
||||||
|
DartColumnDeclaration._(this.declaration, this.element);
|
||||||
|
|
||||||
|
factory DartColumnDeclaration(Element element, FoundFile file) {
|
||||||
|
return DartColumnDeclaration._(
|
||||||
|
SourceRange.fromElementAndFile(element, file),
|
||||||
|
element,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isDefinedInMoorFile => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoorColumnDeclaration implements MoorDeclaration, ColumnDeclaration {
|
||||||
|
@override
|
||||||
|
final SourceRange declaration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final AstNode node;
|
||||||
|
|
||||||
|
MoorColumnDeclaration._(this.declaration, this.node);
|
||||||
|
|
||||||
|
factory MoorColumnDeclaration(AstNode node, FoundFile file) {
|
||||||
|
return MoorColumnDeclaration._(
|
||||||
|
SourceRange.fromNodeAndFile(node, file),
|
||||||
|
node,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isDefinedInMoorFile => true;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
part of 'declaration.dart';
|
||||||
|
|
||||||
|
/// Declaration of a database or dao in a Dart file.
|
||||||
|
class DatabaseOrDaoDeclaration implements DartDeclaration {
|
||||||
|
/// The [ClassElement] with the `UseMoor` or `UseDao` annotation.
|
||||||
|
final ClassElement fromClass;
|
||||||
|
@override
|
||||||
|
final SourceRange declaration;
|
||||||
|
|
||||||
|
DatabaseOrDaoDeclaration._(this.fromClass, this.declaration);
|
||||||
|
|
||||||
|
factory DatabaseOrDaoDeclaration(ClassElement fromClass, FoundFile file) {
|
||||||
|
return DatabaseOrDaoDeclaration._(
|
||||||
|
fromClass,
|
||||||
|
SourceRange.fromElementAndFile(fromClass, file),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Element get element => fromClass;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
||||||
|
import 'package:moor_generator/src/model/sources.dart';
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
part 'columns.dart';
|
||||||
|
part 'database.dart';
|
||||||
|
part 'tables.dart';
|
||||||
|
|
||||||
|
/// Interface for model elements that are declared somewhere.
|
||||||
|
abstract class HasDeclaration {
|
||||||
|
/// Gets the declaration of this element, if set.
|
||||||
|
Declaration get declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Base class for all declarations in the generator model.
|
||||||
|
abstract class Declaration {
|
||||||
|
/// The file and text span where this element was declared.
|
||||||
|
SourceRange get declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Declaration for elements that are declared in a `.dart` file.
|
||||||
|
abstract class DartDeclaration extends Declaration {
|
||||||
|
/// A fitting, enclosing element for this declaration.
|
||||||
|
Element get element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Declaration for elements that are declared in a `.moor` file.
|
||||||
|
abstract class MoorDeclaration extends Declaration {
|
||||||
|
/// The ast node from a moor file for this declaration.
|
||||||
|
AstNode get node;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
part of 'declaration.dart';
|
||||||
|
|
||||||
|
abstract class TableDeclaration extends Declaration {}
|
||||||
|
|
||||||
|
class DartTableDeclaration implements TableDeclaration, DartDeclaration {
|
||||||
|
@override
|
||||||
|
final SourceRange declaration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final ClassElement element;
|
||||||
|
|
||||||
|
DartTableDeclaration._(this.declaration, this.element);
|
||||||
|
|
||||||
|
factory DartTableDeclaration(ClassElement element, FoundFile file) {
|
||||||
|
return DartTableDeclaration._(
|
||||||
|
SourceRange.fromElementAndFile(element, file),
|
||||||
|
element,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoorTableDeclaration implements TableDeclaration, MoorDeclaration {
|
||||||
|
@override
|
||||||
|
final SourceRange declaration;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final TableInducingStatement node;
|
||||||
|
|
||||||
|
MoorTableDeclaration._(this.declaration, this.node);
|
||||||
|
|
||||||
|
factory MoorTableDeclaration(TableInducingStatement node, FoundFile file) {
|
||||||
|
return MoorTableDeclaration._(
|
||||||
|
SourceRange.fromNodeAndFile(node, file),
|
||||||
|
node,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export 'column.dart';
|
||||||
|
export 'database.dart';
|
||||||
|
export 'declarations/declaration.dart';
|
||||||
|
export 'sources.dart';
|
||||||
|
export 'sql_query.dart';
|
||||||
|
export 'table.dart';
|
||||||
|
export 'used_type_converter.dart';
|
|
@ -0,0 +1,40 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
/// Represents a single location accessible to analysis services.
|
||||||
|
class SourceLocation {
|
||||||
|
final FoundFile file;
|
||||||
|
final int offset;
|
||||||
|
|
||||||
|
SourceLocation(this.file, this.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a range in a source file, accessible to analysis services
|
||||||
|
class SourceRange {
|
||||||
|
final SourceLocation start;
|
||||||
|
final int length;
|
||||||
|
SourceLocation _end;
|
||||||
|
|
||||||
|
FoundFile get file => start.file;
|
||||||
|
|
||||||
|
SourceLocation get end {
|
||||||
|
return _end ??= SourceLocation(start.file, start.offset + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceRange(this.start, this.length);
|
||||||
|
|
||||||
|
factory SourceRange.fromElementAndFile(Element element, FoundFile file) {
|
||||||
|
return SourceRange(
|
||||||
|
SourceLocation(file, element.nameOffset),
|
||||||
|
element.nameLength,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SourceRange.fromNodeAndFile(AstNode node, FoundFile file) {
|
||||||
|
return SourceRange(
|
||||||
|
SourceLocation(file, node.firstPosition),
|
||||||
|
node.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
|
||||||
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
|
||||||
|
|
||||||
class SpecifiedDbAccessor {
|
|
||||||
final ClassElement fromClass;
|
|
||||||
|
|
||||||
final List<SpecifiedTable> tables;
|
|
||||||
final List<String> includes;
|
|
||||||
final List<DeclaredQuery> queries;
|
|
||||||
|
|
||||||
List<FoundFile> resolvedImports = [];
|
|
||||||
|
|
||||||
/// Resolved queries. This includes queries that weren't declared on this
|
|
||||||
/// class but imported via an `includes` directive.
|
|
||||||
List<SqlQuery> resolvedQueries = const [];
|
|
||||||
|
|
||||||
/// All tables available to this class. This includes the [tables] and all
|
|
||||||
/// tables defined in a [includes] table.
|
|
||||||
List<SpecifiedTable> allTables = [];
|
|
||||||
|
|
||||||
SpecifiedDbAccessor(this.fromClass, this.tables, this.includes, this.queries);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Model generated from a class that is annotated with `UseDao`.
|
|
||||||
class SpecifiedDao extends SpecifiedDbAccessor {
|
|
||||||
/// The database class this dao belongs to.
|
|
||||||
final DartType dbClass;
|
|
||||||
|
|
||||||
SpecifiedDao(
|
|
||||||
ClassElement fromClass,
|
|
||||||
this.dbClass,
|
|
||||||
List<SpecifiedTable> tables,
|
|
||||||
List<String> includes,
|
|
||||||
List<DeclaredQuery> queries)
|
|
||||||
: super(fromClass, tables, includes, queries);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SpecifiedDatabase extends SpecifiedDbAccessor {
|
|
||||||
final List<DartType> daos;
|
|
||||||
|
|
||||||
SpecifiedDatabase(ClassElement fromClass, List<SpecifiedTable> tables,
|
|
||||||
this.daos, List<String> includes, List<DeclaredQuery> queries)
|
|
||||||
: super(fromClass, tables, includes, queries);
|
|
||||||
}
|
|
|
@ -1,11 +1,12 @@
|
||||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/src/model/used_type_converter.dart';
|
|
||||||
import 'package:moor_generator/src/utils/hash.dart';
|
import 'package:moor_generator/src/utils/hash.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
import 'column.dart';
|
||||||
|
import 'table.dart';
|
||||||
|
import 'used_type_converter.dart';
|
||||||
|
|
||||||
final _illegalChars = RegExp(r'[^0-9a-zA-Z_]');
|
final _illegalChars = RegExp(r'[^0-9a-zA-Z_]');
|
||||||
final _leadingDigits = RegExp(r'^\d*');
|
final _leadingDigits = RegExp(r'^\d*');
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ abstract class SqlQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SqlSelectQuery extends SqlQuery {
|
class SqlSelectQuery extends SqlQuery {
|
||||||
final List<SpecifiedTable> readsFrom;
|
final List<MoorTable> readsFrom;
|
||||||
final InferredResultSet resultSet;
|
final InferredResultSet resultSet;
|
||||||
|
|
||||||
String get resultClassName {
|
String get resultClassName {
|
||||||
|
@ -116,7 +117,7 @@ class SqlSelectQuery extends SqlQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdatingQuery extends SqlQuery {
|
class UpdatingQuery extends SqlQuery {
|
||||||
final List<SpecifiedTable> updates;
|
final List<MoorTable> updates;
|
||||||
final bool isInsert;
|
final bool isInsert;
|
||||||
|
|
||||||
UpdatingQuery(String name, AnalysisContext fromContext,
|
UpdatingQuery(String name, AnalysisContext fromContext,
|
||||||
|
@ -129,7 +130,7 @@ class InferredResultSet {
|
||||||
/// If the result columns of a SELECT statement exactly match one table, we
|
/// If the result columns of a SELECT statement exactly match one table, we
|
||||||
/// can just use the data class generated for that table. Otherwise, we'd have
|
/// can just use the data class generated for that table. Otherwise, we'd have
|
||||||
/// to create another class.
|
/// to create another class.
|
||||||
final SpecifiedTable matchingTable;
|
final MoorTable matchingTable;
|
||||||
final List<ResultColumn> columns;
|
final List<ResultColumn> columns;
|
||||||
final Map<ResultColumn, String> _dartNames = {};
|
final Map<ResultColumn, String> _dartNames = {};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:moor_generator/src/analyzer/options.dart';
|
import 'package:moor_generator/src/analyzer/options.dart';
|
||||||
import 'package:moor_generator/src/analyzer/sql_queries/meta/declarations.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/used_type_converter.dart';
|
import 'package:moor_generator/src/model/used_type_converter.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
|
import 'column.dart';
|
||||||
|
import 'declarations/declaration.dart';
|
||||||
|
|
||||||
/// A parsed table, declared in code by extending `Table` and referencing that
|
/// A parsed table, declared in code by extending `Table` and referencing that
|
||||||
/// table in `@UseMoor` or `@UseDao`.
|
/// table in `@UseMoor` or `@UseDao`.
|
||||||
class SpecifiedTable {
|
class MoorTable implements HasDeclaration {
|
||||||
/// The [ClassElement] for the class that declares this table or null if
|
/// The [ClassElement] for the class that declares this table or null if
|
||||||
/// the table was inferred from a `CREATE TABLE` statement.
|
/// the table was inferred from a `CREATE TABLE` statement.
|
||||||
final ClassElement fromClass;
|
final ClassElement fromClass;
|
||||||
|
|
||||||
TableDeclaration declaration;
|
@override
|
||||||
|
final TableDeclaration declaration;
|
||||||
|
|
||||||
|
/// The associated table to use for the sqlparser package when analyzing
|
||||||
|
/// sql queries. Note that this field is set lazily.
|
||||||
|
Table parserTable;
|
||||||
|
|
||||||
/// If [fromClass] is null, another source to use when determining the name
|
/// If [fromClass] is null, another source to use when determining the name
|
||||||
/// of this table in generated Dart code.
|
/// of this table in generated Dart code.
|
||||||
|
@ -26,7 +32,7 @@ class SpecifiedTable {
|
||||||
String get _baseName => _overriddenName ?? fromClass.name;
|
String get _baseName => _overriddenName ?? fromClass.name;
|
||||||
|
|
||||||
/// The columns declared in this table.
|
/// The columns declared in this table.
|
||||||
final List<SpecifiedColumn> columns;
|
final List<MoorColumn> columns;
|
||||||
|
|
||||||
/// The name of this table when stored in the database
|
/// The name of this table when stored in the database
|
||||||
final String sqlName;
|
final String sqlName;
|
||||||
|
@ -60,7 +66,7 @@ class SpecifiedTable {
|
||||||
/// The set of primary keys, if they have been explicitly defined by
|
/// The set of primary keys, if they have been explicitly defined by
|
||||||
/// overriding `primaryKey` in the table class. `null` if the primary key has
|
/// overriding `primaryKey` in the table class. `null` if the primary key has
|
||||||
/// not been defined that way.
|
/// not been defined that way.
|
||||||
final Set<SpecifiedColumn> primaryKey;
|
final Set<MoorColumn> primaryKey;
|
||||||
|
|
||||||
/// When non-null, the generated table class will override the `withoutRowId`
|
/// When non-null, the generated table class will override the `withoutRowId`
|
||||||
/// getter on the table class with this value.
|
/// getter on the table class with this value.
|
||||||
|
@ -76,7 +82,7 @@ class SpecifiedTable {
|
||||||
|
|
||||||
/// The set of tables referenced somewhere in the declaration of this table,
|
/// The set of tables referenced somewhere in the declaration of this table,
|
||||||
/// for instance by using a `REFERENCES` column constraint.
|
/// for instance by using a `REFERENCES` column constraint.
|
||||||
final Set<SpecifiedTable> references = {};
|
final Set<MoorTable> references = {};
|
||||||
|
|
||||||
/// Returns whether this table was created from a `CREATE VIRTUAL TABLE`
|
/// Returns whether this table was created from a `CREATE VIRTUAL TABLE`
|
||||||
/// statement in a moor file
|
/// statement in a moor file
|
||||||
|
@ -84,26 +90,27 @@ class SpecifiedTable {
|
||||||
if (declaration == null) {
|
if (declaration == null) {
|
||||||
throw StateError("Couldn't determine whether $displayName is a virtual "
|
throw StateError("Couldn't determine whether $displayName is a virtual "
|
||||||
'table since its declaration is unknown.');
|
'table since its declaration is unknown.');
|
||||||
|
} else if (declaration is! MoorTableDeclaration) {
|
||||||
|
// tables declared in Dart can't be virtual
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
final node = declaration?.moorDeclaration;
|
|
||||||
// tables declared in Dart can't be virtual
|
|
||||||
if (node == null) return false;
|
|
||||||
|
|
||||||
assert(node is TableInducingStatement);
|
final node = (declaration as MoorTableDeclaration).node;
|
||||||
return node is CreateVirtualTableStatement;
|
return node is CreateVirtualTableStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpecifiedTable(
|
MoorTable({
|
||||||
{this.fromClass,
|
this.fromClass,
|
||||||
this.columns,
|
this.columns,
|
||||||
this.sqlName,
|
this.sqlName,
|
||||||
this.dartTypeName,
|
this.dartTypeName,
|
||||||
this.primaryKey,
|
this.primaryKey,
|
||||||
String overriddenName,
|
String overriddenName,
|
||||||
this.overrideWithoutRowId,
|
this.overrideWithoutRowId,
|
||||||
this.overrideTableConstraints,
|
this.overrideTableConstraints,
|
||||||
this.overrideDontWriteConstraints})
|
this.overrideDontWriteConstraints,
|
||||||
: _overriddenName = overriddenName;
|
this.declaration,
|
||||||
|
}) : _overriddenName = overriddenName;
|
||||||
|
|
||||||
/// Finds all type converters used in this tables.
|
/// Finds all type converters used in this tables.
|
||||||
Iterable<UsedTypeConverter> get converters =>
|
Iterable<UsedTypeConverter> get converters =>
|
|
@ -1,13 +1,16 @@
|
||||||
import 'package:analyzer/dart/ast/ast.dart';
|
import 'package:analyzer/dart/ast/ast.dart';
|
||||||
import 'package:analyzer/dart/element/type.dart';
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
import 'package:moor_generator/src/model/table.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
|
import 'column.dart';
|
||||||
|
|
||||||
class UsedTypeConverter {
|
class UsedTypeConverter {
|
||||||
/// Index of this converter in the table in which it has been created.
|
/// Index of this converter in the table in which it has been created.
|
||||||
int index;
|
int index;
|
||||||
SpecifiedTable table;
|
|
||||||
|
/// The table using this type converter.
|
||||||
|
MoorTable table;
|
||||||
|
|
||||||
/// The [Expression] that will construct the type converter at runtime. The
|
/// The [Expression] that will construct the type converter at runtime. The
|
||||||
/// type converter constructed will map a [mappedType] to the [sqlType] and
|
/// type converter constructed will map a [mappedType] to the [sqlType] and
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
|
|
||||||
/// Topologically sorts a list of [SpecifiedTable]s by their
|
/// Topologically sorts a list of [MoorTable]s by their
|
||||||
/// [SpecifiedTable.references] relationship: Tables appearing first in the
|
/// [MoorTable.references] relationship: Tables appearing first in the
|
||||||
/// output have to be created first so the table creation script doesn't crash
|
/// output have to be created first so the table creation script doesn't crash
|
||||||
/// because of tables not existing.
|
/// because of tables not existing.
|
||||||
///
|
///
|
||||||
/// If there is a circular reference between [SpecifiedTable]s, an error will
|
/// If there is a circular reference between [MoorTable]s, an error will
|
||||||
/// be added that contains the name of the tables in question.
|
/// be added that contains the name of the tables in question.
|
||||||
List<SpecifiedTable> sortTablesTopologically(Iterable<SpecifiedTable> tables) {
|
List<MoorTable> sortTablesTopologically(Iterable<MoorTable> tables) {
|
||||||
final run = _SortRun();
|
final run = _SortRun();
|
||||||
|
|
||||||
for (final table in tables) {
|
for (final table in tables) {
|
||||||
|
@ -20,7 +20,7 @@ List<SpecifiedTable> sortTablesTopologically(Iterable<SpecifiedTable> tables) {
|
||||||
return run.result;
|
return run.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _visit(SpecifiedTable table, _SortRun run) {
|
void _visit(MoorTable table, _SortRun run) {
|
||||||
for (final reference in table.references) {
|
for (final reference in table.references) {
|
||||||
if (run.result.contains(reference)) {
|
if (run.result.contains(reference)) {
|
||||||
// already handled, nothing to do
|
// already handled, nothing to do
|
||||||
|
@ -38,14 +38,14 @@ void _visit(SpecifiedTable table, _SortRun run) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SortRun {
|
class _SortRun {
|
||||||
final Map<SpecifiedTable, SpecifiedTable> previous = {};
|
final Map<MoorTable, MoorTable> previous = {};
|
||||||
final List<SpecifiedTable> result = [];
|
final List<MoorTable> result = [];
|
||||||
|
|
||||||
/// Throws a [CircularReferenceException] because the [last] table depends on
|
/// Throws a [CircularReferenceException] because the [last] table depends on
|
||||||
/// [first], which (transitively) depends on [last] as well. The path in the
|
/// [first], which (transitively) depends on [last] as well. The path in the
|
||||||
/// thrown exception will go from [first] to [last].
|
/// thrown exception will go from [first] to [last].
|
||||||
void throwCircularException(SpecifiedTable last, SpecifiedTable first) {
|
void throwCircularException(MoorTable last, MoorTable first) {
|
||||||
final constructedPath = <SpecifiedTable>[];
|
final constructedPath = <MoorTable>[];
|
||||||
for (var current = last; current != first; current = previous[current]) {
|
for (var current = last; current != first; current = previous[current]) {
|
||||||
constructedPath.insert(0, current);
|
constructedPath.insert(0, current);
|
||||||
}
|
}
|
||||||
|
@ -54,18 +54,18 @@ class _SortRun {
|
||||||
throw CircularReferenceException(constructedPath);
|
throw CircularReferenceException(constructedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool didVisitAlready(SpecifiedTable table) {
|
bool didVisitAlready(MoorTable table) {
|
||||||
return previous[table] != null || result.contains(table);
|
return previous[table] != null || result.contains(table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Thrown by [sortTablesTopologically] when the graph formed by
|
/// Thrown by [sortTablesTopologically] when the graph formed by
|
||||||
/// [SpecifiedTable]s and their [SpecifiedTable.references] is not acyclic.
|
/// [MoorTable]s and their [MoorTable.references] is not acyclic.
|
||||||
class CircularReferenceException implements Exception {
|
class CircularReferenceException implements Exception {
|
||||||
/// The list of tables forming a circular reference, so that the first table
|
/// The list of tables forming a circular reference, so that the first table
|
||||||
/// in this list references the second one and so on. The last table in this
|
/// in this list references the second one and so on. The last table in this
|
||||||
/// list references the first one.
|
/// list references the first one.
|
||||||
final List<SpecifiedTable> affected;
|
final List<MoorTable> affected;
|
||||||
|
|
||||||
CircularReferenceException(this.affected);
|
CircularReferenceException(this.affected);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import 'package:moor_generator/src/model/specified_db_classes.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/writer.dart';
|
import 'package:moor_generator/writer.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
|
|
||||||
/// Generates the Dart code put into a `.g.dart` file when running the
|
/// Generates the Dart code put into a `.g.dart` file when running the
|
||||||
/// generator.
|
/// generator.
|
||||||
class DatabaseWriter {
|
class DatabaseWriter {
|
||||||
final SpecifiedDatabase db;
|
final Database db;
|
||||||
final Scope scope;
|
final Scope scope;
|
||||||
|
|
||||||
DatabaseWriter(this.db, this.scope);
|
DatabaseWriter(this.db, this.scope);
|
||||||
|
|
||||||
void write() {
|
void write() {
|
||||||
// Write referenced tables
|
// Write referenced tables
|
||||||
for (final table in db.allTables) {
|
for (final table in db.tables) {
|
||||||
TableWriter(table, scope.child()).writeInto();
|
TableWriter(table, scope.child()).writeInto();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class DatabaseWriter {
|
||||||
|
|
||||||
final tableGetters = <String>[];
|
final tableGetters = <String>[];
|
||||||
|
|
||||||
for (final table in db.allTables) {
|
for (final table in db.tables) {
|
||||||
tableGetters.add(table.tableFieldName);
|
tableGetters.add(table.tableFieldName);
|
||||||
final tableClassName = table.tableInfoName;
|
final tableClassName = table.tableInfoName;
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class DatabaseWriter {
|
||||||
|
|
||||||
// Write implementation for query methods
|
// Write implementation for query methods
|
||||||
final writtenMappingMethods = <String>{};
|
final writtenMappingMethods = <String>{};
|
||||||
for (final query in db.resolvedQueries) {
|
for (final query in db.queries) {
|
||||||
QueryWriter(query, dbScope.child(), writtenMappingMethods).write();
|
QueryWriter(query, dbScope.child(), writtenMappingMethods).write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:math' show max;
|
import 'dart:math' show max;
|
||||||
|
|
||||||
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/analyzer/options.dart';
|
import 'package:moor_generator/src/analyzer/options.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:moor_generator/src/utils/string_escaper.dart';
|
import 'package:moor_generator/src/utils/string_escaper.dart';
|
||||||
import 'package:moor_generator/writer.dart';
|
import 'package:moor_generator/writer.dart';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/writer.dart';
|
import 'package:moor_generator/writer.dart';
|
||||||
import 'package:recase/recase.dart';
|
import 'package:recase/recase.dart';
|
||||||
|
|
||||||
class DataClassWriter {
|
class DataClassWriter {
|
||||||
final SpecifiedTable table;
|
final MoorTable table;
|
||||||
final Scope scope;
|
final Scope scope;
|
||||||
|
|
||||||
StringBuffer _buffer;
|
StringBuffer _buffer;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
import 'package:moor_generator/src/model/declarations/declaration.dart';
|
||||||
import 'package:moor_generator/src/utils/string_escaper.dart';
|
import 'package:moor_generator/src/utils/string_escaper.dart';
|
||||||
import 'package:moor_generator/writer.dart';
|
import 'package:moor_generator/writer.dart';
|
||||||
import 'package:sqlparser/sqlparser.dart';
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
|
||||||
class TableWriter {
|
class TableWriter {
|
||||||
final SpecifiedTable table;
|
final MoorTable table;
|
||||||
final Scope scope;
|
final Scope scope;
|
||||||
|
|
||||||
StringBuffer _buffer;
|
StringBuffer _buffer;
|
||||||
|
@ -132,7 +132,7 @@ class TableWriter {
|
||||||
_buffer.write('return map; \n}\n');
|
_buffer.write('return map; \n}\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void _writeColumnGetter(SpecifiedColumn column) {
|
void _writeColumnGetter(MoorColumn column) {
|
||||||
final isNullable = column.nullable;
|
final isNullable = column.nullable;
|
||||||
final additionalParams = <String, String>{};
|
final additionalParams = <String, String>{};
|
||||||
final expressionBuffer = StringBuffer();
|
final expressionBuffer = StringBuffer();
|
||||||
|
@ -192,7 +192,7 @@ class TableWriter {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _writeColumnVerificationMeta(SpecifiedColumn column) {
|
void _writeColumnVerificationMeta(MoorColumn column) {
|
||||||
if (!scope.writer.options.skipVerificationCode) {
|
if (!scope.writer.options.skipVerificationCode) {
|
||||||
_buffer
|
_buffer
|
||||||
..write('final VerificationMeta ${_fieldNameForColumnMeta(column)} = ')
|
..write('final VerificationMeta ${_fieldNameForColumnMeta(column)} = ')
|
||||||
|
@ -233,7 +233,7 @@ class TableWriter {
|
||||||
_buffer.write('return context;\n}\n');
|
_buffer.write('return context;\n}\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
String _fieldNameForColumnMeta(SpecifiedColumn column) {
|
String _fieldNameForColumnMeta(MoorColumn column) {
|
||||||
return '_${column.dartGetterName}Meta';
|
return '_${column.dartGetterName}Meta';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,8 +299,8 @@ class TableWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.isVirtualTable) {
|
if (table.isVirtualTable) {
|
||||||
final stmt =
|
final declaration = table.declaration as MoorTableDeclaration;
|
||||||
table.declaration.moorDeclaration as CreateVirtualTableStatement;
|
final stmt = declaration.node as CreateVirtualTableStatement;
|
||||||
final moduleAndArgs = asDartLiteral(
|
final moduleAndArgs = asDartLiteral(
|
||||||
'${stmt.moduleName}(${stmt.argumentContent.join(', ')})');
|
'${stmt.moduleName}(${stmt.argumentContent.join(', ')})');
|
||||||
_buffer
|
_buffer
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:moor_generator/writer.dart';
|
import 'package:moor_generator/writer.dart';
|
||||||
|
|
||||||
class UpdateCompanionWriter {
|
class UpdateCompanionWriter {
|
||||||
final SpecifiedTable table;
|
final MoorTable table;
|
||||||
final Scope scope;
|
final Scope scope;
|
||||||
|
|
||||||
StringBuffer _buffer;
|
StringBuffer _buffer;
|
||||||
|
@ -44,7 +43,7 @@ class UpdateCompanionWriter {
|
||||||
/// absent during insert are marked `@required` here. Also, we don't need to
|
/// absent during insert are marked `@required` here. Also, we don't need to
|
||||||
/// use value wrappers here - `Value.absent` simply isn't an option.
|
/// use value wrappers here - `Value.absent` simply isn't an option.
|
||||||
void _writeInsertConstructor() {
|
void _writeInsertConstructor() {
|
||||||
final requiredColumns = <SpecifiedColumn>{};
|
final requiredColumns = <MoorColumn>{};
|
||||||
|
|
||||||
// can't be constant because we use initializers (this.a = Value(a)).
|
// can't be constant because we use initializers (this.a = Value(a)).
|
||||||
// for a parameter a which is only potentially constant.
|
// for a parameter a which is only potentially constant.
|
||||||
|
|
|
@ -51,7 +51,7 @@ CREATE TABLE bars (
|
||||||
final result = file.currentResult as ParsedDartFile;
|
final result = file.currentResult as ParsedDartFile;
|
||||||
final database = result.declaredDatabases.single;
|
final database = result.declaredDatabases.single;
|
||||||
|
|
||||||
expect(database.allTables.map((t) => t.sqlName),
|
expect(
|
||||||
containsAll(['foos', 'bars']));
|
database.tables.map((t) => t.sqlName), containsAll(['foos', 'bars']));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
|
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/analyzer/dart/parser.dart';
|
import 'package:moor_generator/src/analyzer/dart/parser.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/session.dart';
|
import 'package:moor_generator/src/analyzer/session.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../../utils/test_backend.dart';
|
import '../../utils/test_backend.dart';
|
||||||
|
@ -85,7 +84,7 @@ void main() {
|
||||||
parser = MoorDartParser(dartStep);
|
parser = MoorDartParser(dartStep);
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<SpecifiedTable> parse(String name) async {
|
Future<MoorTable> parse(String name) async {
|
||||||
return parser.parseTable(dartStep.library.getType(name));
|
return parser.parseTable(dartStep.library.getType(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +112,14 @@ void main() {
|
||||||
table.columns.singleWhere((col) => col.name.name == 'id');
|
table.columns.singleWhere((col) => col.name.name == 'id');
|
||||||
|
|
||||||
expect(idColumn.name, equals(ColumnName.implicitly('id')));
|
expect(idColumn.name, equals(ColumnName.implicitly('id')));
|
||||||
expect(idColumn.declaration.dartDeclaration,
|
expect(
|
||||||
const TypeMatcher<PropertyAccessorElement>());
|
idColumn.declaration,
|
||||||
|
const TypeMatcher<DartColumnDeclaration>().having(
|
||||||
|
(c) => c.element,
|
||||||
|
'element',
|
||||||
|
const TypeMatcher<PropertyAccessorElement>(),
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should use explicit name, if it exists', () async {
|
test('should use explicit name, if it exists', () async {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.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/results.dart';
|
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
||||||
import 'package:moor_generator/src/analyzer/session.dart';
|
import 'package:moor_generator/src/analyzer/session.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
@ -92,14 +92,14 @@ class ProgrammingLanguages extends Table {
|
||||||
final result = file.currentResult as ParsedDartFile;
|
final result = file.currentResult as ParsedDartFile;
|
||||||
final database = result.declaredDatabases.single;
|
final database = result.declaredDatabases.single;
|
||||||
|
|
||||||
expect(database.allTables.map((t) => t.sqlName),
|
expect(database.tables.map((t) => t.sqlName),
|
||||||
containsAll(['used_languages', 'libraries', 'programming_languages']));
|
containsAll(['used_languages', 'libraries', 'programming_languages']));
|
||||||
|
|
||||||
final tableWithReferences =
|
final tableWithReferences =
|
||||||
database.allTables.singleWhere((r) => r.sqlName == 'reference_test');
|
database.tables.singleWhere((r) => r.sqlName == 'reference_test');
|
||||||
expect(tableWithReferences.references.single.sqlName, 'libraries');
|
expect(tableWithReferences.references.single.sqlName, 'libraries');
|
||||||
|
|
||||||
final importQuery = database.resolvedQueries
|
final importQuery = database.queries
|
||||||
.singleWhere((q) => q.name == 'transitiveImportTest') as SqlSelectQuery;
|
.singleWhere((q) => q.name == 'transitiveImportTest') as SqlSelectQuery;
|
||||||
expect(importQuery.resultClassName, 'ProgrammingLanguage');
|
expect(importQuery.resultClassName, 'ProgrammingLanguage');
|
||||||
expect(importQuery.declaredInMoorFile, isFalse);
|
expect(importQuery.declaredInMoorFile, isFalse);
|
||||||
|
@ -108,7 +108,7 @@ class ProgrammingLanguages extends Table {
|
||||||
contains(equals(
|
contains(equals(
|
||||||
FoundDartPlaceholder(DartPlaceholderType.orderBy, null, 'o'))));
|
FoundDartPlaceholder(DartPlaceholderType.orderBy, null, 'o'))));
|
||||||
|
|
||||||
final librariesQuery = database.resolvedQueries
|
final librariesQuery = database.queries
|
||||||
.singleWhere((q) => q.name == 'findLibraries') as SqlSelectQuery;
|
.singleWhere((q) => q.name == 'findLibraries') as SqlSelectQuery;
|
||||||
expect(librariesQuery.variables.single.type, ColumnType.text);
|
expect(librariesQuery.variables.single.type, ColumnType.text);
|
||||||
expect(librariesQuery.declaredInMoorFile, isTrue);
|
expect(librariesQuery.declaredInMoorFile, isTrue);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
|
import 'package:moor_generator/moor_generator.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/results.dart';
|
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
||||||
import 'package:moor_generator/src/analyzer/session.dart';
|
import 'package:moor_generator/src/analyzer/session.dart';
|
||||||
import 'package:moor_generator/src/model/specified_column.dart';
|
|
||||||
import 'package:moor_generator/src/model/sql_query.dart';
|
import 'package:moor_generator/src/model/sql_query.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/analyzer/options.dart';
|
import 'package:moor_generator/src/analyzer/options.dart';
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('companion names', () {
|
test('companion names', () {
|
||||||
final table =
|
final table = MoorTable(overriddenName: 'GoogleUser', dartTypeName: 'User');
|
||||||
SpecifiedTable(overriddenName: 'GoogleUser', dartTypeName: 'User');
|
|
||||||
|
|
||||||
expect(table.getNameForCompanionClass(const MoorOptions()),
|
expect(table.getNameForCompanionClass(const MoorOptions()),
|
||||||
'GoogleUserCompanion');
|
'GoogleUserCompanion');
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:moor_generator/src/model/specified_table.dart';
|
import 'package:moor_generator/moor_generator.dart';
|
||||||
import 'package:moor_generator/src/utils/table_reference_sorter.dart';
|
import 'package:moor_generator/src/utils/table_reference_sorter.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('throws cyclic exception when two tables reference each other', () {
|
test('throws cyclic exception when two tables reference each other', () {
|
||||||
final first = SpecifiedTable(sqlName: 'a');
|
final first = MoorTable(sqlName: 'a');
|
||||||
final second = SpecifiedTable(sqlName: 'b');
|
final second = MoorTable(sqlName: 'b');
|
||||||
first.references.add(second);
|
first.references.add(second);
|
||||||
second.references.add(first);
|
second.references.add(first);
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('throws cyclic exception on a circular reference with three tables', () {
|
test('throws cyclic exception on a circular reference with three tables', () {
|
||||||
final a = SpecifiedTable(sqlName: 'a');
|
final a = MoorTable(sqlName: 'a');
|
||||||
final b = SpecifiedTable(sqlName: 'b');
|
final b = MoorTable(sqlName: 'b');
|
||||||
final c = SpecifiedTable(sqlName: 'c');
|
final c = MoorTable(sqlName: 'c');
|
||||||
final d = SpecifiedTable(sqlName: 'd');
|
final d = MoorTable(sqlName: 'd');
|
||||||
|
|
||||||
a.references.add(b);
|
a.references.add(b);
|
||||||
b.references.add(c);
|
b.references.add(c);
|
||||||
|
@ -31,10 +31,10 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sorts tables topologically when no cycles exist', () {
|
test('sorts tables topologically when no cycles exist', () {
|
||||||
final a = SpecifiedTable(sqlName: 'a');
|
final a = MoorTable(sqlName: 'a');
|
||||||
final b = SpecifiedTable(sqlName: 'b');
|
final b = MoorTable(sqlName: 'b');
|
||||||
final c = SpecifiedTable(sqlName: 'c');
|
final c = MoorTable(sqlName: 'c');
|
||||||
final d = SpecifiedTable(sqlName: 'd');
|
final d = MoorTable(sqlName: 'd');
|
||||||
|
|
||||||
a.references.add(b);
|
a.references.add(b);
|
||||||
b.references.add(c);
|
b.references.add(c);
|
||||||
|
@ -44,7 +44,7 @@ void main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CircularReferenceException _expectFails(Iterable<SpecifiedTable> table) {
|
CircularReferenceException _expectFails(Iterable<MoorTable> table) {
|
||||||
try {
|
try {
|
||||||
sortTablesTopologically(table);
|
sortTablesTopologically(table);
|
||||||
fail('Expected sortTablesTopologically to throw here');
|
fail('Expected sortTablesTopologically to throw here');
|
||||||
|
|
|
@ -26,3 +26,9 @@ abstract class SyntacticEntity {
|
||||||
/// actual source.
|
/// actual source.
|
||||||
bool get synthetic;
|
bool get synthetic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension to report the length of a [SyntacticEntity].
|
||||||
|
extension SyntacticLengthExtension on SyntacticEntity {
|
||||||
|
/// The length of this entity, in characters.
|
||||||
|
int get length => lastPosition - firstPosition;
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ issue_tracker: https://github.com/simolus3/moor/issues
|
||||||
author: Simon Binder <oss@simonbinder.eu>
|
author: Simon Binder <oss@simonbinder.eu>
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.2.2 <3.0.0'
|
sdk: '>=2.6.0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
meta: ^1.1.0
|
meta: ^1.1.0
|
||||||
|
|
Loading…
Reference in New Issue