rdo-postgres 0.0.6 → 0.0.7

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,74 @@
1
+ /*
2
+ * RDO Postgres Driver.
3
+ * Copyright © 2012 Chris Corbyn.
4
+ *
5
+ * See LICENSE file for details.
6
+ */
7
+
8
+ /*
9
+ * Definitions for types taken from postgres/catalog/pg_type.h.
10
+ *
11
+ * Since not all the types we care about have named defines, they exist here.
12
+ */
13
+
14
+ // integers
15
+ #define RDO_PG_INT2OID 21
16
+ #define RDO_PG_INT4OID 23
17
+ #define RDO_PG_INT8OID 20
18
+
19
+ // floats
20
+ #define RDO_PG_FLOAT4OID 700
21
+ #define RDO_PG_FLOAT8OID 701
22
+
23
+ // precision decimals
24
+ #define RDO_PG_NUMERICOID 1700
25
+
26
+ // boolean
27
+ #define RDO_PG_BOOLOID 16
28
+
29
+ // bytea
30
+ #define RDO_PG_BYTEAOID 17
31
+
32
+ // dates
33
+ #define RDO_PG_DATEOID 1082
34
+
35
+ // timestamps
36
+ #define RDO_PG_TIMESTAMPOID 1114
37
+ #define RDO_PG_TIMESTAMPTZOID 1184
38
+
39
+ // text/char
40
+ #define RDO_PG_TEXTOID 25
41
+ #define RDO_PG_CHAROID 18
42
+ #define RDO_PG_VARCHAROID 1043
43
+ #define RDO_PG_BPCHAROID 1042
44
+
45
+ // text[]/char[]
46
+ #define RDO_PG_TEXTARRAYOID 1009
47
+ #define RDO_PG_CHARARRAYOID 1002
48
+ #define RDO_PG_BPCHARARRAYOID 1014
49
+ #define RDO_PG_VARCHARARRAYOID 1015
50
+
51
+ // integer[]
52
+ #define RDO_PG_INT2ARRAYOID 1005
53
+ #define RDO_PG_INT4ARRAYOID 1007
54
+ #define RDO_PG_INT8ARRAYOID 1016
55
+
56
+ // float[]
57
+ #define RDO_PG_FLOAT4ARRAYOID 1021
58
+ #define RDO_PG_FLOAT8ARRAYOID 1022
59
+
60
+ // numeric[]/decimal[]
61
+ #define RDO_PG_NUMERICARRAYOID 1231
62
+
63
+ // boolean[]
64
+ #define RDO_PG_BOOLARRAYOID 1000
65
+
66
+ // bytea[]
67
+ #define RDO_PG_BYTEAARRAYOID 1001
68
+
69
+ // date[]
70
+ #define RDO_PG_DATEARRAYOID 1182
71
+
72
+ // timestamp[]/timestamptz[]
73
+ #define RDO_PG_TIMESTAMPARRAYOID 1115
74
+ #define RDO_PG_TIMESTAMPTZARRAYOID 1185
@@ -6,9 +6,21 @@
6
6
  ##
7
7
 
8
8
  require "rdo"
9
+
9
10
  require "rdo/postgres/version"
10
11
  require "rdo/postgres/driver"
11
12
 
13
+ require "rdo/postgres/array"
14
+ require "rdo/postgres/array/text"
15
+ require "rdo/postgres/array/integer"
16
+ require "rdo/postgres/array/float"
17
+ require "rdo/postgres/array/numeric"
18
+ require "rdo/postgres/array/boolean"
19
+ require "rdo/postgres/array/bytea"
20
+ require "rdo/postgres/array/date"
21
+ require "rdo/postgres/array/timestamp"
22
+ require "rdo/postgres/array/timestamp_tz"
23
+
12
24
  # c extension
13
25
  require "rdo_postgres/rdo_postgres"
14
26
 
