mirror of https://github.com/AMT-Cheif/drift.git
Add `date` and `timestamp` types for postgres
This commit is contained in:
parent
fae81d0456
commit
6aa1a5d734
|
@ -16,12 +16,24 @@ typedef UuidColumn = Column<UuidValue>;
|
||||||
typedef IntervalColumn = Column<Duration>;
|
typedef IntervalColumn = Column<Duration>;
|
||||||
typedef JsonColumn = Column<Object>;
|
typedef JsonColumn = Column<Object>;
|
||||||
typedef PointColumn = Column<PgPoint>;
|
typedef PointColumn = Column<PgPoint>;
|
||||||
|
typedef TimestampColumn = Column<PgDateTime>;
|
||||||
|
typedef PgDateColumn = Column<PgDate>;
|
||||||
|
|
||||||
final class PgTypes {
|
final class PgTypes {
|
||||||
PgTypes._();
|
PgTypes._();
|
||||||
|
|
||||||
static const CustomSqlType<UuidValue> uuid = UuidType();
|
static const CustomSqlType<UuidValue> uuid = UuidType();
|
||||||
static const CustomSqlType<Duration> interval = IntervalType();
|
static const CustomSqlType<Duration> interval = IntervalType();
|
||||||
|
static const CustomSqlType<PgDate> date = DateType(
|
||||||
|
PgDataType.date,
|
||||||
|
'date',
|
||||||
|
PgDate.fromDateTime,
|
||||||
|
);
|
||||||
|
static const CustomSqlType<PgDateTime> timestampNoTimezone = DateType(
|
||||||
|
PgDataType.timestampWithoutTimezone,
|
||||||
|
'timestamp without time zone',
|
||||||
|
PgDateTime.new,
|
||||||
|
);
|
||||||
static const CustomSqlType<Object> json =
|
static const CustomSqlType<Object> json =
|
||||||
PostgresType(type: PgDataType.json, name: 'json');
|
PostgresType(type: PgDataType.json, name: 'json');
|
||||||
static const CustomSqlType<Object> jsonb =
|
static const CustomSqlType<Object> jsonb =
|
||||||
|
@ -29,6 +41,67 @@ final class PgTypes {
|
||||||
static const CustomSqlType<PgPoint> point = PointType();
|
static const CustomSqlType<PgPoint> point = PointType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A wrapper for values with the Postgres `timestamp without timezone` and
|
||||||
|
/// `timestamp with timezone` types.
|
||||||
|
///
|
||||||
|
/// We can't use [DateTime] directly because drift expects to store them as
|
||||||
|
/// unix timestamp or text.
|
||||||
|
final class PgDateTime implements PgTimeValue {
|
||||||
|
final DateTime dateTime;
|
||||||
|
|
||||||
|
PgDateTime(this.dateTime);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => dateTime.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is PgDateTime && other.dateTime == dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime toDateTime() => dateTime;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => dateTime.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A wrapper for the Postgres `date` type, which stores dates (year, month,
|
||||||
|
/// days).
|
||||||
|
final class PgDate implements PgTimeValue {
|
||||||
|
final int year, month, day;
|
||||||
|
final DateTime _dateTime;
|
||||||
|
|
||||||
|
PgDate({required this.year, required this.month, required this.day})
|
||||||
|
: _dateTime = DateTime(year, month, day);
|
||||||
|
|
||||||
|
PgDate.fromDateTime(DateTime dateTime)
|
||||||
|
: _dateTime = dateTime,
|
||||||
|
year = dateTime.year,
|
||||||
|
month = dateTime.month,
|
||||||
|
day = dateTime.day;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(year, month, day);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is PgDate &&
|
||||||
|
other.year == year &&
|
||||||
|
other.month == month &&
|
||||||
|
other.day == day;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'${year.toString().padLeft(4, '0')}-${month.toString().padLeft(2, '0')}-${day.toString().padLeft(2, '0')}';
|
||||||
|
|
||||||
|
@override
|
||||||
|
DateTime toDateTime() {
|
||||||
|
return _dateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls the `gen_random_uuid` function in postgres.
|
/// Calls the `gen_random_uuid` function in postgres.
|
||||||
Expression<UuidValue> genRandomUuid() {
|
Expression<UuidValue> genRandomUuid() {
|
||||||
return FunctionCallExpression('gen_random_uuid', []);
|
return FunctionCallExpression('gen_random_uuid', []);
|
||||||
|
|
|
@ -65,3 +65,32 @@ class IntervalType extends PostgresType<Duration> {
|
||||||
return "'${dartValue.inMicroseconds} microseconds'::interval";
|
return "'${dartValue.inMicroseconds} microseconds'::interval";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract interface class PgTimeValue {
|
||||||
|
DateTime toDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
class DateType<T extends PgTimeValue> extends PostgresType<T> {
|
||||||
|
final T Function(DateTime) _fromDateTime;
|
||||||
|
|
||||||
|
const DateType(
|
||||||
|
PgDataType type,
|
||||||
|
String name,
|
||||||
|
this._fromDateTime,
|
||||||
|
) : super(type: type, name: name);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String mapToSqlLiteral(T dartValue) {
|
||||||
|
return "${PostgresType._encoder.convert(dartValue.toDateTime())}::$name";
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object mapToSqlParameter(T dartValue) {
|
||||||
|
return PgTypedParameter(type, dartValue.toDateTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
T read(Object fromSql) {
|
||||||
|
return _fromDateTime(fromSql as DateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -49,5 +49,10 @@ void main() {
|
||||||
group('json', () => testWith(PgTypes.json, {'foo': 'bar'}));
|
group('json', () => testWith(PgTypes.json, {'foo': 'bar'}));
|
||||||
group('jsonb', () => testWith(PgTypes.jsonb, {'foo': 'bar'}));
|
group('jsonb', () => testWith(PgTypes.jsonb, {'foo': 'bar'}));
|
||||||
group('point', () => testWith(PgTypes.point, PgPoint(90, -90)));
|
group('point', () => testWith(PgTypes.point, PgPoint(90, -90)));
|
||||||
|
group(
|
||||||
|
'timestamp without timezone',
|
||||||
|
() => testWith(PgTypes.timestampNoTimezone,
|
||||||
|
PgDateTime(DateTime.utc(1996, 7, 8, 10, 0, 0))),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue