ahamid-postgres-pr 0.6.1

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.
@@ -0,0 +1,146 @@
1
+ # This is a compatibility layer for using the pure Ruby postgres-pr instead of
2
+ # the C interface of postgres.
3
+
4
+ require 'postgres-pr/connection'
5
+
6
+ class PGconn
7
+ class << self
8
+ alias connect new
9
+
10
+ def quote_ident(name)
11
+ %("#{name}")
12
+ end
13
+ end
14
+
15
+ def initialize(host, port, options, tty, database, user, auth)
16
+ uri =
17
+ if host.nil?
18
+ nil
19
+ elsif host[0] != ?/
20
+ "tcp://#{ host }:#{ port }"
21
+ else
22
+ "unix:#{ host }/.s.PGSQL.#{ port }"
23
+ end
24
+ @host = host
25
+ @db = database
26
+ @user = user
27
+ @conn = PostgresPR::Connection.new(database, user, auth, uri)
28
+ end
29
+
30
+
31
+ def close
32
+ @conn.close
33
+ end
34
+
35
+ attr_reader :host, :db, :user
36
+
37
+ def query(sql)
38
+ PGresult.new(@conn.query(sql))
39
+ end
40
+
41
+ alias exec query
42
+
43
+ def transaction_status
44
+ @conn.transaction_status
45
+ end
46
+
47
+ def self.escape(str)
48
+ str.gsub("'","''").gsub("\\", "\\\\\\\\")
49
+ end
50
+
51
+ end
52
+
53
+ class PGresult
54
+ include Enumerable
55
+
56
+ EMPTY_QUERY = 0
57
+ COMMAND_OK = 1
58
+ TUPLES_OK = 2
59
+ COPY_OUT = 3
60
+ COPY_IN = 4
61
+ BAD_RESPONSE = 5
62
+ NONFATAL_ERROR = 6
63
+ FATAL_ERROR = 7
64
+
65
+ def each(&block)
66
+ @result.each(&block)
67
+ end
68
+
69
+ def [](index)
70
+ @result[index]
71
+ end
72
+
73
+ def initialize(res)
74
+ @res = res
75
+ @fields = @res.fields.map {|f| f.name}
76
+ @result = @res.rows
77
+ end
78
+
79
+ # TODO: status, getlength, cmdstatus
80
+
81
+ attr_reader :result, :fields
82
+
83
+ def num_tuples
84
+ @result.size
85
+ end
86
+
87
+ def num_fields
88
+ @fields.size
89
+ end
90
+
91
+ def fieldname(index)
92
+ @fields[index]
93
+ end
94
+
95
+ def fieldnum(name)
96
+ @fields.index(name)
97
+ end
98
+
99
+ def type(index)
100
+ # TODO: correct?
101
+ @res.fields[index].type_oid
102
+ end
103
+
104
+ def size(index)
105
+ raise
106
+ # TODO: correct?
107
+ @res.fields[index].typlen
108
+ end
109
+
110
+ def getvalue(tup_num, field_num)
111
+ @result[tup_num][field_num]
112
+ end
113
+
114
+ def status
115
+ if num_tuples > 0
116
+ TUPLES_OK
117
+ else
118
+ COMMAND_OK
119
+ end
120
+ end
121
+
122
+ def cmdstatus
123
+ @res.cmd_tag || ''
124
+ end
125
+
126
+ # free the result set
127
+ def clear
128
+ @res = @fields = @result = nil
129
+ end
130
+
131
+ # Returns the number of rows affected by the SQL command
132
+ def cmdtuples
133
+ case @res.cmd_tag
134
+ when nil
135
+ return nil
136
+ when /^INSERT\s+(\d+)\s+(\d+)$/, /^(DELETE|UPDATE|MOVE|FETCH)\s+(\d+)$/
137
+ $2.to_i
138
+ else
139
+ nil
140
+ end
141
+ end
142
+
143
+ end
144
+
145
+ class PGError < Exception
146
+ end
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require 'conv'
3
+ require 'array'
4
+ require 'bytea'
5
+
6
+ class TC_Conversion < Test::Unit::TestCase
7
+ def test_decode_array
8
+ assert_equal ["abcdef ", "hallo", ["1", "2"]], decode_array("{ abcdef , hallo, { 1, 2} }")
9
+ assert_equal [""], decode_array("{ }") # TODO: Correct?
10
+ assert_equal [], decode_array("{}")
11
+ assert_equal ["hallo", ""], decode_array("{hallo,}")
12
+ end
13
+
14
+ def test_bytea
15
+ end
16
+
17
+ include Postgres::Conversion
18
+ end
@@ -0,0 +1,46 @@
1
+ require 'strscan'
2
+
3
+ module Postgres::Conversion
4
+
5
+ def decode_array(str, delim=',', &conv_proc)
6
+ delim = Regexp.escape(delim)
7
+ buf = StringScanner.new(str)
8
+ return parse_arr(buf, delim, &conv_proc)
9
+ ensure
10
+ raise ConversionError, "end of string expected (#{buf.rest})" unless buf.empty?
11
+ end
12
+
13
+ private
14
+
15
+ def parse_arr(buf, delim, &conv_proc)
16
+ # skip whitespace
17
+ buf.skip(/\s*/)
18
+
19
+ raise ConversionError, "'{' expected" unless buf.get_byte == '{'
20
+
21
+ elems = []
22
+ unless buf.scan(/\}/) # array is not empty
23
+ loop do
24
+ # skip whitespace
25
+ buf.skip(/\s+/)
26
+
27
+ elems <<
28
+ if buf.check(/\{/)
29
+ parse_arr(buf, delim, &conv_proc)
30
+ else
31
+ e = buf.scan(/("((\\.)|[^"])*"|\\.|[^\}#{ delim }])*/) || raise(ConversionError)
32
+ if conv_proc then conv_proc.call(e) else e end
33
+ end
34
+
35
+ break if buf.scan(/\}/)
36
+ break unless buf.scan(/#{ delim }/)
37
+ end
38
+ end
39
+
40
+ # skip whitespace
41
+ buf.skip(/\s*/)
42
+
43
+ elems
44
+ end
45
+
46
+ end
@@ -0,0 +1,26 @@
1
+ module Postgres::Conversion
2
+
3
+ #
4
+ # Encodes a string as bytea value.
5
+ #
6
+ # for encoding rules see:
7
+ # http://www.postgresql.org/docs/7.4/static/datatype-binary.html
8
+ #
9
+
10
+ def encode_bytea(str)
11
+ str.gsub(/[\000-\037\047\134\177-\377]/) {|b| "\\#{ b[0].to_s(8).rjust(3, '0') }" }
12
+ end
13
+
14
+ #
15
+ # Decodes a bytea encoded string.
16
+ #
17
+ # for decoding rules see:
18
+ # http://www.postgresql.org/docs/7.4/static/datatype-binary.html
19
+ #
20
+ def decode_bytea(str)
21
+ str.gsub(/\\(\\|'|[0-3][0-7][0-7])/) {|s|
22
+ if s.size == 2 then s[1,1] else s[1,3].oct.chr end
23
+ }
24
+ end
25
+
26
+ end
@@ -0,0 +1,5 @@
1
+ module Postgres
2
+ module Conversion
3
+ class ConversionError < Exception; end
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module PostgresPR
2
+ Version = "0.6.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ # This is a compatibility layer for using the pure Ruby postgres-pr instead of
2
+ # the C interface of postgres.
3
+
4
+ begin
5
+ require 'postgres.so'
6
+ rescue LoadError
7
+ require 'postgres-pr/postgres-compat'
8
+ end
@@ -0,0 +1,103 @@
1
+ require 'test/unit'
2
+ require 'stringio'
3
+
4
+ class Module
5
+ def attr_accessor(*attrs)
6
+ @@attrs = [] unless defined?(@@attrs)
7
+ @@attrs += attrs
8
+
9
+ x = @@attrs.map {|a| "self.#{a} == o.#{a}"}.join(" && ")
10
+ class_eval %{
11
+ def ==(o)
12
+ #{ x }
13
+ end
14
+ }
15
+
16
+ @@attrs.each do |a|
17
+ class_eval %{
18
+ def #{a}() @#{a} end
19
+ def #{a}=(v) @#{a}=v end
20
+ }
21
+ end
22
+ end
23
+ end
24
+
25
+ $LOAD_PATH.unshift '../lib'
26
+ require 'postgres-pr/message'
27
+ include PostgresPR
28
+
29
+ class Buffer
30
+ alias old_content content
31
+ def content
32
+ self
33
+ end
34
+ end
35
+
36
+ class Message
37
+ attr_accessor :buffer
38
+
39
+ class << self
40
+ alias old_create create
41
+ def create(buffer)
42
+ obj = old_create(buffer)
43
+ obj.buffer = buffer
44
+ obj
45
+ end
46
+ end
47
+
48
+ alias old_dump dump
49
+
50
+ def dump(body_size=0, &block)
51
+ buf = old_dump(body_size, &block)
52
+ self.buffer = buf
53
+ buf.old_content
54
+ end
55
+ end
56
+
57
+ class StartupMessage
58
+ alias old_dump dump
59
+ def dump
60
+ buf = old_dump
61
+ self.buffer = buf
62
+ buf.old_content
63
+ end
64
+ end
65
+
66
+ class StringIO
67
+ alias readbytes read
68
+ end
69
+
70
+ class TC_Message < Test::Unit::TestCase
71
+
72
+ CASES = [
73
+ #[AuthentificationOk],
74
+ #[ErrorResponse],
75
+ [ParameterStatus, "key", "value"],
76
+ [BackendKeyData, 234234234, 213434],
77
+ [ReadyForQuery, ?T],
78
+ # TODO: RowDescription
79
+ [DataRow, ["a", "bbbbbb", "ccc", nil, nil, "ddddd", "e" * 10_000]],
80
+ [DataRow, []],
81
+ [CommandComplete, "INSERT"],
82
+ [StartupMessage, 196608, {"user" => "mneumann", "database" => "mneumann"}],
83
+ [Parse, "INSERT INTO blah values (?, ?)", ""],
84
+ [Query, "SELECT * FROM test\nWHERE a='test'"]
85
+ ]
86
+
87
+ def test_pack_unpack_feature
88
+ assert_equal ['a', 'b'], "a\000b\000".unpack('Z*Z*')
89
+ end
90
+
91
+ def test_marshal_unmarshal
92
+ CASES.each do |klass, *params|
93
+ msg = klass.new(*params)
94
+ new_msg = Message.read(StringIO.new(msg.dump), klass == StartupMessage)
95
+ assert_equal(msg, new_msg)
96
+
97
+ msg1, msg2 = klass.new(*params), klass.new(*params)
98
+ msg1.dump
99
+ msg2.dump; msg2.parse(msg2.buffer)
100
+ assert_equal(msg1, msg2)
101
+ end
102
+ end
103
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ahamid-postgres-pr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Neumann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-15 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: mneumann@ntecs.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/binary_reader.rb
26
+ - lib/binary_writer.rb
27
+ - lib/buffer.rb
28
+ - lib/byteorder.rb
29
+ - lib/postgres-pr/connection.rb
30
+ - lib/postgres-pr/message.rb
31
+ - lib/postgres-pr/postgres-compat.rb
32
+ - lib/postgres-pr/typeconv/array.rb
33
+ - lib/postgres-pr/typeconv/bytea.rb
34
+ - lib/postgres-pr/typeconv/conv.rb
35
+ - lib/postgres-pr/typeconv/TC_conv.rb
36
+ - lib/postgres-pr/version.rb
37
+ - lib/postgres.rb
38
+ - test/TC_message.rb
39
+ - examples/client.rb
40
+ - examples/og/test.rb
41
+ - examples/server.rb
42
+ - examples/test_connection.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/ahamid/postgres-pr
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements:
65
+ - PostgreSQL >= 7.4
66
+ rubyforge_project: postgres-pr
67
+ rubygems_version: 1.3.5
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: A pure Ruby interface to the PostgreSQL (>= 7.4) database
71
+ test_files: []
72
+