forked from vapor/postgres-nio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPSQLFrontendMessageEncoder.swift
88 lines (68 loc) · 3.19 KB
/
PSQLFrontendMessageEncoder.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
struct PSQLFrontendMessageEncoder: MessageToByteEncoder {
typealias OutboundIn = PSQLFrontendMessage
let jsonEncoder: PSQLJSONEncoder
init(jsonEncoder: PSQLJSONEncoder) {
self.jsonEncoder = jsonEncoder
}
func encode(data message: PSQLFrontendMessage, out buffer: inout ByteBuffer) throws {
switch message {
case .bind(let bind):
buffer.writeInteger(message.id.rawValue)
let startIndex = buffer.writerIndex
buffer.writeInteger(Int32(0)) // placeholder for length
try bind.encode(into: &buffer, using: self.jsonEncoder)
let length = Int32(buffer.writerIndex - startIndex)
buffer.setInteger(length, at: startIndex)
case .cancel(let cancel):
// cancel requests don't have an identifier
self.encode(payload: cancel, into: &buffer)
case .close(let close):
self.encode(messageID: message.id, payload: close, into: &buffer)
case .describe(let describe):
self.encode(messageID: message.id, payload: describe, into: &buffer)
case .execute(let execute):
self.encode(messageID: message.id, payload: execute, into: &buffer)
case .flush:
self.encode(messageID: message.id, payload: EmptyPayload(), into: &buffer)
case .parse(let parse):
self.encode(messageID: message.id, payload: parse, into: &buffer)
case .password(let password):
self.encode(messageID: message.id, payload: password, into: &buffer)
case .saslInitialResponse(let saslInitialResponse):
self.encode(messageID: message.id, payload: saslInitialResponse, into: &buffer)
case .saslResponse(let saslResponse):
self.encode(messageID: message.id, payload: saslResponse, into: &buffer)
case .sslRequest(let request):
// sslRequests don't have an identifier
self.encode(payload: request, into: &buffer)
case .startup(let startup):
// startup requests don't have an identifier
self.encode(payload: startup, into: &buffer)
case .sync:
self.encode(messageID: message.id, payload: EmptyPayload(), into: &buffer)
case .terminate:
self.encode(messageID: message.id, payload: EmptyPayload(), into: &buffer)
}
}
private struct EmptyPayload: PSQLMessagePayloadEncodable {
func encode(into buffer: inout ByteBuffer) {}
}
private func encode<Payload: PSQLMessagePayloadEncodable>(
messageID: PSQLFrontendMessage.ID,
payload: Payload,
into buffer: inout ByteBuffer)
{
buffer.writeFrontendMessageID(messageID)
self.encode(payload: payload, into: &buffer)
}
private func encode<Payload: PSQLMessagePayloadEncodable>(
payload: Payload,
into buffer: inout ByteBuffer)
{
let startIndex = buffer.writerIndex
buffer.writeInteger(Int32(0)) // placeholder for length
payload.encode(into: &buffer)
let length = Int32(buffer.writerIndex - startIndex)
buffer.setInteger(length, at: startIndex)
}
}