Skip to content

Commit fe0df6d

Browse files
committed
Add substrExpr to query builder
1 parent f9d5443 commit fe0df6d

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

drift/lib/src/runtime/query_builder/expressions/text.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,31 @@ extension StringExpressionOperators on Expression<String> {
137137
/// and [length] can be negative to return a section of the string before
138138
/// [start].
139139
Expression<String> substr(int start, [int? length]) {
140+
return substrExpr(
141+
Constant(start), length != null ? Constant(length) : null);
142+
}
143+
144+
/// Calls the [`substr`](https://sqlite.org/lang_corefunc.html#substr)
145+
/// function with arbitrary expressions as arguments.
146+
///
147+
/// For instance, this call uses [substrExpr] to remove the last 5 characters
148+
/// from a column. As this depends on its [StringExpressionOperators.length],
149+
/// it needs to use expressions:
150+
///
151+
/// ```dart
152+
/// update(table).write(TableCompanion.custom(
153+
/// column: column.substrExpr(Variable(1), column.length - Variable(5))
154+
/// ));
155+
/// ```
156+
///
157+
/// When both [start] and [length] are Dart values (e.g. [Variable]s or
158+
/// [Constant]s), consider using [substr] instead.
159+
Expression<String> substrExpr(Expression<int> start,
160+
[Expression<int>? length]) {
140161
return FunctionCallExpression('SUBSTR', [
141162
this,
142-
Constant<int>(start),
143-
if (length != null) Constant<int>(length),
163+
start,
164+
if (length != null) length,
144165
]);
145166
}
146167
}

drift/test/database/expressions/expressions_integration_test.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ void main() {
125125
});
126126

127127
test('substring', () {
128-
expect(eval(Constant('hello world').substr(7)), completion('world'));
128+
final input = Constant('hello world');
129+
expect(eval(input.substr(7)), completion('world'));
130+
131+
expect(eval(input.substrExpr(Variable(1), input.length - Variable(6))),
132+
completion('hello'));
129133
});
130134
});
131135

drift/test/database/expressions/text_test.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,8 @@ void main() {
5252
test('substr', () {
5353
expect(expression.substr(10), generates('SUBSTR(col, 10)'));
5454
expect(expression.substr(10, 2), generates('SUBSTR(col, 10, 2)'));
55+
56+
expect(expression.substrExpr(Variable(1), expression.length - Variable(5)),
57+
generates('SUBSTR(col, ?, LENGTH(col) - ?)', [1, 5]));
5558
});
5659
}

0 commit comments

Comments
 (0)