sequel 4.10.0 → 4.11.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +58 -0
  3. data/doc/association_basics.rdoc +1 -1
  4. data/doc/cheat_sheet.rdoc +0 -1
  5. data/doc/core_extensions.rdoc +2 -2
  6. data/doc/dataset_filtering.rdoc +5 -5
  7. data/doc/model_hooks.rdoc +9 -0
  8. data/doc/object_model.rdoc +7 -13
  9. data/doc/opening_databases.rdoc +3 -1
  10. data/doc/querying.rdoc +8 -8
  11. data/doc/release_notes/4.11.0.txt +147 -0
  12. data/doc/sql.rdoc +11 -7
  13. data/doc/virtual_rows.rdoc +4 -5
  14. data/lib/sequel/adapters/ibmdb.rb +24 -16
  15. data/lib/sequel/adapters/jdbc/h2.rb +5 -0
  16. data/lib/sequel/adapters/jdbc/hsqldb.rb +5 -0
  17. data/lib/sequel/adapters/mock.rb +14 -2
  18. data/lib/sequel/adapters/shared/access.rb +6 -9
  19. data/lib/sequel/adapters/shared/cubrid.rb +5 -0
  20. data/lib/sequel/adapters/shared/db2.rb +5 -0
  21. data/lib/sequel/adapters/shared/firebird.rb +5 -0
  22. data/lib/sequel/adapters/shared/mssql.rb +23 -16
  23. data/lib/sequel/adapters/shared/mysql.rb +12 -2
  24. data/lib/sequel/adapters/shared/oracle.rb +31 -15
  25. data/lib/sequel/adapters/shared/postgres.rb +28 -4
  26. data/lib/sequel/adapters/shared/sqlanywhere.rb +5 -0
  27. data/lib/sequel/adapters/shared/sqlite.rb +12 -1
  28. data/lib/sequel/ast_transformer.rb +9 -7
  29. data/lib/sequel/connection_pool.rb +10 -4
  30. data/lib/sequel/database/features.rb +15 -0
  31. data/lib/sequel/database/schema_generator.rb +2 -2
  32. data/lib/sequel/database/schema_methods.rb +21 -3
  33. data/lib/sequel/database/transactions.rb +8 -4
  34. data/lib/sequel/dataset/actions.rb +13 -7
  35. data/lib/sequel/dataset/features.rb +7 -0
  36. data/lib/sequel/dataset/query.rb +28 -11
  37. data/lib/sequel/dataset/sql.rb +90 -14
  38. data/lib/sequel/extensions/constraint_validations.rb +2 -2
  39. data/lib/sequel/extensions/date_arithmetic.rb +1 -1
  40. data/lib/sequel/extensions/eval_inspect.rb +12 -6
  41. data/lib/sequel/extensions/pg_array_ops.rb +11 -2
  42. data/lib/sequel/extensions/pg_json.rb +130 -23
  43. data/lib/sequel/extensions/pg_json_ops.rb +196 -28
  44. data/lib/sequel/extensions/to_dot.rb +5 -7
  45. data/lib/sequel/model/associations.rb +0 -50
  46. data/lib/sequel/plugins/class_table_inheritance.rb +49 -21
  47. data/lib/sequel/plugins/many_through_many.rb +10 -11
  48. data/lib/sequel/plugins/serialization.rb +4 -1
  49. data/lib/sequel/plugins/sharding.rb +0 -9
  50. data/lib/sequel/plugins/single_table_inheritance.rb +4 -2
  51. data/lib/sequel/plugins/timestamps.rb +2 -2
  52. data/lib/sequel/sql.rb +166 -44
  53. data/lib/sequel/version.rb +1 -1
  54. data/spec/adapters/postgres_spec.rb +199 -133
  55. data/spec/core/connection_pool_spec.rb +6 -0
  56. data/spec/core/database_spec.rb +12 -0
  57. data/spec/core/dataset_spec.rb +58 -3
  58. data/spec/core/expression_filters_spec.rb +67 -5
  59. data/spec/core/mock_adapter_spec.rb +8 -4
  60. data/spec/core/schema_spec.rb +7 -0
  61. data/spec/core_extensions_spec.rb +14 -0
  62. data/spec/extensions/class_table_inheritance_spec.rb +23 -3
  63. data/spec/extensions/core_refinements_spec.rb +14 -0
  64. data/spec/extensions/eval_inspect_spec.rb +8 -4
  65. data/spec/extensions/pg_array_ops_spec.rb +6 -0
  66. data/spec/extensions/pg_json_ops_spec.rb +99 -0
  67. data/spec/extensions/pg_json_spec.rb +104 -4
  68. data/spec/extensions/serialization_spec.rb +19 -0
  69. data/spec/extensions/single_table_inheritance_spec.rb +11 -3
  70. data/spec/extensions/timestamps_spec.rb +10 -0
  71. data/spec/extensions/to_dot_spec.rb +8 -4
  72. data/spec/integration/database_test.rb +1 -1
  73. data/spec/integration/dataset_test.rb +9 -0
  74. data/spec/integration/schema_test.rb +27 -0
  75. metadata +4 -2
