postgres-pr 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/test_connection.rb +1 -1
- data/lib/buffer.rb +5 -3
- data/lib/postgres-pr/message.rb +40 -25
- data/lib/postgres-pr/version.rb +1 -1
- metadata +2 -2
data/examples/test_connection.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift '../lib'
|
2
2
|
require 'postgres-pr/connection'
|
3
3
|
|
4
|
-
conn = PostgresPR::Connection.new('mneumann', 'mneumann')
|
4
|
+
conn = PostgresPR::Connection.new('mneumann', 'mneumann', nil, 'unix:/var/run/postgresql/.s.PGSQL.5432')
|
5
5
|
p conn.query("DROP TABLE test") rescue nil
|
6
6
|
p conn.query("CREATE TABLE test (a VARCHAR(100))")
|
7
7
|
p conn.query("INSERT INTO test VALUES ('hallo')")
|
data/lib/buffer.rb
CHANGED
@@ -68,15 +68,17 @@ class Buffer
|
|
68
68
|
raise if n < 0
|
69
69
|
end
|
70
70
|
|
71
|
+
NUL = "\000"
|
72
|
+
|
71
73
|
def write_cstring(cstr)
|
72
|
-
raise ArgumentError, "Invalid Ruby/cstring" if cstr.include?(
|
74
|
+
raise ArgumentError, "Invalid Ruby/cstring" if cstr.include?(NUL)
|
73
75
|
write(cstr)
|
74
|
-
write(
|
76
|
+
write(NUL)
|
75
77
|
end
|
76
78
|
|
77
79
|
# returns a Ruby string without the trailing NUL character
|
78
80
|
def read_cstring
|
79
|
-
nul_pos = @content.index(
|
81
|
+
nul_pos = @content.index(NUL, @position)
|
80
82
|
raise Error, "no cstring found!" unless nul_pos
|
81
83
|
|
82
84
|
sz = nul_pos - @position
|
data/lib/postgres-pr/message.rb
CHANGED
@@ -5,7 +5,23 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
require 'buffer'
|
8
|
-
|
8
|
+
class IO
|
9
|
+
def read_exactly_n_bytes(n)
|
10
|
+
buf = read(n)
|
11
|
+
raise EOFError if buf == nil
|
12
|
+
return buf if buf.size == n
|
13
|
+
|
14
|
+
n -= buf.size
|
15
|
+
|
16
|
+
while n > 0
|
17
|
+
str = read(n)
|
18
|
+
raise EOFError if str == nil
|
19
|
+
buf << str
|
20
|
+
n -= str.size
|
21
|
+
end
|
22
|
+
return buf
|
23
|
+
end
|
24
|
+
end
|
9
25
|
|
10
26
|
module PostgresPR
|
11
27
|
|
@@ -19,8 +35,7 @@ class Message
|
|
19
35
|
MsgTypeMap = Hash.new { UnknownMessageType }
|
20
36
|
|
21
37
|
def self.register_message_type(type)
|
22
|
-
raise
|
23
|
-
raise "duplicate message type registration" if MsgTypeMap.has_key? type
|
38
|
+
raise "duplicate message type registration" if MsgTypeMap.has_key?(type)
|
24
39
|
|
25
40
|
MsgTypeMap[type] = self
|
26
41
|
|
@@ -29,14 +44,14 @@ class Message
|
|
29
44
|
end
|
30
45
|
|
31
46
|
def self.read(stream, startup=false)
|
32
|
-
type = stream.
|
33
|
-
length = stream.
|
47
|
+
type = stream.read_exactly_n_bytes(1) unless startup
|
48
|
+
length = stream.read_exactly_n_bytes(4).unpack('N').first # FIXME: length should be signed, not unsigned
|
34
49
|
|
35
50
|
raise ParseError unless length >= 4
|
36
51
|
|
37
52
|
# initialize buffer
|
38
53
|
buffer = Buffer.of_size(startup ? length : 1+length)
|
39
|
-
buffer.
|
54
|
+
buffer.write(type) unless startup
|
40
55
|
buffer.write_int32_network(length)
|
41
56
|
buffer.copy_from_stream(stream, length-4)
|
42
57
|
|
@@ -55,7 +70,7 @@ class Message
|
|
55
70
|
|
56
71
|
def dump(body_size=0)
|
57
72
|
buffer = Buffer.of_size(5 + body_size)
|
58
|
-
buffer.
|
73
|
+
buffer.write(self.message_type)
|
59
74
|
buffer.write_int32_network(4 + body_size)
|
60
75
|
yield buffer if block_given?
|
61
76
|
raise DumpError unless buffer.at_end?
|
@@ -89,7 +104,7 @@ class UnknownMessageType < Message
|
|
89
104
|
end
|
90
105
|
|
91
106
|
class Authentification < Message
|
92
|
-
register_message_type
|
107
|
+
register_message_type 'R'
|
93
108
|
|
94
109
|
AuthTypeMap = Hash.new { UnknownAuthType }
|
95
110
|
|
@@ -187,7 +202,7 @@ class AuthentificationSCMCredential < Authentification
|
|
187
202
|
end
|
188
203
|
|
189
204
|
class PasswordMessage < Message
|
190
|
-
register_message_type
|
205
|
+
register_message_type 'p'
|
191
206
|
fields :password
|
192
207
|
|
193
208
|
def dump
|
@@ -204,7 +219,7 @@ class PasswordMessage < Message
|
|
204
219
|
end
|
205
220
|
|
206
221
|
class ParameterStatus < Message
|
207
|
-
register_message_type
|
222
|
+
register_message_type 'S'
|
208
223
|
fields :key, :value
|
209
224
|
|
210
225
|
def dump
|
@@ -223,7 +238,7 @@ class ParameterStatus < Message
|
|
223
238
|
end
|
224
239
|
|
225
240
|
class BackendKeyData < Message
|
226
|
-
register_message_type
|
241
|
+
register_message_type 'K'
|
227
242
|
fields :process_id, :secret_key
|
228
243
|
|
229
244
|
def dump
|
@@ -242,7 +257,7 @@ class BackendKeyData < Message
|
|
242
257
|
end
|
243
258
|
|
244
259
|
class ReadyForQuery < Message
|
245
|
-
register_message_type
|
260
|
+
register_message_type 'Z'
|
246
261
|
fields :backend_transaction_status_indicator
|
247
262
|
|
248
263
|
def dump
|
@@ -259,7 +274,7 @@ class ReadyForQuery < Message
|
|
259
274
|
end
|
260
275
|
|
261
276
|
class DataRow < Message
|
262
|
-
register_message_type
|
277
|
+
register_message_type 'D'
|
263
278
|
fields :columns
|
264
279
|
|
265
280
|
def dump
|
@@ -289,7 +304,7 @@ class DataRow < Message
|
|
289
304
|
end
|
290
305
|
|
291
306
|
class CommandComplete < Message
|
292
|
-
register_message_type
|
307
|
+
register_message_type 'C'
|
293
308
|
fields :cmd_tag
|
294
309
|
|
295
310
|
def dump
|
@@ -306,7 +321,7 @@ class CommandComplete < Message
|
|
306
321
|
end
|
307
322
|
|
308
323
|
class EmptyQueryResponse < Message
|
309
|
-
register_message_type
|
324
|
+
register_message_type 'I'
|
310
325
|
end
|
311
326
|
|
312
327
|
module NoticeErrorMixin
|
@@ -346,27 +361,27 @@ module NoticeErrorMixin
|
|
346
361
|
end
|
347
362
|
|
348
363
|
class NoticeResponse < Message
|
349
|
-
register_message_type
|
364
|
+
register_message_type 'N'
|
350
365
|
include NoticeErrorMixin
|
351
366
|
end
|
352
367
|
|
353
368
|
class ErrorResponse < Message
|
354
|
-
register_message_type
|
369
|
+
register_message_type 'E'
|
355
370
|
include NoticeErrorMixin
|
356
371
|
end
|
357
372
|
|
358
373
|
# TODO
|
359
374
|
class CopyInResponse < Message
|
360
|
-
register_message_type
|
375
|
+
register_message_type 'G'
|
361
376
|
end
|
362
377
|
|
363
378
|
# TODO
|
364
379
|
class CopyOutResponse < Message
|
365
|
-
register_message_type
|
380
|
+
register_message_type 'H'
|
366
381
|
end
|
367
382
|
|
368
383
|
class Parse < Message
|
369
|
-
register_message_type
|
384
|
+
register_message_type 'P'
|
370
385
|
fields :query, :stmt_name, :parameter_oids
|
371
386
|
|
372
387
|
def initialize(query, stmt_name="", parameter_oids=[])
|
@@ -397,11 +412,11 @@ class Parse < Message
|
|
397
412
|
end
|
398
413
|
|
399
414
|
class ParseComplete < Message
|
400
|
-
register_message_type
|
415
|
+
register_message_type '1'
|
401
416
|
end
|
402
417
|
|
403
418
|
class Query < Message
|
404
|
-
register_message_type
|
419
|
+
register_message_type 'Q'
|
405
420
|
fields :query
|
406
421
|
|
407
422
|
def dump
|
@@ -418,7 +433,7 @@ class Query < Message
|
|
418
433
|
end
|
419
434
|
|
420
435
|
class RowDescription < Message
|
421
|
-
register_message_type
|
436
|
+
register_message_type 'T'
|
422
437
|
fields :fields
|
423
438
|
|
424
439
|
class FieldInfo < Struct.new(:name, :oid, :attr_nr, :type_oid, :typlen, :atttypmod, :formatcode); end
|
@@ -516,12 +531,12 @@ end
|
|
516
531
|
=begin
|
517
532
|
# TODO: duplicate message-type, split into client/server messages
|
518
533
|
class Sync < Message
|
519
|
-
register_message_type
|
534
|
+
register_message_type 'S'
|
520
535
|
end
|
521
536
|
=end
|
522
537
|
|
523
538
|
class Terminate < Message
|
524
|
-
register_message_type
|
539
|
+
register_message_type 'X'
|
525
540
|
end
|
526
541
|
|
527
542
|
end # module PostgresPR
|
data/lib/postgres-pr/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgres-pr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Neumann
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-26 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|