Class: PostgresPR::Message

Inherits:
Utils::ReadBuffer
  • Object
show all
Defined in:
lib/postgres-pr/message.rb

Overview

Base class representing a PostgreSQL protocol message

Constant Summary collapse

MsgTypeMap =

One character message-typecode to class map

Hash.new { UnknownMessageType }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.create(buffer) ⇒ Object



61
62
63
64
65
66
# File 'lib/postgres-pr/message.rb', line 61

def self.create(buffer)
  obj = allocate
  obj.init_buffer buffer
  obj.parse(obj)
  obj
end

.dump(*args) ⇒ Object



68
69
70
# File 'lib/postgres-pr/message.rb', line 68

def self.dump(*args)
  new(*args).dump
end

.fields(*attribs) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/postgres-pr/message.rb', line 92

def self.fields(*attribs)
  names = attribs.map {|name, type| name.to_s}
  arg_list = names.join(", ")
  ivar_list = names.map {|name| "@" + name }.join(", ")
  sym_list = names.map {|name| ":" + name }.join(", ")
  class_eval %[
    attr_accessor #{ sym_list } 
    def initialize(#{ arg_list })
      #{ ivar_list } = #{ arg_list }
    end
  ] 
end

.read(stream, startup = false) ⇒ Object

Raises:



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/postgres-pr/message.rb', line 49

def self.read(stream, startup=false)
  type = stream.read_exactly_n_bytes(1) unless startup
  length_s = stream.read_exactly_n_bytes(4)
  length = length_s.get_int32_network(0)  # FIXME: length should be signed, not unsigned

  raise ParseError unless length >= 4

  # initialize buffer
  body = stream.read_exactly_n_bytes(length - 4)
  (startup ? StartupMessage : MsgTypeMap[type]).create("#{type}#{length_s}#{body}")
end

.register_message_type(type) ⇒ Object

Raises:



40
41
42
43
44
45
46
47
# File 'lib/postgres-pr/message.rb', line 40

def self.register_message_type(type)
  raise(PGError, "duplicate message type registration") if MsgTypeMap.has_key?(type)

  MsgTypeMap[type] = self

  self.const_set(:MsgType, type) 
  class_eval "def message_type; MsgType end"
end

Instance Method Details

#bufferObject



72
73
74
# File 'lib/postgres-pr/message.rb', line 72

def buffer
  self
end

#dump(body_size = 0) {|buffer| ... } ⇒ Object

Yields:

Raises:



76
77
78
79
80
81
82
83
# File 'lib/postgres-pr/message.rb', line 76

def dump(body_size=0)
  buffer = Utils::WriteBuffer.of_size(5 +  body_size)
  buffer.write(self.message_type)
  buffer.write_int32_network(4 + body_size)
  yield buffer if block_given?
  raise DumpError  unless buffer.at_end?
  buffer.content
end

#parse(buffer) {|buffer| ... } ⇒ Object

Yields:

Raises:



85
86
87
88
89
90
# File 'lib/postgres-pr/message.rb', line 85

def parse(buffer)
  buffer.position = 5
  yield buffer if block_given?
  raise ParseError, buffer.inspect unless buffer.at_end?
  buffer.close
end