@@ -8,6 +8,8 @@ describe "pg_json extension" do
8
8
  @m = m::JSONDatabaseMethods
9
9
  @hc = m::JSONHash
10
10
  @ac = m::JSONArray
11
+ @bhc = m::JSONBHash
12
+ @bac = m::JSONBArray
11
13
 
12
14
  # Create subclass in correct namespace for easily overriding methods
13
15
  j = m::JSON = JSON.dup
@@ -46,6 +48,14 @@ describe "pg_json extension" do
46
48
  @m.db_parse_json('1.1').should == 1.1
47
49
  end
48
50
 
51
+ it "should parse json and non-json plain strings, integers, and floats correctly in db_parse_jsonb" do
52
+ @m.db_parse_jsonb('{"a": "b", "c": {"d": "e"}}').to_hash.should == {'a'=>'b', 'c'=>{'d'=>'e'}}
53
+ @m.db_parse_jsonb('[1, [2], {"a": "b"}]').to_a.should == [1, [2], {'a'=>'b'}]
54
+ @m.db_parse_jsonb('1').should == 1
55
+ @m.db_parse_jsonb('"b"').should == 'b'
56
+ @m.db_parse_jsonb('1.1').should == 1.1
57
+ end
58
+
49
59
  it "should raise an error when attempting to parse invalid json" do
50
60
  proc{@m.parse_json('')}.should raise_error(Sequel::InvalidValue)
51
61
  proc{@m.parse_json('1')}.should raise_error(Sequel::InvalidValue)
@@ -72,6 +82,13 @@ describe "pg_json extension" do
72
82
  @db.literal(Sequel.pg_json('a'=>'b')).should == "'{\"a\":\"b\"}'::json"
73
83
  end
74
84
 
85
+ it "should literalize JSONHash and JSONArray to strings correctly" do
86
+ @db.literal(Sequel.pg_jsonb([])).should == "'[]'::jsonb"
87
+ @db.literal(Sequel.pg_jsonb([1, [2], {'a'=>'b'}])).should == "'[1,[2],{\"a\":\"b\"}]'::jsonb"
88
+ @db.literal(Sequel.pg_jsonb({})).should == "'{}'::jsonb"
89
+ @db.literal(Sequel.pg_jsonb('a'=>'b')).should == "'{\"a\":\"b\"}'::jsonb"
90
+ end
91
+
75
92
  it "should have Sequel.pg_json return JSONHash and JSONArray as is" do
76
93
  a = Sequel.pg_json({})
77
94
  Sequel.pg_json(a).should equal(a)
@@ -79,22 +96,72 @@ describe "pg_json extension" do
79
96
  Sequel.pg_json(a).should equal(a)
80
97
  end
81
98
 
