mirror of https://github.com/AMT-Cheif/drift.git
Bug fixes and support for dart placeholder
This commit is contained in:
parent
add33e339c
commit
b5acbbf374
|
@ -107,11 +107,11 @@ class TypeMapper {
|
|||
return engineView;
|
||||
}
|
||||
|
||||
/// Extracts variables and Dart templates from the [ctx]. Variables are
|
||||
/// sorted by their ascending index. Placeholders are sorted by the position
|
||||
/// they have in the query. When comparing variables and placeholders, the
|
||||
/// variable comes first if the first variable with the same index appears
|
||||
/// before the placeholder.
|
||||
/// Extracts variables and Dart templates from the AST tree starting at
|
||||
/// [root], but nested queries are excluded. Variables are sorted by their
|
||||
/// ascending index. Placeholders are sorted by the position they have in the
|
||||
/// query. When comparing variables and placeholders, the variable comes first
|
||||
/// if the first variable with the same index appears before the placeholder.
|
||||
///
|
||||
/// Additionally, the following assumptions can be made if this method returns
|
||||
/// without throwing:
|
||||
|
@ -125,14 +125,16 @@ class TypeMapper {
|
|||
// this contains variable references. For instance, SELECT :a = :a would
|
||||
// contain two entries, both referring to the same variable. To do that,
|
||||
// we use the fact that each variable has a unique index.
|
||||
final collector = _VariableCollector();
|
||||
root.accept(collector, null);
|
||||
final variableCollector = _ElementCollector<Variable>();
|
||||
final placeholderCollector = _ElementCollector<DartPlaceholder>();
|
||||
|
||||
final variables = collector.result;
|
||||
final placeholders =
|
||||
root.allDescendants.whereType<DartPlaceholder>().toList();
|
||||
root.accept(variableCollector, null);
|
||||
root.accept(placeholderCollector, null);
|
||||
|
||||
final merged = _mergeVarsAndPlaceholders(variables, placeholders);
|
||||
final merged = _mergeVarsAndPlaceholders(
|
||||
variableCollector.result,
|
||||
placeholderCollector.result,
|
||||
);
|
||||
|
||||
final foundElements = <FoundElement>[];
|
||||
// we don't allow variables with an explicit index after an array. For
|
||||
|
@ -356,16 +358,24 @@ class TypeMapper {
|
|||
}
|
||||
}
|
||||
|
||||
/// Because nested variables should not be included when extracting all
|
||||
/// FoundElements allDescendants.whereType<Variable>() no longer works.
|
||||
class _VariableCollector extends RecursiveVisitor<void, void> {
|
||||
final List<Variable> result;
|
||||
/// Because FoundElements from nested queries should not be added to the parent
|
||||
/// query, it is necessary to use a visitor to decide when to stop collection
|
||||
/// elements.
|
||||
///
|
||||
/// [T] can either be a [Variable] or [DartPlaceholder]. If the type is anything
|
||||
/// else the result list will be empty.
|
||||
class _ElementCollector<T> extends RecursiveVisitor<void, void> {
|
||||
final List<T> result;
|
||||
|
||||
_VariableCollector() : result = [];
|
||||
_ElementCollector()
|
||||
: result = [],
|
||||
assert(T == Variable || T == DartPlaceholder, 'T is: $T');
|
||||
|
||||
@override
|
||||
void visitVariable(Variable e, void arg) {
|
||||
result.add(e);
|
||||
if (T == Variable) {
|
||||
result.add(e as T);
|
||||
}
|
||||
|
||||
super.visitVariable(e, arg);
|
||||
}
|
||||
|
@ -373,8 +383,13 @@ class _VariableCollector extends RecursiveVisitor<void, void> {
|
|||
@override
|
||||
void visitMoorSpecificNode(MoorSpecificNode e, void arg) {
|
||||
if (e is NestedQueryColumn) {
|
||||
// If the node ist a nested query, return to avoid collecting elements
|
||||
// inside of it
|
||||
return;
|
||||
}
|
||||
if (e is DartPlaceholder && T == DartPlaceholder) {
|
||||
result.add(e as T);
|
||||
}
|
||||
|
||||
super.visitMoorSpecificNode(e, arg);
|
||||
}
|
||||
|
|
|
@ -521,18 +521,12 @@ class NestedResultQuery extends NestedResult {
|
|||
required this.query,
|
||||
});
|
||||
|
||||
String filedName(String? nestedPrefix) {
|
||||
String filedName() {
|
||||
if (from.as != null) {
|
||||
return from.as!;
|
||||
}
|
||||
|
||||
final name = ReCase(query.resultClassName).camelCase;
|
||||
|
||||
if (nestedPrefix != null) {
|
||||
return name + nestedPrefix;
|
||||
}
|
||||
|
||||
return name;
|
||||
return ReCase(query.name).camelCase;
|
||||
}
|
||||
|
||||
String resultTypeCode(String parentResultClassName) {
|
||||
|
|
|
@ -45,7 +45,8 @@ class QueryWriter {
|
|||
// We do this transformation so late because it shouldn't have an impact on
|
||||
// analysis, Dart getter names stay the same.
|
||||
if (resultSet != null && options.newSqlCodeGeneration) {
|
||||
ExplicitAliasTransformer().rewrite(query.root!);
|
||||
_transformer = ExplicitAliasTransformer();
|
||||
_transformer.rewrite(query.root!);
|
||||
NestedQueryTransformer().rewrite(query.root!);
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,12 @@ class QueryWriter {
|
|||
}
|
||||
|
||||
void _writeSelect(SqlSelectQuery select) {
|
||||
if (select.hasNestedQuery && !scope.options.newSqlCodeGeneration) {
|
||||
throw UnsupportedError(
|
||||
'To use nested result queries enable new_sql_code_generation',
|
||||
);
|
||||
}
|
||||
|
||||
_writeSelectStatementCreator(select);
|
||||
|
||||
if (!select.declaredInMoorFile && !options.compactQueryMethods) {
|
||||
|
@ -140,16 +147,7 @@ class QueryWriter {
|
|||
_buffer.write('$fieldName: $tableGetter.$mappingMethod(row, '
|
||||
'tablePrefix: ${asDartLiteral(prefix)}),');
|
||||
} else if (nested is NestedResultQuery) {
|
||||
if (!scope.options.newSqlCodeGeneration) {
|
||||
throw UnsupportedError(
|
||||
'To use nested result queries enable new_sql_code_generation',
|
||||
);
|
||||
}
|
||||
|
||||
final prefix = resultSet.nestedPrefixFor(nested);
|
||||
if (prefix == null) continue;
|
||||
|
||||
final fieldName = nested.filedName(prefix);
|
||||
final fieldName = nested.filedName();
|
||||
_buffer.write('$fieldName: await ');
|
||||
|
||||
_writeCustomSelectStatement(nested.query);
|
||||
|
@ -554,7 +552,9 @@ class QueryWriter {
|
|||
_buffer.write('${table.dbGetterName},');
|
||||
}
|
||||
|
||||
for (final element in select.elements.whereType<FoundDartPlaceholder>()) {
|
||||
for (final element in select
|
||||
.elementsWithNestedQueries()
|
||||
.whereType<FoundDartPlaceholder>()) {
|
||||
_buffer.write('...${placeholderContextName(element)}.watchedTables,');
|
||||
}
|
||||
|
||||
|
@ -686,7 +686,7 @@ class _ExpandedDeclarationWriter {
|
|||
}
|
||||
|
||||
needsIndexCounter = true;
|
||||
for (final element in query.elements) {
|
||||
for (final element in query.elementsWithNestedQueries()) {
|
||||
if (element is FoundVariable) {
|
||||
if (element.isArray) {
|
||||
_writeArrayVariable(element);
|
||||
|
|
|
@ -52,8 +52,7 @@ class ResultSetWriter {
|
|||
fieldNames.add(fieldName);
|
||||
if (!nested.isNullable) nonNullableFields.add(fieldName);
|
||||
} else if (nested is NestedResultQuery) {
|
||||
final nestedPrefix = resultSet.nestedPrefixFor(nested);
|
||||
final fieldName = nested.filedName(nestedPrefix);
|
||||
final fieldName = nested.filedName();
|
||||
final typeName = nested.resultTypeCode(className);
|
||||
|
||||
if (nested.query.resultSet.needsOwnClass) {
|
||||
|
|
|
@ -100,11 +100,7 @@ class ReferenceScope {
|
|||
///
|
||||
/// If [includeParents] is set to false, resolve will only search the current
|
||||
/// scope.
|
||||
T? resolve<T extends Referencable>(
|
||||
String name, {
|
||||
Function()? orElse,
|
||||
bool includeParents = true,
|
||||
}) {
|
||||
T? resolve<T extends Referencable>(String name, {Function()? orElse}) {
|
||||
ReferenceScope? scope = this;
|
||||
var isAtParent = false;
|
||||
final upper = name.toUpperCase();
|
||||
|
@ -122,8 +118,6 @@ class ReferenceScope {
|
|||
|
||||
scope = scope.parent;
|
||||
isAtParent = true;
|
||||
|
||||
if (!includeParents) break;
|
||||
}
|
||||
|
||||
if (orElse != null) orElse();
|
||||
|
|
|
@ -34,8 +34,7 @@ class _NestedQueryTransformer extends Transformer<void> {
|
|||
AstNode? visitReference(Reference e, void arg) {
|
||||
// if the scope of the nested query cannot resolve the reference, the
|
||||
// reference needs to be retrieved from the parent query
|
||||
if (e.entityName != null &&
|
||||
e.scope.resolve(e.entityName!, includeParents: false) == null) {
|
||||
if (e.resultEntity != null && e.resultEntity!.origin.scope != e.scope) {
|
||||
final result = e.scope.resolve(e.entityName!);
|
||||
|
||||
if (result == null) {
|
||||
|
@ -62,7 +61,7 @@ class _NestedQueryTransformer extends Transformer<void> {
|
|||
|
||||
return e;
|
||||
} else {
|
||||
super.visitMoorSpecificNode(e, arg);
|
||||
return super.visitMoorSpecificNode(e, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,12 @@ class AstPreparingVisitor extends RecursiveVisitor<void, void> {
|
|||
|
||||
@override
|
||||
void visitNestedQueryVariable(NestedQueryVariable e, void arg) {
|
||||
assert(
|
||||
false,
|
||||
'This should be unreachable, because NestedQueryVariables are only'
|
||||
'introduced later in the NestedQueryResolver',
|
||||
);
|
||||
|
||||
_foundVariables.add(e);
|
||||
visitChildren(e, arg);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue