Skip to content

Commit d75faf7

Browse files
committed
Even better
1 parent cdabe8c commit d75faf7

File tree

3 files changed

+127
-91
lines changed

3 files changed

+127
-91
lines changed

Sources/PostgresNIO/New/VariadicGenerics.swift

Lines changed: 93 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
extension PostgresRow {
44

5+
// --- snip TODO: Remove once bug is fixed, that disallows tuples of one
6+
@inlinable
57
public func decode<Column: PostgresDecodable>(
68
_: Column.Type,
79
file: String = #file,
@@ -10,6 +12,7 @@ extension PostgresRow {
1012
try self.decode(Column.self, context: .default, file: file, line: line)
1113
}
1214

15+
@inlinable
1316
public func decode<Column: PostgresDecodable>(
1417
_: Column.Type,
1518
context: PostgresDecodingContext<some PostgresJSONDecoder>,
@@ -42,18 +45,64 @@ extension PostgresRow {
4245
)
4346
}
4447
}
48+
// --- snap TODO: Remove once bug is fixed, that disallows tuples of one
4549

50+
// @inlinable // <--- commenting this in, crashes the compiler
4651
public func decode<each Column: PostgresDecodable>(
4752
_ columnType: (repeat each Column).Type,
4853
context: PostgresDecodingContext<some PostgresJSONDecoder>,
4954
file: String = #file,
5055
line: Int = #line
5156
) throws -> (repeat each Column) {
57+
var columnIndex = 0
58+
var cellIterator = self.data.makeIterator()
59+
var columnIterator = self.columns.makeIterator()
60+
61+
return (
62+
repeat try Self.decodeNextColumn(
63+
(each Column).self,
64+
cellIterator: &cellIterator,
65+
columnIterator: &columnIterator,
66+
columnIndex: &columnIndex,
67+
context: context,
68+
file: file,
69+
line: line
70+
)
71+
)
72+
}
5273

53-
var iterator = self.makeIterator()
54-
return (repeat try iterator.next()!.decode((each Column).self, context: context))
74+
@inlinable
75+
static func decodeNextColumn<Column: PostgresDecodable>(
76+
_ columnType: Column.Type,
77+
cellIterator: inout IndexingIterator<DataRow>,
78+
columnIterator: inout IndexingIterator<[RowDescription.Column]>,
79+
columnIndex: inout Int,
80+
context: PostgresDecodingContext<some PostgresJSONDecoder>,
81+
file: String,
82+
line: Int
83+
) throws -> Column {
84+
defer { columnIndex += 1 }
85+
86+
let column = columnIterator.next().unsafelyUnwrapped
87+
var cellData = cellIterator.next().unsafelyUnwrapped
88+
do {
89+
return try Column._decodeRaw(from: &cellData, type: column.dataType, format: column.format, context: context)
90+
} catch let code as PostgresDecodingError.Code {
91+
throw PostgresDecodingError(
92+
code: code,
93+
columnName: column.name,
94+
columnIndex: columnIndex,
95+
targetType: Column.self,
96+
postgresType: column.dataType,
97+
postgresFormat: column.format,
98+
postgresData: cellData,
99+
file: file,
100+
line: line
101+
)
102+
}
55103
}
56104

105+
// @inlinable // <--- commenting this in, crashes the compiler
57106
public func decode<each Column: PostgresDecodable>(
58107
_ columnType: (repeat each Column).Type,
59108
file: String = #file,
@@ -62,48 +111,47 @@ extension PostgresRow {
62111
try self.decode(columnType, context: .default, file: file, line: line)
63112
}
64113
}
65-
//
66-
//extension AsyncSequence where Element == PostgresRow {
67-
//
68-
// public func decode<Column: PostgresDecodable>(
69-
// _: Column.Type,
70-
// context: PostgresDecodingContext<some PostgresJSONDecoder>,
71-
// file: String = #file,
72-
// line: Int = #line
73-
// ) -> AsyncThrowingMapSequence<Self, (Column)> {
74-
// self.map { row in
75-
// try row.decodeSingle(Column.self, context: context, file: file, line: line)
76-
// }
77-
// }
78-
//
79-
// public func decode<Column: PostgresDecodable>(
80-
// _: Column.Type,
81-
// file: String = #file,
82-
// line: Int = #line
83-
// ) -> AsyncThrowingMapSequence<Self, (Column)> {
84-
// self.decode(Column.self, context: .default, file: file, line: line)
85-
// }
86-
//
87-
// public func decode<each Column: PostgresDecodable>(
88-
// _ columnType: (repeat each Column).Type,
89-
// context: PostgresDecodingContext<some PostgresJSONDecoder>,
90-
// file: String = #file,
91-
// line: Int = #line
92-
// ) throws -> AsyncThrowingMapSequence<Self, (repeat each Column)> {
93-
// self.map { row in
94-
// try row.decode(columnType, context: context, file: file, line: line)
95-
// }
96-
// }
97-
//
98-
// public func decode<each Column: PostgresDecodable>(
99-
// _ columnType: (repeat each Column).Type,
100-
// file: String = #file,
101-
// line: Int = #line
102-
// ) throws -> AsyncThrowingMapSequence<Self, (repeat each Column)> {
103-
// try self.decode(columnType, context: .default, file: file, line: line)
104-
// }
105-
//
106-
//
107-
//}
114+
115+
#if false // commented out since, the AsyncSequence map currently crashes the compiler
116+
extension AsyncSequence where Element == PostgresRow {
117+
public func decode<Column: PostgresDecodable>(
118+
_: Column.Type,
119+
context: PostgresDecodingContext<some PostgresJSONDecoder>,
120+
file: String = #file,
121+
line: Int = #line
122+
) -> AsyncThrowingMapSequence<Self, (Column)> {
123+
self.map { row in
124+
try row.decode(Column.self, context: context, file: file, line: line)
125+
}
126+
}
127+
128+
public func decode<Column: PostgresDecodable>(
129+
_: Column.Type,
130+
file: String = #file,
131+
line: Int = #line
132+
) -> AsyncThrowingMapSequence<Self, (Column)> {
133+
self.decode(Column.self, context: .default, file: file, line: line)
134+
}
135+
136+
public func decode<each Column: PostgresDecodable>(
137+
_ columnType: (repeat each Column).Type,
138+
context: PostgresDecodingContext<some PostgresJSONDecoder>,
139+
file: String = #file,
140+
line: Int = #line
141+
) throws -> AsyncThrowingMapSequence<Self, (repeat each Column)> {
142+
self.map { row in
143+
try row.decode(columnType, context: context, file: file, line: line)
144+
}
145+
}
146+
147+
public func decode<each Column: PostgresDecodable>(
148+
_ columnType: (repeat each Column).Type,
149+
file: String = #file,
150+
line: Int = #line
151+
) throws -> AsyncThrowingMapSequence<Self, (repeat each Column)> {
152+
try self.decode(columnType, context: .default, file: file, line: line)
153+
}
154+
}
155+
#endif
108156

109157
#endif

Sources/PostgresNIO/New/VariadicGenerics2.swift

Lines changed: 0 additions & 46 deletions
This file was deleted.

Tests/PostgresNIOTests/New/PostgresRowTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,38 @@ final class PostgresRowTests: XCTestCase {
122122
XCTAssertEqual(randomAccessRow["id"], PostgresCell(bytes: nil, dataType: .uuid, format: .binary, columnName: "id", columnIndex: 0))
123123
XCTAssertEqual(randomAccessRow["name"], PostgresCell(bytes: ByteBuffer(string: "Hello world!"), dataType: .text, format: .binary, columnName: "name", columnIndex: 1))
124124
}
125+
126+
func testDecoding() {
127+
let rowDescription = [
128+
RowDescription.Column(
129+
name: "id",
130+
tableOID: 1,
131+
columnAttributeNumber: 1,
132+
dataType: .uuid,
133+
dataTypeSize: 0,
134+
dataTypeModifier: 0,
135+
format: .binary
136+
),
137+
RowDescription.Column(
138+
name: "name",
139+
tableOID: 1,
140+
columnAttributeNumber: 1,
141+
dataType: .text,
142+
dataTypeSize: 0,
143+
dataTypeModifier: 0,
144+
format: .binary
145+
)
146+
]
147+
148+
let row = PostgresRow(
149+
data: .makeTestDataRow(nil, ByteBuffer(string: "Hello world!")),
150+
lookupTable: ["id": 0, "name": 1],
151+
columns: rowDescription
152+
)
153+
154+
var result: (UUID?, String)?
155+
XCTAssertNoThrow(result = try row.decode((UUID?, String).self))
156+
XCTAssertEqual(result?.0, .some(.none))
157+
XCTAssertEqual(result?.1, "Hello world!")
158+
}
125159
}

0 commit comments

Comments
 (0)