ahamid-postgres-pr 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+