Skip to content

Commit

Permalink
Provide comparable expressions for pg time values
Browse files Browse the repository at this point in the history
  • Loading branch information
simolus3 committed Feb 9, 2024
1 parent 326434c commit fe57822
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 11 deletions.
5 changes: 5 additions & 0 deletions extras/drift_postgres/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.2.0

- Drift's comparable expression operators are now available for expressions
using postgres-specific `date` or `timestamp` types.

## 1.1.0

- Add `PgTypes.timestampWithTimezone`.
Expand Down
14 changes: 12 additions & 2 deletions extras/drift_postgres/lib/drift_postgres.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ final class PgTypes {
///
/// We can't use [DateTime] directly because drift expects to store them as
/// unix timestamp or text.
final class PgDateTime implements PgTimeValue {
final class PgDateTime implements PgTimeValue, Comparable<PgDateTime> {
final DateTime dateTime;

PgDateTime(this.dateTime);
Expand All @@ -98,11 +98,16 @@ final class PgDateTime implements PgTimeValue {

@override
String toString() => dateTime.toString();

@override
int compareTo(PgDateTime other) {
return dateTime.compareTo(other.dateTime);
}
}

/// A wrapper for the Postgres `date` type, which stores dates (year, month,
/// days).
final class PgDate implements PgTimeValue {
final class PgDate implements PgTimeValue, Comparable<PgDate> {
final int year, month, day;
final DateTime _dateTime;

Expand Down Expand Up @@ -134,6 +139,11 @@ final class PgDate implements PgTimeValue {
DateTime toDateTime() {
return _dateTime;
}

@override
int compareTo(PgDate other) {
return _dateTime.compareTo(other._dateTime);
}
}

/// Calls the `gen_random_uuid` function in postgres.
Expand Down
2 changes: 1 addition & 1 deletion extras/drift_postgres/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: drift_postgres
description: Postgres implementation and APIs for the drift database package.
version: 1.1.0
version: 1.2.0-dev
repository: https://github.com/simolus3/drift
homepage: https://drift.simonbinder.eu/docs/platforms/postgres/
issue_tracker: https://github.com/simolus3/drift/issues
Expand Down
39 changes: 31 additions & 8 deletions extras/drift_postgres/test/types_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ void main() {
await executor.clearDatabaseAndClose(database);
});

Future<T> eval<T extends Object>(Expression<T> expression) async {
final query = database.selectOnly(database.users)..addColumns([expression]);
final row = await query.getSingle();
return row.read(expression)!;
}

group('custom types pass through', () {
void testWith<T extends Object>(CustomSqlType<T> type, T value) {
test('with variable', () async {
final variable = Variable(value, type);
final query = database.selectOnly(database.users)
..addColumns([variable]);
final row = await query.getSingle();
expect(row.read(variable), value);
expect(await eval(variable), value);
});

test('with constant', () async {
final constant = Constant(value, type);
final query = database.selectOnly(database.users)
..addColumns([constant]);
final row = await query.getSingle();
expect(row.read(constant), value);
expect(await eval(constant), value);
});
}

Expand All @@ -59,4 +59,27 @@ void main() {
PgDateTime(DateTime.utc(1996, 7, 8, 10, 0, 0))),
);
});

test('compare datetimes', () async {
final time = DateTime.now();
final before = Variable(
PgDateTime(time.subtract(const Duration(minutes: 10))),
PgTypes.timestampNoTimezone);
final now = Variable(PgDateTime(time), PgTypes.timestampNoTimezone);
final after = Variable(PgDateTime(time.add(const Duration(days: 2))),
PgTypes.timestampNoTimezone);

expect(await eval(before.isSmallerOrEqual(after)), isTrue);
expect(await eval(now.isBetween(before, after)), isTrue);
});

test('compare dates', () async {
final moonLanding = PgDate(year: 1969, month: 7, day: 20);
final berlinWallFell = PgDate(year: 1989, month: 11, day: 9);

expect(
await eval(Variable(berlinWallFell, PgTypes.date)
.isBiggerOrEqualValue(moonLanding)),
isTrue);
});
}

0 comments on commit fe57822

Please sign in to comment.