82
- it "should have JSONHash#to_hash method for getting underlying hash" do
99
+ it "should have Sequel.pg_json convert jsonb values" do
100
+ a = {}
101
+ v = Sequel.pg_json(Sequel.pg_jsonb(a))
102
+ v.to_hash.should equal(a)
103
+ v.should be_a_kind_of(@hc)
104
+
105
+ a = []
106
+ v = Sequel.pg_json(Sequel.pg_jsonb(a))
107
+ v.to_a.should equal(a)
108
+ v.should be_a_kind_of(@ac)
109
+ end
110
+
111
+ it "should have Sequel.pg_jsonb return JSONBHash and JSONBArray as is" do
112
+ a = Sequel.pg_jsonb({})
113
+ Sequel.pg_jsonb(a).should equal(a)
114
+ a = Sequel.pg_jsonb([])
115
+ Sequel.pg_jsonb(a).should equal(a)
116
+ end
117
+
118
+ it "should have Sequel.pg_jsonb convert json values" do
119
+ a = {}
120
+ v = Sequel.pg_jsonb(Sequel.pg_json(a))
121
+ v.to_hash.should equal(a)
122
+ v.should be_a_kind_of(@bhc)
123
+
124
+ a = []
125
+ v = Sequel.pg_jsonb(Sequel.pg_json(a))
126
+ v.to_a.should equal(a)
127
+ v.should be_a_kind_of(@bac)
128
+ end
129
+
130
+ it "should have JSONHashBase#to_hash method for getting underlying hash" do
83
131
  Sequel.pg_json({}).to_hash.should be_a_kind_of(Hash)
132
+ Sequel.pg_jsonb({}).to_hash.should be_a_kind_of(Hash)
133
+ end
134
+
135
+ it "should allow aliasing json objects" do
136
+ @db.literal(Sequel.pg_json({}).as(:a)).should == "'{}'::json AS a"
137
+ @db.literal(Sequel.pg_json([]).as(:a)).should == "'[]'::json AS a"
138
+ @db.literal(Sequel.pg_jsonb({}).as(:a)).should == "'{}'::jsonb AS a"
139
+ @db.literal(Sequel.pg_jsonb([]).as(:a)).should == "'[]'::jsonb AS a"
140
+ end
141
+
142
+ it "should allow casting json objects" do
143
+ @db.literal(Sequel.pg_json({}).cast(String)).should == "CAST('{}'::json AS text)"
144
+ @db.literal(Sequel.pg_json([]).cast(String)).should == "CAST('[]'::json AS text)"
145
+ @db.literal(Sequel.pg_jsonb({}).cast(String)).should == "CAST('{}'::jsonb AS text)"
146
+ @db.literal(Sequel.pg_jsonb([]).cast(String)).should == "CAST('[]'::jsonb AS text)"
84
147
  end
85
148
 
86
- it "should have JSONArray#to_a method for getting underlying array" do
149
+ it "should have JSONArrayBase#to_a method for getting underlying array" do
87
150
  Sequel.pg_json([]).to_a.should be_a_kind_of(Array)
151
+ Sequel.pg_jsonb([]).to_a.should be_a_kind_of(Array)
88
152
  end
89
153
 
90
- it "should support using JSONHash and JSONArray as bound variables" do
154
+ it "should support using JSONHashBase and JSONArrayBase as bound variables" do
91
155
  @db.bound_variable_arg(1, nil).should == 1
92
156
  @db.bound_variable_arg(Sequel.pg_json([1]), nil).should == '[1]'
93
157
  @db.bound_variable_arg(Sequel.pg_json('a'=>'b'), nil).should == '{"a":"b"}'
158
+ @db.bound_variable_arg(Sequel.pg_jsonb([1]), nil).should == '[1]'
159
+ @db.bound_variable_arg(Sequel.pg_jsonb('a'=>'b'), nil).should == '{"a":"b"}'
94
160
  end
95
161
 
96
- it "should support using json[] types in bound variables" do
162
+ it "should support using json[] and jsonb[] types in bound variables" do
97
163
  @db.bound_variable_arg(Sequel.pg_array([Sequel.pg_json([{"a"=>1}]), Sequel.pg_json("b"=>[1, 2])]), nil).should == '{"[{\\"a\\":1}]","{\\"b\\":[1,2]}"}'
164
+ @db.bound_variable_arg(Sequel.pg_array([Sequel.pg_jsonb([{"a"=>1}]), Sequel.pg_jsonb("b"=>[1, 2])]), nil).should == '{"[{\\"a\\":1}]","{\\"b\\":[1,2]}"}'
98
165
  end
99
166
 
100
167
  it "should parse json type from the schema correctly" do
@@ -102,23 +169,56 @@ describe "pg_json extension" do
102
169
  @db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :json]
103
170
  end
104
171
 
172
+ it "should parse json type from the schema correctly" do
173
+ @db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i', :db_type=>'jsonb'}]
174
+ @db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :jsonb]
175
+ end
176
+
105
177
  it "should support typecasting for the json type" do
106
178
  h = Sequel.pg_json(1=>2)
107
179
  a = Sequel.pg_json([1])
108
180
  @db.typecast_value(:json, h).should equal(h)
109
181
  @db.typecast_value(:json, h.to_hash).should == h
110
182
  @db.typecast_value(:json, h.to_hash).should be_a_kind_of(@hc)
183
+ @db.typecast_value(:json, Sequel.pg_jsonb(h)).should == h
184
+ @db.typecast_value(:json, Sequel.pg_jsonb(h)).should be_a_kind_of(@hc)
111
185
  @db.typecast_value(:json, a).should equal(a)
112
186
  @db.typecast_value(:json, a.to_a).should == a
113
187
  @db.typecast_value(:json, a.to_a).should be_a_kind_of(@ac)
188
+ @db.typecast_value(:json, Sequel.pg_jsonb(a)).should == a
189
+ @db.typecast_value(:json, Sequel.pg_jsonb(a)).should be_a_kind_of(@ac)
114
190
  @db.typecast_value(:json, '[]').should == Sequel.pg_json([])
191
+ @db.typecast_value(:json, '[]').should be_a_kind_of(@ac)
115
192
  @db.typecast_value(:json, '{"a": "b"}').should == Sequel.pg_json("a"=>"b")
193
+ @db.typecast_value(:json, '{"a": "b"}').should be_a_kind_of(@hc)
116
194
  proc{@db.typecast_value(:json, '')}.should raise_error(Sequel::InvalidValue)
117
195
  proc{@db.typecast_value(:json, 1)}.should raise_error(Sequel::InvalidValue)
118
196
  end
119
197
 
198
+ it "should support typecasting for the jsonb type" do
199
+ h = Sequel.pg_jsonb(1=>2)
200
+ a = Sequel.pg_jsonb([1])
201
+ @db.typecast_value(:jsonb, h).should equal(h)
202
+ @db.typecast_value(:jsonb, h.to_hash).should == h
203
+ @db.typecast_value(:jsonb, h.to_hash).should be_a_kind_of(@bhc)
204
+ @db.typecast_value(:jsonb, Sequel.pg_json(h)).should == h
205
+ @db.typecast_value(:jsonb, Sequel.pg_json(h)).should be_a_kind_of(@bhc)
206
+ @db.typecast_value(:jsonb, a).should equal(a)
207
+ @db.typecast_value(:jsonb, a.to_a).should == a
208
+ @db.typecast_value(:jsonb, a.to_a).should be_a_kind_of(@bac)
209
+ @db.typecast_value(:jsonb, Sequel.pg_json(a)).should == a
210
+ @db.typecast_value(:jsonb, Sequel.pg_json(a)).should be_a_kind_of(@bac)
211
+ @db.typecast_value(:jsonb, '[]').should == Sequel.pg_jsonb([])
212
+ @db.typecast_value(:jsonb, '[]').should be_a_kind_of(@bac)
213
+ @db.typecast_value(:jsonb, '{"a": "b"}').should == Sequel.pg_jsonb("a"=>"b")
214
+ @db.typecast_value(:jsonb, '{"a": "b"}').should be_a_kind_of(@bhc)
215
+ proc{@db.typecast_value(:jsonb, '')}.should raise_error(Sequel::InvalidValue)
216
+ proc{@db.typecast_value(:jsonb, 1)}.should raise_error(Sequel::InvalidValue)
217
+ end
218
+
120
219
  it "should return correct results for Database#schema_type_class" do
121
220
  @db.schema_type_class(:json).should == [Sequel::Postgres::JSONHash, Sequel::Postgres::JSONArray]
221
+ @db.schema_type_class(:jsonb).should == [Sequel::Postgres::JSONBHash, Sequel::Postgres::JSONBArray]
122
222
  @db.schema_type_class(:integer).should == Integer
123
223
  end
124
224
  end
@@ -300,4 +300,23 @@ describe "Serialization plugin" do
300
300
  o.dup.deserialized_values.should == o.deserialized_values
301
301
  o.dup.deserialized_values.should_not equal(o.deserialized_values)
302
302
  end
303
+
304
+ it "should have changed_columns include serialized columns if those columns have changed" do
305
+ @c.plugin :serialization, :yaml, :abc, :def
306
+ @c.dataset._fetch = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
307
+ o = @c.first
308
+ o.changed_columns.should == []
309
+ o.abc = 1
310
+ o.changed_columns.should == []
311
+ o.abc = 1
312
+ o.changed_columns.should == []
313
+ o.abc = 2
314
+ o.changed_columns.should == [:abc]
315
+ o.def = 'hello'
316
+ o.changed_columns.should == [:abc]
317
+ o.def = 'hello'
318
+ o.changed_columns.should == [:abc]
319
+ o.def = 'hello2'
320
+ o.changed_columns.should == [:abc, :def]
321
+ end
303
322
  end
@@ -70,19 +70,27 @@ describe Sequel::Model, "single table inheritance plugin" do
70
70
  called.should == false
71
71
  end
72
72
 
73
- it "should add a before_create hook that sets the model class name for the key" do
73
+ it "should set the model class name when saving" do
74
74
  StiTest.new.save
75
75
  StiTestSub1.new.save
76
76
  StiTestSub2.new.save
77
77
  DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTest')", "SELECT * FROM sti_tests WHERE (id = 10) LIMIT 1", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')", "SELECT * FROM sti_tests WHERE ((sti_tests.kind IN ('StiTestSub1')) AND (id = 10)) LIMIT 1", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub2')", "SELECT * FROM sti_tests WHERE ((sti_tests.kind IN ('StiTestSub2')) AND (id = 10)) LIMIT 1"]
78
78
  end
79
79
 
80
- it "should have the before_create hook not override an existing value" do
80
+ it "should handle validations on the type column field" do
81
+ o = StiTestSub1.new
82
+ def o.validate
83
+ errors.add(:kind, 'not present') unless kind
84
+ end
85
+ o.valid?.should == true
86
+ end
87
+
88
+ it "should override an existing value in the class name field" do
81
89
  StiTest.create(:kind=>'StiTestSub1')
82
90
  DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')", "SELECT * FROM sti_tests WHERE (id = 10) LIMIT 1"]
83
91
  end
84
92
 
85
- it "should have the before_create hook handle columns with the same name as existing method names" do
93
+ it "should handle type column with the same name as existing method names" do
86
94
  StiTest.plugin :single_table_inheritance, :type
87
95
  StiTest.columns :id, :type
88
96
  StiTest.create
@@ -22,6 +22,16 @@ describe "Sequel::Plugins::Timestamps" do
22
22
  Sequel.datetime_class = Time
23
23
  end
24
24
 
25
+ it "should handle validations on the timestamp fields for new objects" do
26
+ @c.plugin :timestamps, :update_on_create=>true
27
+ o = @c.new
28
+ def o.validate
29
+ errors.add(model.create_timestamp_field, 'not present') unless send(model.create_timestamp_field)
30
+ errors.add(model.update_timestamp_field, 'not present') unless send(model.update_timestamp_field)
31
+ end
32
+ o.valid?.should == true
33
+ end
34
+
25
35
  it "should set the create timestamp field on creation" do
26
36
  o = @c.create
27
37
  @c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
@@ -108,6 +108,10 @@ END
108
108
  dot(@ds.from(Sequel.as(:a, :b))).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];"]
109
109
  end
110
110
 
111
+ it "should handle SQL::AliasedExpressions with column aliases" do
112
+ dot(@ds.from(Sequel.as(:a, :b, [:c, :d]))).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];", "3 -> 6 [label=\"columns\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":c\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":d\"];"]
113
+ end
114
+
111
115
  it "should handle SQL::CaseExpressions" do
112
116
  dot(@ds.select(Sequel.case({:a=>:b}, :c, :d))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"CaseExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":d\"];", "3 -> 5 [label=\"conditions\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":a\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"default\"];", "9 [label=\":c\"];"]
113
117
  end
@@ -117,15 +121,15 @@ END
117
121
  end
118
122
 
119
123
  it "should handle SQL::Function" do
