Skip to content

Commit 0b46c10

Browse files
authored
Hide Type internals from public API. (#239)
1 parent b7add8f commit 0b46c10

13 files changed

+164
-126
lines changed

lib/postgres.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export 'src/exceptions.dart';
1616
export 'src/pool/pool_api.dart';
1717
export 'src/replication.dart';
1818
export 'src/types.dart';
19-
export 'src/types/type_registry.dart' show TypeOid, TypeRegistry;
19+
export 'src/types/type_registry.dart' show TypeRegistry;
2020

2121
/// A description of a SQL query as interpreted by this package.
2222
///

lib/src/messages/client_messages.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:convert';
22
import 'dart:typed_data';
33

44
import 'package:charcode/ascii.dart';
5+
import 'package:postgres/src/types/generic_type.dart';
56

67
import '../buffer.dart';
78
import '../replication.dart';

lib/src/types.dart

Lines changed: 55 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'dart:convert';
21
import 'dart:core';
32
import 'dart:core' as core;
43
import 'dart:typed_data';
@@ -139,206 +138,156 @@ class Point {
139138
/// Supported data types.
140139
abstract class Type<T extends Object> {
141140
/// Used to represent value without any type representation.
142-
static const unspecified = GenericType<Object>(null);
141+
static final unspecified = unspecifiedType();
143142

144143
/// Must be a [String].
145-
static const text =
146-
GenericType<String>(TypeOid.text, nameForSubstitution: 'text');
144+
static final text =
145+
_genericType<String>(TypeOid.text, nameForSubstitution: 'text');
147146

148147
/// Must be an [int] (4-byte integer)
149-
static const integer =
150-
GenericType<int>(TypeOid.integer, nameForSubstitution: 'int4');
148+
static final integer =
149+
_genericType<int>(TypeOid.integer, nameForSubstitution: 'int4');
151150

152151
/// Must be an [int] (2-byte integer)
153-
static const smallInteger =
154-
GenericType<int>(TypeOid.smallInteger, nameForSubstitution: 'int2');
152+
static final smallInteger =
153+
_genericType<int>(TypeOid.smallInteger, nameForSubstitution: 'int2');
155154

156155
/// Must be an [int] (8-byte integer)
157-
static const bigInteger =
158-
GenericType<int>(TypeOid.bigInteger, nameForSubstitution: 'int8');
156+
static final bigInteger =
157+
_genericType<int>(TypeOid.bigInteger, nameForSubstitution: 'int8');
159158

160159
/// Must be an [int] (autoincrementing 4-byte integer)
161-
static const serial = GenericType<int>(null, nameForSubstitution: 'int4');
160+
static final serial = _genericType<int>(null, nameForSubstitution: 'int4');
162161

163162
/// Must be an [int] (autoincrementing 8-byte integer)
164-
static const bigSerial = GenericType<int>(null, nameForSubstitution: 'int8');
163+
static final bigSerial = _genericType<int>(null, nameForSubstitution: 'int8');
165164

166165
/// Must be a [double] (32-bit floating point value)
167-
static const real =
168-
GenericType<core.double>(TypeOid.real, nameForSubstitution: 'float4');
166+
static final real =
167+
_genericType<core.double>(TypeOid.real, nameForSubstitution: 'float4');
169168

170169
/// Must be a [double] (64-bit floating point value)
171-
static const double =
172-
GenericType<core.double>(TypeOid.double, nameForSubstitution: 'float8');
170+
static final double =
171+
_genericType<core.double>(TypeOid.double, nameForSubstitution: 'float8');
173172

174173
/// Must be a [bool]
175-
static const boolean =
176-
GenericType<bool>(TypeOid.boolean, nameForSubstitution: 'boolean');
174+
static final boolean =
175+
_genericType<bool>(TypeOid.boolean, nameForSubstitution: 'boolean');
177176

178177
/// Must be a [DateTime] (microsecond date and time precision)
179-
static const timestampWithoutTimezone = GenericType<DateTime>(
178+
static final timestampWithoutTimezone = _genericType<DateTime>(
180179
TypeOid.timestampWithoutTimezone,
181180
nameForSubstitution: 'timestamp');
182181

183182
/// Must be a [DateTime] (microsecond date and time precision)
184-
static const timestampWithTimezone = GenericType<DateTime>(
183+
static final timestampWithTimezone = _genericType<DateTime>(
185184
TypeOid.timestampWithTimezone,
186185
nameForSubstitution: 'timestamptz');
187186

188187
/// Must be a [Interval]
189-
static const interval =
190-
GenericType<Interval>(TypeOid.interval, nameForSubstitution: 'interval');
188+
static final interval =
189+
_genericType<Interval>(TypeOid.interval, nameForSubstitution: 'interval');
191190

192191
/// An arbitrary-precision number.
193192
///
194193
/// This library supports encoding numbers in a textual format, or when
195194
/// passed as [int] or [double]. When decoding values, numeric types are
196195
/// always returned as string.
197-
static const numeric =
198-
GenericType<Object>(TypeOid.numeric, nameForSubstitution: 'numeric');
196+
static final numeric =
197+
_genericType<Object>(TypeOid.numeric, nameForSubstitution: 'numeric');
199198

200199
/// Must be a [DateTime] (contains year, month and day only)
201-
static const date =
202-
GenericType<DateTime>(TypeOid.date, nameForSubstitution: 'date');
200+
static final date =
201+
_genericType<DateTime>(TypeOid.date, nameForSubstitution: 'date');
203202

204203
/// Must be encodable via [json.encode].
205204
///
206205
/// Values will be encoded via [json.encode] before being sent to the database.
207-
static const jsonb = GenericType(TypeOid.jsonb, nameForSubstitution: 'jsonb');
206+
static final jsonb = GenericType(TypeOid.jsonb, nameForSubstitution: 'jsonb');
208207

209208
/// Must be encodable via [core.json.encode].
210209
///
211210
/// Values will be encoded via [core.json.encode] before being sent to the database.
212-
static const json = GenericType(TypeOid.json, nameForSubstitution: 'json');
211+
static final json = GenericType(TypeOid.json, nameForSubstitution: 'json');
213212

214213
/// Must be a [List] of [int].
215214
///
216215
/// Each element of the list must fit into a byte (0-255).
217-
static const byteArray =
218-
GenericType<List<int>>(TypeOid.byteArray, nameForSubstitution: 'bytea');
216+
static final byteArray =
217+
_genericType<List<int>>(TypeOid.byteArray, nameForSubstitution: 'bytea');
219218

220219
/// Must be a [String]
221220
///
222221
/// Used for internal pg structure names
223-
static const name =
224-
GenericType<String>(TypeOid.name, nameForSubstitution: 'name');
222+
static final name =
223+
_genericType<String>(TypeOid.name, nameForSubstitution: 'name');
225224

226225
/// Must be a [String].
227226
///
228227
/// Must contain 32 hexadecimal characters. May contain any number of '-' characters.
229228
/// When returned from database, format will be xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
230-
static const uuid =
231-
GenericType<String>(TypeOid.uuid, nameForSubstitution: 'uuid');
229+
static final uuid =
230+
_genericType<String>(TypeOid.uuid, nameForSubstitution: 'uuid');
232231

233232
/// Must be a [Point]
234-
static const point =
235-
GenericType<Point>(TypeOid.point, nameForSubstitution: 'point');
233+
static final point =
234+
_genericType<Point>(TypeOid.point, nameForSubstitution: 'point');
236235

237236
/// Must be a [List<bool>]
238-
static const booleanArray = GenericType<List<bool>>(TypeOid.booleanArray,
237+
static final booleanArray = _genericType<List<bool>>(TypeOid.booleanArray,
239238
nameForSubstitution: '_bool');
240239

241240
/// Must be a [List<int>]
242-
static const integerArray = GenericType<List<int>>(TypeOid.integerArray,
241+
static final integerArray = _genericType<List<int>>(TypeOid.integerArray,
243242
nameForSubstitution: '_int4');
244243

245244
/// Must be a [List<int>]
246-
static const bigIntegerArray = GenericType<List<int>>(TypeOid.bigIntegerArray,
245+
static final bigIntegerArray = _genericType<List<int>>(
246+
TypeOid.bigIntegerArray,
247247
nameForSubstitution: '_int8');
248248

249249
/// Must be a [List<String>]
250-
static const textArray = GenericType<List<String>>(TypeOid.textArray,
250+
static final textArray = _genericType<List<String>>(TypeOid.textArray,
251251
nameForSubstitution: '_text');
252252

253253
/// Must be a [List<double>]
254-
static const doubleArray = GenericType<List<core.double>>(TypeOid.doubleArray,
254+
static final doubleArray = _genericType<List<core.double>>(
255+
TypeOid.doubleArray,
255256
nameForSubstitution: '_float8');
256257

257258
/// Must be a [String]
258-
static const varChar =
259-
GenericType<String>(TypeOid.varChar, nameForSubstitution: 'varchar');
259+
static final varChar =
260+
_genericType<String>(TypeOid.varChar, nameForSubstitution: 'varchar');
260261

261262
/// Must be a [List<String>]
262-
static const varCharArray = GenericType<List<String>>(TypeOid.varCharArray,
263+
static final varCharArray = _genericType<List<String>>(TypeOid.varCharArray,
263264
nameForSubstitution: '_varchar');
264265

265266
/// Must be a [List] of encodable objects
266-
static const jsonbArray =
267-
GenericType<List>(TypeOid.jsonbArray, nameForSubstitution: '_jsonb');
267+
static final jsonbArray =
268+
_genericType<List>(TypeOid.jsonbArray, nameForSubstitution: '_jsonb');
268269

269270
/// Must be a [Type].
270-
static const regtype =
271-
GenericType<Type>(TypeOid.regtype, nameForSubstitution: 'regtype');
271+
static final regtype =
272+
_genericType<Type>(TypeOid.regtype, nameForSubstitution: 'regtype');
272273

273274
/// Impossible to bind to, always null when read.
274-
static const voidType = GenericType<Object>(TypeOid.voidType);
275+
static final voidType = _genericType<Object>(TypeOid.voidType);
275276

276277
/// The object ID of this data type.
277278
final int? oid;
278279

279-
/// The name of this type as considered by [Sql.named].
280-
///
281-
/// To declare an explicit type for a substituted parameter in a query, this
282-
/// name can be used.
283-
final String? nameForSubstitution;
284-
285-
const Type(
286-
this.oid, {
287-
this.nameForSubstitution,
288-
});
289-
290-
bool get hasOid => oid != null && oid! > 0;
280+
const Type(this.oid);
291281

292282
TypedValue<T> value(T value) => TypedValue<T>(this, value);
293283

294-
EncodeOutput encode(EncodeInput<T> input);
295-
296-
T? decode(DecodeInput input);
297-
298284
@override
299-
String toString() => '$runtimeType(oid:$oid)';
285+
String toString() => 'Type(oid:$oid)';
300286
}
301287

302-
class EncodeInput<T extends Object> {
303-
final T value;
304-
final Encoding encoding;
305-
306-
EncodeInput({
307-
required this.value,
308-
required this.encoding,
309-
});
310-
}
311-
312-
class EncodeOutput {
313-
final Uint8List? bytes;
314-
final String? text;
315-
316-
EncodeOutput.bytes(Uint8List value)
317-
: bytes = value,
318-
text = null;
319-
320-
EncodeOutput.text(String value)
321-
: bytes = null,
322-
text = value;
323-
324-
bool get isBinary => bytes != null;
325-
}
326-
327-
class DecodeInput {
328-
final Uint8List bytes;
329-
final bool isBinary;
330-
final Encoding encoding;
331-
final TypeRegistry typeRegistry;
332-
333-
DecodeInput({
334-
required this.bytes,
335-
required this.isBinary,
336-
required this.encoding,
337-
required this.typeRegistry,
338-
});
339-
340-
late final asText = encoding.decode(bytes);
341-
}
288+
Type<T> _genericType<T extends Object>(int? typeOid,
289+
{String? nameForSubstitution}) =>
290+
GenericType<T>(typeOid, nameForSubstitution: nameForSubstitution);
342291

343292
class TypedValue<T extends Object> {
344293
final Type<T> type;

lib/src/types/binary_codec.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:convert';
22
import 'dart:typed_data';
33

44
import 'package:buffer/buffer.dart';
5+
import 'package:postgres/src/types/generic_type.dart';
56

67
import '../buffer.dart';
78
import '../types.dart';

lib/src/types/generic_type.dart

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,55 @@
1+
import 'dart:convert';
12
import 'dart:typed_data';
23

34
import '../types.dart';
45
import 'binary_codec.dart';
56
import 'text_codec.dart';
7+
import 'type_registry.dart';
8+
9+
class EncodeOutput {
10+
final Uint8List? bytes;
11+
final String? text;
12+
13+
EncodeOutput.bytes(Uint8List value)
14+
: bytes = value,
15+
text = null;
16+
17+
EncodeOutput.text(String value)
18+
: bytes = null,
19+
text = value;
20+
21+
bool get isBinary => bytes != null;
22+
}
23+
24+
class EncodeInput<T extends Object> {
25+
final T value;
26+
final Encoding encoding;
27+
28+
EncodeInput({
29+
required this.value,
30+
required this.encoding,
31+
});
32+
}
33+
34+
class DecodeInput {
35+
final Uint8List bytes;
36+
final bool isBinary;
37+
final Encoding encoding;
38+
final TypeRegistry typeRegistry;
39+
40+
DecodeInput({
41+
required this.bytes,
42+
required this.isBinary,
43+
required this.encoding,
44+
required this.typeRegistry,
45+
});
46+
47+
late final asText = encoding.decode(bytes);
48+
}
649

750
class UnknownType extends Type<Object> {
851
UnknownType(super.oid);
952

10-
@override
1153
EncodeOutput encode(EncodeInput input) {
1254
final v = input.value;
1355
if (v is Uint8List) {
@@ -19,22 +61,32 @@ class UnknownType extends Type<Object> {
1961
'Encoding ${v.runtimeType} for oid:$oid is not supported.');
2062
}
2163

22-
@override
2364
Object? decode(DecodeInput input) {
2465
return TypedBytes(typeOid: oid ?? 0, bytes: input.bytes);
2566
}
2667
}
2768

69+
class UnspecifiedType extends Type<Object> {
70+
const UnspecifiedType() : super(null);
71+
}
72+
73+
Type<Object> unspecifiedType() => const UnspecifiedType();
74+
2875
/// NOTE: do not use this type in client code.
2976
class GenericType<T extends Object> extends Type<T> {
77+
/// The name of this type as considered by [Sql.named].
78+
///
79+
/// To declare an explicit type for a substituted parameter in a query, this
80+
/// name can be used.
81+
final String? nameForSubstitution;
82+
3083
const GenericType(
3184
super.oid, {
32-
super.nameForSubstitution,
85+
this.nameForSubstitution,
3386
});
3487

35-
@override
3688
EncodeOutput encode(EncodeInput input) {
37-
if (hasOid) {
89+
if (oid != null && oid! > 0) {
3890
final encoder = PostgresBinaryEncoder(oid!);
3991
final bytes = encoder.convert(input.value, input.encoding);
4092
return EncodeOutput.bytes(bytes);
@@ -45,7 +97,6 @@ class GenericType<T extends Object> extends Type<T> {
4597
}
4698
}
4799

48-
@override
49100
T? decode(DecodeInput input) {
50101
if (input.isBinary) {
51102
return PostgresBinaryDecoder(oid!).convert(input) as T?;

0 commit comments

Comments
 (0)