Add current_time_millis SQL function (#857)

This commit is contained in:
Simon Binder 2020-10-11 11:25:21 +02:00
parent 9d9658248b
commit 3470d0485a
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
5 changed files with 32 additions and 1 deletions

View File

@ -133,6 +133,7 @@ For more details on sqlite compile options, see [their documentation](https://ww
returns null. Otherwise, returns the result of applying the matching function in `dart:math`.
- `regexp`: Wraps the Dart `RegExp` apis, so that `foo REGEXP bar` is equivalent to `RegExp(bar).hasMatch(foo)`. Note that we have to create a new
`RegExp` instance for each `regexp` sql call, which can impact performance on large queries.
- `current_time_millis`: Returns the current unix timestamp as milliseconds. Equivalent to `DateTime.now().millisecondsSinceEpoch` in Dart.
Note that `NaN`, `-infinity` or `+infinity` are represented as `NULL` in sql.

View File

@ -91,6 +91,13 @@ extension EnableMoorFunctions on Database {
argumentCount: const AllowedArgumentCount(3),
function: _containsImpl,
);
createFunction(
functionName: 'current_time_millis',
deterministic: true,
directOnly: false,
argumentCount: const AllowedArgumentCount(0),
function: (List<dynamic> args) => DateTime.now().millisecondsSinceEpoch,
);
}
}

View File

@ -147,6 +147,11 @@ void main() {
expect(selectSingle("moor_contains('hi', 'i', 1)"), 1);
});
});
test('current_time_millis', () {
final now = DateTime.now().millisecondsSinceEpoch;
expect(selectSingle('current_time_millis()'), closeTo(now, 100));
});
}
// utils to verify the sql functions behave exactly like the ones from the VM

View File

@ -23,7 +23,9 @@ class _MoorFfiFunctions with ArgumentCountLinter implements FunctionHandler {
};
@override
Set<String> get functionNames => const {'pow', ..._unaryFunctions};
Set<String> get functionNames {
return const {'pow', 'current_time_millis', ..._unaryFunctions};
}
@override
int argumentCountFor(String function) {
@ -31,6 +33,8 @@ class _MoorFfiFunctions with ArgumentCountLinter implements FunctionHandler {
return 1;
} else if (function == 'pow') {
return 2;
} else if (function == 'current_time_millis') {
return 0;
}
// ignore: avoid_returning_null
return null;
@ -46,6 +50,11 @@ class _MoorFfiFunctions with ArgumentCountLinter implements FunctionHandler {
@override
ResolveResult inferReturnType(AnalysisContext context, SqlInvocation call,
List<Typeable> expandedArgs) {
if (call.name == 'current_time_millis') {
return const ResolveResult(
ResolvedType(type: BasicType.int, nullable: false));
}
return const ResolveResult(
ResolvedType(type: BasicType.real, nullable: true));
}

View File

@ -64,6 +64,15 @@ void main() {
]);
});
test('infers return type for current_time_millis', () {
final result = engine.analyze('SELECT current_time_millis();');
final stmt = result.root as SelectStatement;
expect(stmt.resolvedColumns.map(result.typeOf), [
const ResolveResult(ResolvedType(type: BasicType.int, nullable: false))
]);
});
test('infers argument type', () {
final result = engine.analyze('SELECT pow(2.5, ?);');
final variable = result.root.allDescendants.whereType<Variable>().first;