120
- dot(@ds.select{a(b)}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: a\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"Identifier\"];", "4 -> 5 [label=\"value\"];", "5 [label=\":b\"];"]
124
+ dot(@ds.select{a(b)}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: a\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"Identifier\"];", "4 -> 5 [label=\"value\"];", "5 [label=\":b\"];", "3 -> 6 [label=\"args\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\"Identifier\"];", "7 -> 8 [label=\"value\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"opts\"];", "9 [label=\"Hash\"];"]
121
125
  end
122
126
 
123
127
  it "should handle SQL::Subscript" do
124
128
  dot(@ds.select(Sequel.subscript(:a, 1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
125
129
  end
126
130
 
127
- it "should handle SQL::WindowFunction" do
128
- dot(@ds.select{sum{}.over(:partition=>:a)}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"WindowFunction\"];", "3 -> 4 [label=\"function\"];", "4 [label=\"Function: sum\"];", "3 -> 5 [label=\"window\"];", "5 [label=\"Window\"];", "5 -> 6 [label=\"opts\"];", "6 [label=\"Hash\"];", "6 -> 7 [label=\"partition\"];", "7 [label=\":a\"];"]
131
+ it "should handle SQL::Function with a window" do
132
+ dot(@ds.select{sum{}.over(:partition=>:a)}).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: sum\"];", "3 -> 4 [label=\"args\"];", "4 [label=\"Array\"];", "3 -> 5 [label=\"opts\"];", "5 [label=\"Hash\"];", "5 -> 6 [label=\"over\"];", "6 [label=\"Window\"];", "6 -> 7 [label=\"opts\"];", "7 [label=\"Hash\"];", "7 -> 8 [label=\"partition\"];", "8 [label=\":a\"];"]
129
133
  end
130
134
 
131
135
  it "should handle SQL::PlaceholderLiteralString" do
@@ -137,7 +141,7 @@ END
137
141
  end
138
142
 
139
143
  it "should handle JOIN USING" do
140
- dot(@ds.from(:a).join(:d, [:c], :table_alias=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN USING\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"alias\"];", "7 [label=\":c\"];", "5 -> 8 [label=\"using\"];", "8 [label=\"Array\"];", "8 -> 9 [label=\"0\"];", "9 [label=\":c\"];"]
144
+ dot(@ds.from(:a).join(:d, [:c], :table_alias=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN USING\"];", "5 -> 6 [label=\"table\"];", "6 [label=\"AliasedExpression\"];", "6 -> 7 [label=\"expression\"];", "7 [label=\":d\"];", "6 -> 8 [label=\"alias\"];", "8 [label=\":c\"];", "5 -> 9 [label=\"using\"];", "9 [label=\"Array\"];", "9 -> 10 [label=\"0\"];", "10 [label=\":c\"];"]
141
145
  end
142
146
 
143
147
  it "should handle other types" do
@@ -21,7 +21,7 @@ describe Sequel::Database do
21
21
  end
22
22
 
23
23
  specify "should raise Sequel::DatabaseError on invalid SQL" do
24
- proc{@db << "SELECT"}.should raise_error(Sequel::DatabaseError)
24
+ proc{@db << "S"}.should raise_error(Sequel::DatabaseError)
25
25
  end
26
26
 
27
27
  specify "should have Sequel::DatabaseError#sql give the SQL causing the error" do
@@ -293,6 +293,10 @@ describe "Simple Dataset operations" do
293
293
  @ds.select(:id___x, :number___n).first.should == {:x=>1, :n=>10}
294
294
  end
295
295
 
296
+ specify "should support table aliases with column aliases" do
297
+ DB.from(@ds.as(:i, [:x, :n])).first.should == {:x=>1, :n=>10}
298
+ end if DB.dataset.supports_derived_column_lists?
299
+
296
300
  specify "should handle true/false properly" do
297
301
  @ds.filter(Sequel::TRUE).select_map(:number).should == [10]
298
302
  @ds.filter(Sequel::FALSE).select_map(:number).should == []
@@ -907,6 +911,11 @@ describe "Sequel::Dataset#import and #multi_insert" do
907
911
  @ids.import([:i], [[10], [20], [30]], :slice_size=>3)
908
912
  @ids.all.should == [{:i=>10}, {:i=>20}, {:i=>30}]
909
913
  end
914
+
915
+ it "should import many rows at once" do
916
+ @ids.import([:i], (1..1000).to_a.map{|x| [x]})
917
+ @ids.select_order_map(:i).should == (1..1000).to_a
918
+ end
910
919
  end
911
920
 
912
921
  describe "Sequel::Dataset#import and #multi_insert :return=>:primary_key " do
@@ -272,12 +272,14 @@ describe "Database schema modifiers" do
272
272
 
273
273
  describe "views" do
274
274
  before do
275
+ @db.drop_view(:items_view2) rescue nil
275
276
  @db.drop_view(:items_view) rescue nil
276
277
  @db.create_table(:items){Integer :number}
277
278
  @ds.insert(:number=>1)
278
279
  @ds.insert(:number=>2)
279
280
  end
280
281
  after do
282
+ @db.drop_view(:items_view2) rescue nil
281
283
  @db.drop_view(:items_view) rescue nil
282
284
  end
283
285
 
@@ -286,6 +288,31 @@ describe "Database schema modifiers" do
286
288
  @db[:items_view].map(:number).should == [1]
287
289
  end
288
290
 
291
+ specify "should create views with check options correctly" do
292
+ @db.create_view(:items_view, @ds.where{number > 2}, :check=>true)
293
+ proc{@db[:items_view].insert(1)}.should raise_error(Sequel::DatabaseError)
294
+ @db[:items_view].insert(3)
295
+ @db[:items_view].select_order_map(:number).should == [3]
296
+ @db.create_view(:items_view2, @db[:items_view].where{number > 1}, :check=>true)
297
+ proc{@db[:items_view2].insert(1)}.should raise_error(Sequel::DatabaseError)
298
+ proc{@db[:items_view2].insert(2)}.should raise_error(Sequel::DatabaseError)
299
+ @db[:items_view2].insert(4)
300
+ @db[:items_view2].select_order_map(:number).should == [3, 4]
301
+ @ds.select_order_map(:number).should == [1, 2, 3, 4]
302
+ end if DB.supports_views_with_check_option?
303
+
304
+ specify "should create views with local check options correctly" do
305
+ @db.create_view(:items_view, @ds.where{number > 2})
306
+ @db[:items_view].insert(3)
307
+ @db[:items_view].select_order_map(:number).should == [3]
308
+ @db.create_view(:items_view2, @db[:items_view].where{number > 1}, :check=>:local)
309
+ proc{@db[:items_view2].insert(1)}.should raise_error(Sequel::DatabaseError)
310
+ @db[:items_view2].insert(2)
311
+ @db[:items_view2].insert(4)
312
+ @db[:items_view2].select_order_map(:number).should == [3, 4]
313
+ @ds.select_order_map(:number).should == [1, 2, 2, 3, 4]
314
+ end if DB.supports_views_with_local_check_option?
315
+
289
316
  cspecify "should create views with explicit columns correctly", :sqlite do
290
317
  @db.create_view(:items_view, @ds.where(:number=>1), :columns=>[:n])
291
318
  @db[:items_view].map(:n).should == [1]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.10.0
4
+ version: 4.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-01 00:00:00.000000000 Z
11
+ date: 2014-06-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The Database Toolkit for Ruby
14
14
  email: code@jeremyevans.net
@@ -127,6 +127,7 @@ extra_rdoc_files:
127
127
  - doc/release_notes/4.8.0.txt
128
128
  - doc/release_notes/4.9.0.txt
129
129
  - doc/release_notes/4.10.0.txt
130
+ - doc/release_notes/4.11.0.txt
130
131
  files:
131
132
  - CHANGELOG
132
133
  - MIT-LICENSE
@@ -224,6 +225,7 @@ files:
224
225
  - doc/release_notes/4.0.0.txt
225
226
  - doc/release_notes/4.1.0.txt
226
227
  - doc/release_notes/4.10.0.txt
228
+ - doc/release_notes/4.11.0.txt
227
229
  - doc/release_notes/4.2.0.txt
228
230
  - doc/release_notes/4.3.0.txt
229
231
  - doc/release_notes/4.4.0.txt