From fe578223afa017a6284b36f487b169b7d5171ca0 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Sat, 10 Feb 2024 00:33:04 +0100 Subject: [PATCH] Provide comparable expressions for pg time values --- extras/drift_postgres/CHANGELOG.md | 5 +++ extras/drift_postgres/lib/drift_postgres.dart | 14 ++++++- extras/drift_postgres/pubspec.yaml | 2 +- extras/drift_postgres/test/types_test.dart | 39 +++++++++++++++---- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/extras/drift_postgres/CHANGELOG.md b/extras/drift_postgres/CHANGELOG.md index 5cccd0c4..5d7bc74b 100644 --- a/extras/drift_postgres/CHANGELOG.md +++ b/extras/drift_postgres/CHANGELOG.md @@ -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`. diff --git a/extras/drift_postgres/lib/drift_postgres.dart b/extras/drift_postgres/lib/drift_postgres.dart index f97f6823..b6eacefe 100644 --- a/extras/drift_postgres/lib/drift_postgres.dart +++ b/extras/drift_postgres/lib/drift_postgres.dart @@ -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 { final DateTime dateTime; PgDateTime(this.dateTime); @@ -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 { final int year, month, day; final DateTime _dateTime; @@ -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. diff --git a/extras/drift_postgres/pubspec.yaml b/extras/drift_postgres/pubspec.yaml index 1bc03da1..772fc3a7 100644 --- a/extras/drift_postgres/pubspec.yaml +++ b/extras/drift_postgres/pubspec.yaml @@ -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 diff --git a/extras/drift_postgres/test/types_test.dart b/extras/drift_postgres/test/types_test.dart index 8cedf3d3..727480d0 100644 --- a/extras/drift_postgres/test/types_test.dart +++ b/extras/drift_postgres/test/types_test.dart @@ -20,22 +20,22 @@ void main() { await executor.clearDatabaseAndClose(database); }); + Future eval(Expression 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(CustomSqlType 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); }); } @@ -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); + }); }