Skip to content

Commit a308b07

Browse files
committed
format code cleanup
1 parent b2d222a commit a308b07

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

Sources/PostgreSQL/Message/Messages/PostgreSQLDataRow.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct PostgreSQLDataRowColumn: Decodable {
2727
/// The value of the column, in the format indicated by the associated format code. n is the above length.
2828
var value: Data?
2929

30+
/// See Decodable.decode
3031
init(from decoder: Decoder) throws {
3132
let single = try decoder.singleValueContainer()
3233
/// The length of the column value, in bytes (this count does not include itself).
@@ -46,4 +47,14 @@ struct PostgreSQLDataRowColumn: Decodable {
4647
default: fatalError("Illegal data row column value count: \(count)")
4748
}
4849
}
50+
51+
52+
func makeString(encoding: String.Encoding = .utf8) throws -> String? {
53+
return try value.flatMap { data in
54+
guard let string = String(data: data, encoding: encoding) else {
55+
throw PostgreSQLError(identifier: "utf8String", reason: "Unexpected non-UTF8 string.")
56+
}
57+
return string
58+
}
59+
}
4960
}

Sources/PostgreSQL/Message/Messages/PostgreSQLRowDescription.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct PostgreSQLRowDescriptionField: Decodable {
4444
/// Currently will be zero (text) or one (binary).
4545
/// In a RowDescription returned from the statement variant of Describe,
4646
/// the format code is not yet known and will always be zero.
47-
var formatCode: Int16
47+
var formatCode: PostgreSQLFormatCode
4848

4949
/// See Decodable.decode
5050
init(from decoder: Decoder) throws {
@@ -55,13 +55,40 @@ struct PostgreSQLRowDescriptionField: Decodable {
5555
dataType = try single.decode(PostgreSQLDataType.self)
5656
dataTypeSize = try single.decode(Int16.self)
5757
dataTypeModifier = try single.decode(Int32.self)
58-
formatCode = try single.decode(Int16.self)
58+
formatCode = try single.decode(PostgreSQLFormatCode.self)
59+
}
60+
}
61+
62+
/// The format code being used for the field.
63+
/// Currently will be zero (text) or one (binary).
64+
/// In a RowDescription returned from the statement variant of Describe,
65+
/// the format code is not yet known and will always be zero.
66+
enum PostgreSQLFormatCode: Int16, Decodable {
67+
case text = 0
68+
case binary = 1
69+
70+
/// See Decodable.decode
71+
init(from decoder: Decoder) throws {
72+
let single = try decoder.singleValueContainer()
73+
let code = try single.decode(Int16.self)
74+
guard let type = PostgreSQLFormatCode.make(code) else {
75+
throw PostgreSQLError(
76+
identifier: "formatCode",
77+
reason: "Unsupported format code: \(code)"
78+
)
79+
}
80+
self = type
81+
}
82+
83+
/// Static make (non-failable)
84+
private static func make(_ code: Int16) -> PostgreSQLFormatCode? {
85+
return PostgreSQLFormatCode(rawValue: code)
5986
}
6087
}
6188

6289
/// The data type's raw object ID.
6390
/// Use `select * from pg_type where oid in (<idhere>);` to lookup more information.
64-
enum PostgreSQLDataType: Int32, Decodable, Equatable {
91+
enum PostgreSQLDataType: Int32, Decodable {
6592
case bool = 16
6693
case char = 18
6794
case name = 19
@@ -79,13 +106,14 @@ enum PostgreSQLDataType: Int32, Decodable, Equatable {
79106
let objectID = try single.decode(Int32.self)
80107
guard let type = PostgreSQLDataType.make(objectID) else {
81108
throw PostgreSQLError(
82-
identifier: "unsupportedColumnType",
109+
identifier: "dataType",
83110
reason: "Unsupported data type: \(objectID)"
84111
)
85112
}
86113
self = type
87114
}
88115

116+
/// Static make (non-failable)
89117
private static func make(_ objectID: Int32) -> PostgreSQLDataType? {
90118
return PostgreSQLDataType(rawValue: objectID)
91119
}

Sources/PostgreSQL/PostgreSQLClient.swift

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ final class PostgreSQLClient {
4444
currentRow = row
4545
case .dataRow(let data):
4646
guard let row = currentRow else {
47-
fatalError("Unexpected PostgreSQLDataRow without preceeding PostgreSQLRowDescription.")
47+
fatalError("Unexpected PostgreSQLDataRow without preceding PostgreSQLRowDescription.")
4848
}
4949

5050
var parsed: [String: PostgreSQLData] = [:]
@@ -55,36 +55,26 @@ final class PostgreSQLClient {
5555
let col = data.columns[i]
5656
let data: PostgreSQLData
5757
switch field.formatCode {
58-
case 0: // text
59-
func makeString() throws -> String? {
60-
return try col.value.flatMap { data in
61-
guard let string = String(data: data, encoding: .utf8) else {
62-
throw PostgreSQLError(identifier: "utf8String", reason: "Unexpected non-UTF8 string.")
63-
}
64-
return string
65-
}
66-
}
67-
58+
case .text:
6859
switch field.dataType {
6960
case .bool:
70-
data = try makeString().flatMap { $0 == "t" }.flatMap { .bool($0) } ?? .null
61+
data = try col.makeString().flatMap { $0 == "t" }.flatMap { .bool($0) } ?? .null
7162
case .text, .name:
72-
data = try makeString().flatMap { .string($0) } ?? .null
63+
data = try col.makeString().flatMap { .string($0) } ?? .null
7364
case .oid, .regproc, .int4:
74-
data = try makeString().flatMap { Int32($0) }.flatMap { .int32($0) } ?? .null
65+
data = try col.makeString().flatMap { Int32($0) }.flatMap { .int32($0) } ?? .null
7566
case .int2:
76-
data = try makeString().flatMap { Int16($0) }.flatMap { .int16($0) } ?? .null
67+
data = try col.makeString().flatMap { Int16($0) }.flatMap { .int16($0) } ?? .null
7768
case .char:
78-
data = try makeString().flatMap { Character($0) }.flatMap { .character($0) } ?? .null
69+
data = try col.makeString().flatMap { Character($0) }.flatMap { .character($0) } ?? .null
7970
case .pg_node_tree:
8071
print("\(field.name): is pg node tree")
8172
data = .null
8273
case ._aclitem:
8374
print("\(field.name): is acl item")
8475
data = .null
8576
}
86-
case 1: fatalError("Binary format code not supported.")
87-
default: fatalError("Unexpected format code: \(field.formatCode)")
77+
case .binary: fatalError("Binary format code not supported.")
8878
}
8979

9080
parsed[field.name] = data

0 commit comments

Comments
 (0)