Skip to content

Commit

Permalink
Preparing custom type converters (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos authored Jun 12, 2020
1 parent e4ceb60 commit c9903bc
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 35 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.2.0

- Preparation for custom type converters.

## 2.1.1

- Fix `RuneIterator.current` use, which no longer returns `null` in 2.8 SDK.
Expand Down
5 changes: 3 additions & 2 deletions lib/src/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ class ParameterValue {
factory ParameterValue.text(dynamic value) {
Uint8List bytes;
if (value != null) {
final converter = PostgresTextEncoder(false);
bytes = castBytes(utf8.encode(converter.convert(value)));
final converter = PostgresTextEncoder();
bytes = castBytes(
utf8.encode(converter.convert(value, escapeStrings: false)));
}
final length = bytes?.length ?? 0;
return ParameterValue._(false, bytes, length);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/substituter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class PostgreSQLFormat {

static String substitute(String fmtString, Map<String, dynamic> values,
{SQLReplaceIdentifierFunction replace}) {
final converter = PostgresTextEncoder(true);
final converter = PostgresTextEncoder();
values ??= <String, dynamic>{};
replace ??= (spec, index) => converter.convert(values[spec.name]);

Expand Down
35 changes: 16 additions & 19 deletions lib/src/text_codec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,42 @@ import 'dart:convert';

import 'package:postgres/postgres.dart';

class PostgresTextEncoder extends Converter<dynamic, String> {
const PostgresTextEncoder(this._escapeStrings);

final bool _escapeStrings;

@override
String convert(dynamic value) {
class PostgresTextEncoder {
String convert(dynamic value, {bool escapeStrings = true}) {
if (value == null) {
return 'null';
}

if (value is int) {
return encodeNumber(value);
return _encodeNumber(value);
}

if (value is double) {
return encodeDouble(value);
return _encodeDouble(value);
}

if (value is String) {
return encodeString(value, _escapeStrings);
return _encodeString(value, escapeStrings);
}

if (value is DateTime) {
return encodeDateTime(value, isDateOnly: false);
return _encodeDateTime(value, isDateOnly: false);
}

if (value is bool) {
return encodeBoolean(value);
return _encodeBoolean(value);
}

if (value is Map) {
return encodeJSON(value);
return _encodeJSON(value);
}

// TODO: use custom type encoders

throw PostgreSQLException("Could not infer type of value '$value'.");
}

String encodeString(String text, bool escapeStrings) {
String _encodeString(String text, bool escapeStrings) {
if (!escapeStrings) {
return text;
}
Expand Down Expand Up @@ -85,7 +82,7 @@ class PostgresTextEncoder extends Converter<dynamic, String> {
return buf.toString();
}

String encodeNumber(num value) {
String _encodeNumber(num value) {
if (value.isNaN) {
return "'nan'";
}
Expand All @@ -97,7 +94,7 @@ class PostgresTextEncoder extends Converter<dynamic, String> {
return value.toInt().toString();
}

String encodeDouble(double value) {
String _encodeDouble(double value) {
if (value.isNaN) {
return "'nan'";
}
Expand All @@ -109,11 +106,11 @@ class PostgresTextEncoder extends Converter<dynamic, String> {
return value.toString();
}

String encodeBoolean(bool value) {
String _encodeBoolean(bool value) {
return value ? 'TRUE' : 'FALSE';
}

String encodeDateTime(DateTime value, {bool isDateOnly}) {
String _encodeDateTime(DateTime value, {bool isDateOnly}) {
var string = value.toIso8601String();

if (isDateOnly) {
Expand Down Expand Up @@ -147,7 +144,7 @@ class PostgresTextEncoder extends Converter<dynamic, String> {
return "'$string'";
}

String encodeJSON(dynamic value) {
String _encodeJSON(dynamic value) {
if (value == null) {
return 'null';
}
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.1.1
version: 2.2.0-dev
homepage: https://github.com/stablekernel/postgresql-dart

environment:
Expand Down
16 changes: 4 additions & 12 deletions test/encoding_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,9 @@ void main() {
});

group('Text encoders', () {
final encoder = PostgresTextEncoder();

test('Escape strings', () {
final encoder = PostgresTextEncoder(true);
// ' b o b '
expect(
utf8.encode(encoder.convert('bob')), equals([39, 98, 111, 98, 39]));
Expand Down Expand Up @@ -294,9 +295,8 @@ void main() {
DateTime(12345, DateTime.february, 3, 4, 5, 6, 0)
};

final encoder = PostgresTextEncoder(false);
pairs.forEach((k, v) {
expect(encoder.convert(v), "'$k'");
expect(encoder.convert(v, escapeStrings: false), "'$k'");
});
});

Expand All @@ -311,37 +311,29 @@ void main() {
'0.0': 0.0
};

final encoder = PostgresTextEncoder(false);
pairs.forEach((k, v) {
expect(encoder.convert(v), '$k');
expect(encoder.convert(v, escapeStrings: false), '$k');
});
});

test('Encode Int', () {
final encoder = PostgresTextEncoder(false);

expect(encoder.convert(1), '1');
expect(encoder.convert(1234324323), '1234324323');
expect(encoder.convert(-1234324323), '-1234324323');
});

test('Encode Bool', () {
final encoder = PostgresTextEncoder(false);

expect(encoder.convert(true), 'TRUE');
expect(encoder.convert(false), 'FALSE');
});

test('Encode JSONB', () {
final encoder = PostgresTextEncoder(false);

expect(encoder.convert({'a': 'b'}), '{"a":"b"}');
expect(encoder.convert({'a': true}), '{"a":true}');
expect(encoder.convert({'b': false}), '{"b":false}');
});

test('Attempt to infer unknown type throws exception', () {
final encoder = PostgresTextEncoder(false);
try {
encoder.convert([]);
fail('unreachable');
Expand Down

0 comments on commit c9903bc

Please sign in to comment.