mirror of https://github.com/AMT-Cheif/drift.git
Introduce extension for DateTime expressions
This commit is contained in:
parent
82a6fd9f2d
commit
5b3bcb1916
|
@ -2,35 +2,39 @@ part of '../query_builder.dart';
|
|||
|
||||
/// Extracts the (UTC) year from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.year instead')
|
||||
Expression<int, IntType> year(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%Y', date);
|
||||
date.year;
|
||||
|
||||
/// Extracts the (UTC) month from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.month instead')
|
||||
Expression<int, IntType> month(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%m', date);
|
||||
date.month;
|
||||
|
||||
/// Extracts the (UTC) day from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.day instead')
|
||||
Expression<int, IntType> day(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%d', date);
|
||||
date.day;
|
||||
|
||||
/// Extracts the (UTC) hour from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.hour instead')
|
||||
Expression<int, IntType> hour(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%H', date);
|
||||
date.hour;
|
||||
|
||||
/// Extracts the (UTC) minute from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.minute instead')
|
||||
Expression<int, IntType> minute(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%M', date);
|
||||
date.minute;
|
||||
|
||||
/// Extracts the (UTC) second from the given expression that resolves
|
||||
/// to a datetime.
|
||||
@Deprecated('Use date.second instead')
|
||||
Expression<int, IntType> second(Expression<DateTime, DateTimeType> date) =>
|
||||
_StrftimeSingleFieldExpression('%S', date);
|
||||
|
||||
// todo: Add difference and unixSeconds method, also convert to extension
|
||||
date.second;
|
||||
|
||||
/// A sql expression that evaluates to the current date represented as a unix
|
||||
/// timestamp. The hour, minute and second fields will be set to 0.
|
||||
|
@ -52,7 +56,38 @@ class _CustomDateTimeExpression
|
|||
|
||||
/// Provides expressions to extract information from date time values, or to
|
||||
/// calculate the difference between datetimes.
|
||||
extension DateTimeExpressions on Expression<DateTime, DateTimeType> {}
|
||||
extension DateTimeExpressions on Expression<DateTime, DateTimeType> {
|
||||
/// Extracts the (UTC) year from `this` datetime expression.
|
||||
Expression<int, IntType> get year =>
|
||||
_StrftimeSingleFieldExpression('%Y', this);
|
||||
|
||||
/// Extracts the (UTC) month from `this` datetime expression.
|
||||
Expression<int, IntType> get month =>
|
||||
_StrftimeSingleFieldExpression('%m', this);
|
||||
|
||||
/// Extracts the (UTC) day from `this` datetime expression.
|
||||
Expression<int, IntType> get day =>
|
||||
_StrftimeSingleFieldExpression('%d', this);
|
||||
|
||||
/// Extracts the (UTC) hour from `this` datetime expression.
|
||||
Expression<int, IntType> get hour =>
|
||||
_StrftimeSingleFieldExpression('%H', this);
|
||||
|
||||
/// Extracts the (UTC) minute from `this` datetime expression.
|
||||
Expression<int, IntType> get minute =>
|
||||
_StrftimeSingleFieldExpression('%M', this);
|
||||
|
||||
/// Extracts the (UTC) second from `this` datetime expression.
|
||||
Expression<int, IntType> get second =>
|
||||
_StrftimeSingleFieldExpression('%S', this);
|
||||
|
||||
/// Returns an expression containing the amount of seconds from the unix
|
||||
/// epoch (January 1st, 1970) to `this` datetime expression. The datetime is
|
||||
/// assumed to be in utc.
|
||||
// for moor, date times are just unix timestamps, so we don't need to rewrite
|
||||
// anything when converting
|
||||
Expression<int, IntType> get secondsSinceEpoch => dartCast();
|
||||
}
|
||||
|
||||
/// Expression that extracts components out of a date time by using the builtin
|
||||
/// sqlite function "strftime" and casting the result to an integer.
|
||||
|
|
|
@ -26,6 +26,13 @@ abstract class Expression<D, T extends SqlType<D>> implements Component {
|
|||
Expression<bool, BoolType> equals(D compare) =>
|
||||
_Comparison.equal(this, Variable<D, T>(compare));
|
||||
|
||||
/// Casts this expression to an expression with [D] and [T] parameter without
|
||||
/// changing what's written with [writeInto]. In particular, using [dartCast]
|
||||
/// will __NOT__ generate a `CAST` expression in sql.
|
||||
Expression<D2, T2> dartCast<D2, T2 extends SqlType<D2>>() {
|
||||
return _CastExpression<D, D2, T, T2>(this);
|
||||
}
|
||||
|
||||
/// Writes this expression into the [GenerationContext], assuming that there's
|
||||
/// an outer expression with [precedence]. If the [Expression.precedence] of
|
||||
/// `this` expression is lower, it will be wrapped in
|
||||
|
@ -238,3 +245,21 @@ class _UnaryMinus<DT, ST extends SqlType<DT>> extends Expression<DT, ST> {
|
|||
inner.writeInto(context);
|
||||
}
|
||||
}
|
||||
|
||||
class _CastExpression<D1, D2, S1 extends SqlType<D1>, S2 extends SqlType<D2>>
|
||||
extends Expression<D2, S2> {
|
||||
final Expression<D1, S1> inner;
|
||||
|
||||
_CastExpression(this.inner);
|
||||
|
||||
@override
|
||||
Precedence get precedence => inner.precedence;
|
||||
|
||||
@override
|
||||
bool get isLiteral => inner.isLiteral;
|
||||
|
||||
@override
|
||||
void writeInto(GenerationContext context) {
|
||||
return inner.writeInto(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
import 'package:meta/meta.dart';
|
||||
// hidden because of https://github.com/dart-lang/sdk/issues/39262
|
||||
import 'package:moor/moor.dart' hide BooleanExpressionOperators;
|
||||
import 'package:moor/moor.dart'
|
||||
hide BooleanExpressionOperators, DateTimeExpressions;
|
||||
import 'package:moor/sqlite_keywords.dart';
|
||||
import 'package:moor/src/runtime/executor/stream_queries.dart';
|
||||
import 'package:moor/src/runtime/types/sql_types.dart';
|
||||
|
|
|
@ -1,27 +1,40 @@
|
|||
import 'package:moor/moor.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
|
||||
typedef Expression<int, IntType> _Extractor(
|
||||
Expression<DateTime, DateTimeType> d);
|
||||
|
||||
/// Tests the top level [year], [month], ..., [second] methods
|
||||
void main() {
|
||||
final expectedResults = <_Extractor, String>{
|
||||
year: 'CAST(strftime("%Y", val, "unixepoch") AS INTEGER)',
|
||||
month: 'CAST(strftime("%m", val, "unixepoch") AS INTEGER)',
|
||||
day: 'CAST(strftime("%d", val, "unixepoch") AS INTEGER)',
|
||||
hour: 'CAST(strftime("%H", val, "unixepoch") AS INTEGER)',
|
||||
minute: 'CAST(strftime("%M", val, "unixepoch") AS INTEGER)',
|
||||
second: 'CAST(strftime("%S", val, "unixepoch") AS INTEGER)',
|
||||
};
|
||||
final column = GeneratedDateTimeColumn('val', null, false);
|
||||
|
||||
expectedResults.forEach((key, value) {
|
||||
test('should extract field', () {
|
||||
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
|
||||
key(column).writeInto(ctx);
|
||||
group('extracting information via top-level method', () {
|
||||
final expectedResults = <_Extractor, String>{
|
||||
year: 'CAST(strftime("%Y", val, "unixepoch") AS INTEGER)',
|
||||
month: 'CAST(strftime("%m", val, "unixepoch") AS INTEGER)',
|
||||
day: 'CAST(strftime("%d", val, "unixepoch") AS INTEGER)',
|
||||
hour: 'CAST(strftime("%H", val, "unixepoch") AS INTEGER)',
|
||||
minute: 'CAST(strftime("%M", val, "unixepoch") AS INTEGER)',
|
||||
second: 'CAST(strftime("%S", val, "unixepoch") AS INTEGER)',
|
||||
};
|
||||
|
||||
expect(ctx.sql, value);
|
||||
expectedResults.forEach((key, value) {
|
||||
test('should extract field', () {
|
||||
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
|
||||
key(column).writeInto(ctx);
|
||||
|
||||
expect(ctx.sql, value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('can cast datetimes to unix timestamps without rewriting', () {
|
||||
final expr = currentDateAndTime.secondsSinceEpoch + const Constant(10);
|
||||
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
|
||||
expr.writeInto(ctx);
|
||||
|
||||
expect(ctx.sql, 'strftime(\'%s\', CURRENT_TIMESTAMP) + 10');
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue