postgres_ext 0.3.1 → 0.4.0

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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +15 -5
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +2 -2
  5. data/README.md +4 -0
  6. data/docs/type_casting.md +19 -0
  7. data/lib/postgres_ext/active_record/connection_adapters/postgres_adapter.rb +149 -3
  8. data/lib/postgres_ext/active_record/relation/predicate_builder.rb +1 -1
  9. data/lib/postgres_ext/version.rb +1 -1
  10. data/spec/columns/array_spec.rb +3 -4
  11. data/spec/columns/ranges/daterange_spec.rb +37 -0
  12. data/spec/columns/ranges/int4range_spec.rb +38 -0
  13. data/spec/columns/ranges/int8range_spec.rb +38 -0
  14. data/spec/columns/ranges/numrange_spec.rb +37 -0
  15. data/spec/columns/ranges/tsrange_spec.rb +37 -0
  16. data/spec/dummy/app/models/person.rb +1 -1
  17. data/spec/dummy/config/application.rb +1 -1
  18. data/spec/dummy/db/migrate/20120501163758_create_people.rb +1 -0
  19. data/spec/dummy/db/schema.rb +9 -8
  20. data/spec/migrations/array_spec.rb +20 -0
  21. data/spec/migrations/ranges/daterange_spec.rb +27 -0
  22. data/spec/migrations/ranges/int4range_spec.rb +27 -0
  23. data/spec/migrations/ranges/int8range_spec.rb +27 -0
  24. data/spec/migrations/ranges/numrange_spec.rb +27 -0
  25. data/spec/migrations/ranges/tsrange_spec.rb +27 -0
  26. data/spec/migrations/ranges/tstzrange_spec.rb +27 -0
  27. data/spec/models/ranges/daterange_spec.rb +88 -0
  28. data/spec/models/ranges/int4range_spec.rb +85 -0
  29. data/spec/models/ranges/int8range_spec.rb +85 -0
  30. data/spec/models/ranges/numrange_spec.rb +85 -0
  31. data/spec/models/ranges/tsrange_spec.rb +89 -0
  32. data/spec/models/ranges/tstzrange_spec.rb +89 -0
  33. data/spec/queries/sanity_spec.rb +1 -0
  34. data/spec/schema_dumper/array_spec.rb +1 -1
  35. data/spec/schema_dumper/ranges/daterange_spec.rb +18 -0
  36. data/spec/schema_dumper/ranges/int4range_spec.rb +18 -0
  37. data/spec/schema_dumper/ranges/int8range_spec.rb +18 -0
  38. data/spec/schema_dumper/ranges/numrange_spec.rb +18 -0
  39. data/spec/schema_dumper/ranges/tsrange_spec.rb +18 -0
  40. data/spec/schema_dumper/ranges/tstzrange_spec.rb +17 -0
  41. metadata +53 -27
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Models with int4range range columns' do
4
+ let!(:adapter) { ActiveRecord::Base.connection }
5
+
6
+ context 'no default value, range' do
7
+ before do
8
+ adapter.create_table :int4_rangers, :force => true do |t|
9
+ t.int4range :best_estimate
10
+ end
11
+ class Int4Ranger < ActiveRecord::Base
12
+ attr_accessible :best_estimate
13
+ end
14
+ end
15
+
16
+ after do
17
+ adapter.drop_table :int4_rangers
18
+ Object.send(:remove_const, :Int4Ranger)
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'creates an record when there is no assignment' do
23
+ range = Int4Ranger.create()
24
+ range.reload
25
+ range.best_estimate.should eq nil
26
+ end
27
+
28
+ it 'creates an record with a range' do
29
+ range = Int4Ranger.create( :best_estimate => 0..4)
30
+ range.reload
31
+ range.best_estimate.should eq 0...5
32
+ end
33
+ end
34
+
35
+ describe 'range assignment' do
36
+ it 'updates an record with an range string' do
37
+ range = Int4Ranger.create( :best_estimate => 0..4)
38
+ range.best_estimate = 0...9
39
+ range.save
40
+
41
+ range.reload
42
+ range.best_estimate.should eq 0...9
43
+ end
44
+
45
+ it 'converts empty strings to nil' do
46
+ range = Int4Ranger.create
47
+ range.best_estimate = ''
48
+ range.save
49
+
50
+ range.reload
51
+ range.best_estimate.should eq nil
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'default value, int4 range' do
57
+ before do
58
+ adapter.create_table :int4_default_rangers, :force => true do |t|
59
+ t.int4range :best_estimate, :default => 0..5
60
+ end
61
+ class Int4DefaultRanger < ActiveRecord::Base
62
+ attr_accessible :best_estimate
63
+ end
64
+ end
65
+
66
+ after do
67
+ adapter.drop_table :int4_default_rangers
68
+ Object.send(:remove_const, :Int4DefaultRanger)
69
+ end
70
+
71
+ describe '#create' do
72
+ it 'creates an record when there is no assignment' do
73
+ range = Int4DefaultRanger.create()
74
+ range.reload
75
+ range.best_estimate.should eq 0...6
76
+ end
77
+
78
+ it 'creates an record with a range' do
79
+ range = Int4DefaultRanger.create( :best_estimate => 0..4)
80
+ range.reload
81
+ range.best_estimate.should eq 0...5
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Models with int8range columns' do
4
+ let!(:adapter) { ActiveRecord::Base.connection }
5
+
6
+ context 'no default value, range' do
7
+ before do
8
+ adapter.create_table :int8_rangers, :force => true do |t|
9
+ t.int8range :best_estimate
10
+ end
11
+ class Int8Ranger < ActiveRecord::Base
12
+ attr_accessible :best_estimate
13
+ end
14
+ end
15
+
16
+ after do
17
+ adapter.drop_table :int8_rangers
18
+ Object.send(:remove_const, :Int8Ranger)
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'creates an record when there is no assignment' do
23
+ range = Int8Ranger.create()
24
+ range.reload
25
+ range.best_estimate.should eq nil
26
+ end
27
+
28
+ it 'creates an record with a range' do
29
+ range = Int8Ranger.create( :best_estimate => 0..4)
30
+ range.reload
31
+ range.best_estimate.should eq 0...5
32
+ end
33
+ end
34
+
35
+ describe 'range assignment' do
36
+ it 'updates an record with an range string' do
37
+ range = Int8Ranger.create( :best_estimate => 0..4)
38
+ range.best_estimate = 0...9
39
+ range.save
40
+
41
+ range.reload
42
+ range.best_estimate.should eq 0...9
43
+ end
44
+
45
+ it 'converts empty strings to nil' do
46
+ range = Int8Ranger.create
47
+ range.best_estimate = ''
48
+ range.save
49
+
50
+ range.reload
51
+ range.best_estimate.should eq nil
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'default value, int8 range' do
57
+ before do
58
+ adapter.create_table :int8_default_rangers, :force => true do |t|
59
+ t.int8range :best_estimate, :default => 0..5
60
+ end
61
+ class Int8DefaultRanger < ActiveRecord::Base
62
+ attr_accessible :best_estimate
63
+ end
64
+ end
65
+
66
+ after do
67
+ adapter.drop_table :int8_default_rangers
68
+ Object.send(:remove_const, :Int8DefaultRanger)
69
+ end
70
+
71
+ describe '#create' do
72
+ it 'creates an record when there is no assignment' do
73
+ range = Int8DefaultRanger.create()
74
+ range.reload
75
+ range.best_estimate.should eq 0...6
76
+ end
77
+
78
+ it 'creates an record with a range' do
79
+ range = Int8DefaultRanger.create( :best_estimate => 0..4)
80
+ range.reload
81
+ range.best_estimate.should eq 0...5
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Models with numeric range columns' do
4
+ let!(:adapter) { ActiveRecord::Base.connection }
5
+
6
+ context 'no default value, range' do
7
+ before do
8
+ adapter.create_table :rangers, :force => true do |t|
9
+ t.numrange :best_estimate
10
+ end
11
+ class Ranger < ActiveRecord::Base
12
+ attr_accessible :best_estimate
13
+ end
14
+ end
15
+
16
+ after do
17
+ adapter.drop_table :rangers
18
+ Object.send(:remove_const, :Ranger)
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'creates an record when there is no assignment' do
23
+ range = Ranger.create()
24
+ range.reload
25
+ range.best_estimate.should eq nil
26
+ end
27
+
28
+ it 'creates an record with a range' do
29
+ range = Ranger.create( :best_estimate => 0..4)
30
+ range.reload
31
+ range.best_estimate.should eq 0..4
32
+ end
33
+ end
34
+
35
+ describe 'range assignment' do
36
+ it 'updates an record with an range string' do
37
+ range = Ranger.create( :best_estimate => 0..4)
38
+ range.best_estimate = 0...9
39
+ range.save
40
+
41
+ range.reload
42
+ range.best_estimate.should eq 0...9
43
+ end
44
+
45
+ it 'converts empty strings to nil' do
46
+ range = Ranger.create
47
+ range.best_estimate = ''
48
+ range.save
49
+
50
+ range.reload
51
+ range.best_estimate.should eq nil
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'default value, numeric range' do
57
+ before do
58
+ adapter.create_table :default_rangers, :force => true do |t|
59
+ t.numrange :best_estimate, :default => 0..5
60
+ end
61
+ class DefaultRanger < ActiveRecord::Base
62
+ attr_accessible :best_estimate
63
+ end
64
+ end
65
+
66
+ after do
67
+ adapter.drop_table :default_rangers
68
+ Object.send(:remove_const, :DefaultRanger)
69
+ end
70
+
71
+ describe '#create' do
72
+ it 'creates an record when there is no assignment' do
73
+ range = DefaultRanger.create()
74
+ range.reload
75
+ range.best_estimate.should eq 0..5
76
+ end
77
+
78
+ it 'creates an record with a range' do
79
+ range = DefaultRanger.create( :best_estimate => 0..4)
80
+ range.reload
81
+ range.best_estimate.should eq 0..4
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Models with tsrange columns' do
4
+ let!(:adapter) { ActiveRecord::Base.connection }
5
+
6
+ context 'no default value, range' do
7
+ before do
8
+ adapter.create_table :ts_rangers, :force => true do |t|
9
+ t.tsrange :best_estimate
10
+ end
11
+ class TsRanger < ActiveRecord::Base
12
+ attr_accessible :best_estimate
13
+ end
14
+ end
15
+
16
+ after do
17
+ adapter.drop_table :ts_rangers
18
+ Object.send(:remove_const, :TsRanger)
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'creates an record when there is no assignment' do
23
+ range = TsRanger.create()
24
+ range.reload
25
+ range.best_estimate.should eq nil
26
+ end
27
+
28
+ it 'creates an record with a range' do
29
+ ts_range = Time.new(2011, 01, 01, 12, 34)..Time.new(2012, 01, 31, 8, 0, 1)
30
+ range = TsRanger.create( :best_estimate => ts_range)
31
+ range.reload
32
+ range.best_estimate.should eq ts_range
33
+ end
34
+ end
35
+
36
+ describe 'range assignment' do
37
+ it 'updates an record with an range string' do
38
+ ts_range = Time.new(2011, 01, 01, 12, 34)..Time.new(2012, 01, 31, 8, 0, 1)
39
+ new_ts_range = Time.new(2012, 01, 01, 11, 0, 0)..Time.new(2012, 02, 01, 13, 0, 0)
40
+ range = TsRanger.create( :best_estimate => ts_range)
41
+ range.best_estimate = new_ts_range
42
+ range.save
43
+
44
+ range.reload
45
+ range.best_estimate.should eq new_ts_range
46
+ end
47
+
48
+ it 'converdate empty strings to nil' do
49
+ range = TsRanger.create
50
+ range.best_estimate = ''
51
+ range.save
52
+
53
+ range.reload
54
+ range.best_estimate.should eq nil
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'default value, ts range' do
60
+ before do
61
+ adapter.create_table :ts_default_rangers, :force => true do |t|
62
+ t.tsrange :best_estimate, :default => Time.new(2011, 01, 01, 12, 34)..Time.new(2011, 01, 31, 1, 0)
63
+ end
64
+ class TsDefaultRanger < ActiveRecord::Base
65
+ attr_accessible :best_estimate
66
+ end
67
+ end
68
+
69
+ after do
70
+ adapter.drop_table :ts_default_rangers
71
+ Object.send(:remove_const, :TsDefaultRanger)
72
+ end
73
+
74
+ describe '#create' do
75
+ it 'creates an record when there is no assignment' do
76
+ range = TsDefaultRanger.create()
77
+ range.reload
78
+ range.best_estimate.should eq Time.new(2011, 01, 01, 12, 34)..Time.new(2011, 01, 31, 1, 0)
79
+ end
80
+
81
+ it 'creates an record with a range' do
82
+ new_ts_range = Time.new(2012, 01, 01, 9, 0, 0)..Time.new(2012, 12, 31, 9, 0, 0)
83
+ range = TsDefaultRanger.create(:best_estimate => new_ts_range)
84
+ range.reload
85
+ range.best_estimate.should eq new_ts_range
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Models with tstzrange columns' do
4
+ let!(:adapter) { ActiveRecord::Base.connection }
5
+
6
+ context 'no default value, range' do
7
+ before do
8
+ adapter.create_table :tstz_rangers, :force => true do |t|
9
+ t.tstzrange :best_estimate
10
+ end
11
+ class TstzRanger < ActiveRecord::Base
12
+ attr_accessible :best_estimate
13
+ end
14
+ end
15
+
16
+ after do
17
+ adapter.drop_table :tstz_rangers
18
+ Object.send(:remove_const, :TstzRanger)
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'creates an record when there is no assignment' do
23
+ range = TstzRanger.create()
24
+ range.reload
25
+ range.best_estimate.should eq nil
26
+ end
27
+
28
+ it 'creates an record with a range' do
29
+ ts_range = Time.new(2011, 01, 01, 12, 34)..Time.new(2012, 01, 31, 8, 0, 1)
30
+ range = TstzRanger.create( :best_estimate => ts_range)
31
+ range.reload
32
+ range.best_estimate.should eq ts_range
33
+ end
34
+ end
35
+
36
+ describe 'range assignment' do
37
+ it 'updates an record with an range string' do
38
+ ts_range = Time.new(2011, 01, 01, 12, 34)..Time.new(2012, 01, 31, 8, 0, 1)
39
+ new_ts_range = Time.new(2012, 01, 01, 11, 0, 0)..Time.new(2012, 02, 01, 13, 0, 0)
40
+ range = TstzRanger.create( :best_estimate => ts_range)
41
+ range.best_estimate = new_ts_range
42
+ range.save
43
+
44
+ range.reload
45
+ range.best_estimate.should eq new_ts_range
46
+ end
47
+
48
+ it 'converdate empty strings to nil' do
49
+ range = TstzRanger.create
50
+ range.best_estimate = ''
51
+ range.save
52
+
53
+ range.reload
54
+ range.best_estimate.should eq nil
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'default value, ts range' do
60
+ before do
61
+ adapter.create_table :tstz_default_rangers, :force => true do |t|
62
+ t.tstzrange :best_estimate, :default => Time.new(2011, 01, 01, 12, 34, 0, '-07:00')..Time.new(2011, 01, 31, 1, 0, 0, '-07:00')
63
+ end
64
+ class TstzDefaultRanger < ActiveRecord::Base
65
+ attr_accessible :best_estimate
66
+ end
67
+ end
68
+
69
+ after do
70
+ adapter.drop_table :tstz_default_rangers
71
+ Object.send(:remove_const, :TstzDefaultRanger)
72
+ end
73
+
74
+ describe '#create' do
75
+ it 'creates an record when there is no assignment' do
76
+ range = TstzDefaultRanger.create()
77
+ range.reload
78
+ range.best_estimate.should eq Time.new(2011, 01, 01, 12, 34,0, '-07:00')..Time.new(2011, 01, 31, 1, 0, 0, '-07:00')
79
+ end
80
+
81
+ it 'creates an record with a range' do
82
+ new_ts_range = Time.new(2012, 01, 01, 9, 0, 0, '-05:00')..Time.new(2012, 12, 31, 9, 0, 0, '-05:00')
83
+ range = TstzDefaultRanger.create(:best_estimate => new_ts_range)
84
+ range.reload
85
+ range.best_estimate.should eq new_ts_range
86
+ end
87
+ end
88
+ end
89
+ end
@@ -7,6 +7,7 @@ describe 'Ensure that we don\'t stomp on Active Record\'s queries' do
7
7
 
8
8
  query.should match /IN \(1, 2, 3\)/
9
9
  end
10
+
10
11
  it 'generates IN clauses for non array columns' do
11
12
  query = Person.where(:id => []).to_sql
12
13