Module: NusaDB::Protocol
- Defined in:
- lib/nusadb/protocol.rb
Overview
Low-level Nusa Wire Protocol codec (docs/wire-protocol.md, PROTOCOL_VERSION 1.1).
A frame is [type:u8][len:u32][payload]; len is the total including the 5-byte header. Big-endian throughout; strings are [len:u32][utf8 bytes], not null-terminated.
Constant Summary collapse
- MAGIC =
"NUSA"
0x4E55_5341- MAJOR =
1- MINOR =
Request minor 1 to receive the typed RowDescription (per-column type tags). A 1.0 server ignores it and answers with the classic untyped form, which the driver still handles.
1- HEADER_LEN =
5- MAX_FRAME_LEN =
256 * 1024 * 1024
- SCRAM_MECHANISM =
'SCRAM-SHA-256'- T_STARTUP =
Frontend type bytes.
'S'.ord
- T_QUERY =
'Q'.ord
- T_PARSE =
'P'.ord
- T_BIND =
'B'.ord
- T_DESCRIBE =
'D'.ord
- T_EXECUTE =
'E'.ord
- T_SYNC =
'Y'.ord
- T_SASL_INITIAL =
'p'.ord
- T_SASL_RESPONSE =
'r'.ord
- T_TERMINATE =
'X'.ord
- T_COPY_DATA =
COPY ... FROM STDIN data chunk (§12.1)
'd'.ord
- T_COPY_DONE =
end of the client's COPY data stream
'c'.ord
- T_COPY_FAIL =
abort the in-progress COPY: [message:Str]
'f'.ord
- B_AUTH =
Backend type bytes.
'R'.ord
- B_BACKEND_KEY =
'K'.ord
- B_READY =
'Z'.ord
- B_COMMAND_COMPLETE =
'C'.ord
- B_ERROR =
'E'.ord
- B_ROW_DESCRIPTION =
'T'.ord
- B_ROW_DESCRIPTION_TYPED =
protocol 1.1 (typed columns)
'y'.ord
- B_DATA_ROW =
'D'.ord
- B_COPY_IN =
CopyInResponse (§12.1)
'G'.ord
- B_COPY_OUT =
CopyOutResponse (§12.2)
'H'.ord
- B_COPY_DATA =
a COPY data chunk
'd'.ord
- B_COPY_DONE =
end of the COPY data stream
'c'.ord
- B_NOTIFICATION =
async LISTEN/NOTIFY: [pid:u32][channel:str][payload:str]
'A'.ord
- TYPE_TAGS =
Column type tags carried by RowDescriptionTyped (protocol 1.1, wire-protocol.md §9.2). Maps the 1-byte tag to a canonical type name; an unknown/0x00 tag is UNKNOWN (treated as text).
{ 0x00 => 'UNKNOWN', 0x01 => 'BOOL', 0x02 => 'INT', 0x03 => 'FLOAT', 0x04 => 'NUMERIC', 0x05 => 'TEXT', 0x06 => 'BYTES', 0x07 => 'DATE', 0x08 => 'TIME', 0x09 => 'TIMETZ', 0x0A => 'TIMESTAMP', 0x0B => 'TIMESTAMPTZ', 0x0C => 'INTERVAL', 0x0D => 'UUID', 0x0E => 'JSON', 0x0F => 'ARRAY', 0x10 => 'VECTOR' }.freeze
- AUTH_OK =
Auth sub-codes.
0- AUTH_SASL =
10- AUTH_SASL_CONTINUE =
11- AUTH_SASL_FINAL =
12
Class Method Summary collapse
- .bind(portal, statement, values) ⇒ Object
- .copy_data(data) ⇒ Object
- .copy_done ⇒ Object
- .copy_fail(message) ⇒ Object
- .describe_portal(name) ⇒ Object
- .execute(portal, max_rows = 0) ⇒ Object
-
.fields(values) ⇒ Object
Encode a Fields list: [count:u16] then per field present byte + optional [len][bytes].
- .frame(type, payload) ⇒ Object
- .parse(name, sql) ⇒ Object
- .query(sql) ⇒ Object
- .sasl_initial(mechanism, data) ⇒ Object
- .sasl_response(data) ⇒ Object
- .startup(user, database) ⇒ Object
- .str(value) ⇒ Object
- .sync ⇒ Object
- .terminate ⇒ Object
-
.type_name(tag) ⇒ Object
Canonical type name for a RowDescriptionTyped type tag (UNKNOWN if unrecognised).
- .u16(value) ⇒ Object
- .u32(value) ⇒ Object
Class Method Details
.bind(portal, statement, values) ⇒ Object
115 116 117 |
# File 'lib/nusadb/protocol.rb', line 115 def bind(portal, statement, values) frame(T_BIND, str(portal) + str(statement) + fields(values) + u16(0)) end |
.copy_data(data) ⇒ Object
143 144 145 |
# File 'lib/nusadb/protocol.rb', line 143 def copy_data(data) frame(T_COPY_DATA, data) end |
.copy_done ⇒ Object
147 148 149 |
# File 'lib/nusadb/protocol.rb', line 147 def copy_done frame(T_COPY_DONE, ''.b) end |
.copy_fail(message) ⇒ Object
151 152 153 |
# File 'lib/nusadb/protocol.rb', line 151 def copy_fail() frame(T_COPY_FAIL, str()) end |
.describe_portal(name) ⇒ Object
119 120 121 |
# File 'lib/nusadb/protocol.rb', line 119 def describe_portal(name) frame(T_DESCRIBE, 'P'.b + str(name)) end |
.execute(portal, max_rows = 0) ⇒ Object
123 124 125 |
# File 'lib/nusadb/protocol.rb', line 123 def execute(portal, max_rows = 0) frame(T_EXECUTE, str(portal) + u32(max_rows)) end |
.fields(values) ⇒ Object
Encode a Fields list: [count:u16] then per field present byte + optional [len][bytes].
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/nusadb/protocol.rb', line 84 def fields(values) out = u16(values.length) values.each do |v| if v.nil? out += "\x00".b else v = v.dup.force_encoding(Encoding::BINARY) out += "\x01".b + u32(v.bytesize) + v end end out end |
.frame(type, payload) ⇒ Object
97 98 99 100 |
# File 'lib/nusadb/protocol.rb', line 97 def frame(type, payload) total = payload.bytesize + HEADER_LEN (type.chr + u32(total) + payload).force_encoding(Encoding::BINARY) end |
.parse(name, sql) ⇒ Object
111 112 113 |
# File 'lib/nusadb/protocol.rb', line 111 def parse(name, sql) frame(T_PARSE, str(name) + str(sql) + u16(0)) end |
.query(sql) ⇒ Object
107 108 109 |
# File 'lib/nusadb/protocol.rb', line 107 def query(sql) frame(T_QUERY, str(sql)) end |
.sasl_initial(mechanism, data) ⇒ Object
135 136 137 |
# File 'lib/nusadb/protocol.rb', line 135 def sasl_initial(mechanism, data) frame(T_SASL_INITIAL, str(mechanism) + u32(data.bytesize) + data) end |
.sasl_response(data) ⇒ Object
139 140 141 |
# File 'lib/nusadb/protocol.rb', line 139 def sasl_response(data) frame(T_SASL_RESPONSE, data) end |
.startup(user, database) ⇒ Object
102 103 104 105 |
# File 'lib/nusadb/protocol.rb', line 102 def startup(user, database) payload = u32(MAGIC) + u16(MAJOR) + u16(MINOR) + str(user) + str(database) frame(T_STARTUP, payload) end |
.str(value) ⇒ Object
78 79 80 81 |
# File 'lib/nusadb/protocol.rb', line 78 def str(value) bytes = value.to_s.dup.force_encoding(Encoding::BINARY) u32(bytes.bytesize) + bytes end |
.sync ⇒ Object
127 128 129 |
# File 'lib/nusadb/protocol.rb', line 127 def sync frame(T_SYNC, ''.b) end |
.terminate ⇒ Object
131 132 133 |
# File 'lib/nusadb/protocol.rb', line 131 def terminate frame(T_TERMINATE, ''.b) end |
.type_name(tag) ⇒ Object
Canonical type name for a RowDescriptionTyped type tag (UNKNOWN if unrecognised).
58 59 60 |
# File 'lib/nusadb/protocol.rb', line 58 def self.type_name(tag) TYPE_TAGS.fetch(tag, 'UNKNOWN') end |
.u16(value) ⇒ Object
70 71 72 |
# File 'lib/nusadb/protocol.rb', line 70 def u16(value) [value].pack('n') end |
.u32(value) ⇒ Object
74 75 76 |
# File 'lib/nusadb/protocol.rb', line 74 def u32(value) [value].pack('N') end |