Skip to content

Commit

Permalink
Add support for int8 array (#88)
Browse files Browse the repository at this point in the history
* Add support for int8 array

* fix tests

* bump version and changelog
  • Loading branch information
Kilian Schulte authored Feb 26, 2023
1 parent fbf3b43 commit 0e3e4ff
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 2.6.1

- Added support for bigInt (int8) arrays. [#41](https://github.com/isoos/postgresql-dart/pull/88) by [schultek](https://github.com/schultek).

## 2.6.0

- Updated to `package:lints`.
Expand Down
14 changes: 14 additions & 0 deletions lib/src/binary_codec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,16 @@ class PostgresBinaryEncoder<T extends Object>
'Invalid type for parameter value. Expected: List<int> Got: ${input.runtimeType}');
}

case PgDataType.bigIntegerArray:
{
if (input is List<int>) {
return writeListBytes<int>(
input, 20, (_) => 8, (writer, item) => writer.writeInt64(item));
}
throw FormatException(
'Invalid type for parameter value. Expected: List<int> Got: ${input.runtimeType}');
}

case PgDataType.varCharArray:
{
if (input is List<String>) {
Expand Down Expand Up @@ -516,6 +526,9 @@ class PostgresBinaryDecoder<T> extends Converter<Uint8List?, T?> {
case PostgreSQLDataType.integerArray:
return readListBytes<int>(input, (reader, _) => reader.readInt32())
as T;
case PostgreSQLDataType.bigIntegerArray:
return readListBytes<int>(input, (reader, _) => reader.readInt64())
as T;

case PostgreSQLDataType.varCharArray:
case PostgreSQLDataType.textArray:
Expand Down Expand Up @@ -586,6 +599,7 @@ class PostgresBinaryDecoder<T> extends Converter<Uint8List?, T?> {
701: PostgreSQLDataType.double,
1000: PostgreSQLDataType.booleanArray,
1007: PostgreSQLDataType.integerArray,
1016: PostgreSQLDataType.bigIntegerArray,
1009: PostgreSQLDataType.textArray,
1015: PostgreSQLDataType.varCharArray,
1043: PostgreSQLDataType.varChar,
Expand Down
1 change: 1 addition & 0 deletions lib/src/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ class PostgreSQLFormatIdentifier {
'point': PostgreSQLDataType.point,
'_bool': PostgreSQLDataType.booleanArray,
'_int4': PostgreSQLDataType.integerArray,
'_int8': PostgreSQLDataType.bigIntegerArray,
'_text': PostgreSQLDataType.textArray,
'_float8': PostgreSQLDataType.doubleArray,
'varchar': PostgreSQLDataType.varChar,
Expand Down
2 changes: 2 additions & 0 deletions lib/src/substituter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class PostgreSQLFormat {
return '_bool';
case PostgreSQLDataType.integerArray:
return '_int4';
case PostgreSQLDataType.bigIntegerArray:
return '_int8';
case PostgreSQLDataType.textArray:
return '_text';
case PostgreSQLDataType.doubleArray:
Expand Down
3 changes: 3 additions & 0 deletions lib/src/v3/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ enum PgDataType<Dart extends Object> {
/// Must be a [List<int>]
integerArray<List<int>>(1007),

/// Must be a [List<int>]
bigIntegerArray<List<int>>(1016),

/// Must be a [List<String>]
textArray<List<String>>(1009),

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: postgres
description: PostgreSQL database driver. Supports statement reuse and binary protocol.
version: 2.6.0
version: 2.6.1
homepage: https://github.com/isoos/postgresql-dart

environment:
Expand Down
45 changes: 24 additions & 21 deletions test/decode_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,40 @@ void main() {
CREATE TEMPORARY TABLE t (
i int, s serial, bi bigint, bs bigserial, bl boolean, si smallint,
t text, f real, d double precision, dt date, ts timestamp, tsz timestamptz, n numeric, j jsonb, ba bytea,
u uuid, v varchar, p point, jj json, ia _int4, ta _text, da _float8, ja _jsonb, va varchar(20)[],
u uuid, v varchar, p point, jj json, ia _int4, bia _int8, ta _text, da _float8, ja _jsonb, va varchar(20)[],
boola _bool
)
''');

await connection.execute(
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, ta, da, ja, va, boola) '
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, bia, ta, da, ja, va, boola) '
'VALUES (-2147483648, -9223372036854775808, TRUE, -32768, '
"'string', 10.0, 10.0, '1983-11-06', "
"'1983-11-06 06:00:00.000000', '1983-11-06 06:00:00.000000', "
"'-1234567890.0987654321', "
"'{\"key\":\"value\"}', E'\\\\000', '00000000-0000-0000-0000-000000000000', "
"'abcdef', '(0.01, 12.34)', '{\"key\": \"value\"}', '{}', '{}', '{}', '{}', "
"'abcdef', '(0.01, 12.34)', '{\"key\": \"value\"}', '{}', '{}', '{}', '{}', '{}', "
"'{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"}', "
"'{true, false, false}'"
')');

await connection.execute(
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, ta, da, ja, va, boola) '
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, bia, ta, da, ja, va, boola) '
'VALUES (2147483647, 9223372036854775807, FALSE, 32767, '
"'a significantly longer string to the point where i doubt this actually matters', "
"10.25, 10.125, '2183-11-06', '2183-11-06 00:00:00.111111', "
"'2183-11-06 00:00:00.999999', "
"'1000000000000000000000000000.0000000000000000000000000001', "
"'[{\"key\":1}]', E'\\\\377', 'FFFFFFFF-ffff-ffff-ffff-ffffffffffff', "
"'01234', '(0.2, 100)', '{}', '{-123, 999}', '{\"a\", \"lorem ipsum\", \"\"}', "
"'01234', '(0.2, 100)', '{}', '{-123, 999}', '{-123, 999}', '{\"a\", \"lorem ipsum\", \"\"}', "
"'{1, 2, 4.5, 1234.5}', '{1, \"\\\"test\\\"\", \"{\\\"a\\\": \\\"b\\\"}\"}', "
"'{\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"}', "
"'{false, false, true}' "
')');

await connection.execute(
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, ta, da, ja, va, boola) '
'VALUES (null, null, null, null, null, null, null, null, null, null, null, null, null, '
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, n, j, ba, u, v, p, jj, ia, bia, ta, da, ja, va, boola) '
'VALUES (null, null, null, null, null, null, null, null, null, null, null, null, null, null, '
'null, null, null, null, null, null, null, null, null, null)');
});
tearDown(() async {
Expand Down Expand Up @@ -88,13 +88,14 @@ void main() {
expect(row1[17], equals(PgPoint(0.01, 12.34)));
expect(row1[18], equals({'key': 'value'}));
expect(row1[19], equals(<int>[]));
expect(row1[20], equals(<String>[]));
expect(row1[21], equals(<double>[]));
expect(row1[22], equals([]));
expect(row1[23] is List<String>, true);
expect(row1[23], equals(['a', 'b', 'c', 'd', 'e', 'f']));
expect(row1[24] is List<bool>, true);
expect(row1[24], equals([true, false, false]));
expect(row1[20], equals(<int>[]));
expect(row1[21], equals(<String>[]));
expect(row1[22], equals(<double>[]));
expect(row1[23], equals([]));
expect(row1[24] is List<String>, true);
expect(row1[24], equals(['a', 'b', 'c', 'd', 'e', 'f']));
expect(row1[25] is List<bool>, true);
expect(row1[25], equals([true, false, false]));

// upper bound row
expect(row2[0], equals(2147483647));
Expand Down Expand Up @@ -127,19 +128,20 @@ void main() {
expect(row2[17], equals(PgPoint(0.2, 100)));
expect(row2[18], equals({}));
expect(row2[19], equals(<int>[-123, 999]));
expect(row2[20], equals(<String>['a', 'lorem ipsum', '']));
expect(row2[21], equals(<double>[1, 2, 4.5, 1234.5]));
expect(row2[20], equals(<int>[-123, 999]));
expect(row2[21], equals(<String>['a', 'lorem ipsum', '']));
expect(row2[22], equals(<double>[1, 2, 4.5, 1234.5]));
expect(
row2[22],
row2[23],
equals([
1,
'test',
{'a': 'b'}
]));
expect(row2[23] is List<String>, true);
expect(row2[23], equals(['a', 'b', 'c', 'd', 'e', 'f']));
expect(row2[24] is List<bool>, true);
expect(row2[24], equals([false, false, true]));
expect(row2[24] is List<String>, true);
expect(row2[24], equals(['a', 'b', 'c', 'd', 'e', 'f']));
expect(row2[25] is List<bool>, true);
expect(row2[25], equals([false, false, true]));

// all null row
expect(row3[0], isNull);
Expand Down Expand Up @@ -167,6 +169,7 @@ void main() {
expect(row3[22], isNull);
expect(row3[23], isNull);
expect(row3[24], isNull);
expect(row3[25], isNull);
});

test('Fetch/insert empty string', () async {
Expand Down
13 changes: 13 additions & 0 deletions test/encoding_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,19 @@ void main() {
}
});

test('bigIntegerArray', () async {
await expectInverse(<int>[], PostgreSQLDataType.bigIntegerArray);
await expectInverse([-1, 0, 200], PostgreSQLDataType.bigIntegerArray);
await expectInverse([-123], PostgreSQLDataType.bigIntegerArray);
try {
await conn.query('INSERT INTO t (v) VALUES (@v:_int8)',
substitutionValues: {'v': 'not-list-int'});
fail('unreachable');
} on FormatException catch (e) {
expect(e.toString(), contains('Expected: List<int>'));
}
});

test('doubleArray', () async {
await expectInverse(<double>[], PostgreSQLDataType.doubleArray);
await expectInverse([-123.0, 0.0, 1.0], PostgreSQLDataType.doubleArray);
Expand Down
22 changes: 14 additions & 8 deletions test/query_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void main() {
'bs bigserial, bl boolean, si smallint, '
't text, f real, d double precision, '
'dt date, ts timestamp, tsz timestamptz, j jsonb, u uuid, '
'v varchar, p point, jj json, ia _int4, ta _text, da _float8, ja _jsonb, va _varchar(20), '
'v varchar, p point, jj json, ia _int4, bia _int8, ta _text, da _float8, ja _jsonb, va _varchar(20), '
'ba _bool'
')');
await connection.execute(
Expand Down Expand Up @@ -114,7 +114,7 @@ void main() {

test('Query without specifying types', () async {
var result = await connection.query(
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba) values '
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba) values '
'(${PostgreSQLFormat.id('i')},'
'${PostgreSQLFormat.id('bi')},'
'${PostgreSQLFormat.id('bl')},'
Expand All @@ -131,12 +131,13 @@ void main() {
'${PostgreSQLFormat.id('p')},'
'${PostgreSQLFormat.id('jj')},'
'${PostgreSQLFormat.id('ia')},'
'${PostgreSQLFormat.id('bia')},'
'${PostgreSQLFormat.id('ta')},'
'${PostgreSQLFormat.id('da')},'
'${PostgreSQLFormat.id('ja')},'
'${PostgreSQLFormat.id('va')},'
'${PostgreSQLFormat.id('ba')}'
') returning i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba',
') returning i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba',
substitutionValues: {
'i': 1,
'bi': 2,
Expand All @@ -154,6 +155,7 @@ void main() {
'p': PgPoint(1.0, 0.1),
'jj': {'k': 'v'},
'ia': [1, 2, 3],
'bia': [4, 5, 6],
'ta': ['a', 'b"\'\\"'],
'da': [0.1, 2.3, 1],
'ja': [
Expand Down Expand Up @@ -184,6 +186,7 @@ void main() {
PgPoint(1.0, 0.1),
{'k': 'v'},
[1, 2, 3],
[4, 5, 6],
['a', 'b"\'\\"'],
[0.1, 2.3, 1],
[
Expand All @@ -194,20 +197,20 @@ void main() {
['a', 'b', 'c', 'd', 'e', 'f'],
[false, true, false]
];
expect(result.columnDescriptions, hasLength(23));
expect(result.columnDescriptions, hasLength(24));
expect(result.columnDescriptions.first.tableName, 't');
expect(result.columnDescriptions.first.columnName, 'i');
expect(result.columnDescriptions.last.tableName, 't');
expect(result.columnDescriptions.last.columnName, 'ba');
expect(result, [expectedRow]);
result = await connection.query(
'select i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba from t');
'select i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba from t');
expect(result, [expectedRow]);
});

test('Query by specifying all types', () async {
var result = await connection.query(
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba) values '
'INSERT INTO t (i, bi, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba) values '
'(${PostgreSQLFormat.id('i', type: PostgreSQLDataType.integer)},'
'${PostgreSQLFormat.id('bi', type: PostgreSQLDataType.bigInteger)},'
'${PostgreSQLFormat.id('bl', type: PostgreSQLDataType.boolean)},'
Expand All @@ -224,12 +227,13 @@ void main() {
'${PostgreSQLFormat.id('p', type: PostgreSQLDataType.point)},'
'${PostgreSQLFormat.id('jj', type: PostgreSQLDataType.json)},'
'${PostgreSQLFormat.id('ia', type: PostgreSQLDataType.integerArray)},'
'${PostgreSQLFormat.id('bia', type: PostgreSQLDataType.bigIntegerArray)},'
'${PostgreSQLFormat.id('ta', type: PostgreSQLDataType.textArray)},'
'${PostgreSQLFormat.id('da', type: PostgreSQLDataType.doubleArray)},'
'${PostgreSQLFormat.id('ja', type: PostgreSQLDataType.jsonbArray)},'
'${PostgreSQLFormat.id('va', type: PostgreSQLDataType.varCharArray)},'
'${PostgreSQLFormat.id('ba', type: PostgreSQLDataType.booleanArray)}'
') returning i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba',
') returning i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba',
substitutionValues: {
'i': 1,
'bi': 2,
Expand All @@ -247,6 +251,7 @@ void main() {
'p': PgPoint(1.0, 0.1),
'jj': {'k': 'v'},
'ia': [1, 2, 3],
'bia': [4, 5, 6],
'ta': ['a', 'b'],
'da': [0.1, 2.3, 1.0],
'ja': [
Expand Down Expand Up @@ -277,6 +282,7 @@ void main() {
PgPoint(1.0, 0.1),
{'k': 'v'},
[1, 2, 3],
[4, 5, 6],
['a', 'b'],
[0.1, 2.3, 1],
[
Expand All @@ -290,7 +296,7 @@ void main() {
expect(result, [expectedRow]);

result = await connection.query(
'select i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, ta, da, ja, va, ba from t');
'select i,s, bi, bs, bl, si, t, f, d, dt, ts, tsz, j, u, v, p, jj, ia, bia, ta, da, ja, va, ba from t');
expect(result, [expectedRow]);
});

Expand Down

0 comments on commit 0e3e4ff

Please sign in to comment.