mirror of https://github.com/AMT-Cheif/drift.git
Find variables reliably
This commit is contained in:
parent
2cca2f517e
commit
1a4ac27415
|
@ -894,8 +894,27 @@ class FoundVariable extends FoundElement implements HasType {
|
|||
/// three [Variable]s in its AST, but only two [FoundVariable]s, where the
|
||||
/// `?` will have index 1 and (both) `:xyz` variables will have index 2. We
|
||||
/// only report one [FoundVariable] per index.
|
||||
///
|
||||
/// This [index] might change in the generator as variables are moved around.
|
||||
/// See [originalIndex] for the original index and a further discussion of
|
||||
/// this.
|
||||
int index;
|
||||
|
||||
/// The original index this variable had in the SQL string written by the
|
||||
/// user.
|
||||
///
|
||||
/// In the generator, we might have to shuffle variable indices around a bit
|
||||
/// to support array variables which occupy a dynamic amount of variable
|
||||
/// indices at runtime.
|
||||
/// For instance, consider `SELECT * FROM foo WHERE a = :a OR b IN :b OR c = :c`.
|
||||
/// Here, `:c` will have an original index of 3. Since `:b` is an array
|
||||
/// variable though, the actual query sent to the database system at runtime
|
||||
/// will look like `SELECT * FROM foo WHERE a = ?1 OR b IN (?3, ?4) OR c = ?2`
|
||||
/// when a size-2 list is passed for `b`. All non-array variables have been
|
||||
/// given indices that appear before the array to support this, so the [index]
|
||||
/// of `c` would then be `2`.
|
||||
final int originalIndex;
|
||||
|
||||
/// The name of this variable, or null if it's not a named variable.
|
||||
@override
|
||||
String? name;
|
||||
|
@ -939,7 +958,8 @@ class FoundVariable extends FoundElement implements HasType {
|
|||
this.isArray = false,
|
||||
this.isRequired = false,
|
||||
this.typeConverter,
|
||||
}) : hidden = false,
|
||||
}) : originalIndex = index,
|
||||
hidden = false,
|
||||
syntacticOrigin = variable,
|
||||
forCaptured = null;
|
||||
|
||||
|
@ -949,7 +969,8 @@ class FoundVariable extends FoundElement implements HasType {
|
|||
required this.sqlType,
|
||||
required Variable variable,
|
||||
required this.forCaptured,
|
||||
}) : typeConverter = null,
|
||||
}) : originalIndex = index,
|
||||
typeConverter = null,
|
||||
nullable = false,
|
||||
isArray = false,
|
||||
isRequired = true,
|
||||
|
|
|
@ -103,12 +103,12 @@ class SqlWriter extends NodeSqlBuilder {
|
|||
return dialect.escape(identifier);
|
||||
}
|
||||
|
||||
FoundVariable? _findMoorVar(Variable target) {
|
||||
FoundVariable? _findVariable(Variable target) {
|
||||
return query!.variables
|
||||
.firstWhereOrNull((f) => f.index == target.resolvedIndex);
|
||||
.firstWhereOrNull((f) => f.originalIndex == target.resolvedIndex);
|
||||
}
|
||||
|
||||
void _writeMoorVariable(FoundVariable variable) {
|
||||
void _writeAnalyzedVariable(FoundVariable variable) {
|
||||
if (variable.isArray) {
|
||||
_writeRawInSpaces('(\$${expandedName(variable)})');
|
||||
} else {
|
||||
|
@ -175,9 +175,9 @@ class SqlWriter extends NodeSqlBuilder {
|
|||
|
||||
@override
|
||||
void visitNamedVariable(ColonNamedVariable e, void arg) {
|
||||
final moor = _findMoorVar(e);
|
||||
if (moor != null) {
|
||||
_writeMoorVariable(moor);
|
||||
final found = _findVariable(e);
|
||||
if (found != null) {
|
||||
_writeAnalyzedVariable(found);
|
||||
} else {
|
||||
super.visitNamedVariable(e, arg);
|
||||
}
|
||||
|
@ -185,9 +185,9 @@ class SqlWriter extends NodeSqlBuilder {
|
|||
|
||||
@override
|
||||
void visitNumberedVariable(NumberedVariable e, void arg) {
|
||||
final moor = _findMoorVar(e);
|
||||
if (moor != null) {
|
||||
_writeMoorVariable(moor);
|
||||
final found = _findVariable(e);
|
||||
if (found != null) {
|
||||
_writeAnalyzedVariable(found);
|
||||
} else {
|
||||
super.visitNumberedVariable(e, arg);
|
||||
}
|
||||
|
|
|
@ -169,9 +169,8 @@ void main() {
|
|||
expect(generated, contains('.toList()'));
|
||||
});
|
||||
|
||||
group('generates correct code for expanded arrays', () {
|
||||
Future<void> runTest(DriftOptions options, Matcher expectation) async {
|
||||
final result = await generateForQueryInDriftFile('''
|
||||
test('generates correct code for expanded arrays', () async {
|
||||
final result = await generateForQueryInDriftFile('''
|
||||
CREATE TABLE tbl (
|
||||
a TEXT,
|
||||
b TEXT,
|
||||
|
@ -179,22 +178,17 @@ CREATE TABLE tbl (
|
|||
);
|
||||
|
||||
query: SELECT * FROM tbl WHERE a = :a AND b IN :b AND c = :c;
|
||||
''', options: options);
|
||||
expect(result, expectation);
|
||||
}
|
||||
|
||||
test('with the new query generator', () {
|
||||
return runTest(
|
||||
const DriftOptions.defaults(),
|
||||
allOf(
|
||||
contains(r'var $arrayStartIndex = 3;'),
|
||||
contains(r'SELECT * FROM tbl WHERE a = ?1 AND b IN ($expandedb) '
|
||||
'AND c = ?2'),
|
||||
contains(r'variables: [Variable<String>(a), Variable<String>(c), '
|
||||
r'for (var $ in b) Variable<String>($)], readsFrom: {tbl'),
|
||||
),
|
||||
);
|
||||
});
|
||||
''');
|
||||
expect(
|
||||
result,
|
||||
allOf(
|
||||
contains(r'var $arrayStartIndex = 3;'),
|
||||
contains(r'SELECT * FROM tbl WHERE a = ?1 AND b IN ($expandedb) '
|
||||
'AND c = ?2'),
|
||||
contains(r'variables: [Variable<String>(a), Variable<String>(c), '
|
||||
r'for (var $ in b) Variable<String>($)], readsFrom: {tbl'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
Loading…
Reference in New Issue