@@ -0,0 +1,84 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Utility class used to handle PostgreSQL arrays.
11
+ #
12
+ # The default implementation assumes only String support.
13
+ # Subclasses override #parse_value and #format_value for typed-arrays.
14
+ #
15
+ # @example Turn a Ruby Array into a PostgreSQL array String
16
+ # RDO::Postgres::Array.new(original).to_s
17
+ # # => {"John Smith","Sarah Doe"}
18
+ #
19
+ # @example Turn a PostgreSQL array String into a Ruby Array
20
+ # RDO::Postgres::Array.parse('{"John Smith","Sarah Doe"}').to_a
21
+ # # => ["John Smith", "Sarah Doe"]
22
+ class Array < ::Array
23
+ class << self
24
+ # Read a PostgreSQL array in its string form.
25
+ #
26
+ # @param [String] str
27
+ # an array string from postgresql
28
+ #
29
+ # @return [Array]
30
+ # a Ruby Array for this string
31
+ def parse(str)
32
+ new.tap do |a|
33
+ a.replace(str[1...-1].split(",").map(&a.method(:parse_value_or_null)))
34
+ end
35
+ end
36
+ end
37
+
38
+ # Convert the Array to the format used by PostgreSQL.
39
+ #
40
+ # @return [String]
41
+ # a postgresql array string
42
+ def to_s
43
+ "{#{map(&method(:format_value_or_null)).join(",")}}"
44
+ end
45
+
46
+ # Format an individual element in the Array for building into a String.
47
+ #
48
+ # The default implementation wraps quotes around the element.
49
+ #
50
+ # @param [Object] v
51
+ # the Ruby type in the Array
52
+ #
53
+ # @return [String]
54
+ # a String used to build the formatted array
55
+ def format_value(v)
56
+ %Q{"#{v.to_s.gsub('\\', '\\\\\\\\').gsub('"', '\\\\"')}"}
57
+ end
58
+
59
+ # Parse an individual element from the array.
60
+ #
61
+ # The default implementation parses as if it were text.
62
+ # Subclasses should override this.
63
+ #
64
+ # @param [String] s
65
+ # the string form of the array element
66
+ #
67
+ # @return [Object]
68
+ # the Ruby value
69
+ def parse_value(s)
70
+ s[0] == '"' ? s[1...-1].gsub(/\\(.)/, "\\1") : s
71
+ end
72
+
73
+ private
74
+
75
+ def format_value_or_null(v)
76
+ v.nil? ? "NULL" : format_value(v)
77
+ end
78
+
79
+ def parse_value_or_null(s)
80
+ s == "NULL" ? nil : parse_value(s)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,21 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for boolean[] type in PostgreSQL.
11
+ class Array::Boolean < Array
12
+ def parse_value(s)
13
+ s[0] == "t"
14
+ end
15
+
16
+ def format_value(v)
17
+ (!!v).to_s
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for bytea[] type in PostgreSQL.
11
+ class Array::Bytea < Array
12
+ def parse_value(s)
13
+ # defined in ext/rdo_postgres/arrays.c
14
+ end
15
+
16
+ def format_value(v)
17
+ # defined in ext/rdo_postgres/arrays.c
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,17 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for date[] type in PostgreSQL.
11
+ class Array::Date < Array
12
+ def parse_value(s)
13
+ RDO::Util.date(s)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for float[] type in PostgreSQL.
11
+ class Array::Float < Array
12
+ def parse_value(s)
13
+ case s
14
+ when "Infinity"
15
+ ::Float::INFINITY
16
+ when "-Infinity"
17
+ -::Float::INFINITY
18
+ when "NaN"
19
+ ::Float::NAN
20
+ else
21
+ s.to_f
22
+ end
23
+ end
24
+
25
+ def format_value(v)
26
+ v.to_s
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for integer[] type in PostgreSQL.
11
+ class Array::Integer < Array
12
+ def parse_value(s)
13
+ s.to_i
14
+ end
15
+
16
+ def format_value(v)
17
+ v.to_s
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ require "bigdecimal"
9
+
10
+ module RDO
11
+ module Postgres
12
+ # Ruby handling for numeric[] type in PostgreSQL.
13
+ class Array::Numeric < Array
14
+ def parse_value(s)
15
+ BigDecimal.new(s)
16
+ end
17
+
18
+ def format_value(v)
19
+ v.to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for text[] type in PostgreSQL.
11
+ class Array::Text < Array
12
+ # abstract class behaves as text anyway
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for timestamp[] type in PostgreSQL.
11
+ class Array::Timestamp < Array
12
+ def parse_value(s)
13
+ RDO::Util.date_time_without_zone(s)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # RDO PostgreSQL driver.
3
+ # Copyright © 2012 Chris Corbyn.
4
+ #
5
+ # See LICENSE file for details.
6
+ ##
7
+
8
+ module RDO
9
+ module Postgres
10
+ # Ruby handling for timestamptz[] type in PostgreSQL.
11
+ class Array::TimestampTZ < Array
12
+ def parse_value(s)
13
+ RDO::Util.date_time_with_zone(s)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -7,6 +7,6 @@
7
7
 
