Skip to content

Commit

Permalink
Cleanup of PostgreSQLDataType (using PgDataType instead). (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos authored Oct 15, 2023
1 parent e2bdea5 commit 0971b55
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 217 deletions.
4 changes: 4 additions & 0 deletions lib/postgres.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
library postgres;

import 'package:postgres/src/v3/types.dart';

export 'src/connection.dart';
export 'src/execution_context.dart';
export 'src/replication.dart' show ReplicationMode;
export 'src/substituter.dart';
export 'src/types.dart';
export 'src/v3/types.dart' show PgPoint;

typedef PostgreSQLDataType = PgDataType<Object>;
63 changes: 31 additions & 32 deletions lib/src/binary_codec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:buffer/buffer.dart';
import 'package:postgres/src/v3/types.dart';

import 'buffer.dart';
import 'types.dart';

final _bool0 = Uint8List(1)..[0] = 0;
final _bool1 = Uint8List(1)..[0] = 1;
Expand Down Expand Up @@ -515,56 +514,56 @@ class PostgresBinaryDecoder<T> {
ByteData.view(input.buffer, input.offsetInBytes, input.lengthInBytes);

switch (type) {
case PostgreSQLDataType.name:
case PostgreSQLDataType.text:
case PostgreSQLDataType.varChar:
case PgDataType.name:
case PgDataType.text:
case PgDataType.varChar:
return encoding.decode(input) as T;
case PostgreSQLDataType.boolean:
case PgDataType.boolean:
return (buffer.getInt8(0) != 0) as T;
case PostgreSQLDataType.smallInteger:
case PgDataType.smallInteger:
return buffer.getInt16(0) as T;
case PostgreSQLDataType.serial:
case PostgreSQLDataType.integer:
case PgDataType.serial:
case PgDataType.integer:
return buffer.getInt32(0) as T;
case PostgreSQLDataType.bigSerial:
case PostgreSQLDataType.bigInteger:
case PgDataType.bigSerial:
case PgDataType.bigInteger:
return buffer.getInt64(0) as T;
case PostgreSQLDataType.real:
case PgDataType.real:
return buffer.getFloat32(0) as T;
case PostgreSQLDataType.double:
case PgDataType.double:
return buffer.getFloat64(0) as T;
case PostgreSQLDataType.timestampWithoutTimezone:
case PostgreSQLDataType.timestampWithTimezone:
case PgDataType.timestampWithoutTimezone:
case PgDataType.timestampWithTimezone:
return DateTime.utc(2000)
.add(Duration(microseconds: buffer.getInt64(0))) as T;

case PostgreSQLDataType.interval:
case PgDataType.interval:
{
if (buffer.getInt64(8) != 0) throw UnimplementedError();
return Duration(microseconds: buffer.getInt64(0)) as T;
}

case PostgreSQLDataType.numeric:
case PgDataType.numeric:
return _decodeNumeric(input) as T;

case PostgreSQLDataType.date:
case PgDataType.date:
return DateTime.utc(2000).add(Duration(days: buffer.getInt32(0))) as T;

case PostgreSQLDataType.jsonb:
case PgDataType.jsonb:
{
// Removes version which is first character and currently always '1'
final bytes = input.buffer
.asUint8List(input.offsetInBytes + 1, input.lengthInBytes - 1);
return _jsonFusedEncoding(encoding).decode(bytes) as T;
}

case PostgreSQLDataType.json:
case PgDataType.json:
return _jsonFusedEncoding(encoding).decode(input) as T;

case PostgreSQLDataType.byteArray:
case PgDataType.byteArray:
return input as T;

case PostgreSQLDataType.uuid:
case PgDataType.uuid:
{
final buf = StringBuffer();
for (var i = 0; i < buffer.lengthInBytes; i++) {
Expand All @@ -590,39 +589,39 @@ class PostgresBinaryDecoder<T> {
case PgDataType.voidType:
return null;

case PostgreSQLDataType.point:
case PgDataType.point:
return PgPoint(buffer.getFloat64(0), buffer.getFloat64(8)) as T;

case PostgreSQLDataType.booleanArray:
case PgDataType.booleanArray:
return readListBytes<bool>(
input, (reader, _) => reader.readUint8() != 0) as T;

case PostgreSQLDataType.integerArray:
case PgDataType.integerArray:
return readListBytes<int>(input, (reader, _) => reader.readInt32())
as T;
case PostgreSQLDataType.bigIntegerArray:
case PgDataType.bigIntegerArray:
return readListBytes<int>(input, (reader, _) => reader.readInt64())
as T;

case PostgreSQLDataType.varCharArray:
case PostgreSQLDataType.textArray:
case PgDataType.varCharArray:
case PgDataType.textArray:
return readListBytes<String>(input, (reader, length) {
return encoding.decode(length > 0 ? reader.read(length) : []);
}) as T;

case PostgreSQLDataType.doubleArray:
case PgDataType.doubleArray:
return readListBytes<double>(input, (reader, _) => reader.readFloat64())
as T;

case PostgreSQLDataType.jsonbArray:
case PgDataType.jsonbArray:
return readListBytes<dynamic>(input, (reader, length) {
reader.read(1);
final bytes = reader.read(length - 1);
return _jsonFusedEncoding(encoding).decode(bytes);
}) as T;

case PostgreSQLDataType.unknownType:
case PostgreSQLDataType.unspecified:
case PgDataType.unknownType:
case PgDataType.unspecified:
{
// We'll try and decode this as a utf8 string and return that
// for many internal types, this is valid. If it fails,
Expand Down Expand Up @@ -660,7 +659,7 @@ class PostgresBinaryDecoder<T> {
}

/// See: https://github.com/postgres/postgres/blob/master/src/include/catalog/pg_type.dat
static final Map<int, PostgreSQLDataType> typeMap = PgDataType.byTypeOid;
static final Map<int, PgDataType> typeMap = PgDataType.byTypeOid;

/// Decode numeric / decimal to String without loosing precision.
/// See encoding: https://github.com/postgres/postgres/blob/0e39a608ed5545cc6b9d538ac937c3c1ee8cdc36/src/backend/utils/adt/numeric.c#L305
Expand Down
5 changes: 3 additions & 2 deletions lib/src/execution_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import 'dart:async';
import 'connection.dart';
import 'query.dart';
import 'substituter.dart';
import 'types.dart';

import 'v3/types.dart';

abstract class PostgreSQLExecutionContext {
/// Returns this context queue size
Expand All @@ -22,7 +23,7 @@ abstract class PostgreSQLExecutionContext {
/// connection.query("SELECT * FROM table WHERE id = @idParam:int4", {"idParam" : 2});
///
/// Available types are listed in [PostgreSQLFormatIdentifier.typeStringToCodeMap]. Some types have multiple options. It is preferable to use the [PostgreSQLFormat.id]
/// function to add parameters to a query string. This method inserts a parameter name and the appropriate ':type' string for a [PostgreSQLDataType].
/// function to add parameters to a query string. This method inserts a parameter name and the appropriate ':type' string for a [PgDataType].
///
/// If successful, the returned [Future] completes with a [List] of rows. Each is row is represented by a [List] of column values for that row that were returned by the query.
///
Expand Down
14 changes: 6 additions & 8 deletions lib/src/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import 'connection.dart';
import 'execution_context.dart';
import 'substituter.dart';
import 'text_codec.dart';
import 'types.dart';

class Query<T> {
Query(
Expand All @@ -38,7 +37,7 @@ class Query<T> {
final PostgreSQLExecutionContext transaction;
final PostgreSQLConnection connection;

late List<PostgreSQLDataType?> _specifiedParameterTypeCodes;
late List<PgDataType?> _specifiedParameterTypeCodes;
final rows = <List<dynamic>>[];

CachedQuery? cache;
Expand Down Expand Up @@ -298,8 +297,7 @@ class FieldDescription implements ColumnDescription {
final formatCode = reader.readUint16();

final converter = PostgresBinaryDecoder(
PostgreSQLDataType.byTypeOid[typeOid] ??
PostgreSQLDataType.unknownType);
PgDataType.byTypeOid[typeOid] ?? PgDataType.unknownType);
return FieldDescription._(
converter, fieldName, tableID, columnID, typeOid,
dataTypeSize, typeModifier, formatCode,
Expand Down Expand Up @@ -331,12 +329,12 @@ class PostgreSQLFormatToken {
}

class PostgreSQLFormatIdentifier {
static Map<String, PostgreSQLDataType> typeStringToCodeMap =
PostgreSQLDataType.bySubstitutionName;
static Map<String, PgDataType> typeStringToCodeMap =
PgDataType.bySubstitutionName;

factory PostgreSQLFormatIdentifier(String t) {
String name;
PostgreSQLDataType? type;
PgDataType? type;
String? typeCast;

final components = t.split('::');
Expand Down Expand Up @@ -369,6 +367,6 @@ class PostgreSQLFormatIdentifier {
PostgreSQLFormatIdentifier._(this.name, this.type, this.typeCast);

final String name;
final PostgreSQLDataType? type;
final PgDataType? type;
final String? typeCast;
}
7 changes: 4 additions & 3 deletions lib/src/substituter.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import 'package:postgres/src/v3/types.dart';

import 'query.dart';
import 'text_codec.dart';
import 'types.dart';

class PostgreSQLFormat {
static final int _atSignCodeUnit = '@'.codeUnitAt(0);

static String id(String name, {PostgreSQLDataType? type}) {
static String id(String name, {PgDataType? type}) {
if (type != null) {
return '@$name:${dataTypeStringForDataType(type)}';
}

return '@$name';
}

static String? dataTypeStringForDataType(PostgreSQLDataType? dt) {
static String? dataTypeStringForDataType(PgDataType? dt) {
return dt?.nameForSubstitution;
}

Expand Down
4 changes: 0 additions & 4 deletions lib/src/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
5. add identifying key to PostgreSQLFormat.dataTypeStringForDataType
*/

import 'package:postgres/src/v3/types.dart';

typedef PostgreSQLDataType = PgDataType<Object>;

/// LSN is a PostgreSQL Log Sequence Number.
///
/// For more details, see: https://www.postgresql.org/docs/current/datatype-pg-lsn.html
Expand Down
3 changes: 2 additions & 1 deletion test/decode_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:typed_data';

import 'package:postgres/postgres.dart';
import 'package:postgres/src/binary_codec.dart';
import 'package:postgres/src/v3/types.dart';
import 'package:test/test.dart';

import 'docker.dart';
Expand Down Expand Up @@ -249,7 +250,7 @@ void main() {
'0.0': [0, 0, 0, 0, 0, 0, 0, 1], // .0 or 0.0
};

final decoder = PostgresBinaryDecoder(PostgreSQLDataType.numeric);
final decoder = PostgresBinaryDecoder(PgDataType.numeric);
binaries.forEach((key, value) {
final uint8List = Uint8List.fromList(value);
final res = decoder.convert(uint8List, utf8);
Expand Down
Loading

0 comments on commit 0971b55

Please sign in to comment.