Module: StickyElephant::PostgresProtocol
- Included in:
- PostgresSimulator
- Defined in:
- lib/sticky_elephant/postgres_protocol.rb
Constant Summary collapse
- READY_FOR_QUERY_STATUSES =
{ idle: 'I', transaction: 'T', failed: 'E' }.freeze
- COMMAND_COMPLETE_COMMANDS =
%i(insert delete update select move fetch copy create).freeze
Instance Method Summary collapse
- #command_complete(sym, num) ⇒ Object
- #data_row(*rows) ⇒ Object
- #int16_bytes(num) ⇒ Object
- #int32_bytes(num) ⇒ Object
- #ready_for_query(sym) ⇒ Object
- #row_description(*rows) ⇒ Object
- #with_length(obj) ⇒ Object
Instance Method Details
#command_complete(sym, num) ⇒ Object
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 15 def command_complete(sym, num) unless COMMAND_COMPLETE_COMMANDS.include?(sym) raise ArgumentError.new("#{sym} not in #{COMMAND_COMPLETE_COMMANDS}") end sym = :select if sym == :create ( ["C".ord ] + with_length("#{sym.to_s.upcase} #{num}\x00") ).pack("C*") end |
#data_row(*rows) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 26 def data_row(*rows) results_block = rows.flat_map do |row| (int32_bytes(row.length) + row.bytes) end ( [ "D".ord ] + with_length( int16_bytes(rows.count) + results_block ) ).pack("C*") end |
#int16_bytes(num) ⇒ Object
69 70 71 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 69 def int16_bytes(num) [num].pack("n").unpack("C*") end |
#int32_bytes(num) ⇒ Object
65 66 67 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 65 def int32_bytes(num) [num].pack("N").unpack("C*") end |
#ready_for_query(sym) ⇒ Object
4 5 6 7 8 9 10 11 12 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 4 def ready_for_query(sym) unless READY_FOR_QUERY_STATUSES.include?(sym) raise ArgumentError.new("#{sym} not in #{READY_FOR_QUERY_STATUSES}") end ( [ 'Z'.ord ] + with_length(READY_FOR_QUERY_STATUSES.fetch(sym)) ).pack('C*') end |
#row_description(*rows) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 40 def row_description(*rows) fields_block = rows.map do |row| row + "\x00" + # str Field name ("\x00" * 4) + # int32 If column of specific table, object ID of table; else zero. ("\x00" * 2) + # int16 If column of specific table, attribute# of column; else zero. ("\x00\x00\x00\x19") + # int32 Object ID of field's data type ("\xFF\xFF") + # int16 Data type size ("\xFF\xFF\xFF\xFF") + # int32 Type modifier ("\x00\x00") # int16 Format code: 0 for text, 1 for binary end.join.bytes num_fields = int16_bytes(rows.count) ( ['T'.ord ] + # byte - message with_length(num_fields + fields_block) ).pack("C*") end |
#with_length(obj) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/sticky_elephant/postgres_protocol.rb', line 57 def with_length(obj) bytes = obj.respond_to?(:bytes) ? obj.bytes : obj raise ArgumentError.new("Must be an array or respond to #bytes") unless bytes.is_a?(Array) length = 4 + bytes.size int32_bytes(length) + bytes end |