8
8
  module RDO
9
9
  module Postgres
10
- VERSION = "0.0.6"
10
+ VERSION = "0.0.7"
11
11
  end
12
12
  end
@@ -0,0 +1,74 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Postgres::Array::Boolean do
4
+ it "is a kind of ::Array" do
5
+ RDO::Postgres::Array::Boolean.new.should be_a_kind_of(::Array)
6
+ end
7
+
8
+ describe "#to_s" do
9
+ context "with an empty array" do
10
+ let(:arr) { RDO::Postgres::Array::Boolean[] }
11
+
12
+ it "returns {}" do
13
+ arr.to_s.should == '{}'
14
+ end
15
+ end
16
+
17
+ context "with an array of Booleans" do
18
+ let(:arr) { RDO::Postgres::Array::Boolean[true, false, false] }
19
+
20
+ it "uses truth literals" do
21
+ arr.to_s.should == '{true,false,false}'
22
+ end
23
+
24
+ context "containing nil" do
25
+ let(:arr) { RDO::Postgres::Array::Boolean[true, nil] }
26
+
27
+ it "uses NULL" do
28
+ arr.to_s.should == '{true,NULL}'
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#to_a" do
35
+ let(:arr) { RDO::Postgres::Array::Bytea["\x00\x11", "\x22\x33", "\x44\x55"] }
36
+
37
+ it "returns a Ruby ::Array" do
38
+ arr.to_a.should == ["\x00\x11", "\x22\x33", "\x44\x55"]
39
+ end
40
+ end
41
+
42
+ describe ".parse" do
43
+ let(:str) { '{}' }
44
+ let(:arr) { RDO::Postgres::Array::Bytea.parse(str) }
45
+
46
+ it "returns a RDO::Postgres::Array::Bytea" do
47
+ arr.should be_a_kind_of(RDO::Postgres::Array::Bytea)
48
+ end
49
+
50
+ context "with an empty array string" do
51
+ let(:str) { '{}' }
52
+
53
+ it "returns an empty Array" do
54
+ arr.should be_empty
55
+ end
56
+ end
57
+
58
+ context "with an array of byteas" do
59
+ let(:str) { '{"\\\\x0011","\\\\x2233"}' }
60
+
61
+ it "returns an Array of Strings" do
62
+ arr.to_a.should == ["\x00\x11", "\x22\x33"]
63
+ end
64
+ end
65
+
66
+ context "with an array containing NULL" do
67
+ let(:str) { '{NULL,NULL,"\\\\x0011"}' }
68
+
69
+ it "uses nil as the value" do
70
+ arr.to_a.should == [nil, nil, "\x00\x11"]
71
+ end
72
+ end
73
+ end
74
+ end