postgres-pr-opt 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +25 -0
- data/Rakefile +2 -0
- data/examples/client.rb +34 -0
- data/examples/og/test.rb +50 -0
- data/examples/server.rb +12 -0
- data/examples/test_connection.rb +18 -0
- data/ext/postgres-pr/utils/extconf.rb +8 -0
- data/ext/postgres-pr/utils/string_unpack_single.c +73 -0
- data/lib/pg.rb +8 -0
- data/lib/postgres-pr/connection.rb +175 -0
- data/lib/postgres-pr/message.rb +589 -0
- data/lib/postgres-pr/pg-compat.rb +225 -0
- data/lib/postgres-pr/postgres-compat.rb +169 -0
- data/lib/postgres-pr/typeconv/TC_conv.rb +18 -0
- data/lib/postgres-pr/typeconv/array.rb +46 -0
- data/lib/postgres-pr/typeconv/bytea.rb +32 -0
- data/lib/postgres-pr/typeconv/conv.rb +5 -0
- data/lib/postgres-pr/utils/buffer.rb +252 -0
- data/lib/postgres-pr/utils/byteorder.rb +45 -0
- data/lib/postgres-pr/version.rb +3 -0
- data/lib/postgres.rb +8 -0
- metadata +102 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module Postgres::Conversion
|
2
|
+
# Encodes a string as bytea value.
|
3
|
+
#
|
4
|
+
# For encoding rules see:
|
5
|
+
# http://www.postgresql.org/docs/7.4/static/datatype-binary.html
|
6
|
+
#
|
7
|
+
# The historical bytea escape format is always used, for maximum compatibility.
|
8
|
+
def encode_bytea(str)
|
9
|
+
# each_byte used instead of [] for 1.9 compatibility
|
10
|
+
str.gsub(/[\000-\037\047\134\177-\377]/){|b| "\\#{sprintf('%o', b.each_byte{|x| break x}).rjust(3, '0')}"}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Decodes a bytea encoded string.
|
14
|
+
#
|
15
|
+
# For decoding rules see:
|
16
|
+
# http://www.postgresql.org/docs/7.4/static/datatype-binary.html
|
17
|
+
#
|
18
|
+
# Supports both the historical escape format and the new 9.0+ hex format.
|
19
|
+
def decode_bytea(str)
|
20
|
+
if str =~ /\A\\x/
|
21
|
+
# PostgreSQL 9.0+ bytea hex format
|
22
|
+
str[2..-1].gsub(/(..)/){|s| s.to_i(16).chr}
|
23
|
+
else
|
24
|
+
# Historical PostgreSQL bytea escape format
|
25
|
+
str.gsub(/\\(\\|'|[0-3][0-7][0-7])/) {|s|
|
26
|
+
if s.size == 2 then s[1,1] else s[1,3].oct.chr end
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
alias unescape_bytea decode_bytea
|
32
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
unless "".respond_to?(:getbyte)
|
3
|
+
class String
|
4
|
+
alias :getbyte :[]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
unless "".respond_to?(:setbyte)
|
8
|
+
class String
|
9
|
+
alias :setbyte :[]=
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
if RUBY_ENGINE == 'ruby'
|
14
|
+
begin
|
15
|
+
require 'postgres-pr/utils/unpack_single'
|
16
|
+
rescue LoadError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module PostgresPR
|
21
|
+
module Utils
|
22
|
+
STRING_NATIVE_UNPACK_SINGLE = "".respond_to?(:get_int16_network)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
unless PostgresPR::Utils::STRING_NATIVE_UNPACK_SINGLE
|
27
|
+
class String
|
28
|
+
def get_int16_network(pos)
|
29
|
+
byte1, byte2 = getbyte(pos), getbyte(pos+1)
|
30
|
+
(byte1 < 128 ? byte1 : byte1 - 256) * 256 + byte2
|
31
|
+
end
|
32
|
+
def get_int32_network(pos)
|
33
|
+
byte1, byte2 = getbyte(pos), getbyte(pos+1)
|
34
|
+
byte3, byte4 = getbyte(pos+2), getbyte(pos+3)
|
35
|
+
((((byte1 < 128 ? byte1 : byte1 - 256) * 256 + byte2) * 256) + byte3) * 256 + byte4
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module PostgresPR
|
41
|
+
module Utils
|
42
|
+
class NativeBuffer < StringIO
|
43
|
+
def self.of_size(size)
|
44
|
+
new('#'*size, 'r+')
|
45
|
+
end
|
46
|
+
alias position pos
|
47
|
+
alias position= pos=
|
48
|
+
alias read_byte readbyte
|
49
|
+
alias at_end? eof?
|
50
|
+
alias content string
|
51
|
+
alias init_buffer initialize
|
52
|
+
public :init_buffer
|
53
|
+
if STRING_NATIVE_UNPACK_SINGLE
|
54
|
+
include ReadUnpack
|
55
|
+
else
|
56
|
+
def read_int16_network
|
57
|
+
byte1, byte2 = readbyte, readbyte
|
58
|
+
(byte1 < 128 ? byte1 : byte1 - 256) * 256 + byte2
|
59
|
+
end
|
60
|
+
def read_int32_network
|
61
|
+
byte1, byte2 = readbyte, readbyte
|
62
|
+
byte3, byte4 = readbyte, readbyte
|
63
|
+
((((byte1 < 128 ? byte1 : byte1 - 256) * 256 + byte2) * 256) + byte3) * 256 + byte4
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def write_byte(byte)
|
67
|
+
write(byte.chr)
|
68
|
+
end
|
69
|
+
def write_int32_network(int32)
|
70
|
+
write([int32].pack('N'))
|
71
|
+
end
|
72
|
+
def write_int16_network(int16)
|
73
|
+
write([int16].pack('n'))
|
74
|
+
end
|
75
|
+
|
76
|
+
def copy_from_stream(stream, n)
|
77
|
+
raise ArgumentError if n < 0
|
78
|
+
while n > 0
|
79
|
+
str = stream.read(n)
|
80
|
+
write(str)
|
81
|
+
n -= str.size
|
82
|
+
end
|
83
|
+
raise if n < 0
|
84
|
+
end
|
85
|
+
|
86
|
+
NUL = "\000"
|
87
|
+
def write_cstring(cstr)
|
88
|
+
raise ArgumentError, "Invalid Ruby/cstring" if cstr.include?(NUL)
|
89
|
+
write(cstr)
|
90
|
+
write(NUL)
|
91
|
+
end
|
92
|
+
|
93
|
+
# returns a Ruby string without the trailing NUL character
|
94
|
+
def read_cstring
|
95
|
+
s = readline(NUL)
|
96
|
+
s.chop!
|
97
|
+
s
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
class CustomBuffer
|
103
|
+
|
104
|
+
class Error < RuntimeError; end
|
105
|
+
class EOF < Error; end
|
106
|
+
|
107
|
+
def self.from_string(str)
|
108
|
+
new(str)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.of_size(size)
|
112
|
+
raise ArgumentError if size < 0
|
113
|
+
new('#' * size)
|
114
|
+
end
|
115
|
+
|
116
|
+
def initialize(content)
|
117
|
+
self.init_buffer content
|
118
|
+
end
|
119
|
+
|
120
|
+
def init_buffer(content)
|
121
|
+
@size = content.size
|
122
|
+
@content = content
|
123
|
+
@position = 0
|
124
|
+
end
|
125
|
+
|
126
|
+
def close
|
127
|
+
end
|
128
|
+
|
129
|
+
def size
|
130
|
+
@size
|
131
|
+
end
|
132
|
+
|
133
|
+
def position
|
134
|
+
@position
|
135
|
+
end
|
136
|
+
|
137
|
+
def position=(new_pos)
|
138
|
+
raise ArgumentError if new_pos < 0 or new_pos > @size
|
139
|
+
@position = new_pos
|
140
|
+
end
|
141
|
+
|
142
|
+
def at_end?
|
143
|
+
@position == @size
|
144
|
+
end
|
145
|
+
|
146
|
+
def content
|
147
|
+
@content
|
148
|
+
end
|
149
|
+
|
150
|
+
def read(n)
|
151
|
+
raise EOF, 'cannot read beyond the end of buffer' if @position + n > @size
|
152
|
+
str = @content[@position, n]
|
153
|
+
@position += n
|
154
|
+
str
|
155
|
+
end
|
156
|
+
|
157
|
+
def write(str)
|
158
|
+
sz = str.size
|
159
|
+
raise EOF, 'cannot write beyond the end of buffer' if @position + sz > @size
|
160
|
+
@content[@position, sz] = str
|
161
|
+
@position += sz
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
def readbyte
|
166
|
+
raise EOF, 'cannot read beyond the end of buffer' if @position >= @size
|
167
|
+
byte = @content.getbyte(@position)
|
168
|
+
@position += 1
|
169
|
+
byte
|
170
|
+
end
|
171
|
+
alias read_byte readbyte
|
172
|
+
|
173
|
+
def read_int16_network
|
174
|
+
pos = @position
|
175
|
+
raise EOF, 'cannot read beyond the end of buffer' if pos + 2 > @size
|
176
|
+
@position += 2
|
177
|
+
@content.get_int16_network(pos)
|
178
|
+
end
|
179
|
+
|
180
|
+
def read_int32_network
|
181
|
+
pos = @position
|
182
|
+
raise EOF, 'cannot read beyond the end of buffer' if pos + 4 > @size
|
183
|
+
@position += 4
|
184
|
+
@content.get_int32_network(pos)
|
185
|
+
end
|
186
|
+
|
187
|
+
def copy_from_stream(stream, n)
|
188
|
+
raise ArgumentError if n < 0
|
189
|
+
while n > 0
|
190
|
+
str = stream.read(n)
|
191
|
+
write(str)
|
192
|
+
n -= str.size
|
193
|
+
end
|
194
|
+
raise if n < 0
|
195
|
+
end
|
196
|
+
|
197
|
+
def writebyte(byte)
|
198
|
+
raise EOF, 'cannot write beyond the end of buffer' if @position >= @size
|
199
|
+
@content.setbyte(@position, byte)
|
200
|
+
@position += 1
|
201
|
+
self
|
202
|
+
end
|
203
|
+
alias write_byte writebyte
|
204
|
+
|
205
|
+
def write_int16_network(int16)
|
206
|
+
raise EOF, 'cannot write beyond the end of buffer' if @position + 2 > @size
|
207
|
+
@content[@position, 2] = [int16].pack('n')
|
208
|
+
@position += 2
|
209
|
+
self
|
210
|
+
end
|
211
|
+
|
212
|
+
def write_int32_network(int32)
|
213
|
+
raise EOF, 'cannot write beyond the end of buffer' if @position + 4 > @size
|
214
|
+
@content[@position, 4] = [int32].pack('N')
|
215
|
+
@position += 4
|
216
|
+
self
|
217
|
+
end
|
218
|
+
|
219
|
+
NUL = "\000"
|
220
|
+
|
221
|
+
def write_cstring(cstr)
|
222
|
+
raise ArgumentError, "Invalid Ruby/cstring" if cstr.include?(NUL)
|
223
|
+
write(cstr)
|
224
|
+
write(NUL)
|
225
|
+
end
|
226
|
+
|
227
|
+
# returns a Ruby string without the trailing NUL character
|
228
|
+
def read_cstring
|
229
|
+
nul_pos = @content.index(NUL, @position)
|
230
|
+
raise Error, "no cstring found!" unless nul_pos
|
231
|
+
|
232
|
+
sz = nul_pos - @position
|
233
|
+
str = @content[@position, sz]
|
234
|
+
@position += sz + 1
|
235
|
+
return str
|
236
|
+
end
|
237
|
+
|
238
|
+
# read till the end of the buffer
|
239
|
+
def read_rest
|
240
|
+
read(self.size-@position)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
if RUBY_ENGINE == 'jruby' || (RUBY_ENGINE == 'ruby' && RUBY_VERSION < '1.9')
|
245
|
+
ReadBuffer = NativeBuffer
|
246
|
+
WriteBuffer = NativeBuffer
|
247
|
+
else
|
248
|
+
ReadBuffer = CustomBuffer
|
249
|
+
WriteBuffer = CustomBuffer
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module PostgresPR
|
2
|
+
module Utils
|
3
|
+
module ByteOrder
|
4
|
+
Native = :Native
|
5
|
+
BigEndian = Big = Network = :BigEndian
|
6
|
+
LittleEndian = Little = :LittleEndian
|
7
|
+
|
8
|
+
# examines the byte order of the underlying machine
|
9
|
+
if [0x12345678].pack("L") == "\x12\x34\x56\x78"
|
10
|
+
def byte_order
|
11
|
+
BigEndian
|
12
|
+
end
|
13
|
+
|
14
|
+
def little_endian?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def big_endian?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
else
|
22
|
+
def byte_order
|
23
|
+
LittleEndian
|
24
|
+
end
|
25
|
+
|
26
|
+
def little_endian?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def big_endian?
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
alias byteorder byte_order
|
36
|
+
alias little? little_endian?
|
37
|
+
alias big? big_endian?
|
38
|
+
alias network? big_endian?
|
39
|
+
|
40
|
+
module_function :byte_order, :byteorder
|
41
|
+
module_function :little_endian?, :little?
|
42
|
+
module_function :big_endian?, :big?, :network?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/postgres.rb
ADDED
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: postgres-pr-opt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 9
|
10
|
+
version: 0.6.9
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Michael Neumann
|
14
|
+
- Jeremy Evans
|
15
|
+
- Alexander E. Fischer
|
16
|
+
- Aaron Hamid
|
17
|
+
- Rahim Packir Saibo
|
18
|
+
- Lars Christensen
|
19
|
+
- Kashif Rasul
|
20
|
+
- Sokolov Yura aka funny_falcon
|
21
|
+
autorequire:
|
22
|
+
bindir: bin
|
23
|
+
cert_chain: []
|
24
|
+
|
25
|
+
date: 2011-11-25 00:00:00 +04:00
|
26
|
+
default_executable:
|
27
|
+
dependencies: []
|
28
|
+
|
29
|
+
description:
|
30
|
+
email:
|
31
|
+
- mneumann@ntecs.de
|
32
|
+
- code@jeremyevans.net
|
33
|
+
- aef@raxys.net
|
34
|
+
- larsch@belunktum.dk
|
35
|
+
- kashif@nomad-labs.com
|
36
|
+
- funny.falcon@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions:
|
40
|
+
- ext/postgres-pr/utils/extconf.rb
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- README
|
45
|
+
- Rakefile
|
46
|
+
- lib/postgres-pr/version.rb
|
47
|
+
- lib/postgres-pr/pg-compat.rb
|
48
|
+
- lib/postgres-pr/postgres-compat.rb
|
49
|
+
- lib/postgres-pr/typeconv/TC_conv.rb
|
50
|
+
- lib/postgres-pr/typeconv/array.rb
|
51
|
+
- lib/postgres-pr/typeconv/conv.rb
|
52
|
+
- lib/postgres-pr/typeconv/bytea.rb
|
53
|
+
- lib/postgres-pr/utils/buffer.rb
|
54
|
+
- lib/postgres-pr/utils/byteorder.rb
|
55
|
+
- lib/postgres-pr/connection.rb
|
56
|
+
- lib/postgres-pr/message.rb
|
57
|
+
- lib/pg.rb
|
58
|
+
- lib/postgres.rb
|
59
|
+
- examples/test_connection.rb
|
60
|
+
- examples/server.rb
|
61
|
+
- examples/client.rb
|
62
|
+
- examples/og/test.rb
|
63
|
+
- ext/postgres-pr/utils/extconf.rb
|
64
|
+
- ext/postgres-pr/utils/string_unpack_single.c
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: https://github.com/funny-falcon/postgres-pr
|
67
|
+
licenses:
|
68
|
+
- Ruby
|
69
|
+
- GPL
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
- ext
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.6.2
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: A pure Ruby interface to the PostgreSQL (>= 7.4) database.
|
101
|
+
test_files: []
|
102
|
+
|