activerecord-postgres-composite-types 0.2.4 → 0.2.5
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.
- checksums.yaml +4 -4
- data/Gemfile +9 -9
- data/Rakefile +13 -13
- data/VERSION +1 -1
- data/activerecord-postgres-composite-types.gemspec +4 -4
- data/lib/activerecord-postgres-composite-types.rb +5 -5
- data/lib/activerecord-postgres-composite-types/active_record.rb +141 -148
- data/lib/activerecord-postgres-composite-types/active_record_3.rb +86 -86
- data/lib/activerecord-postgres-composite-types/active_record_4.rb +90 -90
- data/lib/activerecord-postgres-composite-types/composite_type_parser.rb +44 -93
- data/lib/activerecord-postgres-composite-types/railtie.rb +6 -6
- data/lib/postgres_composite_type.rb +89 -89
- data/test/composite_types.rb +5 -5
- data/test/helper.rb +4 -4
- data/test/internal/db/schema.rb +16 -16
- data/test/test_composite_type_class.rb +52 -36
- data/test/test_nested_types.rb +34 -16
- data/test/test_postgres_composite_types.rb +44 -44
- metadata +3 -3
data/test/composite_types.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
require 'postgres_composite_type'
|
2
2
|
|
3
3
|
if ActiveRecord::VERSION::MAJOR > 3
|
4
|
-
|
4
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.alias_type 'rgb_color', 'text'
|
5
5
|
end
|
6
6
|
|
7
7
|
class Compfoo < PostgresCompositeType
|
8
|
-
|
8
|
+
register_type :compfoo
|
9
9
|
end
|
10
10
|
|
11
11
|
class MyType < PostgresCompositeType
|
12
|
-
|
12
|
+
register_type :my_type
|
13
13
|
end
|
14
14
|
|
15
15
|
class NestedType < PostgresCompositeType
|
16
|
-
|
16
|
+
register_type :nested_type
|
17
17
|
end
|
18
18
|
|
19
19
|
class NestedNestedType < PostgresCompositeType
|
20
|
-
|
20
|
+
register_type :nested_nested_type
|
21
21
|
end
|
data/test/helper.rb
CHANGED
@@ -30,14 +30,14 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
30
30
|
require 'activerecord-postgres-composite-types'
|
31
31
|
|
32
32
|
ActiveSupport.on_load :active_record do
|
33
|
-
|
33
|
+
require_relative 'composite_types'
|
34
34
|
end
|
35
35
|
|
36
36
|
Combustion.path = 'test/internal'
|
37
37
|
Combustion.initialize! :active_record
|
38
38
|
|
39
39
|
class Test::Unit::TestCase
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def connection
|
41
|
+
ActiveRecord::Base.connection
|
42
|
+
end
|
43
43
|
end
|
data/test/internal/db/schema.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
require "activerecord-postgres-composite-types/active_record"
|
2
2
|
|
3
3
|
ActiveRecord::Schema.define do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
execute "CREATE TYPE compfoo AS (f1 int, f2 text)"
|
5
|
+
execute "CREATE TYPE my_type AS (name varchar, number int, date timestamp)"
|
6
|
+
execute "CREATE DOMAIN rgb_color AS TEXT CHECK(VALUE IN ('red', 'green', 'blue'))"
|
7
|
+
execute "CREATE TYPE nested_type AS (comp compfoo, color rgb_color)"
|
8
|
+
execute "CREATE TYPE nested_nested_type AS (nested nested_type, color rgb_color)"
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
create_table :foos, :id => false do |t|
|
11
|
+
t.column :comp, :compfoo, default: "(0,\"\")"
|
12
|
+
end
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
create_table :bars, :id => false do |t|
|
15
|
+
t.column :nested, :nested_type
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
create_table :bar2s, :id => false do |t|
|
19
|
+
t.column :nested, :nested_nested_type
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
execute "INSERT INTO foos VALUES ((0,'abc')), ((1,'a/b''c\\d e f'))"
|
23
|
+
execute "INSERT INTO bars VALUES (((0,'abc'),'red')), (((1,'cba'),'blue'))"
|
24
24
|
end
|
@@ -2,40 +2,56 @@ require_relative 'helper'
|
|
2
2
|
|
3
3
|
class TestCompositeTypeClass < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
5
|
+
PostgreSQLColumn = ActiveRecord::ConnectionAdapters::PostgreSQLColumn
|
6
|
+
|
7
|
+
should "define accessors" do
|
8
|
+
assert MyType.method_defined?(:name)
|
9
|
+
assert MyType.method_defined?(:name=)
|
10
|
+
assert MyType.method_defined?(:number)
|
11
|
+
assert MyType.method_defined?(:number=)
|
12
|
+
assert MyType.method_defined?(:date)
|
13
|
+
assert MyType.method_defined?(:date=)
|
14
|
+
end
|
15
|
+
|
16
|
+
should "be created by adapter from string" do
|
17
|
+
value = PostgreSQLColumn.string_to_composite_type(MyType, "(text,5,2014-08-27 00:00:00)")
|
18
|
+
assert_equal 'text', value.name
|
19
|
+
assert_equal 5, value.number
|
20
|
+
assert_equal Time.parse('2014-08-27 00:00:00 UTC'), value.date
|
21
|
+
end
|
22
|
+
|
23
|
+
should "accept escaped string" do
|
24
|
+
value = PostgreSQLColumn.string_to_composite_type(MyType, '("text\'s",125,"2014-08-27 10:00:00")')
|
25
|
+
assert_equal "text's", value.name
|
26
|
+
assert_equal 125, value.number
|
27
|
+
assert_equal Time.parse('2014-08-27 10:00:00 UTC'), value.date
|
28
|
+
end
|
29
|
+
|
30
|
+
should "initialize with hash" do
|
31
|
+
value = MyType.new(number: 1, name: 'abc', date: Time.parse('2014-08-27 12:00:00 UTC'))
|
32
|
+
assert_equal 'abc', value.name
|
33
|
+
assert_equal 1, value.number
|
34
|
+
assert_equal Time.parse('2014-08-27 12:00:00 UTC'), value.date
|
35
|
+
end
|
36
|
+
|
37
|
+
should "cast to qouted string" do
|
38
|
+
value = MyType.new(number: 1, name: '"\'a\'bc[]*/\"', date: Time.parse('2014-08-27 12:00:00 UTC'))
|
39
|
+
assert_equal %Q{'("\\\"''a''bc[]*/\\\\\\\"",1,2014-08-27 12:00:00.000000)'}, connection.quote(value)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "parse string and return array" do
|
43
|
+
result = PostgreSQLColumn::CompositeTypeParser.parse_data("(text,5,2014-08-27 00:00:00)")
|
44
|
+
assert_equal ["text", "5", "2014-08-27 00:00:00"], result
|
45
|
+
end
|
46
|
+
|
47
|
+
should "parse string and return array 2" do
|
48
|
+
result = PostgreSQLColumn::CompositeTypeParser.parse_data('(text,5,"(titi,tata)",2014-08-27 00:00:00)')
|
49
|
+
assert_equal ["text", "5", '(titi,tata)', "2014-08-27 00:00:00"], result
|
50
|
+
end
|
51
|
+
|
52
|
+
should "parse string and return array 3" do
|
53
|
+
result = PostgreSQLColumn::CompositeTypeParser.parse_data('(text,5,"(titi,tata,""(tutu""""tata,tete)"")",2014-08-27 00:00:00)')
|
54
|
+
assert_equal ["text", "5", '(titi,tata,"(tutu""tata,tete)")', "2014-08-27 00:00:00"], result
|
55
|
+
end
|
56
|
+
|
41
57
|
end
|
data/test/test_nested_types.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
|
3
3
|
class TestNestedTypes < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
4
|
+
class Bar < ActiveRecord::Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class Bar2 < ActiveRecord::Base
|
8
|
+
end
|
9
|
+
|
10
|
+
should "cast value properly" do
|
11
|
+
bars = Bar.order('(nested).comp.f1').all
|
12
|
+
assert_equal 2, bars.size
|
13
|
+
assert_kind_of NestedType, bars[0].nested
|
14
|
+
assert_equal Compfoo.new([0, 'abc']), bars[0].nested.comp
|
15
|
+
assert_equal 'red', bars[0].nested.color
|
16
|
+
assert_kind_of NestedType, bars[1].nested
|
17
|
+
assert_equal Compfoo.new([1, 'cba']), bars[1].nested.comp
|
18
|
+
assert_equal 'blue', bars[1].nested.color
|
19
|
+
end
|
20
20
|
|
21
21
|
should "insert with nested type" do
|
22
22
|
bar = Bar.new(nested: {comp: Compfoo.new([2, 'bac']), color: 'red'})
|
@@ -44,4 +44,22 @@ class TestNestedTypes < Test::Unit::TestCase
|
|
44
44
|
assert !Bar2.where(nested: NestedNestedType.new(nested: {comp: [1, 'dca'], color: 'red'}, color: 'red')).exists?
|
45
45
|
assert Bar2.where(nested: NestedNestedType.new(nested: {comp: [1, 'dca'], color: 'blue'}, color: 'red')).exists?
|
46
46
|
end
|
47
|
+
|
48
|
+
should "parser should work when nested attribute contains parenthesis" do
|
49
|
+
bar = Bar2.create!(nested: {nested: {comp: [1, 'dc)))a'], color: 'blue'}, color: 'red'})
|
50
|
+
Bar2.all.to_a.last.nested
|
51
|
+
assert true
|
52
|
+
end
|
53
|
+
|
54
|
+
should "parser should work when nested attribute contains double quote" do
|
55
|
+
bar = Bar2.create!(nested: {nested: {comp: [1, "dc\"a"], color: 'blue'}, color: 'blue'})
|
56
|
+
assert_equal 'blue', Bar2.all.to_a.last.nested.color
|
57
|
+
assert_equal 'dc"a', Bar2.all.to_a.last.nested.nested.comp.f2
|
58
|
+
end
|
59
|
+
|
60
|
+
should "parser should work when nested attribute contains backslash" do
|
61
|
+
bar = Bar2.create!(nested: {nested: {comp: [1, "dc\\a"], color: 'blue'}, color: 'green'})
|
62
|
+
assert_equal 'green', Bar2.all.to_a.last.nested.color
|
63
|
+
assert_equal 'dc\\a', Bar2.all.to_a.last.nested.nested.comp.f2
|
64
|
+
end
|
47
65
|
end
|
@@ -1,48 +1,48 @@
|
|
1
1
|
require_relative 'helper'
|
2
2
|
|
3
3
|
class TestPostgresCompositeTypes < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
4
|
+
class Foo < ActiveRecord::Base
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
should "cast value properly" do
|
9
|
+
foos = Foo.all
|
10
|
+
assert_equal 2, foos.size
|
11
|
+
assert_equal 0, foos[0].comp.f1
|
12
|
+
assert_equal "abc", foos[0].comp.f2
|
13
|
+
assert_equal 1, foos[1].comp.f1
|
14
|
+
assert_equal "a/b'c\\d e f", foos[1].comp.f2
|
15
|
+
end
|
16
|
+
|
17
|
+
should "accept composite type in where clausure" do
|
18
|
+
sql = Foo.where(comp: Compfoo.new([123, 'text 1'])).to_sql
|
19
|
+
assert_equal %Q(SELECT "foos".* FROM "foos" WHERE "foos"."comp" = '(123,"text 1")'::compfoo), sql.gsub(/ +/, ' ')
|
20
|
+
end
|
21
|
+
|
22
|
+
should "create new record with compound object" do
|
23
|
+
foo = Foo.create!(comp: Compfoo.new([123, 'text 1']))
|
24
|
+
|
25
|
+
assert_kind_of Compfoo, foo.comp
|
26
|
+
assert_equal 123, foo.comp.f1
|
27
|
+
assert_equal 'text 1', foo.comp.f2
|
28
|
+
assert Foo.where(comp: Compfoo.new([123, 'text 1'])).exists?
|
29
|
+
end
|
30
|
+
|
31
|
+
should "create new record with hash" do
|
32
|
+
foo = Foo.create!(comp: {f1: 321, f2: 'text 2'})
|
33
|
+
|
34
|
+
assert_kind_of Compfoo, foo.comp
|
35
|
+
assert_equal 321, foo.comp.f1
|
36
|
+
assert_equal 'text 2', foo.comp.f2
|
37
|
+
assert Foo.where(comp: Compfoo.new({f1: 321, f2: 'text 2'})).exists?
|
38
|
+
end
|
39
|
+
|
40
|
+
should "create new record with array" do
|
41
|
+
foo = Foo.create!(comp: [111, 'text 3'])
|
42
|
+
|
43
|
+
assert_kind_of Compfoo, foo.comp
|
44
|
+
assert_equal 111, foo.comp.f1
|
45
|
+
assert_equal 'text 3', foo.comp.f2
|
46
|
+
assert Foo.where(comp: Compfoo.new({f1: 111, f2: 'text 3'})).exists?
|
47
|
+
end
|
48
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-postgres-composite-types
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafal Bigaj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11
|
11
|
+
date: 2014-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -202,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
202
|
version: '0'
|
203
203
|
requirements: []
|
204
204
|
rubyforge_project:
|
205
|
-
rubygems_version: 2.4.
|
205
|
+
rubygems_version: 2.4.3
|
206
206
|
signing_key:
|
207
207
|
specification_version: 4
|
208
208
|
summary: ActiveRecord composite types support
|