Skip to content

Commit e2d2f86

Browse files
committed
better query method names
1 parent e04a2e0 commit e2d2f86

File tree

4 files changed

+123
-123
lines changed

4 files changed

+123
-123
lines changed

Sources/PostgreSQL/Client/PostgreSQLClient+ParamaterizedQuery.swift

Lines changed: 0 additions & 100 deletions
This file was deleted.
Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,100 @@
11
import Async
22

33
extension PostgreSQLClient {
4-
/// Sends a simple PostgreSQL query command, collecting the parsed results.
5-
public func query(_ string: String) -> Future<[[String: PostgreSQLData]]> {
4+
/// Sends a parameterized PostgreSQL query command, collecting the parsed results.
5+
public func query(
6+
_ string: String,
7+
_ parameters: [PostgreSQLData] = []
8+
) throws -> Future<[[String: PostgreSQLData]]> {
69
var rows: [[String: PostgreSQLData]] = []
7-
return query(string) { row in
10+
return try query(string, parameters) { row in
811
rows.append(row)
9-
}.map(to: [[String: PostgreSQLData]].self) {
10-
return rows
12+
}.map(to: [[String: PostgreSQLData]].self) {
13+
return rows
1114
}
1215
}
1316

14-
/// Sends a simple PostgreSQL query command, returning the parsed results to
17+
/// Sends a parameterized PostgreSQL query command, returning the parsed results to
1518
/// the supplied closure.
16-
public func query(_ string: String, onRow: @escaping ([String: PostgreSQLData]) -> ()) -> Future<Void> {
19+
public func query(
20+
_ string: String,
21+
_ parameters: [PostgreSQLData] = [],
22+
onRow: @escaping ([String: PostgreSQLData]) -> ()
23+
) throws -> Future<Void> {
24+
let parse = PostgreSQLParseRequest(
25+
statementName: "",
26+
query: string,
27+
parameterTypes: parameters.map { .type(forData: $0) }
28+
)
29+
let describe = PostgreSQLDescribeRequest(type: .statement, name: "")
1730
var currentRow: PostgreSQLRowDescription?
18-
let query = PostgreSQLQuery(query: string)
19-
return send([.query(query)]) { message in
31+
var currentParameters: PostgreSQLParameterDescription?
32+
return send([
33+
.parse(parse), .describe(describe), .sync
34+
]) { message in
2035
switch message {
21-
case .rowDescription(let row):
22-
currentRow = row
23-
case .dataRow(let data):
24-
let row = currentRow !! "Unexpected PostgreSQLDataRow without preceding PostgreSQLRowDescription."
25-
let parsed = try row.parse(data: data, formats: row.fields.map { $0.formatCode })
26-
onRow(parsed)
27-
case .close: break // query over, waiting for `readyForQuery`
28-
default: fatalError("Unexpected message during PostgreSQLQuery: \(message)")
36+
case .parseComplete: break
37+
case .rowDescription(let row): currentRow = row
38+
case .parameterDescription(let parameters): currentParameters = parameters
39+
case .noData: break
40+
default: fatalError("Unexpected message during PostgreSQLParseRequest: \(message)")
41+
}
42+
}.flatMap(to: Void.self) {
43+
let parameterDataTypes = (currentParameters !! "Unexpected nil parameters").dataTypes
44+
let resultDataTypes = currentRow?.fields.map { $0.dataType } ?? [] // nil currentRow means no resutls
45+
46+
// cache so we don't compute twice
47+
let _parameterFormats = parameterDataTypes.map { $0.preferredFormat }
48+
let _resultFormats = resultDataTypes.map { $0.preferredFormat }
49+
let bind = try PostgreSQLBindRequest(
50+
portalName: "",
51+
statementName: "",
52+
parameterFormatCodes: _parameterFormats,
53+
parameters: parameters.enumerated().map { try .make(data: $0.1, format: _parameterFormats[$0.0]) },
54+
resultFormatCodes: _resultFormats
55+
)
56+
let execute = PostgreSQLExecuteRequest(
57+
portalName: "",
58+
maxRows: 0
59+
)
60+
return self.send([
61+
.bind(bind), .execute(execute), .sync
62+
]) { message in
63+
switch message {
64+
case .bindComplete: break
65+
case .dataRow(let data):
66+
let row = currentRow !! "Unexpected PostgreSQLDataRow without preceding PostgreSQLRowDescription."
67+
let parsed = try row.parse(data: data, formats: _resultFormats)
68+
onRow(parsed)
69+
case .close: break
70+
case .noData: break
71+
default: fatalError("Unexpected message during PostgreSQLParseRequest: \(message)")
72+
}
2973
}
3074
}
3175
}
3276
}
77+
78+
/// MARK: Codable
79+
80+
extension PostgreSQLClient {
81+
/// Sends a parameterized PostgreSQL query command, collecting the parsed results.
82+
public func query(
83+
_ string: String,
84+
encoding parameters: [Encodable]
85+
) throws -> Future<[[String: PostgreSQLData]]> {
86+
let parameters = try parameters.map { try PostgreSQLDataEncoder().encode($0) }
87+
return try query(string, parameters)
88+
}
89+
90+
/// Sends a parameterized PostgreSQL query command, returning the parsed results to
91+
/// the supplied closure.
92+
public func query(
93+
_ string: String,
94+
encoding parameters: [Encodable],
95+
onRow: @escaping ([String: PostgreSQLData]) -> ()
96+
) throws -> Future<Void> {
97+
let parameters = try parameters.map { try PostgreSQLDataEncoder().encode($0) }
98+
return try query(string, parameters, onRow: onRow)
99+
}
100+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Async
2+
3+
extension PostgreSQLClient {
4+
/// Sends a simple PostgreSQL query command, collecting the parsed results.
5+
public func simpleQuery(_ string: String) -> Future<[[String: PostgreSQLData]]> {
6+
var rows: [[String: PostgreSQLData]] = []
7+
return simpleQuery(string) { row in
8+
rows.append(row)
9+
}.map(to: [[String: PostgreSQLData]].self) {
10+
return rows
11+
}
12+
}
13+
14+
/// Sends a simple PostgreSQL query command, returning the parsed results to
15+
/// the supplied closure.
16+
public func simpleQuery(_ string: String, onRow: @escaping ([String: PostgreSQLData]) -> ()) -> Future<Void> {
17+
var currentRow: PostgreSQLRowDescription?
18+
let query = PostgreSQLQuery(query: string)
19+
return send([.query(query)]) { message in
20+
switch message {
21+
case .rowDescription(let row):
22+
currentRow = row
23+
case .dataRow(let data):
24+
let row = currentRow !! "Unexpected PostgreSQLDataRow without preceding PostgreSQLRowDescription."
25+
let parsed = try row.parse(data: data, formats: row.fields.map { $0.formatCode })
26+
onRow(parsed)
27+
case .close: break // query over, waiting for `readyForQuery`
28+
default: fatalError("Unexpected message during PostgreSQLQuery: \(message)")
29+
}
30+
}
31+
}
32+
}

Tests/PostgreSQLTests/PostgreSQLClientTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import TCP
77
class PostgreSQLClientTests: XCTestCase {
88
func testVersion() throws {
99
let (client, eventLoop) = try PostgreSQLClient.makeTest()
10-
let results = try client.query("SELECT version();").await(on: eventLoop)
10+
let results = try client.simpleQuery("SELECT version();").await(on: eventLoop)
1111
XCTAssert(results[0]["version"]?.string?.contains("10.1") == true)
1212
}
1313

@@ -22,7 +22,7 @@ class PostgreSQLClientTests: XCTestCase {
2222
let query = """
2323
select * from "pg_type" where "typlen" = $1 or "typlen" = $2
2424
"""
25-
let rows = try client.parameterizedQuery(query, [
25+
let rows = try client.query(query, [
2626
.int32(1),
2727
.int32(2),
2828
]).await(on: eventLoop)
@@ -190,7 +190,7 @@ class PostgreSQLClientTests: XCTestCase {
190190
-- "uuid" uuid
191191
);
192192
"""
193-
let insertResult = try client.parameterizedQuery(insertQuery, [
193+
let insertResult = try client.query(insertQuery, [
194194
PostgreSQLData.int16(1), // smallint
195195
PostgreSQLData.int32(2), // integer
196196
PostgreSQLData.int64(3), // bigint
@@ -210,7 +210,7 @@ class PostgreSQLClientTests: XCTestCase {
210210
]).await(on: eventLoop)
211211
XCTAssertEqual(insertResult.count, 0)
212212

213-
let parameterizedResult = try client.parameterizedQuery("select * from kitchen_sink").await(on: eventLoop)
213+
let parameterizedResult = try client.query("select * from kitchen_sink").await(on: eventLoop)
214214
if parameterizedResult.count == 1 {
215215
let row = parameterizedResult[0]
216216
XCTAssertEqual(row["smallint"], .int16(1))
@@ -235,9 +235,9 @@ class PostgreSQLClientTests: XCTestCase {
235235
_ = try client.query("drop table if exists foo;").await(on: eventLoop)
236236
let createResult = try client.query("create table foo (fooid integer);").await(on: eventLoop)
237237
XCTAssertEqual(createResult.count, 0)
238-
let insertResult = try client.parameterizedQuery("insert into foo values ($1);", encoding: [Int(123)]).await(on: eventLoop)
238+
let insertResult = try client.query("insert into foo values ($1);", encoding: [Int(123)]).await(on: eventLoop)
239239
XCTAssertEqual(insertResult.count, 0)
240-
let parameterizedResult = try client.parameterizedQuery("select * from foo").await(on: eventLoop)
240+
let parameterizedResult = try client.query("select * from foo").await(on: eventLoop)
241241
if parameterizedResult.count == 1 {
242242
let row = parameterizedResult[0]
243243
XCTAssertEqual(row["fooid"], .int32(123))

0 commit comments

Comments
 (0)