sequel 3.28.0 → 3.29.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.
- data/CHANGELOG +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- metadata +14 -8
data/spec/core/dataset_spec.rb
CHANGED
|
@@ -60,12 +60,6 @@ describe "Dataset" do
|
|
|
60
60
|
db = Sequel::Database.new(:identifier_output_method=>:downcase)
|
|
61
61
|
db[:a].identifier_output_method.should == :downcase
|
|
62
62
|
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
describe "Dataset" do
|
|
66
|
-
before do
|
|
67
|
-
@dataset = Sequel::Dataset.new("db")
|
|
68
|
-
end
|
|
69
63
|
|
|
70
64
|
specify "should have quote_identifiers= method which changes literalization of identifiers" do
|
|
71
65
|
@dataset.quote_identifiers = true
|
|
@@ -111,27 +105,25 @@ describe "Dataset#clone" do
|
|
|
111
105
|
|
|
112
106
|
specify "should create an exact copy of the dataset" do
|
|
113
107
|
@dataset.row_proc = Proc.new{|r| r}
|
|
114
|
-
|
|
108
|
+
clone = @dataset.clone
|
|
115
109
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
110
|
+
clone.object_id.should_not === @dataset.object_id
|
|
111
|
+
clone.class.should == @dataset.class
|
|
112
|
+
clone.db.should == @dataset.db
|
|
113
|
+
clone.opts.should == @dataset.opts
|
|
114
|
+
clone.row_proc.should == @dataset.row_proc
|
|
120
115
|
end
|
|
121
116
|
|
|
122
117
|
specify "should deep-copy the dataset opts" do
|
|
123
|
-
|
|
118
|
+
clone = @dataset.clone
|
|
124
119
|
|
|
125
|
-
|
|
120
|
+
clone.opts.should_not equal(@dataset.opts)
|
|
126
121
|
@dataset.filter!(:a => 'b')
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
clone
|
|
132
|
-
clone.class.should == @dataset.class
|
|
133
|
-
clone.db.should == @dataset.db
|
|
134
|
-
clone.opts.should == @dataset.opts
|
|
122
|
+
clone.opts[:filter].should be_nil
|
|
123
|
+
|
|
124
|
+
clone = @dataset.clone(:from => [:other])
|
|
125
|
+
@dataset.opts[:from].should == [:items]
|
|
126
|
+
clone.opts[:from].should == [:other]
|
|
135
127
|
end
|
|
136
128
|
|
|
137
129
|
specify "should merge the specified options" do
|
|
@@ -144,12 +136,6 @@ describe "Dataset#clone" do
|
|
|
144
136
|
clone.opts.should == {:from => [:other]}
|
|
145
137
|
end
|
|
146
138
|
|
|
147
|
-
specify "should create a clone with a deep copy of options" do
|
|
148
|
-
clone = @dataset.clone(:from => [:other])
|
|
149
|
-
@dataset.opts[:from].should == [:items]
|
|
150
|
-
clone.opts[:from].should == [:other]
|
|
151
|
-
end
|
|
152
|
-
|
|
153
139
|
specify "should return an object with the same modules included" do
|
|
154
140
|
m = Module.new do
|
|
155
141
|
def __xyz__; "xyz"; end
|
|
@@ -161,7 +147,7 @@ end
|
|
|
161
147
|
|
|
162
148
|
describe "Dataset#==" do
|
|
163
149
|
before do
|
|
164
|
-
@db =
|
|
150
|
+
@db = Sequel.mock
|
|
165
151
|
@h = {}
|
|
166
152
|
end
|
|
167
153
|
|
|
@@ -170,7 +156,7 @@ describe "Dataset#==" do
|
|
|
170
156
|
end
|
|
171
157
|
|
|
172
158
|
specify "should be different for datasets with different dbs" do
|
|
173
|
-
@db[:t].should_not ==
|
|
159
|
+
@db[:t].should_not == Sequel.mock[:t]
|
|
174
160
|
end
|
|
175
161
|
|
|
176
162
|
specify "should be different for datasets with different opts" do
|
|
@@ -186,7 +172,7 @@ end
|
|
|
186
172
|
|
|
187
173
|
describe "Dataset#hash" do
|
|
188
174
|
before do
|
|
189
|
-
@db =
|
|
175
|
+
@db = Sequel.mock
|
|
190
176
|
@h = {}
|
|
191
177
|
end
|
|
192
178
|
|
|
@@ -197,7 +183,7 @@ describe "Dataset#hash" do
|
|
|
197
183
|
end
|
|
198
184
|
|
|
199
185
|
specify "should be different for datasets with different dbs" do
|
|
200
|
-
@db[:t].hash.should_not ==
|
|
186
|
+
@db[:t].hash.should_not == Sequel.mock[:t].hash
|
|
201
187
|
end
|
|
202
188
|
|
|
203
189
|
specify "should be different for datasets with different opts" do
|
|
@@ -232,6 +218,12 @@ describe "A simple dataset" do
|
|
|
232
218
|
@dataset.insert_sql.should == 'INSERT INTO test DEFAULT VALUES'
|
|
233
219
|
end
|
|
234
220
|
|
|
221
|
+
specify "should use a single column with a default value when the dataset doesn't support using insert statement with default values" do
|
|
222
|
+
@dataset.meta_def(:insert_supports_empty_values?){false}
|
|
223
|
+
@dataset.meta_def(:columns){[:a, :b]}
|
|
224
|
+
@dataset.insert_sql.should == 'INSERT INTO test (b) VALUES (DEFAULT)'
|
|
225
|
+
end
|
|
226
|
+
|
|
235
227
|
specify "should format an insert statement with hash" do
|
|
236
228
|
@dataset.insert_sql(:name => 'wxyz', :price => 342).
|
|
237
229
|
should match(/INSERT INTO test \(name, price\) VALUES \('wxyz', 342\)|INSERT INTO test \(price, name\) VALUES \(342, 'wxyz'\)/)
|
|
@@ -245,8 +237,6 @@ describe "A simple dataset" do
|
|
|
245
237
|
end
|
|
246
238
|
|
|
247
239
|
specify "should format an insert statement with an object that respond_to? :values" do
|
|
248
|
-
dbb = Sequel::Database.new
|
|
249
|
-
|
|
250
240
|
v = Object.new
|
|
251
241
|
def v.values; {:a => 1}; end
|
|
252
242
|
|
|
@@ -261,29 +251,24 @@ describe "A simple dataset" do
|
|
|
261
251
|
end
|
|
262
252
|
|
|
263
253
|
specify "should format an insert statement with sub-query" do
|
|
264
|
-
@
|
|
265
|
-
@dataset.insert_sql(@sub).should == \
|
|
266
|
-
"INSERT INTO test SELECT * FROM something WHERE (x = 2)"
|
|
254
|
+
@dataset.insert_sql(@dataset.from(:something).filter(:x => 2)).should == "INSERT INTO test SELECT * FROM something WHERE (x = 2)"
|
|
267
255
|
end
|
|
268
256
|
|
|
269
257
|
specify "should format an insert statement with array" do
|
|
270
|
-
@dataset.insert_sql('a', 2, 6.5).should ==
|
|
271
|
-
"INSERT INTO test VALUES ('a', 2, 6.5)"
|
|
258
|
+
@dataset.insert_sql('a', 2, 6.5).should == "INSERT INTO test VALUES ('a', 2, 6.5)"
|
|
272
259
|
end
|
|
273
260
|
|
|
274
261
|
specify "should format an update statement" do
|
|
275
|
-
@dataset.update_sql(:name => 'abc').should ==
|
|
276
|
-
"UPDATE test SET name = 'abc'"
|
|
262
|
+
@dataset.update_sql(:name => 'abc').should == "UPDATE test SET name = 'abc'"
|
|
277
263
|
end
|
|
278
264
|
|
|
279
265
|
specify "should be able to return rows for arbitrary SQL" do
|
|
280
|
-
@dataset.clone(:sql => 'xxx yyy zzz').select_sql.should ==
|
|
281
|
-
"xxx yyy zzz"
|
|
266
|
+
@dataset.clone(:sql => 'xxx yyy zzz').select_sql.should == "xxx yyy zzz"
|
|
282
267
|
end
|
|
283
268
|
|
|
284
269
|
specify "should use the :sql option for all sql methods" do
|
|
285
270
|
sql = "X"
|
|
286
|
-
ds =
|
|
271
|
+
ds = @dataset.clone(:sql=>sql)
|
|
287
272
|
ds.sql.should == sql
|
|
288
273
|
ds.select_sql.should == sql
|
|
289
274
|
ds.insert_sql.should == sql
|
|
@@ -418,7 +403,7 @@ describe "Dataset#where" do
|
|
|
418
403
|
b.should == a
|
|
419
404
|
end
|
|
420
405
|
|
|
421
|
-
specify "should not replace named placeholders that don't
|
|
406
|
+
specify "should not replace named placeholders that don't exist in the hash" do
|
|
422
407
|
@dataset.where('price < :price AND id in :ids', :price=>100).select_sql.should ==
|
|
423
408
|
"SELECT * FROM test WHERE (price < 100 AND id in :ids)"
|
|
424
409
|
end
|
|
@@ -538,53 +523,31 @@ describe "Dataset#where" do
|
|
|
538
523
|
|
|
539
524
|
specify "should handle IN/NOT IN queries with multiple columns and a dataset where the database doesn't support it" do
|
|
540
525
|
@dataset.meta_def(:supports_multiple_column_in?){false}
|
|
541
|
-
db =
|
|
542
|
-
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia')
|
|
543
|
-
d1.instance_variable_set(:@columns, [:id1, :id2])
|
|
544
|
-
def d1.fetch_rows(sql)
|
|
545
|
-
db << sql
|
|
546
|
-
@columns = [:id1, :id2]
|
|
547
|
-
yield(:id1=>1, :id2=>2)
|
|
548
|
-
yield(:id1=>3, :id2=>4)
|
|
549
|
-
end
|
|
526
|
+
db = Sequel.mock(:fetch=>[{:id1=>1, :id2=>2}, {:id1=>3, :id2=>4}])
|
|
527
|
+
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
|
|
550
528
|
@dataset.filter([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (((id1 = 1) AND (id2 = 2)) OR ((id1 = 3) AND (id2 = 4)))"
|
|
551
529
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
552
|
-
db.sqls.clear
|
|
553
530
|
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (((id1 != 1) OR (id2 != 2)) AND ((id1 != 3) OR (id2 != 4)))"
|
|
554
531
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
555
532
|
end
|
|
556
533
|
|
|
557
534
|
specify "should handle IN/NOT IN queries with multiple columns and an empty dataset where the database doesn't support it" do
|
|
558
535
|
@dataset.meta_def(:supports_multiple_column_in?){false}
|
|
559
|
-
db =
|
|
560
|
-
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia')
|
|
561
|
-
d1.instance_variable_set(:@columns, [:id1, :id2])
|
|
562
|
-
def d1.fetch_rows(sql)
|
|
563
|
-
db << sql
|
|
564
|
-
@columns = [:id1, :id2]
|
|
565
|
-
end
|
|
536
|
+
db = Sequel.mock
|
|
537
|
+
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
|
|
566
538
|
@dataset.filter([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
|
|
567
539
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
568
|
-
db.sqls.clear
|
|
569
540
|
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (1 = 1)"
|
|
570
541
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
571
542
|
end
|
|
572
543
|
|
|
573
544
|
specify "should handle IN/NOT IN queries for datasets with row_procs" do
|
|
574
545
|
@dataset.meta_def(:supports_multiple_column_in?){false}
|
|
575
|
-
db =
|
|
576
|
-
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia')
|
|
546
|
+
db = Sequel.mock(:fetch=>[{:id1=>1, :id2=>2}, {:id1=>3, :id2=>4}])
|
|
547
|
+
d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
|
|
577
548
|
d1.row_proc = proc{|h| Object.new}
|
|
578
|
-
d1.instance_variable_set(:@columns, [:id1, :id2])
|
|
579
|
-
def d1.fetch_rows(sql)
|
|
580
|
-
db << sql
|
|
581
|
-
@columns = [:id1, :id2]
|
|
582
|
-
yield(:id1=>1, :id2=>2)
|
|
583
|
-
yield(:id1=>3, :id2=>4)
|
|
584
|
-
end
|
|
585
549
|
@dataset.filter([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (((id1 = 1) AND (id2 = 2)) OR ((id1 = 3) AND (id2 = 4)))"
|
|
586
550
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
587
|
-
db.sqls.clear
|
|
588
551
|
@dataset.exclude([:id1, :id2] => d1).sql.should == "SELECT * FROM test WHERE (((id1 != 1) OR (id2 != 2)) AND ((id1 != 3) OR (id2 != 4)))"
|
|
589
552
|
db.sqls.should == ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
|
|
590
553
|
end
|
|
@@ -687,33 +650,25 @@ describe "Dataset#or" do
|
|
|
687
650
|
end
|
|
688
651
|
|
|
689
652
|
specify "should add an alternative expression to the where clause" do
|
|
690
|
-
@d1.or(:y => 2).sql.should ==
|
|
691
|
-
'SELECT * FROM test WHERE ((x = 1) OR (y = 2))'
|
|
653
|
+
@d1.or(:y => 2).sql.should == 'SELECT * FROM test WHERE ((x = 1) OR (y = 2))'
|
|
692
654
|
end
|
|
693
655
|
|
|
694
656
|
specify "should accept all forms of filters" do
|
|
695
|
-
@d1.or('y > ?', 2).sql.should ==
|
|
696
|
-
|
|
697
|
-
@d1.or(:yy.sql_number > 3).sql.should ==
|
|
698
|
-
'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
|
657
|
+
@d1.or('y > ?', 2).sql.should == 'SELECT * FROM test WHERE ((x = 1) OR (y > 2))'
|
|
658
|
+
@d1.or(:yy.sql_number > 3).sql.should == 'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
|
699
659
|
end
|
|
700
660
|
|
|
701
661
|
specify "should accept blocks passed to filter" do
|
|
702
|
-
@d1.or{:yy.sql_number > 3}.sql.should ==
|
|
703
|
-
'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
|
662
|
+
@d1.or{:yy.sql_number > 3}.sql.should == 'SELECT * FROM test WHERE ((x = 1) OR (yy > 3))'
|
|
704
663
|
end
|
|
705
664
|
|
|
706
665
|
specify "should correctly add parens to give predictable results" do
|
|
707
|
-
@d1.filter(:y => 2).or(:z => 3).sql.should ==
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
@d1.or(:y => 2).filter(:z => 3).sql.should ==
|
|
711
|
-
'SELECT * FROM test WHERE (((x = 1) OR (y = 2)) AND (z = 3))'
|
|
666
|
+
@d1.filter(:y => 2).or(:z => 3).sql.should == 'SELECT * FROM test WHERE (((x = 1) AND (y = 2)) OR (z = 3))'
|
|
667
|
+
@d1.or(:y => 2).filter(:z => 3).sql.should == 'SELECT * FROM test WHERE (((x = 1) OR (y = 2)) AND (z = 3))'
|
|
712
668
|
end
|
|
713
669
|
|
|
714
670
|
specify "should allow the use of blocks and arguments simultaneously" do
|
|
715
|
-
@d1.or(:zz.sql_number < 3){:yy.sql_number > 3}.sql.should ==
|
|
716
|
-
'SELECT * FROM test WHERE ((x = 1) OR ((zz < 3) AND (yy > 3)))'
|
|
671
|
+
@d1.or(:zz.sql_number < 3){:yy.sql_number > 3}.sql.should == 'SELECT * FROM test WHERE ((x = 1) OR ((zz < 3) AND (yy > 3)))'
|
|
717
672
|
end
|
|
718
673
|
end
|
|
719
674
|
|
|
@@ -726,34 +681,25 @@ describe "Dataset#and" do
|
|
|
726
681
|
specify "should raise if no filter exists" do
|
|
727
682
|
proc {@dataset.and(:a => 1)}.should raise_error(Sequel::Error)
|
|
728
683
|
proc {@dataset.where(:a => 1).group(:t).and(:b => 2)}.should_not raise_error(Sequel::Error)
|
|
729
|
-
@dataset.where(:a => 1).group(:t).and(:b => 2).sql ==
|
|
730
|
-
"SELECT * FROM test WHERE (a = 1) AND (b = 2) GROUP BY t"
|
|
684
|
+
@dataset.where(:a => 1).group(:t).and(:b => 2).sql == "SELECT * FROM test WHERE (a = 1) AND (b = 2) GROUP BY t"
|
|
731
685
|
end
|
|
732
686
|
|
|
733
687
|
specify "should add an alternative expression to the where clause" do
|
|
734
|
-
@d1.and(:y => 2).sql.should ==
|
|
735
|
-
'SELECT * FROM test WHERE ((x = 1) AND (y = 2))'
|
|
688
|
+
@d1.and(:y => 2).sql.should == 'SELECT * FROM test WHERE ((x = 1) AND (y = 2))'
|
|
736
689
|
end
|
|
737
690
|
|
|
738
|
-
specify "should accept
|
|
739
|
-
|
|
740
|
-
@d1.and(
|
|
741
|
-
'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
|
|
742
|
-
@d1.and(:yy.sql_number > 3).sql.should ==
|
|
743
|
-
'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
|
691
|
+
specify "should accept different types of filters" do
|
|
692
|
+
@d1.and('y > ?', 2).sql.should == 'SELECT * FROM test WHERE ((x = 1) AND (y > 2))'
|
|
693
|
+
@d1.and(:yy.sql_number > 3).sql.should == 'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
|
744
694
|
end
|
|
745
695
|
|
|
746
696
|
specify "should accept blocks passed to filter" do
|
|
747
|
-
@d1.and {:yy.sql_number > 3}.sql.should ==
|
|
748
|
-
'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
|
697
|
+
@d1.and {:yy.sql_number > 3}.sql.should == 'SELECT * FROM test WHERE ((x = 1) AND (yy > 3))'
|
|
749
698
|
end
|
|
750
699
|
|
|
751
700
|
specify "should correctly add parens to give predictable results" do
|
|
752
|
-
@d1.or(:y => 2).and(:z => 3).sql.should ==
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
@d1.and(:y => 2).or(:z => 3).sql.should ==
|
|
756
|
-
'SELECT * FROM test WHERE (((x = 1) AND (y = 2)) OR (z = 3))'
|
|
701
|
+
@d1.or(:y => 2).and(:z => 3).sql.should == 'SELECT * FROM test WHERE (((x = 1) OR (y = 2)) AND (z = 3))'
|
|
702
|
+
@d1.and(:y => 2).or(:z => 3).sql.should == 'SELECT * FROM test WHERE (((x = 1) AND (y = 2)) OR (z = 3))'
|
|
757
703
|
end
|
|
758
704
|
end
|
|
759
705
|
|
|
@@ -763,13 +709,11 @@ describe "Dataset#exclude" do
|
|
|
763
709
|
end
|
|
764
710
|
|
|
765
711
|
specify "should correctly negate the expression when one condition is given" do
|
|
766
|
-
@dataset.exclude(:region=>'Asia').select_sql.should ==
|
|
767
|
-
"SELECT * FROM test WHERE (region != 'Asia')"
|
|
712
|
+
@dataset.exclude(:region=>'Asia').select_sql.should == "SELECT * FROM test WHERE (region != 'Asia')"
|
|
768
713
|
end
|
|
769
714
|
|
|
770
715
|
specify "should affect the having clause if having clause is already used" do
|
|
771
|
-
@dataset.group_and_count(:name).having{count > 2}.exclude{count > 5}.sql.should ==
|
|
772
|
-
"SELECT name, count(*) AS count FROM test GROUP BY name HAVING ((count > 2) AND (count <= 5))"
|
|
716
|
+
@dataset.group_and_count(:name).having{count > 2}.exclude{count > 5}.sql.should == "SELECT name, count(*) AS count FROM test GROUP BY name HAVING ((count > 2) AND (count <= 5))"
|
|
773
717
|
end
|
|
774
718
|
|
|
775
719
|
specify "should take multiple conditions as a hash and express the logic correctly in SQL" do
|
|
@@ -779,30 +723,24 @@ describe "Dataset#exclude" do
|
|
|
779
723
|
end
|
|
780
724
|
|
|
781
725
|
specify "should parenthesize a single string condition correctly" do
|
|
782
|
-
@dataset.exclude("region = 'Asia' AND name = 'Japan'").select_sql.should ==
|
|
783
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
|
726
|
+
@dataset.exclude("region = 'Asia' AND name = 'Japan'").select_sql.should == "SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
|
784
727
|
end
|
|
785
728
|
|
|
786
729
|
specify "should parenthesize an array condition correctly" do
|
|
787
|
-
@dataset.exclude('region = ? AND name = ?', 'Asia', 'Japan').select_sql.should ==
|
|
788
|
-
"SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
|
730
|
+
@dataset.exclude('region = ? AND name = ?', 'Asia', 'Japan').select_sql.should == "SELECT * FROM test WHERE NOT (region = 'Asia' AND name = 'Japan')"
|
|
789
731
|
end
|
|
790
732
|
|
|
791
733
|
specify "should correctly parenthesize when it is used twice" do
|
|
792
|
-
@dataset.exclude(:region => 'Asia').exclude(:name => 'Japan').select_sql.should ==
|
|
793
|
-
"SELECT * FROM test WHERE ((region != 'Asia') AND (name != 'Japan'))"
|
|
734
|
+
@dataset.exclude(:region => 'Asia').exclude(:name => 'Japan').select_sql.should == "SELECT * FROM test WHERE ((region != 'Asia') AND (name != 'Japan'))"
|
|
794
735
|
end
|
|
795
736
|
|
|
796
737
|
specify "should support proc expressions" do
|
|
797
|
-
@dataset.exclude{:id.sql_number < 6}.sql.should ==
|
|
798
|
-
'SELECT * FROM test WHERE (id >= 6)'
|
|
738
|
+
@dataset.exclude{:id.sql_number < 6}.sql.should == 'SELECT * FROM test WHERE (id >= 6)'
|
|
799
739
|
end
|
|
800
740
|
|
|
801
741
|
specify "should allow the use of blocks and arguments simultaneously" do
|
|
802
|
-
@dataset.exclude(:id => (7..11)){:id.sql_number < 6}.sql.should ==
|
|
803
|
-
|
|
804
|
-
@dataset.exclude([:id, 1], [:x, 3]){:id.sql_number < 6}.sql.should ==
|
|
805
|
-
'SELECT * FROM test WHERE ((id != 1) OR (x != 3) OR (id >= 6))'
|
|
742
|
+
@dataset.exclude(:id => (7..11)){:id.sql_number < 6}.sql.should == 'SELECT * FROM test WHERE ((id < 7) OR (id > 11) OR (id >= 6))'
|
|
743
|
+
@dataset.exclude([:id, 1], [:x, 3]){:id.sql_number < 6}.sql.should == 'SELECT * FROM test WHERE ((id != 1) OR (x != 3) OR (id >= 6))'
|
|
806
744
|
end
|
|
807
745
|
end
|
|
808
746
|
|
|
@@ -850,9 +788,6 @@ describe "Dataset#having" do
|
|
|
850
788
|
before do
|
|
851
789
|
@dataset = Sequel::Dataset.new(nil).from(:test)
|
|
852
790
|
@grouped = @dataset.group(:region).select(:region, :sum.sql_function(:population), :avg.sql_function(:gdp))
|
|
853
|
-
@d1 = @grouped.having('sum(population) > 10')
|
|
854
|
-
@d2 = @grouped.having(:region => 'Asia')
|
|
855
|
-
@columns = "region, sum(population), avg(gdp)"
|
|
856
791
|
end
|
|
857
792
|
|
|
858
793
|
specify "should just clone if given an empty argument" do
|
|
@@ -862,18 +797,15 @@ describe "Dataset#having" do
|
|
|
862
797
|
end
|
|
863
798
|
|
|
864
799
|
specify "should affect select statements" do
|
|
865
|
-
@
|
|
866
|
-
"SELECT #{@columns} FROM test GROUP BY region HAVING (sum(population) > 10)"
|
|
800
|
+
@grouped.having('sum(population) > 10').select_sql.should == "SELECT region, sum(population), avg(gdp) FROM test GROUP BY region HAVING (sum(population) > 10)"
|
|
867
801
|
end
|
|
868
802
|
|
|
869
803
|
specify "should support proc expressions" do
|
|
870
|
-
@grouped.having {:sum.sql_function(:population) > 10}.sql.should ==
|
|
871
|
-
"SELECT #{@columns} FROM test GROUP BY region HAVING (sum(population) > 10)"
|
|
804
|
+
@grouped.having {:sum.sql_function(:population) > 10}.sql.should == "SELECT region, sum(population), avg(gdp) FROM test GROUP BY region HAVING (sum(population) > 10)"
|
|
872
805
|
end
|
|
873
806
|
|
|
874
807
|
specify "should work with and on the having clause" do
|
|
875
|
-
@grouped.having( :a.sql_number > 1 ).and( :b.sql_number < 2 ).sql.should ==
|
|
876
|
-
"SELECT #{@columns} FROM test GROUP BY region HAVING ((a > 1) AND (b < 2))"
|
|
808
|
+
@grouped.having( :a.sql_number > 1 ).and( :b.sql_number < 2 ).sql.should == "SELECT region, sum(population), avg(gdp) FROM test GROUP BY region HAVING ((a > 1) AND (b < 2))"
|
|
877
809
|
end
|
|
878
810
|
end
|
|
879
811
|
|
|
@@ -904,7 +836,7 @@ describe "a grouped dataset" do
|
|
|
904
836
|
end
|
|
905
837
|
|
|
906
838
|
specify "should format the right statement for counting (as a subquery)" do
|
|
907
|
-
db =
|
|
839
|
+
db = Sequel.mock
|
|
908
840
|
db[:test].select(:name).group(:name).count
|
|
909
841
|
db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT name FROM test GROUP BY name) AS t1 LIMIT 1"]
|
|
910
842
|
end
|
|
@@ -924,31 +856,23 @@ describe "Dataset#group_by" do
|
|
|
924
856
|
end
|
|
925
857
|
|
|
926
858
|
specify "should specify the grouping in generated select statement" do
|
|
927
|
-
@dataset.select_sql.should ==
|
|
928
|
-
|
|
929
|
-
@dataset.group_by(:
|
|
930
|
-
"SELECT * FROM test GROUP BY a, b"
|
|
931
|
-
@dataset.group_by(:type_id=>nil).select_sql.should ==
|
|
932
|
-
"SELECT * FROM test GROUP BY (type_id IS NULL)"
|
|
859
|
+
@dataset.select_sql.should == "SELECT * FROM test GROUP BY type_id"
|
|
860
|
+
@dataset.group_by(:a, :b).select_sql.should == "SELECT * FROM test GROUP BY a, b"
|
|
861
|
+
@dataset.group_by(:type_id=>nil).select_sql.should == "SELECT * FROM test GROUP BY (type_id IS NULL)"
|
|
933
862
|
end
|
|
934
863
|
|
|
935
864
|
specify "should ungroup when passed nil or no arguments" do
|
|
936
|
-
@dataset.group_by.select_sql.should ==
|
|
937
|
-
|
|
938
|
-
@dataset.group_by(nil).select_sql.should ==
|
|
939
|
-
"SELECT * FROM test"
|
|
865
|
+
@dataset.group_by.select_sql.should == "SELECT * FROM test"
|
|
866
|
+
@dataset.group_by(nil).select_sql.should == "SELECT * FROM test"
|
|
940
867
|
end
|
|
941
868
|
|
|
942
869
|
specify "should undo previous grouping" do
|
|
943
|
-
@dataset.group_by(:a).group_by(:b).select_sql.should ==
|
|
944
|
-
|
|
945
|
-
@dataset.group_by(:a, :b).group_by.select_sql.should ==
|
|
946
|
-
"SELECT * FROM test"
|
|
870
|
+
@dataset.group_by(:a).group_by(:b).select_sql.should == "SELECT * FROM test GROUP BY b"
|
|
871
|
+
@dataset.group_by(:a, :b).group_by.select_sql.should == "SELECT * FROM test"
|
|
947
872
|
end
|
|
948
873
|
|
|
949
874
|
specify "should be aliased as #group" do
|
|
950
|
-
@dataset.group(:type_id=>nil).select_sql.should ==
|
|
951
|
-
"SELECT * FROM test GROUP BY (type_id IS NULL)"
|
|
875
|
+
@dataset.group(:type_id=>nil).select_sql.should == "SELECT * FROM test GROUP BY (type_id IS NULL)"
|
|
952
876
|
end
|
|
953
877
|
|
|
954
878
|
specify "should take a virtual row block" do
|
|
@@ -962,14 +886,13 @@ end
|
|
|
962
886
|
describe "Dataset#as" do
|
|
963
887
|
specify "should set up an alias" do
|
|
964
888
|
dataset = Sequel::Dataset.new(nil).from(:test)
|
|
965
|
-
dataset.select(dataset.limit(1).select(:name).as(:n)).sql.should ==
|
|
966
|
-
'SELECT (SELECT name FROM test LIMIT 1) AS n FROM test'
|
|
889
|
+
dataset.select(dataset.limit(1).select(:name).as(:n)).sql.should == 'SELECT (SELECT name FROM test LIMIT 1) AS n FROM test'
|
|
967
890
|
end
|
|
968
891
|
end
|
|
969
892
|
|
|
970
893
|
describe "Dataset#literal" do
|
|
971
894
|
before do
|
|
972
|
-
@dataset = Sequel::
|
|
895
|
+
@dataset = Sequel::Database.new.from(:test)
|
|
973
896
|
end
|
|
974
897
|
|
|
975
898
|
specify "should escape strings properly" do
|
|
@@ -1138,35 +1061,25 @@ describe "Dataset#from" do
|
|
|
1138
1061
|
end
|
|
1139
1062
|
|
|
1140
1063
|
specify "should format a Dataset as a subquery if it has had options set" do
|
|
1141
|
-
@dataset.from(@dataset.from(:a).where(:a=>1)).select_sql.should ==
|
|
1142
|
-
"SELECT * FROM (SELECT * FROM a WHERE (a = 1)) AS t1"
|
|
1064
|
+
@dataset.from(@dataset.from(:a).where(:a=>1)).select_sql.should == "SELECT * FROM (SELECT * FROM a WHERE (a = 1)) AS t1"
|
|
1143
1065
|
end
|
|
1144
1066
|
|
|
1145
1067
|
specify "should automatically alias sub-queries" do
|
|
1146
|
-
@dataset.from(@dataset.from(:a).group(:b)).select_sql.should ==
|
|
1147
|
-
"SELECT * FROM (SELECT * FROM a GROUP BY b) AS t1"
|
|
1068
|
+
@dataset.from(@dataset.from(:a).group(:b)).select_sql.should == "SELECT * FROM (SELECT * FROM a GROUP BY b) AS t1"
|
|
1148
1069
|
|
|
1149
1070
|
d1 = @dataset.from(:a).group(:b)
|
|
1150
1071
|
d2 = @dataset.from(:c).group(:d)
|
|
1151
|
-
|
|
1152
|
-
@dataset.from(d1, d2).sql.should ==
|
|
1153
|
-
"SELECT * FROM (SELECT * FROM a GROUP BY b) AS t1, (SELECT * FROM c GROUP BY d) AS t2"
|
|
1072
|
+
@dataset.from(d1, d2).sql.should == "SELECT * FROM (SELECT * FROM a GROUP BY b) AS t1, (SELECT * FROM c GROUP BY d) AS t2"
|
|
1154
1073
|
end
|
|
1155
1074
|
|
|
1156
1075
|
specify "should accept a hash for aliasing" do
|
|
1157
|
-
@dataset.from(:a => :b).sql.should ==
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
@dataset.from(:a => 'b').sql.should ==
|
|
1161
|
-
"SELECT * FROM a AS b"
|
|
1162
|
-
|
|
1163
|
-
@dataset.from(@dataset.from(:a).group(:b) => :c).sql.should ==
|
|
1164
|
-
"SELECT * FROM (SELECT * FROM a GROUP BY b) AS c"
|
|
1076
|
+
@dataset.from(:a => :b).sql.should == "SELECT * FROM a AS b"
|
|
1077
|
+
@dataset.from(:a => 'b').sql.should == "SELECT * FROM a AS b"
|
|
1078
|
+
@dataset.from(@dataset.from(:a).group(:b) => :c).sql.should == "SELECT * FROM (SELECT * FROM a GROUP BY b) AS c"
|
|
1165
1079
|
end
|
|
1166
1080
|
|
|
1167
1081
|
specify "should always use a subquery if given a dataset" do
|
|
1168
|
-
@dataset.from(@dataset.from(:a)).select_sql.should ==
|
|
1169
|
-
"SELECT * FROM (SELECT * FROM a) AS t1"
|
|
1082
|
+
@dataset.from(@dataset.from(:a)).select_sql.should == "SELECT * FROM (SELECT * FROM a) AS t1"
|
|
1170
1083
|
end
|
|
1171
1084
|
|
|
1172
1085
|
specify "should remove all FROM tables if called with no arguments" do
|
|
@@ -1174,32 +1087,27 @@ describe "Dataset#from" do
|
|
|
1174
1087
|
end
|
|
1175
1088
|
|
|
1176
1089
|
specify "should accept sql functions" do
|
|
1177
|
-
@dataset.from(:abc.sql_function(:def)).select_sql.should ==
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
@dataset.from(:a.sql_function(:i)).select_sql.should ==
|
|
1181
|
-
"SELECT * FROM a(i)"
|
|
1090
|
+
@dataset.from(:abc.sql_function(:def)).select_sql.should == "SELECT * FROM abc(def)"
|
|
1091
|
+
@dataset.from(:a.sql_function(:i)).select_sql.should == "SELECT * FROM a(i)"
|
|
1182
1092
|
end
|
|
1183
1093
|
|
|
1184
1094
|
specify "should accept :schema__table___alias symbol format" do
|
|
1185
|
-
@dataset.from(:abc__def).select_sql.should ==
|
|
1186
|
-
|
|
1187
|
-
@dataset.from(:
|
|
1188
|
-
|
|
1189
|
-
@dataset.from(:
|
|
1190
|
-
|
|
1191
|
-
@dataset.from(:
|
|
1192
|
-
|
|
1193
|
-
@dataset.from(:
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
@dataset.
|
|
1198
|
-
|
|
1199
|
-
@dataset.from(:
|
|
1200
|
-
|
|
1201
|
-
@dataset.from(:'#___#').select_sql.should ==
|
|
1202
|
-
'SELECT * FROM # AS #'
|
|
1095
|
+
@dataset.from(:abc__def).select_sql.should == "SELECT * FROM abc.def"
|
|
1096
|
+
@dataset.from(:a_b__c).select_sql.should == "SELECT * FROM a_b.c"
|
|
1097
|
+
@dataset.from(:'#__#').select_sql.should == 'SELECT * FROM #.#'
|
|
1098
|
+
@dataset.from(:abc__def___d).select_sql.should == "SELECT * FROM abc.def AS d"
|
|
1099
|
+
@dataset.from(:a_b__d_e___f_g).select_sql.should == "SELECT * FROM a_b.d_e AS f_g"
|
|
1100
|
+
@dataset.from(:'#__#___#').select_sql.should == 'SELECT * FROM #.# AS #'
|
|
1101
|
+
@dataset.from(:abc___def).select_sql.should == "SELECT * FROM abc AS def"
|
|
1102
|
+
@dataset.from(:a_b___c_d).select_sql.should == "SELECT * FROM a_b AS c_d"
|
|
1103
|
+
@dataset.from(:'#___#').select_sql.should == 'SELECT * FROM # AS #'
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
specify "should hoist WITH clauses from subqueries if the dataset doesn't support CTEs in subselects" do
|
|
1107
|
+
@dataset.meta_def(:supports_cte?){true}
|
|
1108
|
+
@dataset.meta_def(:supports_cte_in_subselect?){false}
|
|
1109
|
+
@dataset.from(@dataset.from(:a).with(:a, @dataset.from(:b))).sql.should == 'WITH a AS (SELECT * FROM b) SELECT * FROM (SELECT * FROM a) AS t1'
|
|
1110
|
+
@dataset.from(@dataset.from(:a).with(:a, @dataset.from(:b)), @dataset.from(:c).with(:c, @dataset.from(:d))).sql.should == 'WITH a AS (SELECT * FROM b), c AS (SELECT * FROM d) SELECT * FROM (SELECT * FROM a) AS t1, (SELECT * FROM c) AS t2'
|
|
1203
1111
|
end
|
|
1204
1112
|
end
|
|
1205
1113
|
|
|
@@ -1216,18 +1124,17 @@ describe "Dataset#select" do
|
|
|
1216
1124
|
specify "should accept symbols and literal strings" do
|
|
1217
1125
|
@d.select('aaa'.lit).sql.should == 'SELECT aaa FROM test'
|
|
1218
1126
|
@d.select(:a, 'b'.lit).sql.should == 'SELECT a, b FROM test'
|
|
1219
|
-
@d.select(:test__cc, 'test.d AS e'.lit).sql.should ==
|
|
1220
|
-
|
|
1221
|
-
@d.select(
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
@d.select(:test.*).sql.should ==
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
@d.select(:
|
|
1230
|
-
'SELECT test.name AS n FROM test'
|
|
1127
|
+
@d.select(:test__cc, 'test.d AS e'.lit).sql.should == 'SELECT test.cc, test.d AS e FROM test'
|
|
1128
|
+
@d.select('test.d AS e'.lit, :test__cc).sql.should == 'SELECT test.d AS e, test.cc FROM test'
|
|
1129
|
+
@d.select(:test__name___n).sql.should == 'SELECT test.name AS n FROM test'
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
specify "should accept ColumnAlls" do
|
|
1133
|
+
@d.select(:test.*).sql.should == 'SELECT test.* FROM test'
|
|
1134
|
+
end
|
|
1135
|
+
|
|
1136
|
+
specify "should accept QualifiedIdentifiers" do
|
|
1137
|
+
@d.select(:test__name.as(:n)).sql.should == 'SELECT test.name AS n FROM test'
|
|
1231
1138
|
end
|
|
1232
1139
|
|
|
1233
1140
|
specify "should use the wildcard if no arguments are given" do
|
|
@@ -1235,20 +1142,17 @@ describe "Dataset#select" do
|
|
|
1235
1142
|
end
|
|
1236
1143
|
|
|
1237
1144
|
specify "should accept a hash for AS values" do
|
|
1238
|
-
@d.select(:name => 'n', :__ggh => 'age').sql.should =~
|
|
1239
|
-
/SELECT ((name AS n, __ggh AS age)|(__ggh AS age, name AS n)) FROM test/
|
|
1145
|
+
@d.select(:name => 'n', :__ggh => 'age').sql.should =~ /SELECT ((name AS n, __ggh AS age)|(__ggh AS age, name AS n)) FROM test/
|
|
1240
1146
|
end
|
|
1241
1147
|
|
|
1242
|
-
specify "should
|
|
1148
|
+
specify "should override the previous select option" do
|
|
1243
1149
|
@d.select!(:a, :b, :c).select.sql.should == 'SELECT * FROM test'
|
|
1244
1150
|
@d.select!(:price).select(:name).sql.should == 'SELECT name FROM test'
|
|
1245
1151
|
end
|
|
1246
1152
|
|
|
1247
1153
|
specify "should accept arbitrary objects and literalize them correctly" do
|
|
1248
1154
|
@d.select(1, :a, 't').sql.should == "SELECT 1, a, 't' FROM test"
|
|
1249
|
-
|
|
1250
1155
|
@d.select(nil, :sum.sql_function(:t), :x___y).sql.should == "SELECT NULL, sum(t), x AS y FROM test"
|
|
1251
|
-
|
|
1252
1156
|
@d.select(nil, 1, :x => :y).sql.should == "SELECT NULL, 1, x AS y FROM test"
|
|
1253
1157
|
end
|
|
1254
1158
|
|
|
@@ -1297,7 +1201,7 @@ describe "Dataset#select_all" do
|
|
|
1297
1201
|
@d.select_all.sql.should == 'SELECT * FROM test'
|
|
1298
1202
|
end
|
|
1299
1203
|
|
|
1300
|
-
specify "should
|
|
1204
|
+
specify "should override the previous select option" do
|
|
1301
1205
|
@d.select!(:a, :b, :c).select_all.sql.should == 'SELECT * FROM test'
|
|
1302
1206
|
end
|
|
1303
1207
|
|
|
@@ -1394,38 +1298,31 @@ describe "Dataset#order" do
|
|
|
1394
1298
|
end
|
|
1395
1299
|
|
|
1396
1300
|
specify "should include an ORDER BY clause in the select statement" do
|
|
1397
|
-
@dataset.order(:name).sql.should ==
|
|
1398
|
-
'SELECT * FROM test ORDER BY name'
|
|
1301
|
+
@dataset.order(:name).sql.should == 'SELECT * FROM test ORDER BY name'
|
|
1399
1302
|
end
|
|
1400
1303
|
|
|
1401
1304
|
specify "should accept multiple arguments" do
|
|
1402
|
-
@dataset.order(:name, :price.desc).sql.should ==
|
|
1403
|
-
'SELECT * FROM test ORDER BY name, price DESC'
|
|
1305
|
+
@dataset.order(:name, :price.desc).sql.should == 'SELECT * FROM test ORDER BY name, price DESC'
|
|
1404
1306
|
end
|
|
1405
1307
|
|
|
1406
1308
|
specify "should accept :nulls options for asc and desc" do
|
|
1407
|
-
@dataset.order(:name.asc(:nulls=>:last), :price.desc(:nulls=>:first)).sql.should ==
|
|
1408
|
-
'SELECT * FROM test ORDER BY name ASC NULLS LAST, price DESC NULLS FIRST'
|
|
1309
|
+
@dataset.order(:name.asc(:nulls=>:last), :price.desc(:nulls=>:first)).sql.should == 'SELECT * FROM test ORDER BY name ASC NULLS LAST, price DESC NULLS FIRST'
|
|
1409
1310
|
end
|
|
1410
1311
|
|
|
1411
|
-
specify "should
|
|
1412
|
-
@dataset.order(:name).order(:stamp).sql.should ==
|
|
1413
|
-
'SELECT * FROM test ORDER BY stamp'
|
|
1312
|
+
specify "should override a previous ordering" do
|
|
1313
|
+
@dataset.order(:name).order(:stamp).sql.should == 'SELECT * FROM test ORDER BY stamp'
|
|
1414
1314
|
end
|
|
1415
1315
|
|
|
1416
1316
|
specify "should accept a literal string" do
|
|
1417
|
-
@dataset.order('dada ASC'.lit).sql.should ==
|
|
1418
|
-
'SELECT * FROM test ORDER BY dada ASC'
|
|
1317
|
+
@dataset.order('dada ASC'.lit).sql.should == 'SELECT * FROM test ORDER BY dada ASC'
|
|
1419
1318
|
end
|
|
1420
1319
|
|
|
1421
1320
|
specify "should accept a hash as an expression" do
|
|
1422
|
-
@dataset.order(:name=>nil).sql.should ==
|
|
1423
|
-
'SELECT * FROM test ORDER BY (name IS NULL)'
|
|
1321
|
+
@dataset.order(:name=>nil).sql.should == 'SELECT * FROM test ORDER BY (name IS NULL)'
|
|
1424
1322
|
end
|
|
1425
1323
|
|
|
1426
1324
|
specify "should accept a nil to remove ordering" do
|
|
1427
|
-
@dataset.order(:bah).order(nil).sql.should ==
|
|
1428
|
-
'SELECT * FROM test'
|
|
1325
|
+
@dataset.order(:bah).order(nil).sql.should == 'SELECT * FROM test'
|
|
1429
1326
|
end
|
|
1430
1327
|
|
|
1431
1328
|
specify "should accept a block that yields a virtual row" do
|
|
@@ -1502,28 +1399,23 @@ describe "Dataset#order_by" do
|
|
|
1502
1399
|
end
|
|
1503
1400
|
|
|
1504
1401
|
specify "should include an ORDER BY clause in the select statement" do
|
|
1505
|
-
@dataset.order_by(:name).sql.should ==
|
|
1506
|
-
'SELECT * FROM test ORDER BY name'
|
|
1402
|
+
@dataset.order_by(:name).sql.should == 'SELECT * FROM test ORDER BY name'
|
|
1507
1403
|
end
|
|
1508
1404
|
|
|
1509
1405
|
specify "should accept multiple arguments" do
|
|
1510
|
-
@dataset.order_by(:name, :price.desc).sql.should ==
|
|
1511
|
-
'SELECT * FROM test ORDER BY name, price DESC'
|
|
1406
|
+
@dataset.order_by(:name, :price.desc).sql.should == 'SELECT * FROM test ORDER BY name, price DESC'
|
|
1512
1407
|
end
|
|
1513
1408
|
|
|
1514
|
-
specify "should
|
|
1515
|
-
@dataset.order_by(:name).order(:stamp).sql.should ==
|
|
1516
|
-
'SELECT * FROM test ORDER BY stamp'
|
|
1409
|
+
specify "should override a previous ordering" do
|
|
1410
|
+
@dataset.order_by(:name).order(:stamp).sql.should == 'SELECT * FROM test ORDER BY stamp'
|
|
1517
1411
|
end
|
|
1518
1412
|
|
|
1519
1413
|
specify "should accept a string" do
|
|
1520
|
-
@dataset.order_by('dada ASC'.lit).sql.should ==
|
|
1521
|
-
'SELECT * FROM test ORDER BY dada ASC'
|
|
1414
|
+
@dataset.order_by('dada ASC'.lit).sql.should == 'SELECT * FROM test ORDER BY dada ASC'
|
|
1522
1415
|
end
|
|
1523
1416
|
|
|
1524
1417
|
specify "should accept a nil to remove ordering" do
|
|
1525
|
-
@dataset.order_by(:bah).order_by(nil).sql.should ==
|
|
1526
|
-
'SELECT * FROM test'
|
|
1418
|
+
@dataset.order_by(:bah).order_by(nil).sql.should == 'SELECT * FROM test'
|
|
1527
1419
|
end
|
|
1528
1420
|
end
|
|
1529
1421
|
|
|
@@ -1556,13 +1448,11 @@ describe "Dataset#order_prepend" do
|
|
|
1556
1448
|
end
|
|
1557
1449
|
|
|
1558
1450
|
specify "should include an ORDER BY clause in the select statement" do
|
|
1559
|
-
@dataset.order_prepend(:name).sql.should ==
|
|
1560
|
-
'SELECT * FROM test ORDER BY name'
|
|
1451
|
+
@dataset.order_prepend(:name).sql.should == 'SELECT * FROM test ORDER BY name'
|
|
1561
1452
|
end
|
|
1562
1453
|
|
|
1563
1454
|
specify "should add to the beginning of a previous ordering" do
|
|
1564
|
-
@dataset.order(:name).order_prepend(:stamp.desc).sql.should ==
|
|
1565
|
-
'SELECT * FROM test ORDER BY stamp DESC, name'
|
|
1455
|
+
@dataset.order(:name).order_prepend(:stamp.desc).sql.should == 'SELECT * FROM test ORDER BY stamp DESC, name'
|
|
1566
1456
|
end
|
|
1567
1457
|
|
|
1568
1458
|
specify "should accept a block that yields a virtual row" do
|
|
@@ -1577,45 +1467,36 @@ describe "Dataset#reverse_order" do
|
|
|
1577
1467
|
end
|
|
1578
1468
|
|
|
1579
1469
|
specify "should use DESC as default order" do
|
|
1580
|
-
@dataset.reverse_order(:name).sql.should ==
|
|
1581
|
-
'SELECT * FROM test ORDER BY name DESC'
|
|
1470
|
+
@dataset.reverse_order(:name).sql.should == 'SELECT * FROM test ORDER BY name DESC'
|
|
1582
1471
|
end
|
|
1583
1472
|
|
|
1584
1473
|
specify "should invert the order given" do
|
|
1585
|
-
@dataset.reverse_order(:name.desc).sql.should ==
|
|
1586
|
-
'SELECT * FROM test ORDER BY name ASC'
|
|
1474
|
+
@dataset.reverse_order(:name.desc).sql.should == 'SELECT * FROM test ORDER BY name ASC'
|
|
1587
1475
|
end
|
|
1588
1476
|
|
|
1589
1477
|
specify "should invert the order for ASC expressions" do
|
|
1590
|
-
@dataset.reverse_order(:name.asc).sql.should ==
|
|
1591
|
-
'SELECT * FROM test ORDER BY name DESC'
|
|
1478
|
+
@dataset.reverse_order(:name.asc).sql.should == 'SELECT * FROM test ORDER BY name DESC'
|
|
1592
1479
|
end
|
|
1593
1480
|
|
|
1594
1481
|
specify "should accept multiple arguments" do
|
|
1595
|
-
@dataset.reverse_order(:name, :price.desc).sql.should ==
|
|
1596
|
-
'SELECT * FROM test ORDER BY name DESC, price ASC'
|
|
1482
|
+
@dataset.reverse_order(:name, :price.desc).sql.should == 'SELECT * FROM test ORDER BY name DESC, price ASC'
|
|
1597
1483
|
end
|
|
1598
1484
|
|
|
1599
1485
|
specify "should handles NULLS ordering correctly when reversing" do
|
|
1600
|
-
@dataset.reverse_order(:name.asc(:nulls=>:first), :price.desc(:nulls=>:last)).sql.should ==
|
|
1601
|
-
'SELECT * FROM test ORDER BY name DESC NULLS LAST, price ASC NULLS FIRST'
|
|
1486
|
+
@dataset.reverse_order(:name.asc(:nulls=>:first), :price.desc(:nulls=>:last)).sql.should == 'SELECT * FROM test ORDER BY name DESC NULLS LAST, price ASC NULLS FIRST'
|
|
1602
1487
|
end
|
|
1603
1488
|
|
|
1604
1489
|
specify "should reverse a previous ordering if no arguments are given" do
|
|
1605
|
-
@dataset.order(:name).reverse_order.sql.should ==
|
|
1606
|
-
|
|
1607
|
-
@dataset.order(:clumsy.desc, :fool).reverse_order.sql.should ==
|
|
1608
|
-
'SELECT * FROM test ORDER BY clumsy ASC, fool DESC'
|
|
1490
|
+
@dataset.order(:name).reverse_order.sql.should == 'SELECT * FROM test ORDER BY name DESC'
|
|
1491
|
+
@dataset.order(:clumsy.desc, :fool).reverse_order.sql.should == 'SELECT * FROM test ORDER BY clumsy ASC, fool DESC'
|
|
1609
1492
|
end
|
|
1610
1493
|
|
|
1611
1494
|
specify "should return an unordered dataset for a dataset with no order" do
|
|
1612
|
-
@dataset.unordered.reverse_order.sql.should ==
|
|
1613
|
-
'SELECT * FROM test'
|
|
1495
|
+
@dataset.unordered.reverse_order.sql.should == 'SELECT * FROM test'
|
|
1614
1496
|
end
|
|
1615
1497
|
|
|
1616
1498
|
specify "should have #reverse alias" do
|
|
1617
|
-
@dataset.order(:name).reverse.sql.should ==
|
|
1618
|
-
'SELECT * FROM test ORDER BY name DESC'
|
|
1499
|
+
@dataset.order(:name).reverse.sql.should == 'SELECT * FROM test ORDER BY name DESC'
|
|
1619
1500
|
end
|
|
1620
1501
|
end
|
|
1621
1502
|
|
|
@@ -1625,42 +1506,33 @@ describe "Dataset#limit" do
|
|
|
1625
1506
|
end
|
|
1626
1507
|
|
|
1627
1508
|
specify "should include a LIMIT clause in the select statement" do
|
|
1628
|
-
@dataset.limit(10).sql.should ==
|
|
1629
|
-
'SELECT * FROM test LIMIT 10'
|
|
1509
|
+
@dataset.limit(10).sql.should == 'SELECT * FROM test LIMIT 10'
|
|
1630
1510
|
end
|
|
1631
1511
|
|
|
1632
1512
|
specify "should accept ranges" do
|
|
1633
|
-
@dataset.limit(3..7).sql.should ==
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
@dataset.limit(3...7).sql.should ==
|
|
1637
|
-
'SELECT * FROM test LIMIT 4 OFFSET 3'
|
|
1513
|
+
@dataset.limit(3..7).sql.should == 'SELECT * FROM test LIMIT 5 OFFSET 3'
|
|
1514
|
+
@dataset.limit(3...7).sql.should == 'SELECT * FROM test LIMIT 4 OFFSET 3'
|
|
1638
1515
|
end
|
|
1639
1516
|
|
|
1640
1517
|
specify "should include an offset if a second argument is given" do
|
|
1641
|
-
@dataset.limit(6, 10).sql.should ==
|
|
1642
|
-
|
|
1643
|
-
end
|
|
1518
|
+
@dataset.limit(6, 10).sql.should == 'SELECT * FROM test LIMIT 6 OFFSET 10'
|
|
1519
|
+
end
|
|
1644
1520
|
|
|
1645
1521
|
specify "should convert regular strings to integers" do
|
|
1646
|
-
@dataset.limit('6', 'a() - 1').sql.should ==
|
|
1647
|
-
'SELECT * FROM test LIMIT 6 OFFSET 0'
|
|
1522
|
+
@dataset.limit('6', 'a() - 1').sql.should == 'SELECT * FROM test LIMIT 6 OFFSET 0'
|
|
1648
1523
|
end
|
|
1649
1524
|
|
|
1650
1525
|
specify "should not convert literal strings to integers" do
|
|
1651
|
-
@dataset.limit('6'.lit, 'a() - 1'.lit).sql.should ==
|
|
1652
|
-
'SELECT * FROM test LIMIT 6 OFFSET a() - 1'
|
|
1526
|
+
@dataset.limit('6'.lit, 'a() - 1'.lit).sql.should == 'SELECT * FROM test LIMIT 6 OFFSET a() - 1'
|
|
1653
1527
|
end
|
|
1654
1528
|
|
|
1655
1529
|
specify "should not convert other objects" do
|
|
1656
|
-
@dataset.limit(6, :a.sql_function - 1).sql.should ==
|
|
1657
|
-
'SELECT * FROM test LIMIT 6 OFFSET (a() - 1)'
|
|
1530
|
+
@dataset.limit(6, :a.sql_function - 1).sql.should == 'SELECT * FROM test LIMIT 6 OFFSET (a() - 1)'
|
|
1658
1531
|
end
|
|
1659
1532
|
|
|
1660
1533
|
specify "should work with fixed sql datasets" do
|
|
1661
1534
|
@dataset.opts[:sql] = 'select * from cccc'
|
|
1662
|
-
@dataset.limit(6, 10).sql.should ==
|
|
1663
|
-
'SELECT * FROM (select * from cccc) AS t1 LIMIT 6 OFFSET 10'
|
|
1535
|
+
@dataset.limit(6, 10).sql.should == 'SELECT * FROM (select * from cccc) AS t1 LIMIT 6 OFFSET 10'
|
|
1664
1536
|
end
|
|
1665
1537
|
|
|
1666
1538
|
specify "should raise an error if an invalid limit or offset is used" do
|
|
@@ -1674,15 +1546,10 @@ describe "Dataset#limit" do
|
|
|
1674
1546
|
end
|
|
1675
1547
|
|
|
1676
1548
|
describe "Dataset#naked" do
|
|
1677
|
-
before do
|
|
1678
|
-
@d1 = Sequel::Dataset.new(nil, {1 => 2, 3 => 4})
|
|
1679
|
-
@d2 = @d1.clone
|
|
1680
|
-
@d2.row_proc = Proc.new{|r| r}
|
|
1681
|
-
end
|
|
1682
|
-
|
|
1683
1549
|
specify "should remove any existing row_proc" do
|
|
1684
|
-
|
|
1685
|
-
|
|
1550
|
+
d = Sequel::Dataset.new(nil)
|
|
1551
|
+
d.row_proc = Proc.new{|r| r}
|
|
1552
|
+
d.naked.row_proc.should be_nil
|
|
1686
1553
|
end
|
|
1687
1554
|
end
|
|
1688
1555
|
|
|
@@ -1712,11 +1579,11 @@ end
|
|
|
1712
1579
|
|
|
1713
1580
|
describe "Dataset#map" do
|
|
1714
1581
|
before do
|
|
1715
|
-
@d =
|
|
1582
|
+
@d = Sequel.mock(:fetch=>[{:a => 1, :b => 2}, {:a => 3, :b => 4}, {:a => 5, :b => 6}])[:items]
|
|
1716
1583
|
end
|
|
1717
1584
|
|
|
1718
1585
|
specify "should provide the usual functionality if no argument is given" do
|
|
1719
|
-
@d.map
|
|
1586
|
+
@d.map{|n| n[:a] + n[:b]}.should == [3, 7, 11]
|
|
1720
1587
|
end
|
|
1721
1588
|
|
|
1722
1589
|
specify "should map using #[column name] if column name is given" do
|
|
@@ -1727,14 +1594,25 @@ describe "Dataset#map" do
|
|
|
1727
1594
|
@d.map([:a, :b]).should == [[1, 2], [3, 4], [5, 6]]
|
|
1728
1595
|
end
|
|
1729
1596
|
|
|
1597
|
+
specify "should not call the row_proc if an argument is given" do
|
|
1598
|
+
@d.row_proc = proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h}
|
|
1599
|
+
@d.map(:a).should == [1, 3, 5]
|
|
1600
|
+
@d.map([:a, :b]).should == [[1, 2], [3, 4], [5, 6]]
|
|
1601
|
+
end
|
|
1602
|
+
|
|
1603
|
+
specify "should call the row_proc if no argument is given" do
|
|
1604
|
+
@d.row_proc = proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h}
|
|
1605
|
+
@d.map{|n| n[:a] + n[:b]}.should == [6, 14, 22]
|
|
1606
|
+
end
|
|
1607
|
+
|
|
1730
1608
|
specify "should return the complete dataset values if nothing is given" do
|
|
1731
|
-
@d.map.to_a.should ==
|
|
1609
|
+
@d.map.to_a.should == [{:a => 1, :b => 2}, {:a => 3, :b => 4}, {:a => 5, :b => 6}]
|
|
1732
1610
|
end
|
|
1733
1611
|
end
|
|
1734
1612
|
|
|
1735
1613
|
describe "Dataset#to_hash" do
|
|
1736
1614
|
before do
|
|
1737
|
-
@d =
|
|
1615
|
+
@d = Sequel.mock(:fetch=>[{:a => 1, :b => 2}, {:a => 3, :b => 4}, {:a => 5, :b => 6}])[:items]
|
|
1738
1616
|
end
|
|
1739
1617
|
|
|
1740
1618
|
specify "should provide a hash with the first column as key and the second as value" do
|
|
@@ -1753,11 +1631,28 @@ describe "Dataset#to_hash" do
|
|
|
1753
1631
|
@d.to_hash([:b, :a], [:a, :b]).should == {[2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6]}
|
|
1754
1632
|
@d.to_hash([:a, :b]).should == {[1, 2] => {:a => 1, :b => 2}, [3, 4] => {:a => 3, :b => 4}, [5, 6] => {:a => 5, :b => 6}}
|
|
1755
1633
|
end
|
|
1634
|
+
|
|
1635
|
+
specify "should not call the row_proc if two arguments are given" do
|
|
1636
|
+
@d.row_proc = proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h}
|
|
1637
|
+
@d.to_hash(:a, :b).should == {1 => 2, 3 => 4, 5 => 6}
|
|
1638
|
+
@d.to_hash(:b, :a).should == {2 => 1, 4 => 3, 6 => 5}
|
|
1639
|
+
@d.to_hash([:a, :b], :b).should == {[1, 2] => 2, [3, 4] => 4, [5, 6] => 6}
|
|
1640
|
+
@d.to_hash(:b, [:a, :b]).should == {2 => [1, 2], 4 => [3, 4], 6 => [5, 6]}
|
|
1641
|
+
@d.to_hash([:b, :a], [:a, :b]).should == {[2, 1] => [1, 2], [4, 3] => [3, 4], [6, 5] => [5, 6]}
|
|
1642
|
+
end
|
|
1643
|
+
|
|
1644
|
+
specify "should call the row_proc if only a single argument is given" do
|
|
1645
|
+
@d.row_proc = proc{|r| h = {}; r.keys.each{|k| h[k] = r[k] * 2}; h}
|
|
1646
|
+
@d.to_hash(:a).should == {2 => {:a => 2, :b => 4}, 6 => {:a => 6, :b => 8}, 10 => {:a => 10, :b => 12}}
|
|
1647
|
+
@d.to_hash(:b).should == {4 => {:a => 2, :b => 4}, 8 => {:a => 6, :b => 8}, 12 => {:a => 10, :b => 12}}
|
|
1648
|
+
@d.to_hash([:a, :b]).should == {[2, 4] => {:a => 2, :b => 4}, [6, 8] => {:a => 6, :b => 8}, [10, 12] => {:a => 10, :b => 12}}
|
|
1649
|
+
end
|
|
1650
|
+
|
|
1756
1651
|
end
|
|
1757
1652
|
|
|
1758
1653
|
describe "Dataset#distinct" do
|
|
1759
1654
|
before do
|
|
1760
|
-
@db =
|
|
1655
|
+
@db = Sequel.mock
|
|
1761
1656
|
@dataset = @db[:test].select(:name)
|
|
1762
1657
|
end
|
|
1763
1658
|
|
|
@@ -1784,113 +1679,84 @@ end
|
|
|
1784
1679
|
|
|
1785
1680
|
describe "Dataset#count" do
|
|
1786
1681
|
before do
|
|
1787
|
-
@
|
|
1788
|
-
|
|
1789
|
-
@@sql
|
|
1790
|
-
end
|
|
1791
|
-
|
|
1792
|
-
def fetch_rows(sql)
|
|
1793
|
-
@columns = [sql =~ /SELECT COUNT/i ? :count : :a]
|
|
1794
|
-
@@sql = sql
|
|
1795
|
-
yield({@columns.first=>1})
|
|
1796
|
-
end
|
|
1797
|
-
end
|
|
1798
|
-
@dataset = @c.new(nil).from(:test)
|
|
1682
|
+
@db = Sequel.mock(:fetch=>{:count=>1})
|
|
1683
|
+
@dataset = @db.from(:test).columns(:count)
|
|
1799
1684
|
end
|
|
1800
1685
|
|
|
1801
1686
|
specify "should format SQL properly" do
|
|
1802
1687
|
@dataset.count.should == 1
|
|
1803
|
-
@
|
|
1688
|
+
@db.sqls.should == ['SELECT COUNT(*) AS count FROM test LIMIT 1']
|
|
1804
1689
|
end
|
|
1805
1690
|
|
|
1806
1691
|
specify "should include the where clause if it's there" do
|
|
1807
1692
|
@dataset.filter(:abc.sql_number < 30).count.should == 1
|
|
1808
|
-
@
|
|
1693
|
+
@db.sqls.should == ['SELECT COUNT(*) AS count FROM test WHERE (abc < 30) LIMIT 1']
|
|
1809
1694
|
end
|
|
1810
1695
|
|
|
1811
1696
|
specify "should count properly for datasets with fixed sql" do
|
|
1812
1697
|
@dataset.opts[:sql] = "select abc from xyz"
|
|
1813
1698
|
@dataset.count.should == 1
|
|
1814
|
-
@
|
|
1699
|
+
@db.sqls.should == ["SELECT COUNT(*) AS count FROM (select abc from xyz) AS t1 LIMIT 1"]
|
|
1815
1700
|
end
|
|
1816
1701
|
|
|
1817
1702
|
specify "should count properly when using UNION, INTERSECT, or EXCEPT" do
|
|
1818
1703
|
@dataset.union(@dataset).count.should == 1
|
|
1819
|
-
@
|
|
1704
|
+
@db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test UNION SELECT * FROM test) AS t1 LIMIT 1"]
|
|
1820
1705
|
@dataset.intersect(@dataset).count.should == 1
|
|
1821
|
-
@
|
|
1706
|
+
@db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test INTERSECT SELECT * FROM test) AS t1 LIMIT 1"]
|
|
1822
1707
|
@dataset.except(@dataset).count.should == 1
|
|
1823
|
-
@
|
|
1708
|
+
@db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test EXCEPT SELECT * FROM test) AS t1 LIMIT 1"]
|
|
1824
1709
|
end
|
|
1825
1710
|
|
|
1826
1711
|
specify "should return limit if count is greater than it" do
|
|
1827
1712
|
@dataset.limit(5).count.should == 1
|
|
1828
|
-
@
|
|
1713
|
+
@db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test LIMIT 5) AS t1 LIMIT 1"]
|
|
1829
1714
|
end
|
|
1830
1715
|
|
|
1831
1716
|
it "should work on a graphed_dataset" do
|
|
1832
1717
|
@dataset.should_receive(:columns).twice.and_return([:a])
|
|
1833
1718
|
@dataset.graph(@dataset, [:a], :table_alias=>:test2).count.should == 1
|
|
1834
|
-
@
|
|
1719
|
+
@db.sqls.should == ['SELECT COUNT(*) AS count FROM test LEFT OUTER JOIN test AS test2 USING (a) LIMIT 1']
|
|
1835
1720
|
end
|
|
1836
1721
|
|
|
1837
1722
|
specify "should not cache the columns value" do
|
|
1838
|
-
ds = @dataset.from(:blah)
|
|
1723
|
+
ds = @dataset.from(:blah).columns(:a)
|
|
1839
1724
|
ds.columns.should == [:a]
|
|
1840
1725
|
ds.count.should == 1
|
|
1841
|
-
@
|
|
1726
|
+
@db.sqls.should == ['SELECT COUNT(*) AS count FROM blah LIMIT 1']
|
|
1842
1727
|
ds.columns.should == [:a]
|
|
1843
1728
|
end
|
|
1844
1729
|
end
|
|
1845
1730
|
|
|
1846
|
-
|
|
1847
1731
|
describe "Dataset#group_and_count" do
|
|
1848
1732
|
before do
|
|
1849
|
-
@
|
|
1850
|
-
def self.sql
|
|
1851
|
-
@@sql
|
|
1852
|
-
end
|
|
1853
|
-
|
|
1854
|
-
def fetch_rows(sql)
|
|
1855
|
-
@@sql = sql
|
|
1856
|
-
yield({1 => 1})
|
|
1857
|
-
end
|
|
1858
|
-
end
|
|
1859
|
-
@ds = @c.new(nil).from(:test)
|
|
1733
|
+
@ds = Sequel::Dataset.new(nil).from(:test)
|
|
1860
1734
|
end
|
|
1861
1735
|
|
|
1862
1736
|
specify "should format SQL properly" do
|
|
1863
|
-
@ds.group_and_count(:name).sql.should ==
|
|
1864
|
-
"SELECT name, count(*) AS count FROM test GROUP BY name"
|
|
1737
|
+
@ds.group_and_count(:name).sql.should == "SELECT name, count(*) AS count FROM test GROUP BY name"
|
|
1865
1738
|
end
|
|
1866
1739
|
|
|
1867
1740
|
specify "should accept multiple columns for grouping" do
|
|
1868
|
-
@ds.group_and_count(:a, :b).sql.should ==
|
|
1869
|
-
"SELECT a, b, count(*) AS count FROM test GROUP BY a, b"
|
|
1741
|
+
@ds.group_and_count(:a, :b).sql.should == "SELECT a, b, count(*) AS count FROM test GROUP BY a, b"
|
|
1870
1742
|
end
|
|
1871
1743
|
|
|
1872
1744
|
specify "should format column aliases in the select clause but not in the group clause" do
|
|
1873
|
-
@ds.group_and_count(:name___n).sql.should ==
|
|
1874
|
-
|
|
1875
|
-
@ds.group_and_count(:name__n).sql.should ==
|
|
1876
|
-
"SELECT name.n, count(*) AS count FROM test GROUP BY name.n"
|
|
1745
|
+
@ds.group_and_count(:name___n).sql.should == "SELECT name AS n, count(*) AS count FROM test GROUP BY name"
|
|
1746
|
+
@ds.group_and_count(:name__n).sql.should == "SELECT name.n, count(*) AS count FROM test GROUP BY name.n"
|
|
1877
1747
|
end
|
|
1878
1748
|
|
|
1879
1749
|
specify "should handle identifiers" do
|
|
1880
|
-
@ds.group_and_count(:name___n.identifier).sql.should ==
|
|
1881
|
-
"SELECT name___n, count(*) AS count FROM test GROUP BY name___n"
|
|
1750
|
+
@ds.group_and_count(:name___n.identifier).sql.should == "SELECT name___n, count(*) AS count FROM test GROUP BY name___n"
|
|
1882
1751
|
end
|
|
1883
1752
|
|
|
1884
1753
|
specify "should handle literal strings" do
|
|
1885
|
-
@ds.group_and_count("name".lit).sql.should ==
|
|
1886
|
-
"SELECT name, count(*) AS count FROM test GROUP BY name"
|
|
1754
|
+
@ds.group_and_count("name".lit).sql.should == "SELECT name, count(*) AS count FROM test GROUP BY name"
|
|
1887
1755
|
end
|
|
1888
1756
|
|
|
1889
1757
|
specify "should handle aliased expressions" do
|
|
1890
|
-
@ds.group_and_count(:name.as(:n)).sql.should ==
|
|
1891
|
-
|
|
1892
|
-
@ds.group_and_count(:name.identifier.as(:n)).sql.should ==
|
|
1893
|
-
"SELECT name AS n, count(*) AS count FROM test GROUP BY name"
|
|
1758
|
+
@ds.group_and_count(:name.as(:n)).sql.should == "SELECT name AS n, count(*) AS count FROM test GROUP BY name"
|
|
1759
|
+
@ds.group_and_count(:name.identifier.as(:n)).sql.should == "SELECT name AS n, count(*) AS count FROM test GROUP BY name"
|
|
1894
1760
|
end
|
|
1895
1761
|
|
|
1896
1762
|
specify "should take a virtual row block" do
|
|
@@ -1902,20 +1768,11 @@ end
|
|
|
1902
1768
|
|
|
1903
1769
|
describe "Dataset#empty?" do
|
|
1904
1770
|
specify "should return true if records exist in the dataset" do
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
def fetch_rows(sql)
|
|
1911
|
-
@@sql = sql
|
|
1912
|
-
yield({1 => 1}) unless sql =~ /WHERE 'f'/
|
|
1913
|
-
end
|
|
1914
|
-
end
|
|
1915
|
-
@c.new(nil).from(:test).should_not be_empty
|
|
1916
|
-
@c.sql.should == 'SELECT 1 FROM test LIMIT 1'
|
|
1917
|
-
@c.new(nil).from(:test).filter(false).should be_empty
|
|
1918
|
-
@c.sql.should == "SELECT 1 FROM test WHERE 'f' LIMIT 1"
|
|
1771
|
+
db = Sequel.mock(:fetch=>proc{|sql| {1=>1} unless sql =~ /WHERE 'f'/})
|
|
1772
|
+
db.from(:test).should_not be_empty
|
|
1773
|
+
db.sqls.should == ['SELECT 1 FROM test LIMIT 1']
|
|
1774
|
+
db.from(:test).filter(false).should be_empty
|
|
1775
|
+
db.sqls.should == ["SELECT 1 FROM test WHERE 'f' LIMIT 1"]
|
|
1919
1776
|
end
|
|
1920
1777
|
end
|
|
1921
1778
|
|
|
@@ -1994,25 +1851,31 @@ describe "Dataset#from_self" do
|
|
|
1994
1851
|
'SELECT * FROM (SELECT name FROM test LIMIT 1) AS some_name INNER JOIN posts ON (posts.alias = some_name.name)'
|
|
1995
1852
|
end
|
|
1996
1853
|
|
|
1997
|
-
specify "should not options such as server" do
|
|
1854
|
+
specify "should not remove non-SQL options such as :server" do
|
|
1998
1855
|
@ds.server(:blah).from_self(:alias=>:some_name).opts[:server].should == :blah
|
|
1999
1856
|
end
|
|
2000
1857
|
|
|
1858
|
+
specify "should hoist WITH clauses in current dataset if dataset doesn't support WITH in subselect" do
|
|
1859
|
+
ds = Sequel::Dataset.new(nil)
|
|
1860
|
+
ds.meta_def(:supports_cte?){true}
|
|
1861
|
+
ds.meta_def(:supports_cte_in_subselect?){false}
|
|
1862
|
+
ds.from(:a).with(:a, ds.from(:b)).from_self.sql.should == 'WITH a AS (SELECT * FROM b) SELECT * FROM (SELECT * FROM a) AS t1'
|
|
1863
|
+
ds.from(:a, :c).with(:a, ds.from(:b)).with(:c, ds.from(:d)).from_self.sql.should == 'WITH a AS (SELECT * FROM b), c AS (SELECT * FROM d) SELECT * FROM (SELECT * FROM a, c) AS t1'
|
|
1864
|
+
end
|
|
2001
1865
|
end
|
|
2002
1866
|
|
|
2003
1867
|
describe "Dataset#join_table" do
|
|
2004
1868
|
before do
|
|
2005
|
-
@d =
|
|
1869
|
+
@d = Sequel::Dataset.new(nil).from(:items)
|
|
2006
1870
|
@d.quote_identifiers = true
|
|
2007
1871
|
end
|
|
2008
1872
|
|
|
2009
1873
|
specify "should format the JOIN clause properly" do
|
|
2010
|
-
@d.join_table(:left_outer, :categories, :category_id => :id).sql.should ==
|
|
2011
|
-
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1874
|
+
@d.join_table(:left_outer, :categories, :category_id => :id).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
2012
1875
|
end
|
|
2013
1876
|
|
|
2014
1877
|
specify "should handle multiple conditions on the same join table column" do
|
|
2015
|
-
@d.join_table(:left_outer, :categories, [[:category_id, :id], [:category_id, 0..100]]).sql.should ==
|
|
1878
|
+
@d.join_table(:left_outer, :categories, [[:category_id, :id], [:category_id, 0..100]]).sql.should ==
|
|
2016
1879
|
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON (("categories"."category_id" = "items"."id") AND ("categories"."category_id" >= 0) AND ("categories"."category_id" <= 100))'
|
|
2017
1880
|
end
|
|
2018
1881
|
|
|
@@ -2022,45 +1885,30 @@ describe "Dataset#join_table" do
|
|
|
2022
1885
|
end
|
|
2023
1886
|
|
|
2024
1887
|
specify "should include ORDER BY clause if applicable" do
|
|
2025
|
-
@d.order(:stamp).join_table(:full_outer, :categories, :category_id => :id).sql.should ==
|
|
2026
|
-
'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id") ORDER BY "stamp"'
|
|
1888
|
+
@d.order(:stamp).join_table(:full_outer, :categories, :category_id => :id).sql.should == 'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id") ORDER BY "stamp"'
|
|
2027
1889
|
end
|
|
2028
1890
|
|
|
2029
1891
|
specify "should support multiple joins" do
|
|
2030
|
-
@d.join_table(:inner, :b, :items_id=>:id).join_table(:left_outer, :c, :b_id => :b__id).sql.should ==
|
|
2031
|
-
'SELECT * FROM "items" INNER JOIN "b" ON ("b"."items_id" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")'
|
|
1892
|
+
@d.join_table(:inner, :b, :items_id=>:id).join_table(:left_outer, :c, :b_id => :b__id).sql.should == 'SELECT * FROM "items" INNER JOIN "b" ON ("b"."items_id" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")'
|
|
2032
1893
|
end
|
|
2033
1894
|
|
|
2034
1895
|
specify "should support arbitrary join types" do
|
|
2035
|
-
@d.join_table(:magic, :categories, :category_id=>:id).sql.should ==
|
|
2036
|
-
'SELECT * FROM "items" MAGIC JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1896
|
+
@d.join_table(:magic, :categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" MAGIC JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
2037
1897
|
end
|
|
2038
1898
|
|
|
2039
1899
|
specify "should support many join methods" do
|
|
2040
|
-
@d.left_outer_join(:categories, :category_id=>:id).sql.should ==
|
|
2041
|
-
|
|
2042
|
-
@d.
|
|
2043
|
-
|
|
2044
|
-
@d.
|
|
2045
|
-
|
|
2046
|
-
@d.
|
|
2047
|
-
|
|
2048
|
-
@d.
|
|
2049
|
-
|
|
2050
|
-
@d.
|
|
2051
|
-
|
|
2052
|
-
@d.full_join(:categories, :category_id=>:id).sql.should ==
|
|
2053
|
-
'SELECT * FROM "items" FULL JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
2054
|
-
@d.natural_join(:categories).sql.should ==
|
|
2055
|
-
'SELECT * FROM "items" NATURAL JOIN "categories"'
|
|
2056
|
-
@d.natural_left_join(:categories).sql.should ==
|
|
2057
|
-
'SELECT * FROM "items" NATURAL LEFT JOIN "categories"'
|
|
2058
|
-
@d.natural_right_join(:categories).sql.should ==
|
|
2059
|
-
'SELECT * FROM "items" NATURAL RIGHT JOIN "categories"'
|
|
2060
|
-
@d.natural_full_join(:categories).sql.should ==
|
|
2061
|
-
'SELECT * FROM "items" NATURAL FULL JOIN "categories"'
|
|
2062
|
-
@d.cross_join(:categories).sql.should ==
|
|
2063
|
-
'SELECT * FROM "items" CROSS JOIN "categories"'
|
|
1900
|
+
@d.left_outer_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1901
|
+
@d.right_outer_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1902
|
+
@d.full_outer_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1903
|
+
@d.inner_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1904
|
+
@d.left_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" LEFT JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1905
|
+
@d.right_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" RIGHT JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1906
|
+
@d.full_join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" FULL JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1907
|
+
@d.natural_join(:categories).sql.should == 'SELECT * FROM "items" NATURAL JOIN "categories"'
|
|
1908
|
+
@d.natural_left_join(:categories).sql.should == 'SELECT * FROM "items" NATURAL LEFT JOIN "categories"'
|
|
1909
|
+
@d.natural_right_join(:categories).sql.should == 'SELECT * FROM "items" NATURAL RIGHT JOIN "categories"'
|
|
1910
|
+
@d.natural_full_join(:categories).sql.should == 'SELECT * FROM "items" NATURAL FULL JOIN "categories"'
|
|
1911
|
+
@d.cross_join(:categories).sql.should == 'SELECT * FROM "items" CROSS JOIN "categories"'
|
|
2064
1912
|
end
|
|
2065
1913
|
|
|
2066
1914
|
specify "should raise an error if additional arguments are provided to join methods that don't take conditions" do
|
|
@@ -2080,95 +1928,68 @@ describe "Dataset#join_table" do
|
|
|
2080
1928
|
end
|
|
2081
1929
|
|
|
2082
1930
|
specify "should default to a plain join if nil is used for the type" do
|
|
2083
|
-
@d.join_table(nil, :categories, :category_id=>:id).sql.should ==
|
|
2084
|
-
'SELECT * FROM "items" JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1931
|
+
@d.join_table(nil, :categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
2085
1932
|
end
|
|
2086
1933
|
|
|
2087
1934
|
specify "should use an inner join for Dataset#join" do
|
|
2088
|
-
@d.join(:categories, :category_id=>:id).sql.should ==
|
|
2089
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
1935
|
+
@d.join(:categories, :category_id=>:id).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
|
2090
1936
|
end
|
|
2091
1937
|
|
|
2092
1938
|
specify "should support aliased tables using the deprecated argument" do
|
|
2093
|
-
@d.from('stats').join('players', {:id => :player_id}, 'p').sql.should ==
|
|
2094
|
-
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
1939
|
+
@d.from('stats').join('players', {:id => :player_id}, 'p').sql.should == 'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
2095
1940
|
end
|
|
2096
1941
|
|
|
2097
1942
|
specify "should support aliased tables using the :table_alias option" do
|
|
2098
|
-
@d.from('stats').join('players', {:id => :player_id}, :table_alias=>:p).sql.should ==
|
|
2099
|
-
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
1943
|
+
@d.from('stats').join('players', {:id => :player_id}, :table_alias=>:p).sql.should == 'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
2100
1944
|
end
|
|
2101
1945
|
|
|
2102
1946
|
specify "should support aliased tables using an implicit alias" do
|
|
2103
|
-
@d.from('stats').join(:players.as(:p), {:id => :player_id}).sql.should ==
|
|
2104
|
-
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
1947
|
+
@d.from('stats').join(:players.as(:p), {:id => :player_id}).sql.should == 'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
|
2105
1948
|
end
|
|
2106
1949
|
|
|
2107
1950
|
specify "should support using an alias for the FROM when doing the first join with unqualified condition columns" do
|
|
2108
|
-
|
|
2109
|
-
ds.quote_identifiers = true
|
|
2110
|
-
ds.join_table(:inner, :bar, :id => :bar_id).sql.should ==
|
|
2111
|
-
'SELECT * FROM "foo" AS "f" INNER JOIN "bar" ON ("bar"."id" = "f"."bar_id")'
|
|
1951
|
+
@d.from(:foo=>:f).join_table(:inner, :bar, :id => :bar_id).sql.should == 'SELECT * FROM "foo" AS "f" INNER JOIN "bar" ON ("bar"."id" = "f"."bar_id")'
|
|
2112
1952
|
end
|
|
2113
1953
|
|
|
2114
1954
|
specify "should support implicit schemas in from table symbols" do
|
|
2115
|
-
@d.from(:s__t).join(:u__v, {:id => :player_id}).sql.should ==
|
|
2116
|
-
'SELECT * FROM "s"."t" INNER JOIN "u"."v" ON ("u"."v"."id" = "s"."t"."player_id")'
|
|
1955
|
+
@d.from(:s__t).join(:u__v, {:id => :player_id}).sql.should == 'SELECT * FROM "s"."t" INNER JOIN "u"."v" ON ("u"."v"."id" = "s"."t"."player_id")'
|
|
2117
1956
|
end
|
|
2118
1957
|
|
|
2119
1958
|
specify "should support implicit aliases in from table symbols" do
|
|
2120
|
-
@d.from(:t___z).join(:v___y, {:id => :player_id}).sql.should ==
|
|
2121
|
-
|
|
2122
|
-
@d.from(:s__t___z).join(:u__v___y, {:id => :player_id}).sql.should ==
|
|
2123
|
-
'SELECT * FROM "s"."t" AS "z" INNER JOIN "u"."v" AS "y" ON ("y"."id" = "z"."player_id")'
|
|
1959
|
+
@d.from(:t___z).join(:v___y, {:id => :player_id}).sql.should == 'SELECT * FROM "t" AS "z" INNER JOIN "v" AS "y" ON ("y"."id" = "z"."player_id")'
|
|
1960
|
+
@d.from(:s__t___z).join(:u__v___y, {:id => :player_id}).sql.should == 'SELECT * FROM "s"."t" AS "z" INNER JOIN "u"."v" AS "y" ON ("y"."id" = "z"."player_id")'
|
|
2124
1961
|
end
|
|
2125
1962
|
|
|
2126
1963
|
specify "should support AliasedExpressions" do
|
|
2127
|
-
@d.from(:s.as(:t)).join(:u.as(:v), {:id => :player_id}).sql.should ==
|
|
2128
|
-
'SELECT * FROM "s" AS "t" INNER JOIN "u" AS "v" ON ("v"."id" = "t"."player_id")'
|
|
1964
|
+
@d.from(:s.as(:t)).join(:u.as(:v), {:id => :player_id}).sql.should == 'SELECT * FROM "s" AS "t" INNER JOIN "u" AS "v" ON ("v"."id" = "t"."player_id")'
|
|
2129
1965
|
end
|
|
2130
1966
|
|
|
2131
1967
|
specify "should support the :implicit_qualifier option" do
|
|
2132
|
-
@d.from('stats').join('players', {:id => :player_id}, :implicit_qualifier=>:p).sql.should ==
|
|
2133
|
-
'SELECT * FROM "stats" INNER JOIN "players" ON ("players"."id" = "p"."player_id")'
|
|
1968
|
+
@d.from('stats').join('players', {:id => :player_id}, :implicit_qualifier=>:p).sql.should == 'SELECT * FROM "stats" INNER JOIN "players" ON ("players"."id" = "p"."player_id")'
|
|
2134
1969
|
end
|
|
2135
1970
|
|
|
2136
1971
|
specify "should allow for arbitrary conditions in the JOIN clause" do
|
|
2137
|
-
@d.join_table(:left_outer, :categories, :status => 0).sql.should ==
|
|
2138
|
-
|
|
2139
|
-
@d.join_table(:left_outer, :categories, :
|
|
2140
|
-
|
|
2141
|
-
@d.join_table(:left_outer, :categories, :timestamp => "CURRENT_TIMESTAMP".lit).sql.should ==
|
|
2142
|
-
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."timestamp" = CURRENT_TIMESTAMP)'
|
|
2143
|
-
@d.join_table(:left_outer, :categories, :status => [1, 2, 3]).sql.should ==
|
|
2144
|
-
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."status" IN (1, 2, 3))'
|
|
1972
|
+
@d.join_table(:left_outer, :categories, :status => 0).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."status" = 0)'
|
|
1973
|
+
@d.join_table(:left_outer, :categories, :categorizable_type => "Post").sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."categorizable_type" = \'Post\')'
|
|
1974
|
+
@d.join_table(:left_outer, :categories, :timestamp => "CURRENT_TIMESTAMP".lit).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."timestamp" = CURRENT_TIMESTAMP)'
|
|
1975
|
+
@d.join_table(:left_outer, :categories, :status => [1, 2, 3]).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."status" IN (1, 2, 3))'
|
|
2145
1976
|
end
|
|
2146
1977
|
|
|
2147
1978
|
specify "should raise error for a table without a source" do
|
|
2148
|
-
proc {Sequel::Dataset.new(nil).join('players', :id => :player_id)}.
|
|
2149
|
-
should raise_error(Sequel::Error)
|
|
1979
|
+
proc {Sequel::Dataset.new(nil).join('players', :id => :player_id)}.should raise_error(Sequel::Error)
|
|
2150
1980
|
end
|
|
2151
1981
|
|
|
2152
1982
|
specify "should support joining datasets" do
|
|
2153
1983
|
ds = Sequel::Dataset.new(nil).from(:categories)
|
|
2154
|
-
|
|
2155
|
-
@d.join_table(:left_outer, ds, :item_id => :id).sql.should ==
|
|
2156
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
|
2157
|
-
|
|
1984
|
+
@d.join_table(:left_outer, ds, :item_id => :id).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
|
2158
1985
|
ds.filter!(:active => true)
|
|
2159
|
-
|
|
2160
|
-
@d.join_table(:left_outer, ds, :item_id => :id).sql.should ==
|
|
2161
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active IS TRUE)) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
|
2162
|
-
|
|
2163
|
-
@d.from_self.join_table(:left_outer, ds, :item_id => :id).sql.should ==
|
|
2164
|
-
'SELECT * FROM (SELECT * FROM "items") AS "t1" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active IS TRUE)) AS "t2" ON ("t2"."item_id" = "t1"."id")'
|
|
1986
|
+
@d.join_table(:left_outer, ds, :item_id => :id).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active IS TRUE)) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
|
1987
|
+
@d.from_self.join_table(:left_outer, ds, :item_id => :id).sql.should == 'SELECT * FROM (SELECT * FROM "items") AS "t1" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active IS TRUE)) AS "t2" ON ("t2"."item_id" = "t1"."id")'
|
|
2165
1988
|
end
|
|
2166
1989
|
|
|
2167
1990
|
specify "should support joining datasets and aliasing the join" do
|
|
2168
1991
|
ds = Sequel::Dataset.new(nil).from(:categories)
|
|
2169
|
-
|
|
2170
|
-
@d.join_table(:left_outer, ds, {:ds__item_id => :id}, :ds).sql.should ==
|
|
2171
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "ds" ON ("ds"."item_id" = "items"."id")'
|
|
1992
|
+
@d.join_table(:left_outer, ds, {:ds__item_id => :id}, :ds).sql.should == 'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "ds" ON ("ds"."item_id" = "items"."id")'
|
|
2172
1993
|
end
|
|
2173
1994
|
|
|
2174
1995
|
specify "should support joining multiple datasets" do
|
|
@@ -2185,40 +2006,30 @@ describe "Dataset#join_table" do
|
|
|
2185
2006
|
specify "should support joining objects that respond to :table_name" do
|
|
2186
2007
|
ds = Object.new
|
|
2187
2008
|
def ds.table_name; :categories end
|
|
2188
|
-
|
|
2189
|
-
@d.join(ds, :item_id => :id).sql.should ==
|
|
2190
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."item_id" = "items"."id")'
|
|
2009
|
+
@d.join(ds, :item_id => :id).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."item_id" = "items"."id")'
|
|
2191
2010
|
end
|
|
2192
2011
|
|
|
2193
|
-
specify "should support using
|
|
2194
|
-
@d.join(:categories,
|
|
2195
|
-
'SELECT * FROM "items" INNER JOIN "categories" AS "c" ON (c.item_id = items.id)'
|
|
2012
|
+
specify "should support using an SQL String as the join condition" do
|
|
2013
|
+
@d.join(:categories, "c.item_id = items.id", :c).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" AS "c" ON (c.item_id = items.id)'
|
|
2196
2014
|
end
|
|
2197
2015
|
|
|
2198
2016
|
specify "should support using a boolean column as the join condition" do
|
|
2199
|
-
@d.join(:categories, :active).sql.should ==
|
|
2200
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON "active"'
|
|
2017
|
+
@d.join(:categories, :active).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON "active"'
|
|
2201
2018
|
end
|
|
2202
2019
|
|
|
2203
2020
|
specify "should support using an expression as the join condition" do
|
|
2204
|
-
@d.join(:categories, :number.sql_number > 10).sql.should ==
|
|
2205
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON ("number" > 10)'
|
|
2021
|
+
@d.join(:categories, :number.sql_number > 10).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("number" > 10)'
|
|
2206
2022
|
end
|
|
2207
2023
|
|
|
2208
|
-
specify "should support natural and cross joins
|
|
2209
|
-
@d.join_table(:natural, :categories).sql.should ==
|
|
2210
|
-
|
|
2211
|
-
@d.join_table(:
|
|
2212
|
-
'SELECT * FROM "items" CROSS JOIN "categories"'
|
|
2213
|
-
@d.join_table(:natural, :categories, nil, :c).sql.should ==
|
|
2214
|
-
'SELECT * FROM "items" NATURAL JOIN "categories" AS "c"'
|
|
2024
|
+
specify "should support natural and cross joins" do
|
|
2025
|
+
@d.join_table(:natural, :categories).sql.should == 'SELECT * FROM "items" NATURAL JOIN "categories"'
|
|
2026
|
+
@d.join_table(:cross, :categories, nil).sql.should == 'SELECT * FROM "items" CROSS JOIN "categories"'
|
|
2027
|
+
@d.join_table(:natural, :categories, nil, :c).sql.should == 'SELECT * FROM "items" NATURAL JOIN "categories" AS "c"'
|
|
2215
2028
|
end
|
|
2216
2029
|
|
|
2217
2030
|
specify "should support joins with a USING clause if an array of symbols is used" do
|
|
2218
|
-
@d.join(:categories, [:id]).sql.should ==
|
|
2219
|
-
|
|
2220
|
-
@d.join(:categories, [:id1, :id2]).sql.should ==
|
|
2221
|
-
'SELECT * FROM "items" INNER JOIN "categories" USING ("id1", "id2")'
|
|
2031
|
+
@d.join(:categories, [:id]).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" USING ("id")'
|
|
2032
|
+
@d.join(:categories, [:id1, :id2]).sql.should == 'SELECT * FROM "items" INNER JOIN "categories" USING ("id1", "id2")'
|
|
2222
2033
|
end
|
|
2223
2034
|
|
|
2224
2035
|
specify "should emulate JOIN USING (poorly) if the dataset doesn't support it" do
|
|
@@ -2286,22 +2097,17 @@ describe "Dataset#join_table" do
|
|
|
2286
2097
|
end
|
|
2287
2098
|
|
|
2288
2099
|
specify "should use the block result as the only condition if no condition is given" do
|
|
2289
|
-
@d.join(:categories){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should ==
|
|
2290
|
-
|
|
2291
|
-
@d.join(:categories){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should ==
|
|
2292
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."b" > "items"."c")'
|
|
2100
|
+
@d.join(:categories){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."b" = "items"."c")'
|
|
2101
|
+
@d.join(:categories){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."b" > "items"."c")'
|
|
2293
2102
|
end
|
|
2294
2103
|
|
|
2295
2104
|
specify "should combine the block conditions and argument conditions if both given" do
|
|
2296
|
-
@d.join(:categories, :a=>:d){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should ==
|
|
2297
|
-
|
|
2298
|
-
@d.join(:categories, :a=>:d){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should ==
|
|
2299
|
-
'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" > "items"."c"))'
|
|
2105
|
+
@d.join(:categories, :a=>:d){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" = "items"."c"))'
|
|
2106
|
+
@d.join(:categories, :a=>:d){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should == 'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" > "items"."c"))'
|
|
2300
2107
|
end
|
|
2301
2108
|
|
|
2302
2109
|
specify "should prefer explicit aliases over implicit" do
|
|
2303
|
-
@d.from(:items___i).join(:categories___c, {:category_id => :id}, {:table_alias=>:c2, :implicit_qualifier=>:i2}).sql.should ==
|
|
2304
|
-
'SELECT * FROM "items" AS "i" INNER JOIN "categories" AS "c2" ON ("c2"."category_id" = "i2"."id")'
|
|
2110
|
+
@d.from(:items___i).join(:categories___c, {:category_id => :id}, {:table_alias=>:c2, :implicit_qualifier=>:i2}).sql.should == 'SELECT * FROM "items" AS "i" INNER JOIN "categories" AS "c2" ON ("c2"."category_id" = "i2"."id")'
|
|
2305
2111
|
@d.from(:items.as(:i)).join(:categories.as(:c), {:category_id => :id}, {:table_alias=>:c2, :implicit_qualifier=>:i2}).sql.should ==
|
|
2306
2112
|
'SELECT * FROM "items" AS "i" INNER JOIN "categories" AS "c2" ON ("c2"."category_id" = "i2"."id")'
|
|
2307
2113
|
end
|
|
@@ -2320,81 +2126,48 @@ describe "Dataset#join_table" do
|
|
|
2320
2126
|
end
|
|
2321
2127
|
|
|
2322
2128
|
describe "Dataset#[]=" do
|
|
2323
|
-
before do
|
|
2324
|
-
c = Class.new(Sequel::Dataset) do
|
|
2325
|
-
def last_sql
|
|
2326
|
-
@@last_sql
|
|
2327
|
-
end
|
|
2328
|
-
|
|
2329
|
-
def update(*args)
|
|
2330
|
-
@@last_sql = update_sql(*args)
|
|
2331
|
-
end
|
|
2332
|
-
end
|
|
2333
|
-
|
|
2334
|
-
@d = c.new(nil).from(:items)
|
|
2335
|
-
end
|
|
2336
|
-
|
|
2337
2129
|
specify "should perform an update on the specified filter" do
|
|
2338
|
-
|
|
2339
|
-
|
|
2130
|
+
db = Sequel.mock
|
|
2131
|
+
ds = db[:items]
|
|
2132
|
+
ds[:a => 1] = {:x => 3}
|
|
2133
|
+
db.sqls.should == ['UPDATE items SET x = 3 WHERE (a = 1)']
|
|
2340
2134
|
end
|
|
2341
2135
|
end
|
|
2342
2136
|
|
|
2343
2137
|
describe "Dataset#set" do
|
|
2344
|
-
before do
|
|
2345
|
-
c = Class.new(Sequel::Dataset) do
|
|
2346
|
-
def last_sql
|
|
2347
|
-
@@last_sql
|
|
2348
|
-
end
|
|
2349
|
-
|
|
2350
|
-
def update(*args, &block)
|
|
2351
|
-
@@last_sql = update_sql(*args, &block)
|
|
2352
|
-
end
|
|
2353
|
-
end
|
|
2354
|
-
|
|
2355
|
-
@d = c.new(nil).from(:items)
|
|
2356
|
-
end
|
|
2357
|
-
|
|
2358
2138
|
specify "should act as alias to #update" do
|
|
2359
|
-
|
|
2360
|
-
|
|
2139
|
+
db = Sequel.mock
|
|
2140
|
+
ds = db[:items]
|
|
2141
|
+
ds.set({:x => 3})
|
|
2142
|
+
db.sqls.should == ['UPDATE items SET x = 3']
|
|
2361
2143
|
end
|
|
2362
2144
|
end
|
|
2363
2145
|
|
|
2364
|
-
|
|
2365
2146
|
describe "Dataset#insert_multiple" do
|
|
2366
2147
|
before do
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
def insert(arg)
|
|
2370
|
-
@inserts ||= []
|
|
2371
|
-
@inserts << arg
|
|
2372
|
-
end
|
|
2373
|
-
end
|
|
2374
|
-
|
|
2375
|
-
@d = c.new(nil)
|
|
2148
|
+
@db = Sequel.mock
|
|
2149
|
+
@ds = @db[:items]
|
|
2376
2150
|
end
|
|
2377
2151
|
|
|
2378
2152
|
specify "should insert all items in the supplied array" do
|
|
2379
|
-
@
|
|
2380
|
-
@
|
|
2153
|
+
@ds.insert_multiple(['aa', 5, 3, {:a => 2}])
|
|
2154
|
+
@db.sqls.should == ["INSERT INTO items VALUES ('aa')",
|
|
2155
|
+
"INSERT INTO items VALUES (5)",
|
|
2156
|
+
"INSERT INTO items VALUES (3)",
|
|
2157
|
+
"INSERT INTO items (a) VALUES (2)"]
|
|
2381
2158
|
end
|
|
2382
2159
|
|
|
2383
2160
|
specify "should pass array items through the supplied block if given" do
|
|
2384
|
-
|
|
2385
|
-
@
|
|
2386
|
-
|
|
2161
|
+
@ds.insert_multiple(["inevitable", "hello", "the ticking clock"]){|i| i.gsub('l', 'r')}
|
|
2162
|
+
@db.sqls.should == ["INSERT INTO items VALUES ('inevitabre')",
|
|
2163
|
+
"INSERT INTO items VALUES ('herro')",
|
|
2164
|
+
"INSERT INTO items VALUES ('the ticking crock')"]
|
|
2387
2165
|
end
|
|
2388
2166
|
end
|
|
2389
2167
|
|
|
2390
2168
|
describe "Dataset aggregate methods" do
|
|
2391
2169
|
before do
|
|
2392
|
-
|
|
2393
|
-
def fetch_rows(sql)
|
|
2394
|
-
yield({1 => sql})
|
|
2395
|
-
end
|
|
2396
|
-
end
|
|
2397
|
-
@d = c.new(nil).from(:test)
|
|
2170
|
+
@d = Sequel.mock(:fetch=>proc{|s| {1=>s}})[:test]
|
|
2398
2171
|
end
|
|
2399
2172
|
|
|
2400
2173
|
specify "should include min" do
|
|
@@ -2428,116 +2201,88 @@ end
|
|
|
2428
2201
|
|
|
2429
2202
|
describe "Dataset#range" do
|
|
2430
2203
|
before do
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
def last_sql; self.class.send(:class_variable_get, :@@sql); end
|
|
2435
|
-
|
|
2436
|
-
def fetch_rows(sql)
|
|
2437
|
-
self.class.send(:class_variable_set, :@@sql, sql)
|
|
2438
|
-
yield(:v1 => 1, :v2 => 10)
|
|
2439
|
-
end
|
|
2440
|
-
end
|
|
2441
|
-
@d = c.new(nil).from(:test)
|
|
2204
|
+
@db = Sequel.mock(:fetch=>{:v1 => 1, :v2 => 10})
|
|
2205
|
+
@ds = @db[:test]
|
|
2442
2206
|
end
|
|
2443
2207
|
|
|
2444
2208
|
specify "should generate a correct SQL statement" do
|
|
2445
|
-
@
|
|
2446
|
-
@
|
|
2209
|
+
@ds.range(:stamp)
|
|
2210
|
+
@db.sqls.should == ["SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test LIMIT 1"]
|
|
2447
2211
|
|
|
2448
|
-
@
|
|
2449
|
-
@
|
|
2212
|
+
@ds.filter(:price.sql_number > 100).range(:stamp)
|
|
2213
|
+
@db.sqls.should == ["SELECT min(stamp) AS v1, max(stamp) AS v2 FROM test WHERE (price > 100) LIMIT 1"]
|
|
2450
2214
|
end
|
|
2451
2215
|
|
|
2452
2216
|
specify "should return a range object" do
|
|
2453
|
-
@
|
|
2217
|
+
@ds.range(:tryme).should == (1..10)
|
|
2454
2218
|
end
|
|
2455
2219
|
|
|
2456
2220
|
specify "should use a subselect for the same conditions as count" do
|
|
2457
|
-
@
|
|
2458
|
-
@
|
|
2221
|
+
@ds.order(:stamp).limit(5).range(:stamp).should == (1..10)
|
|
2222
|
+
@db.sqls.should == ['SELECT min(stamp) AS v1, max(stamp) AS v2 FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
|
|
2459
2223
|
end
|
|
2460
2224
|
end
|
|
2461
2225
|
|
|
2462
2226
|
describe "Dataset#interval" do
|
|
2463
2227
|
before do
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
def last_sql; self.class.send(:class_variable_get, :@@sql); end
|
|
2468
|
-
|
|
2469
|
-
def fetch_rows(sql)
|
|
2470
|
-
self.class.send(:class_variable_set, :@@sql, sql)
|
|
2471
|
-
yield(:v => 1234)
|
|
2472
|
-
end
|
|
2473
|
-
end
|
|
2474
|
-
@d = c.new(nil).from(:test)
|
|
2228
|
+
@db = Sequel.mock(:fetch=>{:v => 1234})
|
|
2229
|
+
@ds = @db[:test]
|
|
2475
2230
|
end
|
|
2476
2231
|
|
|
2477
|
-
specify "should generate
|
|
2478
|
-
@
|
|
2479
|
-
@
|
|
2232
|
+
specify "should generate the correct SQL statement" do
|
|
2233
|
+
@ds.interval(:stamp)
|
|
2234
|
+
@db.sqls.should == ["SELECT (max(stamp) - min(stamp)) FROM test LIMIT 1"]
|
|
2480
2235
|
|
|
2481
|
-
@
|
|
2482
|
-
@
|
|
2483
|
-
end
|
|
2484
|
-
|
|
2485
|
-
specify "should return an integer" do
|
|
2486
|
-
@d.interval(:tryme).should == 1234
|
|
2236
|
+
@ds.filter(:price.sql_number > 100).interval(:stamp)
|
|
2237
|
+
@db.sqls.should == ["SELECT (max(stamp) - min(stamp)) FROM test WHERE (price > 100) LIMIT 1"]
|
|
2487
2238
|
end
|
|
2488
2239
|
|
|
2489
2240
|
specify "should use a subselect for the same conditions as count" do
|
|
2490
|
-
@
|
|
2491
|
-
@
|
|
2241
|
+
@ds.order(:stamp).limit(5).interval(:stamp).should == 1234
|
|
2242
|
+
@db.sqls.should == ['SELECT (max(stamp) - min(stamp)) FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
|
|
2492
2243
|
end
|
|
2493
2244
|
end
|
|
2494
2245
|
|
|
2495
2246
|
describe "Dataset #first and #last" do
|
|
2496
2247
|
before do
|
|
2497
|
-
@
|
|
2498
|
-
|
|
2499
|
-
s = select_sql
|
|
2500
|
-
x = [:a,1,:b,2,s]
|
|
2501
|
-
i = /LIMIT (\d+)/.match(s)[1].to_i.times{yield x}
|
|
2502
|
-
end
|
|
2503
|
-
end
|
|
2504
|
-
@d = @c.new(nil).from(:test)
|
|
2248
|
+
@db = Sequel.mock(:fetch=>proc{|s| {:s=>s}})
|
|
2249
|
+
@d = @db[:test]
|
|
2505
2250
|
end
|
|
2506
2251
|
|
|
2507
2252
|
specify "should return a single record if no argument is given" do
|
|
2508
|
-
@d.order(:a).first.should ==
|
|
2509
|
-
@d.order(:a).last.should ==
|
|
2253
|
+
@d.order(:a).first.should == {:s=>'SELECT * FROM test ORDER BY a LIMIT 1'}
|
|
2254
|
+
@d.order(:a).last.should == {:s=>'SELECT * FROM test ORDER BY a DESC LIMIT 1'}
|
|
2510
2255
|
end
|
|
2511
2256
|
|
|
2512
2257
|
specify "should return the first/last matching record if argument is not an Integer" do
|
|
2513
|
-
@d.order(:a).first(:z => 26).should ==
|
|
2514
|
-
@d.order(:a).first('z = ?', 15).should ==
|
|
2515
|
-
@d.order(:a).last(:z => 26).should ==
|
|
2516
|
-
@d.order(:a).last('z = ?', 15).should ==
|
|
2258
|
+
@d.order(:a).first(:z => 26).should == {:s=>'SELECT * FROM test WHERE (z = 26) ORDER BY a LIMIT 1'}
|
|
2259
|
+
@d.order(:a).first('z = ?', 15).should == {:s=>'SELECT * FROM test WHERE (z = 15) ORDER BY a LIMIT 1'}
|
|
2260
|
+
@d.order(:a).last(:z => 26).should == {:s=>'SELECT * FROM test WHERE (z = 26) ORDER BY a DESC LIMIT 1'}
|
|
2261
|
+
@d.order(:a).last('z = ?', 15).should == {:s=>'SELECT * FROM test WHERE (z = 15) ORDER BY a DESC LIMIT 1'}
|
|
2517
2262
|
end
|
|
2518
2263
|
|
|
2519
2264
|
specify "should set the limit and return an array of records if the given number is > 1" do
|
|
2520
2265
|
i = rand(10) + 10
|
|
2521
|
-
r = @d.order(:a).first(i).should == [
|
|
2266
|
+
r = @d.order(:a).first(i).should == [{:s=>"SELECT * FROM test ORDER BY a LIMIT #{i}"}]
|
|
2522
2267
|
i = rand(10) + 10
|
|
2523
|
-
r = @d.order(:a).last(i).should == [
|
|
2268
|
+
r = @d.order(:a).last(i).should == [{:s=>"SELECT * FROM test ORDER BY a DESC LIMIT #{i}"}]
|
|
2524
2269
|
end
|
|
2525
2270
|
|
|
2526
2271
|
specify "should return the first matching record if a block is given without an argument" do
|
|
2527
|
-
@d.first{:z.sql_number > 26}.should ==
|
|
2528
|
-
@d.order(:name).last{:z.sql_number > 26}.should ==
|
|
2272
|
+
@d.first{:z.sql_number > 26}.should == {:s=>'SELECT * FROM test WHERE (z > 26) LIMIT 1'}
|
|
2273
|
+
@d.order(:name).last{:z.sql_number > 26}.should == {:s=>'SELECT * FROM test WHERE (z > 26) ORDER BY name DESC LIMIT 1'}
|
|
2529
2274
|
end
|
|
2530
2275
|
|
|
2531
2276
|
specify "should combine block and standard argument filters if argument is not an Integer" do
|
|
2532
|
-
@d.first(:y=>25){:z.sql_number > 26}.should ==
|
|
2533
|
-
@d.order(:name).last('y = ?', 16){:z.sql_number > 26}.should ==
|
|
2277
|
+
@d.first(:y=>25){:z.sql_number > 26}.should == {:s=>'SELECT * FROM test WHERE ((z > 26) AND (y = 25)) LIMIT 1'}
|
|
2278
|
+
@d.order(:name).last('y = ?', 16){:z.sql_number > 26}.should == {:s=>'SELECT * FROM test WHERE ((z > 26) AND (y = 16)) ORDER BY name DESC LIMIT 1'}
|
|
2534
2279
|
end
|
|
2535
2280
|
|
|
2536
2281
|
specify "should filter and return an array of records if an Integer argument is provided and a block is given" do
|
|
2537
2282
|
i = rand(10) + 10
|
|
2538
|
-
r = @d.order(:a).first(i){:z.sql_number > 26}.should == [
|
|
2283
|
+
r = @d.order(:a).first(i){:z.sql_number > 26}.should == [{:s=>"SELECT * FROM test WHERE (z > 26) ORDER BY a LIMIT #{i}"}]
|
|
2539
2284
|
i = rand(10) + 10
|
|
2540
|
-
r = @d.order(:a).last(i){:z.sql_number > 26}.should == [
|
|
2285
|
+
r = @d.order(:a).last(i){:z.sql_number > 26}.should == [{:s=>"SELECT * FROM test WHERE (z > 26) ORDER BY a DESC LIMIT #{i}"}]
|
|
2541
2286
|
end
|
|
2542
2287
|
|
|
2543
2288
|
specify "#last should raise if no order is given" do
|
|
@@ -2548,10 +2293,10 @@ describe "Dataset #first and #last" do
|
|
|
2548
2293
|
end
|
|
2549
2294
|
|
|
2550
2295
|
specify "#last should invert the order" do
|
|
2551
|
-
@d.order(:a).last.
|
|
2552
|
-
@d.order(:b.desc).last.
|
|
2553
|
-
@d.order(:c, :d).last.
|
|
2554
|
-
@d.order(:e.desc, :f).last.
|
|
2296
|
+
@d.order(:a).last.should == {:s=>'SELECT * FROM test ORDER BY a DESC LIMIT 1'}
|
|
2297
|
+
@d.order(:b.desc).last.should == {:s=>'SELECT * FROM test ORDER BY b ASC LIMIT 1'}
|
|
2298
|
+
@d.order(:c, :d).last.should == {:s=>'SELECT * FROM test ORDER BY c DESC, d DESC LIMIT 1'}
|
|
2299
|
+
@d.order(:e.desc, :f).last.should == {:s=>'SELECT * FROM test ORDER BY e ASC, f DESC LIMIT 1'}
|
|
2555
2300
|
end
|
|
2556
2301
|
end
|
|
2557
2302
|
|
|
@@ -2562,55 +2307,37 @@ describe "Dataset compound operations" do
|
|
|
2562
2307
|
end
|
|
2563
2308
|
|
|
2564
2309
|
specify "should support UNION and UNION ALL" do
|
|
2565
|
-
@a.union(@b).sql.should ==
|
|
2566
|
-
|
|
2567
|
-
@b.union(@a, true).sql.should ==
|
|
2568
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2569
|
-
@b.union(@a, :all=>true).sql.should == \
|
|
2570
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2310
|
+
@a.union(@b).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) UNION SELECT * FROM b WHERE (z = 2)) AS t1"
|
|
2311
|
+
@b.union(@a, true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2312
|
+
@b.union(@a, :all=>true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2571
2313
|
end
|
|
2572
2314
|
|
|
2573
2315
|
specify "should support INTERSECT and INTERSECT ALL" do
|
|
2574
|
-
@a.intersect(@b).sql.should ==
|
|
2575
|
-
|
|
2576
|
-
@b.intersect(@a, true).sql.should ==
|
|
2577
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2578
|
-
@b.intersect(@a, :all=>true).sql.should == \
|
|
2579
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2316
|
+
@a.intersect(@b).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT SELECT * FROM b WHERE (z = 2)) AS t1"
|
|
2317
|
+
@b.intersect(@a, true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2318
|
+
@b.intersect(@a, :all=>true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2580
2319
|
end
|
|
2581
2320
|
|
|
2582
2321
|
specify "should support EXCEPT and EXCEPT ALL" do
|
|
2583
|
-
@a.except(@b).sql.should ==
|
|
2584
|
-
|
|
2585
|
-
@b.except(@a, true).sql.should ==
|
|
2586
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2587
|
-
@b.except(@a, :all=>true).sql.should == \
|
|
2588
|
-
"SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2322
|
+
@a.except(@b).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM b WHERE (z = 2)) AS t1"
|
|
2323
|
+
@b.except(@a, true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2324
|
+
@b.except(@a, :all=>true).sql.should == "SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2589
2325
|
end
|
|
2590
2326
|
|
|
2591
2327
|
specify "should support :alias option for specifying identifier" do
|
|
2592
|
-
@a.union(@b, :alias=>:xx).sql.should ==
|
|
2593
|
-
|
|
2594
|
-
@a.
|
|
2595
|
-
"SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT SELECT * FROM b WHERE (z = 2)) AS xx"
|
|
2596
|
-
@a.except(@b, :alias=>:xx).sql.should == \
|
|
2597
|
-
"SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM b WHERE (z = 2)) AS xx"
|
|
2328
|
+
@a.union(@b, :alias=>:xx).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) UNION SELECT * FROM b WHERE (z = 2)) AS xx"
|
|
2329
|
+
@a.intersect(@b, :alias=>:xx).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT SELECT * FROM b WHERE (z = 2)) AS xx"
|
|
2330
|
+
@a.except(@b, :alias=>:xx).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM b WHERE (z = 2)) AS xx"
|
|
2598
2331
|
end
|
|
2599
2332
|
|
|
2600
2333
|
specify "should support :from_self=>false option to not wrap the compound in a SELECT * FROM (...)" do
|
|
2601
|
-
@b.union(@a, :from_self=>false).sql.should ==
|
|
2602
|
-
|
|
2603
|
-
@b.
|
|
2604
|
-
"SELECT * FROM b WHERE (z = 2) INTERSECT SELECT * FROM a WHERE (z = 1)"
|
|
2605
|
-
@b.except(@a, :from_self=>false).sql.should == \
|
|
2606
|
-
"SELECT * FROM b WHERE (z = 2) EXCEPT SELECT * FROM a WHERE (z = 1)"
|
|
2334
|
+
@b.union(@a, :from_self=>false).sql.should == "SELECT * FROM b WHERE (z = 2) UNION SELECT * FROM a WHERE (z = 1)"
|
|
2335
|
+
@b.intersect(@a, :from_self=>false).sql.should == "SELECT * FROM b WHERE (z = 2) INTERSECT SELECT * FROM a WHERE (z = 1)"
|
|
2336
|
+
@b.except(@a, :from_self=>false).sql.should == "SELECT * FROM b WHERE (z = 2) EXCEPT SELECT * FROM a WHERE (z = 1)"
|
|
2607
2337
|
|
|
2608
|
-
@b.union(@a, :from_self=>false, :all=>true).sql.should ==
|
|
2609
|
-
|
|
2610
|
-
@b.
|
|
2611
|
-
"SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)"
|
|
2612
|
-
@b.except(@a, :from_self=>false, :all=>true).sql.should == \
|
|
2613
|
-
"SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)"
|
|
2338
|
+
@b.union(@a, :from_self=>false, :all=>true).sql.should == "SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)"
|
|
2339
|
+
@b.intersect(@a, :from_self=>false, :all=>true).sql.should == "SELECT * FROM b WHERE (z = 2) INTERSECT ALL SELECT * FROM a WHERE (z = 1)"
|
|
2340
|
+
@b.except(@a, :from_self=>false, :all=>true).sql.should == "SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)"
|
|
2614
2341
|
end
|
|
2615
2342
|
|
|
2616
2343
|
specify "should raise an InvalidOperation if INTERSECT or EXCEPT is used and they are not supported" do
|
|
@@ -2630,141 +2357,105 @@ describe "Dataset compound operations" do
|
|
|
2630
2357
|
end
|
|
2631
2358
|
|
|
2632
2359
|
specify "should handle chained compound operations" do
|
|
2633
|
-
@a.union(@b).union(@a, true).sql.should ==
|
|
2634
|
-
|
|
2635
|
-
@a.
|
|
2636
|
-
"SELECT * FROM (SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT ALL SELECT * FROM b WHERE (z = 2)) AS t1 INTERSECT SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2637
|
-
@a.except(@b).except(@a, true).sql.should == \
|
|
2638
|
-
"SELECT * FROM (SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM b WHERE (z = 2)) AS t1 EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2360
|
+
@a.union(@b).union(@a, true).sql.should == "SELECT * FROM (SELECT * FROM (SELECT * FROM a WHERE (z = 1) UNION SELECT * FROM b WHERE (z = 2)) AS t1 UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2361
|
+
@a.intersect(@b, true).intersect(@a).sql.should == "SELECT * FROM (SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT ALL SELECT * FROM b WHERE (z = 2)) AS t1 INTERSECT SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2362
|
+
@a.except(@b).except(@a, true).sql.should == "SELECT * FROM (SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM b WHERE (z = 2)) AS t1 EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1"
|
|
2639
2363
|
end
|
|
2640
2364
|
|
|
2641
2365
|
specify "should use a subselect when using a compound operation with a dataset that already has a compound operation" do
|
|
2642
|
-
@a.union(@b.union(@a, true)).sql.should ==
|
|
2643
|
-
|
|
2644
|
-
@a.
|
|
2645
|
-
"SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT ALL SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT SELECT * FROM a WHERE (z = 1)) AS t1) AS t1"
|
|
2646
|
-
@a.except(@b.except(@a, true)).sql.should == \
|
|
2647
|
-
"SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1) AS t1"
|
|
2366
|
+
@a.union(@b.union(@a, true)).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) UNION SELECT * FROM (SELECT * FROM b WHERE (z = 2) UNION ALL SELECT * FROM a WHERE (z = 1)) AS t1) AS t1"
|
|
2367
|
+
@a.intersect(@b.intersect(@a), true).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) INTERSECT ALL SELECT * FROM (SELECT * FROM b WHERE (z = 2) INTERSECT SELECT * FROM a WHERE (z = 1)) AS t1) AS t1"
|
|
2368
|
+
@a.except(@b.except(@a, true)).sql.should == "SELECT * FROM (SELECT * FROM a WHERE (z = 1) EXCEPT SELECT * FROM (SELECT * FROM b WHERE (z = 2) EXCEPT ALL SELECT * FROM a WHERE (z = 1)) AS t1) AS t1"
|
|
2648
2369
|
end
|
|
2649
2370
|
|
|
2650
2371
|
specify "should order and limit properly when using UNION, INTERSECT, or EXCEPT" do
|
|
2651
2372
|
@dataset = Sequel::Dataset.new(nil).from(:test)
|
|
2652
|
-
@dataset.union(@dataset).limit(2).sql.should ==
|
|
2653
|
-
|
|
2654
|
-
@dataset.limit(2)
|
|
2655
|
-
|
|
2656
|
-
@dataset.
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
@dataset.union(@dataset).order(:num).sql.should ==
|
|
2660
|
-
"SELECT * FROM (SELECT * FROM test UNION SELECT * FROM test) AS t1 ORDER BY num"
|
|
2661
|
-
@dataset.order(:num).intersect(@dataset).sql.should ==
|
|
2662
|
-
"SELECT * FROM (SELECT * FROM (SELECT * FROM test ORDER BY num) AS t1 INTERSECT SELECT * FROM test) AS t1"
|
|
2663
|
-
@dataset.except(@dataset.order(:num)).sql.should ==
|
|
2664
|
-
"SELECT * FROM (SELECT * FROM test EXCEPT SELECT * FROM (SELECT * FROM test ORDER BY num) AS t1) AS t1"
|
|
2373
|
+
@dataset.union(@dataset).limit(2).sql.should == "SELECT * FROM (SELECT * FROM test UNION SELECT * FROM test) AS t1 LIMIT 2"
|
|
2374
|
+
@dataset.limit(2).intersect(@dataset).sql.should == "SELECT * FROM (SELECT * FROM (SELECT * FROM test LIMIT 2) AS t1 INTERSECT SELECT * FROM test) AS t1"
|
|
2375
|
+
@dataset.except(@dataset.limit(2)).sql.should == "SELECT * FROM (SELECT * FROM test EXCEPT SELECT * FROM (SELECT * FROM test LIMIT 2) AS t1) AS t1"
|
|
2376
|
+
|
|
2377
|
+
@dataset.union(@dataset).order(:num).sql.should == "SELECT * FROM (SELECT * FROM test UNION SELECT * FROM test) AS t1 ORDER BY num"
|
|
2378
|
+
@dataset.order(:num).intersect(@dataset).sql.should == "SELECT * FROM (SELECT * FROM (SELECT * FROM test ORDER BY num) AS t1 INTERSECT SELECT * FROM test) AS t1"
|
|
2379
|
+
@dataset.except(@dataset.order(:num)).sql.should == "SELECT * FROM (SELECT * FROM test EXCEPT SELECT * FROM (SELECT * FROM test ORDER BY num) AS t1) AS t1"
|
|
2665
2380
|
|
|
2666
2381
|
@dataset.limit(2).order(:a).union(@dataset.limit(3).order(:b)).order(:c).limit(4).sql.should ==
|
|
2667
2382
|
"SELECT * FROM (SELECT * FROM (SELECT * FROM test ORDER BY a LIMIT 2) AS t1 UNION SELECT * FROM (SELECT * FROM test ORDER BY b LIMIT 3) AS t1) AS t1 ORDER BY c LIMIT 4"
|
|
2668
2383
|
end
|
|
2669
2384
|
|
|
2385
|
+
specify "should hoist WITH clauses in given dataset if dataset doesn't support WITH in subselect" do
|
|
2386
|
+
ds = Sequel::Dataset.new(nil)
|
|
2387
|
+
ds.meta_def(:supports_cte?){true}
|
|
2388
|
+
ds.meta_def(:supports_cte_in_subselect?){false}
|
|
2389
|
+
ds.from(:a).union(ds.from(:c).with(:c, ds.from(:d)), :from_self=>false).sql.should == 'WITH c AS (SELECT * FROM d) SELECT * FROM a UNION SELECT * FROM c'
|
|
2390
|
+
ds.from(:a).except(ds.from(:c).with(:c, ds.from(:d))).sql.should == 'WITH c AS (SELECT * FROM d) SELECT * FROM (SELECT * FROM a EXCEPT SELECT * FROM c) AS t1'
|
|
2391
|
+
ds.from(:a).with(:a, ds.from(:b)).intersect(ds.from(:c).with(:c, ds.from(:d)), :from_self=>false).sql.should == 'WITH a AS (SELECT * FROM b), c AS (SELECT * FROM d) SELECT * FROM a INTERSECT SELECT * FROM c'
|
|
2392
|
+
end
|
|
2670
2393
|
end
|
|
2671
2394
|
|
|
2672
2395
|
describe "Dataset#[]" do
|
|
2673
2396
|
before do
|
|
2674
|
-
@
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
def self.last_dataset
|
|
2678
|
-
class_variable_get(:@@last_dataset)
|
|
2679
|
-
end
|
|
2680
|
-
|
|
2681
|
-
def single_record
|
|
2682
|
-
self.class.send(:class_variable_set, :@@last_dataset, opts ? clone(opts) : self)
|
|
2683
|
-
{1 => 2, 3 => 4}
|
|
2684
|
-
end
|
|
2685
|
-
end
|
|
2686
|
-
@d = @c.new(nil).from(:test)
|
|
2397
|
+
@db = Sequel.mock(:fetch=>{1 => 2, 3 => 4})
|
|
2398
|
+
@d = @db[:items]
|
|
2687
2399
|
end
|
|
2688
2400
|
|
|
2689
2401
|
specify "should return a single record filtered according to the given conditions" do
|
|
2690
2402
|
@d[:name => 'didi'].should == {1 => 2, 3 => 4}
|
|
2691
|
-
@
|
|
2403
|
+
@db.sqls.should == ["SELECT * FROM items WHERE (name = 'didi') LIMIT 1"]
|
|
2692
2404
|
|
|
2693
2405
|
@d[:id => 5..45].should == {1 => 2, 3 => 4}
|
|
2694
|
-
@
|
|
2406
|
+
@db.sqls.should == ["SELECT * FROM items WHERE ((id >= 5) AND (id <= 45)) LIMIT 1"]
|
|
2695
2407
|
end
|
|
2696
2408
|
end
|
|
2697
2409
|
|
|
2698
2410
|
describe "Dataset#single_record" do
|
|
2699
2411
|
before do
|
|
2700
|
-
@
|
|
2701
|
-
def fetch_rows(sql)
|
|
2702
|
-
yield sql
|
|
2703
|
-
end
|
|
2704
|
-
end
|
|
2705
|
-
@cc = Class.new(@c) do
|
|
2706
|
-
def fetch_rows(sql); end
|
|
2707
|
-
end
|
|
2708
|
-
|
|
2709
|
-
@d = @c.new(nil).from(:test)
|
|
2710
|
-
@e = @cc.new(nil).from(:test)
|
|
2412
|
+
@db = Sequel.mock
|
|
2711
2413
|
end
|
|
2712
2414
|
|
|
2713
2415
|
specify "should call each with a limit of 1 and return the record" do
|
|
2714
|
-
@
|
|
2416
|
+
@db.fetch = {:a=>1}
|
|
2417
|
+
@db[:test].single_record.should == {:a=>1}
|
|
2418
|
+
@db.sqls.should == ['SELECT * FROM test LIMIT 1']
|
|
2715
2419
|
end
|
|
2716
2420
|
|
|
2717
2421
|
specify "should return nil if no record is present" do
|
|
2718
|
-
@
|
|
2422
|
+
@db[:test].single_record.should be_nil
|
|
2423
|
+
@db.sqls.should == ['SELECT * FROM test LIMIT 1']
|
|
2719
2424
|
end
|
|
2720
2425
|
end
|
|
2721
2426
|
|
|
2722
2427
|
describe "Dataset#single_value" do
|
|
2723
2428
|
before do
|
|
2724
|
-
@
|
|
2725
|
-
def fetch_rows(sql)
|
|
2726
|
-
yield({1 => sql})
|
|
2727
|
-
end
|
|
2728
|
-
end
|
|
2729
|
-
@cc = Class.new(@c) do
|
|
2730
|
-
def fetch_rows(sql); end
|
|
2731
|
-
end
|
|
2732
|
-
|
|
2733
|
-
@d = @c.new(nil).from(:test)
|
|
2734
|
-
@e = @cc.new(nil).from(:test)
|
|
2429
|
+
@db = Sequel.mock
|
|
2735
2430
|
end
|
|
2736
2431
|
|
|
2737
2432
|
specify "should call each and return the first value of the first record" do
|
|
2738
|
-
@
|
|
2433
|
+
@db.fetch = {:a=>1}
|
|
2434
|
+
@db[:test].single_value.should == 1
|
|
2435
|
+
@db.sqls.should == ['SELECT * FROM test LIMIT 1']
|
|
2739
2436
|
end
|
|
2740
2437
|
|
|
2741
2438
|
specify "should return nil if no records" do
|
|
2742
|
-
@
|
|
2439
|
+
@db[:test].single_value.should be_nil
|
|
2440
|
+
@db.sqls.should == ['SELECT * FROM test LIMIT 1']
|
|
2743
2441
|
end
|
|
2744
2442
|
|
|
2745
2443
|
it "should work on a graphed_dataset" do
|
|
2746
|
-
@
|
|
2747
|
-
@
|
|
2444
|
+
@db.fetch = {:a=>1}
|
|
2445
|
+
ds = @db[:test].columns(:a)
|
|
2446
|
+
ds.graph(ds, [:a], :table_alias=>:test2).single_value.should == 1
|
|
2447
|
+
@db.sqls.should == ['SELECT test.a, test2.a AS test2_a FROM test LEFT OUTER JOIN test AS test2 USING (a) LIMIT 1']
|
|
2748
2448
|
end
|
|
2749
2449
|
end
|
|
2750
2450
|
|
|
2751
2451
|
describe "Dataset#get" do
|
|
2752
2452
|
before do
|
|
2753
|
-
@
|
|
2754
|
-
attr_reader :last_sql
|
|
2755
|
-
|
|
2756
|
-
def fetch_rows(sql)
|
|
2757
|
-
@last_sql = sql
|
|
2758
|
-
yield(:name => sql)
|
|
2759
|
-
end
|
|
2760
|
-
end
|
|
2761
|
-
|
|
2762
|
-
@d = @c.new(nil).from(:test)
|
|
2453
|
+
@d = Sequel.mock(:fetch=>proc{|s| {:name=>s}})[:test]
|
|
2763
2454
|
end
|
|
2764
2455
|
|
|
2765
2456
|
specify "should select the specified column and fetch its value" do
|
|
2766
2457
|
@d.get(:name).should == "SELECT name FROM test LIMIT 1"
|
|
2767
|
-
@d.get(:abc).should == "SELECT abc FROM test LIMIT 1"
|
|
2458
|
+
@d.get(:abc).should == "SELECT abc FROM test LIMIT 1"
|
|
2768
2459
|
end
|
|
2769
2460
|
|
|
2770
2461
|
specify "should work with filters" do
|
|
@@ -2787,239 +2478,206 @@ end
|
|
|
2787
2478
|
|
|
2788
2479
|
describe "Dataset#set_row_proc" do
|
|
2789
2480
|
before do
|
|
2790
|
-
@
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
(1..10).each {|i| block.call({:kind => i[0]})}
|
|
2794
|
-
end
|
|
2795
|
-
end
|
|
2796
|
-
@dataset = @c.new(nil).from(:items)
|
|
2481
|
+
@db = Sequel.mock(:fetch=>[{:a=>1}, {:a=>2}])
|
|
2482
|
+
@dataset = @db[:items]
|
|
2483
|
+
@dataset.row_proc = proc{|h| h[:der] = h[:a] + 2; h}
|
|
2797
2484
|
end
|
|
2798
2485
|
|
|
2799
2486
|
specify "should cause dataset to pass all rows through the filter" do
|
|
2800
|
-
@dataset.row_proc = proc{|h| h[:der] = h[:kind] + 2; h}
|
|
2801
|
-
|
|
2802
2487
|
rows = @dataset.all
|
|
2803
|
-
rows.
|
|
2804
|
-
|
|
2805
|
-
rows.each {|r| r[:der].should == (r[:kind] + 2)}
|
|
2488
|
+
rows.map{|h| h[:der]}.should == [3, 4]
|
|
2489
|
+
@db.sqls.should == ['SELECT * FROM items']
|
|
2806
2490
|
end
|
|
2807
2491
|
|
|
2808
2492
|
specify "should be copied over when dataset is cloned" do
|
|
2809
|
-
@dataset.
|
|
2810
|
-
|
|
2811
|
-
@dataset.filter(:a => 1).first.should == {:kind => 1, :der => 3}
|
|
2493
|
+
@dataset.filter(:a => 1).all.should == [{:a=>1, :der=>3}, {:a=>2, :der=>4}]
|
|
2812
2494
|
end
|
|
2813
2495
|
end
|
|
2814
2496
|
|
|
2815
2497
|
describe "Dataset#<<" do
|
|
2816
2498
|
before do
|
|
2817
|
-
@
|
|
2818
|
-
@d.meta_def(:insert) do |*args|
|
|
2819
|
-
1234567890
|
|
2820
|
-
end
|
|
2499
|
+
@db = Sequel.mock
|
|
2821
2500
|
end
|
|
2822
|
-
|
|
2501
|
+
|
|
2823
2502
|
specify "should call #insert" do
|
|
2824
|
-
|
|
2503
|
+
@db[:items] << {:name => 1}
|
|
2504
|
+
@db.sqls.should == ['INSERT INTO items (name) VALUES (1)']
|
|
2505
|
+
end
|
|
2506
|
+
|
|
2507
|
+
specify "should be chainable" do
|
|
2508
|
+
@db[:items] << {:name => 1} << @db[:old_items].select(:name)
|
|
2509
|
+
@db.sqls.should == ['INSERT INTO items (name) VALUES (1)', 'INSERT INTO items SELECT name FROM old_items']
|
|
2825
2510
|
end
|
|
2826
2511
|
end
|
|
2827
2512
|
|
|
2828
2513
|
describe "Dataset#columns" do
|
|
2829
2514
|
before do
|
|
2830
|
-
@dataset =
|
|
2831
|
-
@dataset.meta_def(:columns=) {|c| @columns = c}
|
|
2832
|
-
i = 'a'
|
|
2833
|
-
@dataset.meta_def(:each){@columns = select_sql + i; i = i.next}
|
|
2515
|
+
@dataset = Sequel.mock[:items]
|
|
2834
2516
|
end
|
|
2835
2517
|
|
|
2836
2518
|
specify "should return the value of @columns if @columns is not nil" do
|
|
2837
|
-
@dataset.columns
|
|
2838
|
-
@dataset.
|
|
2519
|
+
@dataset.columns(:a, :b, :c).columns.should == [:a, :b, :c]
|
|
2520
|
+
@dataset.db.sqls.should == []
|
|
2839
2521
|
end
|
|
2840
2522
|
|
|
2841
2523
|
specify "should attempt to get a single record and return @columns if @columns is nil" do
|
|
2842
|
-
@dataset.columns =
|
|
2843
|
-
@dataset.columns.should ==
|
|
2844
|
-
@dataset.
|
|
2845
|
-
|
|
2524
|
+
@dataset.db.columns = [:a]
|
|
2525
|
+
@dataset.columns.should == [:a]
|
|
2526
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2527
|
+
end
|
|
2528
|
+
|
|
2529
|
+
specify "should be cleared if you change the selected columns" do
|
|
2530
|
+
@dataset.db.columns = [[:a], [:b]]
|
|
2531
|
+
@dataset.columns.should == [:a]
|
|
2532
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2533
|
+
@dataset.columns.should == [:a]
|
|
2534
|
+
@dataset.db.sqls.should == []
|
|
2535
|
+
ds = @dataset.select{foo{}}
|
|
2536
|
+
ds.columns.should == [:b]
|
|
2537
|
+
@dataset.db.sqls.should == ['SELECT foo() FROM items LIMIT 1']
|
|
2538
|
+
end
|
|
2539
|
+
|
|
2540
|
+
specify "should be cleared if you change the FROM table" do
|
|
2541
|
+
@dataset.db.columns = [[:a], [:b]]
|
|
2542
|
+
@dataset.columns.should == [:a]
|
|
2543
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2544
|
+
ds = @dataset.from(:foo)
|
|
2545
|
+
ds.columns.should == [:b]
|
|
2546
|
+
@dataset.db.sqls.should == ['SELECT * FROM foo LIMIT 1']
|
|
2547
|
+
end
|
|
2548
|
+
|
|
2549
|
+
specify "should be cleared if you join a table to the dataset" do
|
|
2550
|
+
@dataset.db.columns = [[:a], [:a, :b]]
|
|
2551
|
+
@dataset.columns.should == [:a]
|
|
2552
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2553
|
+
ds = @dataset.cross_join(:foo)
|
|
2554
|
+
ds.columns.should == [:a, :b]
|
|
2555
|
+
@dataset.db.sqls.should == ['SELECT * FROM items CROSS JOIN foo LIMIT 1']
|
|
2556
|
+
end
|
|
2557
|
+
|
|
2558
|
+
specify "should be cleared if you set custom SQL for the dataset" do
|
|
2559
|
+
@dataset.db.columns = [[:a], [:b]]
|
|
2560
|
+
@dataset.columns.should == [:a]
|
|
2561
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2562
|
+
ds = @dataset.with_sql('SELECT b FROM foo')
|
|
2563
|
+
ds.columns.should == [:b]
|
|
2564
|
+
@dataset.db.sqls.should == ['SELECT b FROM foo']
|
|
2846
2565
|
end
|
|
2847
2566
|
|
|
2848
2567
|
specify "should ignore any filters, orders, or DISTINCT clauses" do
|
|
2568
|
+
@dataset.db.columns = [:a]
|
|
2849
2569
|
@dataset.filter!(:b=>100).order!(:b).distinct!
|
|
2850
|
-
@dataset.columns
|
|
2851
|
-
@dataset.
|
|
2570
|
+
@dataset.columns.should == [:a]
|
|
2571
|
+
@dataset.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2852
2572
|
end
|
|
2853
2573
|
end
|
|
2854
2574
|
|
|
2855
2575
|
describe "Dataset#columns!" do
|
|
2856
|
-
before do
|
|
2857
|
-
@dataset = DummyDataset.new(nil).from(:items)
|
|
2858
|
-
i = 'a'
|
|
2859
|
-
@dataset.meta_def(:each){@columns = select_sql + i; i = i.next}
|
|
2860
|
-
end
|
|
2861
|
-
|
|
2862
2576
|
specify "should always attempt to get a record and return @columns" do
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2577
|
+
ds = Sequel.mock(:columns=>[[:a, :b, :c], [:d, :e, :f]])[:items]
|
|
2578
|
+
ds.columns!.should == [:a, :b, :c]
|
|
2579
|
+
ds.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2580
|
+
ds.columns!.should == [:d, :e, :f]
|
|
2581
|
+
ds.db.sqls.should == ['SELECT * FROM items LIMIT 1']
|
|
2867
2582
|
end
|
|
2868
2583
|
end
|
|
2869
2584
|
|
|
2870
2585
|
describe "Dataset#import" do
|
|
2871
2586
|
before do
|
|
2872
|
-
@
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
def execute(sql, opts={})
|
|
2876
|
-
@sqls ||= []
|
|
2877
|
-
@sqls << sql
|
|
2878
|
-
end
|
|
2879
|
-
alias execute_dui execute
|
|
2880
|
-
|
|
2881
|
-
def transaction(opts={})
|
|
2882
|
-
@sqls ||= []
|
|
2883
|
-
@sqls << 'BEGIN'
|
|
2884
|
-
yield
|
|
2885
|
-
@sqls << 'COMMIT'
|
|
2886
|
-
end
|
|
2887
|
-
end
|
|
2888
|
-
@db = @dbc.new
|
|
2889
|
-
|
|
2890
|
-
@ds = Sequel::Dataset.new(@db).from(:items)
|
|
2891
|
-
|
|
2892
|
-
@list = [{:name => 'abc'}, {:name => 'def'}, {:name => 'ghi'}]
|
|
2587
|
+
@db = Sequel.mock
|
|
2588
|
+
@ds = @db[:items]
|
|
2893
2589
|
end
|
|
2894
2590
|
|
|
2895
2591
|
specify "should accept string keys as column names" do
|
|
2896
2592
|
@ds.import(['x', 'y'], [[1, 2], [3, 4]])
|
|
2897
|
-
@db.sqls.should == [
|
|
2898
|
-
'BEGIN',
|
|
2593
|
+
@db.sqls.should == ['BEGIN',
|
|
2899
2594
|
"INSERT INTO items (x, y) VALUES (1, 2)",
|
|
2900
2595
|
"INSERT INTO items (x, y) VALUES (3, 4)",
|
|
2901
|
-
'COMMIT'
|
|
2902
|
-
]
|
|
2596
|
+
'COMMIT']
|
|
2903
2597
|
end
|
|
2904
2598
|
|
|
2905
2599
|
specify "should accept a columns array and a values array" do
|
|
2906
2600
|
@ds.import([:x, :y], [[1, 2], [3, 4]])
|
|
2907
|
-
@db.sqls.should == [
|
|
2908
|
-
'BEGIN',
|
|
2601
|
+
@db.sqls.should == ['BEGIN',
|
|
2909
2602
|
"INSERT INTO items (x, y) VALUES (1, 2)",
|
|
2910
2603
|
"INSERT INTO items (x, y) VALUES (3, 4)",
|
|
2911
|
-
'COMMIT'
|
|
2912
|
-
]
|
|
2604
|
+
'COMMIT']
|
|
2913
2605
|
end
|
|
2914
2606
|
|
|
2915
2607
|
specify "should accept a columns array and a dataset" do
|
|
2916
|
-
@ds2 =
|
|
2608
|
+
@ds2 = @ds.from(:cats).filter(:purr => true).select(:a, :b)
|
|
2917
2609
|
|
|
2918
2610
|
@ds.import([:x, :y], @ds2)
|
|
2919
|
-
@db.sqls.should == [
|
|
2920
|
-
'BEGIN',
|
|
2611
|
+
@db.sqls.should == ['BEGIN',
|
|
2921
2612
|
"INSERT INTO items (x, y) SELECT a, b FROM cats WHERE (purr IS TRUE)",
|
|
2922
|
-
'COMMIT'
|
|
2923
|
-
]
|
|
2613
|
+
'COMMIT']
|
|
2924
2614
|
end
|
|
2925
2615
|
|
|
2926
2616
|
specify "should accept a columns array and a values array with :commit_every option" do
|
|
2927
2617
|
@ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]], :commit_every => 3)
|
|
2928
|
-
@db.sqls.should == [
|
|
2929
|
-
'BEGIN',
|
|
2618
|
+
@db.sqls.should == ['BEGIN',
|
|
2930
2619
|
"INSERT INTO items (x, y) VALUES (1, 2)",
|
|
2931
2620
|
"INSERT INTO items (x, y) VALUES (3, 4)",
|
|
2932
2621
|
"INSERT INTO items (x, y) VALUES (5, 6)",
|
|
2933
|
-
'COMMIT'
|
|
2934
|
-
]
|
|
2622
|
+
'COMMIT']
|
|
2935
2623
|
end
|
|
2936
|
-
specify "should accept a columns array and a values array with slice option" do
|
|
2624
|
+
specify "should accept a columns array and a values array with :slice option" do
|
|
2937
2625
|
@ds.import([:x, :y], [[1, 2], [3, 4], [5, 6]], :slice => 2)
|
|
2938
|
-
@db.sqls.should == [
|
|
2939
|
-
'BEGIN',
|
|
2626
|
+
@db.sqls.should == ['BEGIN',
|
|
2940
2627
|
"INSERT INTO items (x, y) VALUES (1, 2)",
|
|
2941
2628
|
"INSERT INTO items (x, y) VALUES (3, 4)",
|
|
2942
2629
|
'COMMIT',
|
|
2943
2630
|
'BEGIN',
|
|
2944
2631
|
"INSERT INTO items (x, y) VALUES (5, 6)",
|
|
2945
|
-
'COMMIT'
|
|
2946
|
-
]
|
|
2632
|
+
'COMMIT']
|
|
2947
2633
|
end
|
|
2948
2634
|
end
|
|
2949
2635
|
|
|
2950
2636
|
describe "Dataset#multi_insert" do
|
|
2951
2637
|
before do
|
|
2952
|
-
@
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
def execute(sql, opts={})
|
|
2956
|
-
@sqls ||= []
|
|
2957
|
-
@sqls << sql
|
|
2958
|
-
end
|
|
2959
|
-
alias execute_dui execute
|
|
2960
|
-
|
|
2961
|
-
def transaction(opts={})
|
|
2962
|
-
@sqls ||= []
|
|
2963
|
-
@sqls << 'BEGIN'
|
|
2964
|
-
yield
|
|
2965
|
-
@sqls << 'COMMIT'
|
|
2966
|
-
end
|
|
2967
|
-
end
|
|
2968
|
-
@db = @dbc.new
|
|
2969
|
-
|
|
2970
|
-
@ds = Sequel::Dataset.new(@db).from(:items)
|
|
2971
|
-
|
|
2638
|
+
@db = Sequel.mock
|
|
2639
|
+
@ds = @db[:items]
|
|
2972
2640
|
@list = [{:name => 'abc'}, {:name => 'def'}, {:name => 'ghi'}]
|
|
2973
2641
|
end
|
|
2974
2642
|
|
|
2975
2643
|
specify "should issue multiple insert statements inside a transaction" do
|
|
2976
2644
|
@ds.multi_insert(@list)
|
|
2977
|
-
@db.sqls.should == [
|
|
2978
|
-
'BEGIN',
|
|
2645
|
+
@db.sqls.should == ['BEGIN',
|
|
2979
2646
|
"INSERT INTO items (name) VALUES ('abc')",
|
|
2980
2647
|
"INSERT INTO items (name) VALUES ('def')",
|
|
2981
2648
|
"INSERT INTO items (name) VALUES ('ghi')",
|
|
2982
|
-
'COMMIT'
|
|
2983
|
-
]
|
|
2649
|
+
'COMMIT']
|
|
2984
2650
|
end
|
|
2985
2651
|
|
|
2986
2652
|
specify "should handle different formats for tables" do
|
|
2987
2653
|
@ds = @ds.from(:sch__tab)
|
|
2988
2654
|
@ds.multi_insert(@list)
|
|
2989
|
-
@db.sqls.should == [
|
|
2990
|
-
'BEGIN',
|
|
2655
|
+
@db.sqls.should == ['BEGIN',
|
|
2991
2656
|
"INSERT INTO sch.tab (name) VALUES ('abc')",
|
|
2992
2657
|
"INSERT INTO sch.tab (name) VALUES ('def')",
|
|
2993
2658
|
"INSERT INTO sch.tab (name) VALUES ('ghi')",
|
|
2994
|
-
'COMMIT'
|
|
2995
|
-
]
|
|
2996
|
-
@db.sqls.clear
|
|
2659
|
+
'COMMIT']
|
|
2997
2660
|
|
|
2998
2661
|
@ds = @ds.from(:tab.qualify(:sch))
|
|
2999
2662
|
@ds.multi_insert(@list)
|
|
3000
|
-
@db.sqls.should == [
|
|
3001
|
-
'BEGIN',
|
|
2663
|
+
@db.sqls.should == ['BEGIN',
|
|
3002
2664
|
"INSERT INTO sch.tab (name) VALUES ('abc')",
|
|
3003
2665
|
"INSERT INTO sch.tab (name) VALUES ('def')",
|
|
3004
2666
|
"INSERT INTO sch.tab (name) VALUES ('ghi')",
|
|
3005
|
-
'COMMIT'
|
|
3006
|
-
|
|
3007
|
-
@db.sqls.clear
|
|
2667
|
+
'COMMIT']
|
|
2668
|
+
|
|
3008
2669
|
@ds = @ds.from(:sch__tab.identifier)
|
|
3009
2670
|
@ds.multi_insert(@list)
|
|
3010
|
-
@db.sqls.should == [
|
|
3011
|
-
'BEGIN',
|
|
2671
|
+
@db.sqls.should == ['BEGIN',
|
|
3012
2672
|
"INSERT INTO sch__tab (name) VALUES ('abc')",
|
|
3013
2673
|
"INSERT INTO sch__tab (name) VALUES ('def')",
|
|
3014
2674
|
"INSERT INTO sch__tab (name) VALUES ('ghi')",
|
|
3015
|
-
'COMMIT'
|
|
3016
|
-
]
|
|
2675
|
+
'COMMIT']
|
|
3017
2676
|
end
|
|
3018
2677
|
|
|
3019
2678
|
specify "should accept the :commit_every option for committing every x records" do
|
|
3020
2679
|
@ds.multi_insert(@list, :commit_every => 1)
|
|
3021
|
-
@db.sqls.should == [
|
|
3022
|
-
'BEGIN',
|
|
2680
|
+
@db.sqls.should == ['BEGIN',
|
|
3023
2681
|
"INSERT INTO items (name) VALUES ('abc')",
|
|
3024
2682
|
'COMMIT',
|
|
3025
2683
|
'BEGIN',
|
|
@@ -3027,36 +2685,31 @@ describe "Dataset#multi_insert" do
|
|
|
3027
2685
|
'COMMIT',
|
|
3028
2686
|
'BEGIN',
|
|
3029
2687
|
"INSERT INTO items (name) VALUES ('ghi')",
|
|
3030
|
-
'COMMIT'
|
|
3031
|
-
]
|
|
2688
|
+
'COMMIT']
|
|
3032
2689
|
end
|
|
3033
2690
|
|
|
3034
2691
|
specify "should accept the :slice option for committing every x records" do
|
|
3035
2692
|
@ds.multi_insert(@list, :slice => 2)
|
|
3036
|
-
@db.sqls.should == [
|
|
3037
|
-
'BEGIN',
|
|
2693
|
+
@db.sqls.should == ['BEGIN',
|
|
3038
2694
|
"INSERT INTO items (name) VALUES ('abc')",
|
|
3039
2695
|
"INSERT INTO items (name) VALUES ('def')",
|
|
3040
2696
|
'COMMIT',
|
|
3041
2697
|
'BEGIN',
|
|
3042
2698
|
"INSERT INTO items (name) VALUES ('ghi')",
|
|
3043
|
-
'COMMIT'
|
|
3044
|
-
]
|
|
2699
|
+
'COMMIT']
|
|
3045
2700
|
end
|
|
3046
2701
|
|
|
3047
2702
|
specify "should accept string keys as column names" do
|
|
3048
2703
|
@ds.multi_insert([{'x'=>1, 'y'=>2}, {'x'=>3, 'y'=>4}])
|
|
3049
|
-
@db.sqls.should == [
|
|
3050
|
-
'BEGIN',
|
|
2704
|
+
@db.sqls.should == ['BEGIN',
|
|
3051
2705
|
"INSERT INTO items (x, y) VALUES (1, 2)",
|
|
3052
2706
|
"INSERT INTO items (x, y) VALUES (3, 4)",
|
|
3053
|
-
'COMMIT'
|
|
3054
|
-
]
|
|
2707
|
+
'COMMIT']
|
|
3055
2708
|
end
|
|
3056
2709
|
|
|
3057
2710
|
specify "should not do anything if no hashes are provided" do
|
|
3058
2711
|
@ds.multi_insert([])
|
|
3059
|
-
@db.sqls.should
|
|
2712
|
+
@db.sqls.should == []
|
|
3060
2713
|
end
|
|
3061
2714
|
end
|
|
3062
2715
|
|
|
@@ -3101,41 +2754,21 @@ describe "Dataset" do
|
|
|
3101
2754
|
end
|
|
3102
2755
|
|
|
3103
2756
|
specify "should support chaining of bang methods" do
|
|
3104
|
-
@d.order!(:y)
|
|
3105
|
-
@d.filter!(:y => 1)
|
|
3106
|
-
@d.sql.should == "SELECT * FROM x WHERE (y = 1) ORDER BY y"
|
|
2757
|
+
@d.order!(:y).filter!(:y => 1).sql.should == "SELECT * FROM x WHERE (y = 1) ORDER BY y"
|
|
3107
2758
|
end
|
|
3108
2759
|
end
|
|
3109
2760
|
|
|
3110
2761
|
describe "Dataset#to_csv" do
|
|
3111
2762
|
before do
|
|
3112
|
-
@
|
|
3113
|
-
attr_accessor :data
|
|
3114
|
-
attr_accessor :columns
|
|
3115
|
-
|
|
3116
|
-
def fetch_rows(sql, &block)
|
|
3117
|
-
@data.each(&block)
|
|
3118
|
-
end
|
|
3119
|
-
|
|
3120
|
-
# naked should return self here because to_csv wants a naked result set.
|
|
3121
|
-
def naked
|
|
3122
|
-
self
|
|
3123
|
-
end
|
|
3124
|
-
end
|
|
3125
|
-
|
|
3126
|
-
@ds = @c.new(nil).from(:items)
|
|
3127
|
-
@ds.columns = [:a, :b, :c]
|
|
3128
|
-
@ds.data = [ {:a=>1, :b=>2, :c=>3}, {:a=>4, :b=>5, :c=>6}, {:a=>7, :b=>8, :c=>9} ]
|
|
2763
|
+
@ds = Sequel.mock(:fetch=>[{:a=>1, :b=>2, :c=>3}, {:a=>4, :b=>5, :c=>6}, {:a=>7, :b=>8, :c=>9}])[:items].columns(:a, :b, :c)
|
|
3129
2764
|
end
|
|
3130
2765
|
|
|
3131
2766
|
specify "should format a CSV representation of the records" do
|
|
3132
|
-
@ds.to_csv.should ==
|
|
3133
|
-
"a, b, c\r\n1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
|
|
2767
|
+
@ds.to_csv.should == "a, b, c\r\n1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
|
|
3134
2768
|
end
|
|
3135
2769
|
|
|
3136
2770
|
specify "should exclude column titles if so specified" do
|
|
3137
|
-
@ds.to_csv(false).should ==
|
|
3138
|
-
"1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
|
|
2771
|
+
@ds.to_csv(false).should == "1, 2, 3\r\n4, 5, 6\r\n7, 8, 9\r\n"
|
|
3139
2772
|
end
|
|
3140
2773
|
end
|
|
3141
2774
|
|
|
@@ -3233,66 +2866,40 @@ describe "Dataset#insert_sql" do
|
|
|
3233
2866
|
end
|
|
3234
2867
|
end
|
|
3235
2868
|
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
true
|
|
2869
|
+
describe "Dataset#inspect" do
|
|
2870
|
+
before do
|
|
2871
|
+
class ::InspectDataset < Sequel::Dataset; end
|
|
3240
2872
|
end
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
class DummyMummyDatabase < Sequel::Database
|
|
3244
|
-
attr_reader :sqls
|
|
3245
|
-
|
|
3246
|
-
def execute(sql)
|
|
3247
|
-
@sqls ||= []
|
|
3248
|
-
@sqls << sql
|
|
2873
|
+
after do
|
|
2874
|
+
Object.send(:remove_const, :InspectDataset) if defined?(::InspectDataset)
|
|
3249
2875
|
end
|
|
3250
|
-
|
|
3251
|
-
def transaction; yield; end
|
|
3252
2876
|
|
|
3253
|
-
|
|
3254
|
-
|
|
2877
|
+
specify "should include the class name and the corresponding SQL statement" do
|
|
2878
|
+
Sequel::Dataset.new(nil).from(:blah).inspect.should == '#<Sequel::Dataset: "SELECT * FROM blah">'
|
|
2879
|
+
InspectDataset.new(nil).from(:blah).inspect.should == '#<InspectDataset: "SELECT * FROM blah">'
|
|
3255
2880
|
end
|
|
3256
|
-
end
|
|
3257
2881
|
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
end
|
|
3262
|
-
|
|
3263
|
-
specify "should include the class name and the corresponding SQL statement" do
|
|
3264
|
-
@ds.inspect.should == '#<%s: %s>' % [@ds.class.to_s, @ds.sql.inspect]
|
|
2882
|
+
specify "should skip anonymous classes" do
|
|
2883
|
+
Class.new(Class.new(Sequel::Dataset)).new(nil).from(:blah).inspect.should == '#<Sequel::Dataset: "SELECT * FROM blah">'
|
|
2884
|
+
Class.new(InspectDataset).new(nil).from(:blah).inspect.should == '#<InspectDataset: "SELECT * FROM blah">'
|
|
3265
2885
|
end
|
|
3266
2886
|
end
|
|
3267
2887
|
|
|
3268
2888
|
describe "Dataset#all" do
|
|
3269
2889
|
before do
|
|
3270
|
-
@
|
|
3271
|
-
def fetch_rows(sql, &block)
|
|
3272
|
-
block.call({:x => 1, :y => 2})
|
|
3273
|
-
block.call({:x => 3, :y => 4})
|
|
3274
|
-
block.call(sql)
|
|
3275
|
-
end
|
|
3276
|
-
end
|
|
3277
|
-
@dataset = @c.new(nil).from(:items)
|
|
2890
|
+
@dataset = Sequel.mock(:fetch=>[{:x => 1, :y => 2}, {:x => 3, :y => 4}])[:items]
|
|
3278
2891
|
end
|
|
3279
2892
|
|
|
3280
2893
|
specify "should return an array with all records" do
|
|
3281
|
-
@dataset.all.should == [
|
|
3282
|
-
|
|
3283
|
-
{:x => 3, :y => 4},
|
|
3284
|
-
"SELECT * FROM items"
|
|
3285
|
-
]
|
|
2894
|
+
@dataset.all.should == [{:x => 1, :y => 2}, {:x => 3, :y => 4}]
|
|
2895
|
+
@dataset.db.sqls.should == ["SELECT * FROM items"]
|
|
3286
2896
|
end
|
|
3287
2897
|
|
|
3288
2898
|
specify "should iterate over the array if a block is given" do
|
|
3289
2899
|
a = []
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
end
|
|
3294
|
-
|
|
3295
|
-
a.should == [1, 3, "SELECT * FROM items"]
|
|
2900
|
+
@dataset.all{|r| a << r.values_at(:x, :y)}.should == [{:x => 1, :y => 2}, {:x => 3, :y => 4}]
|
|
2901
|
+
a.should == [[1, 2], [3, 4]]
|
|
2902
|
+
@dataset.db.sqls.should == ["SELECT * FROM items"]
|
|
3296
2903
|
end
|
|
3297
2904
|
end
|
|
3298
2905
|
|
|
@@ -3302,71 +2909,56 @@ describe "Dataset#grep" do
|
|
|
3302
2909
|
end
|
|
3303
2910
|
|
|
3304
2911
|
specify "should format a SQL filter correctly" do
|
|
3305
|
-
@ds.grep(:title, 'ruby').sql.should ==
|
|
3306
|
-
"SELECT * FROM posts WHERE ((title LIKE 'ruby'))"
|
|
2912
|
+
@ds.grep(:title, 'ruby').sql.should == "SELECT * FROM posts WHERE ((title LIKE 'ruby'))"
|
|
3307
2913
|
end
|
|
3308
2914
|
|
|
3309
2915
|
specify "should support multiple columns" do
|
|
3310
|
-
@ds.grep([:title, :body], 'ruby').sql.should ==
|
|
3311
|
-
"SELECT * FROM posts WHERE ((title LIKE 'ruby') OR (body LIKE 'ruby'))"
|
|
2916
|
+
@ds.grep([:title, :body], 'ruby').sql.should == "SELECT * FROM posts WHERE ((title LIKE 'ruby') OR (body LIKE 'ruby'))"
|
|
3312
2917
|
end
|
|
3313
2918
|
|
|
3314
2919
|
specify "should support multiple search terms" do
|
|
3315
|
-
@ds.grep(:title, ['abc', 'def']).sql.should ==
|
|
3316
|
-
"SELECT * FROM posts WHERE ((title LIKE 'abc') OR (title LIKE 'def'))"
|
|
2920
|
+
@ds.grep(:title, ['abc', 'def']).sql.should == "SELECT * FROM posts WHERE ((title LIKE 'abc') OR (title LIKE 'def'))"
|
|
3317
2921
|
end
|
|
3318
2922
|
|
|
3319
2923
|
specify "should support multiple columns and search terms" do
|
|
3320
|
-
@ds.grep([:title, :body], ['abc', 'def']).sql.should ==
|
|
3321
|
-
"SELECT * FROM posts WHERE ((title LIKE 'abc') OR (title LIKE 'def') OR (body LIKE 'abc') OR (body LIKE 'def'))"
|
|
2924
|
+
@ds.grep([:title, :body], ['abc', 'def']).sql.should == "SELECT * FROM posts WHERE ((title LIKE 'abc') OR (title LIKE 'def') OR (body LIKE 'abc') OR (body LIKE 'def'))"
|
|
3322
2925
|
end
|
|
3323
2926
|
|
|
3324
2927
|
specify "should support the :all_patterns option" do
|
|
3325
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true).sql.should ==
|
|
3326
|
-
"SELECT * FROM posts WHERE (((title LIKE 'abc') OR (body LIKE 'abc')) AND ((title LIKE 'def') OR (body LIKE 'def')))"
|
|
2928
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true).sql.should == "SELECT * FROM posts WHERE (((title LIKE 'abc') OR (body LIKE 'abc')) AND ((title LIKE 'def') OR (body LIKE 'def')))"
|
|
3327
2929
|
end
|
|
3328
2930
|
|
|
3329
2931
|
specify "should support the :all_columns option" do
|
|
3330
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_columns=>true).sql.should ==
|
|
3331
|
-
"SELECT * FROM posts WHERE (((title LIKE 'abc') OR (title LIKE 'def')) AND ((body LIKE 'abc') OR (body LIKE 'def')))"
|
|
2932
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_columns=>true).sql.should == "SELECT * FROM posts WHERE (((title LIKE 'abc') OR (title LIKE 'def')) AND ((body LIKE 'abc') OR (body LIKE 'def')))"
|
|
3332
2933
|
end
|
|
3333
2934
|
|
|
3334
2935
|
specify "should support the :case_insensitive option" do
|
|
3335
|
-
@ds.grep([:title, :body], ['abc', 'def'], :case_insensitive=>true).sql.should ==
|
|
3336
|
-
"SELECT * FROM posts WHERE ((title ILIKE 'abc') OR (title ILIKE 'def') OR (body ILIKE 'abc') OR (body ILIKE 'def'))"
|
|
2936
|
+
@ds.grep([:title, :body], ['abc', 'def'], :case_insensitive=>true).sql.should == "SELECT * FROM posts WHERE ((title ILIKE 'abc') OR (title ILIKE 'def') OR (body ILIKE 'abc') OR (body ILIKE 'def'))"
|
|
3337
2937
|
end
|
|
3338
2938
|
|
|
3339
2939
|
specify "should support the :all_patterns and :all_columns options together" do
|
|
3340
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :all_columns=>true).sql.should ==
|
|
3341
|
-
"SELECT * FROM posts WHERE ((title LIKE 'abc') AND (body LIKE 'abc') AND (title LIKE 'def') AND (body LIKE 'def'))"
|
|
2940
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :all_columns=>true).sql.should == "SELECT * FROM posts WHERE ((title LIKE 'abc') AND (body LIKE 'abc') AND (title LIKE 'def') AND (body LIKE 'def'))"
|
|
3342
2941
|
end
|
|
3343
2942
|
|
|
3344
2943
|
specify "should support the :all_patterns and :case_insensitive options together" do
|
|
3345
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :case_insensitive=>true).sql.should ==
|
|
3346
|
-
"SELECT * FROM posts WHERE (((title ILIKE 'abc') OR (body ILIKE 'abc')) AND ((title ILIKE 'def') OR (body ILIKE 'def')))"
|
|
2944
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :case_insensitive=>true).sql.should == "SELECT * FROM posts WHERE (((title ILIKE 'abc') OR (body ILIKE 'abc')) AND ((title ILIKE 'def') OR (body ILIKE 'def')))"
|
|
3347
2945
|
end
|
|
3348
2946
|
|
|
3349
2947
|
specify "should support the :all_columns and :case_insensitive options together" do
|
|
3350
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_columns=>true, :case_insensitive=>true).sql.should ==
|
|
3351
|
-
"SELECT * FROM posts WHERE (((title ILIKE 'abc') OR (title ILIKE 'def')) AND ((body ILIKE 'abc') OR (body ILIKE 'def')))"
|
|
2948
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_columns=>true, :case_insensitive=>true).sql.should == "SELECT * FROM posts WHERE (((title ILIKE 'abc') OR (title ILIKE 'def')) AND ((body ILIKE 'abc') OR (body ILIKE 'def')))"
|
|
3352
2949
|
end
|
|
3353
2950
|
|
|
3354
2951
|
specify "should support the :all_patterns, :all_columns, and :case_insensitive options together" do
|
|
3355
|
-
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :all_columns=>true, :case_insensitive=>true).sql.should ==
|
|
3356
|
-
"SELECT * FROM posts WHERE ((title ILIKE 'abc') AND (body ILIKE 'abc') AND (title ILIKE 'def') AND (body ILIKE 'def'))"
|
|
2952
|
+
@ds.grep([:title, :body], ['abc', 'def'], :all_patterns=>true, :all_columns=>true, :case_insensitive=>true).sql.should == "SELECT * FROM posts WHERE ((title ILIKE 'abc') AND (body ILIKE 'abc') AND (title ILIKE 'def') AND (body ILIKE 'def'))"
|
|
3357
2953
|
end
|
|
3358
2954
|
|
|
3359
2955
|
specify "should support regexps though the database may not support it" do
|
|
3360
|
-
@ds.grep(:title, /ruby/).sql.should ==
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
@ds.grep(:title, [/^ruby/, 'ruby']).sql.should ==
|
|
3364
|
-
"SELECT * FROM posts WHERE ((title ~ '^ruby') OR (title LIKE 'ruby'))"
|
|
2956
|
+
@ds.grep(:title, /ruby/).sql.should == "SELECT * FROM posts WHERE ((title ~ 'ruby'))"
|
|
2957
|
+
@ds.grep(:title, [/^ruby/, 'ruby']).sql.should == "SELECT * FROM posts WHERE ((title ~ '^ruby') OR (title LIKE 'ruby'))"
|
|
3365
2958
|
end
|
|
3366
2959
|
|
|
3367
2960
|
specify "should support searching against other columns" do
|
|
3368
|
-
@ds.grep(:title, :body).sql.should ==
|
|
3369
|
-
"SELECT * FROM posts WHERE ((title LIKE body))"
|
|
2961
|
+
@ds.grep(:title, :body).sql.should == "SELECT * FROM posts WHERE ((title LIKE body))"
|
|
3370
2962
|
end
|
|
3371
2963
|
end
|
|
3372
2964
|
|
|
@@ -3420,18 +3012,7 @@ end
|
|
|
3420
3012
|
|
|
3421
3013
|
describe "Dataset prepared statements and bound variables " do
|
|
3422
3014
|
before do
|
|
3423
|
-
@db = Sequel
|
|
3424
|
-
@db.meta_def(:sqls){@sqls||=[]}
|
|
3425
|
-
def @db.execute(sql, opts={})
|
|
3426
|
-
sqls << sql
|
|
3427
|
-
end
|
|
3428
|
-
def @db.dataset
|
|
3429
|
-
ds = super()
|
|
3430
|
-
def ds.fetch_rows(sql, &block)
|
|
3431
|
-
execute(sql)
|
|
3432
|
-
end
|
|
3433
|
-
ds
|
|
3434
|
-
end
|
|
3015
|
+
@db = Sequel.mock
|
|
3435
3016
|
@ds = @db[:items]
|
|
3436
3017
|
@ds.meta_def(:insert_sql){|*v| "#{super(*v)}#{' RETURNING *' if opts.has_key?(:returning)}" }
|
|
3437
3018
|
end
|
|
@@ -3477,7 +3058,7 @@ describe "Dataset prepared statements and bound variables " do
|
|
|
3477
3058
|
|
|
3478
3059
|
specify "#inspect should indicate it is a prepared statement with the prepared SQL" do
|
|
3479
3060
|
@ds.filter(:num=>:$n).prepare(:select, :sn).inspect.should == \
|
|
3480
|
-
'<Sequel::Dataset/PreparedStatement "SELECT * FROM items WHERE (num = $n)">'
|
|
3061
|
+
'<Sequel::Mock::Dataset/PreparedStatement "SELECT * FROM items WHERE (num = $n)">'
|
|
3481
3062
|
end
|
|
3482
3063
|
|
|
3483
3064
|
specify "should handle literal strings" do
|
|
@@ -3513,23 +3094,16 @@ end
|
|
|
3513
3094
|
|
|
3514
3095
|
describe Sequel::Dataset::UnnumberedArgumentMapper do
|
|
3515
3096
|
before do
|
|
3516
|
-
@db = Sequel
|
|
3517
|
-
@db.meta_def(:sqls){@sqls||=[]}
|
|
3518
|
-
def @db.execute(sql, opts={})
|
|
3519
|
-
sqls << [sql, *opts[:arguments]]
|
|
3520
|
-
end
|
|
3097
|
+
@db = Sequel.mock
|
|
3521
3098
|
@ds = @db[:items].filter(:num=>:$n)
|
|
3522
|
-
def @ds.fetch_rows(sql, &block)
|
|
3523
|
-
execute(sql)
|
|
3524
|
-
end
|
|
3525
3099
|
def @ds.execute(sql, opts={}, &block)
|
|
3526
|
-
|
|
3100
|
+
super(sql, opts.merge({:arguments=>bind_arguments}), &block)
|
|
3527
3101
|
end
|
|
3528
|
-
def @ds.execute_dui(
|
|
3529
|
-
|
|
3102
|
+
def @ds.execute_dui(sql, opts={}, &block)
|
|
3103
|
+
super(sql, opts.merge({:arguments=>bind_arguments}), &block)
|
|
3530
3104
|
end
|
|
3531
|
-
def @ds.execute_insert(
|
|
3532
|
-
|
|
3105
|
+
def @ds.execute_insert(sql, opts={}, &block)
|
|
3106
|
+
super(sql, opts.merge({:arguments=>bind_arguments}), &block)
|
|
3533
3107
|
end
|
|
3534
3108
|
@ps = []
|
|
3535
3109
|
@ps << @ds.prepare(:select, :s)
|
|
@@ -3542,64 +3116,43 @@ describe Sequel::Dataset::UnnumberedArgumentMapper do
|
|
|
3542
3116
|
end
|
|
3543
3117
|
|
|
3544
3118
|
specify "#inspect should show the actual SQL submitted to the database" do
|
|
3545
|
-
@ps.first.inspect.should == '<Sequel::Dataset/PreparedStatement "SELECT * FROM items WHERE (num = ?)">'
|
|
3119
|
+
@ps.first.inspect.should == '<Sequel::Mock::Dataset/PreparedStatement "SELECT * FROM items WHERE (num = ?)">'
|
|
3546
3120
|
end
|
|
3547
3121
|
|
|
3548
3122
|
specify "should submitted the SQL to the database with placeholders and bind variables" do
|
|
3549
3123
|
@ps.each{|p| p.prepared_sql; p.call(:n=>1)}
|
|
3550
|
-
@db.sqls.should == [
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
]
|
|
3124
|
+
@db.sqls.should == ["SELECT * FROM items WHERE (num = ?) -- args: [1]",
|
|
3125
|
+
"SELECT * FROM items WHERE (num = ?) -- args: [1]",
|
|
3126
|
+
"SELECT * FROM items WHERE (num = ?) LIMIT 1 -- args: [1]",
|
|
3127
|
+
"DELETE FROM items WHERE (num = ?) -- args: [1]",
|
|
3128
|
+
"INSERT INTO items (num) VALUES (?) -- args: [1]",
|
|
3129
|
+
"UPDATE items SET num = ? WHERE (num = ?) -- args: [1, 1]"]
|
|
3557
3130
|
end
|
|
3558
3131
|
end
|
|
3559
3132
|
|
|
3560
3133
|
describe "Sequel::Dataset#server" do
|
|
3561
3134
|
specify "should set the server to use for the dataset" do
|
|
3562
|
-
@db = Sequel
|
|
3135
|
+
@db = Sequel.mock(:servers=>{:s=>{}, :i=>{}, :d=>{}, :u=>{}})
|
|
3563
3136
|
@ds = @db[:items].server(:s)
|
|
3564
|
-
sqls = []
|
|
3565
|
-
@db.meta_def(:execute) do |sql, opts|
|
|
3566
|
-
sqls << [sql, opts[:server]]
|
|
3567
|
-
end
|
|
3568
|
-
def @ds.fetch_rows(sql, &block)
|
|
3569
|
-
execute(sql)
|
|
3570
|
-
end
|
|
3571
3137
|
@ds.all
|
|
3572
3138
|
@ds.server(:i).insert(:a=>1)
|
|
3573
3139
|
@ds.server(:d).delete
|
|
3574
3140
|
@ds.server(:u).update(:a=>:a+1)
|
|
3575
|
-
sqls.should == [
|
|
3576
|
-
['INSERT INTO items (a) VALUES (1)', :i],
|
|
3577
|
-
['DELETE FROM items', :d],
|
|
3578
|
-
['UPDATE items SET a = (a + 1)', :u]]
|
|
3141
|
+
@db.sqls.should == ['SELECT * FROM items -- s', 'INSERT INTO items (a) VALUES (1) -- i', 'DELETE FROM items -- d', 'UPDATE items SET a = (a + 1) -- u']
|
|
3579
3142
|
end
|
|
3580
3143
|
end
|
|
3581
3144
|
|
|
3582
3145
|
describe "Sequel::Dataset#each_server" do
|
|
3583
|
-
before do
|
|
3584
|
-
@db = Sequel::Database.new(:servers=>{:s=>{}, :i=>{}})
|
|
3585
|
-
@ds = @db[:items]
|
|
3586
|
-
sqls = @sqls = []
|
|
3587
|
-
@db.meta_def(:execute) do |sql, opts|
|
|
3588
|
-
sqls << [sql, opts[:server]]
|
|
3589
|
-
end
|
|
3590
|
-
def @ds.fetch_rows(sql, &block)
|
|
3591
|
-
execute(sql)
|
|
3592
|
-
end
|
|
3593
|
-
end
|
|
3594
|
-
|
|
3595
3146
|
specify "should yield a dataset for each server" do
|
|
3147
|
+
@db = Sequel.mock(:servers=>{:s=>{}, :i=>{}})
|
|
3148
|
+
@ds = @db[:items]
|
|
3596
3149
|
@ds.each_server do |ds|
|
|
3597
3150
|
ds.should be_a_kind_of(Sequel::Dataset)
|
|
3598
3151
|
ds.should_not == @ds
|
|
3599
3152
|
ds.sql.should == @ds.sql
|
|
3600
3153
|
ds.all
|
|
3601
3154
|
end
|
|
3602
|
-
@sqls.
|
|
3155
|
+
@db.sqls.sort.should == ['SELECT * FROM items', 'SELECT * FROM items -- i', 'SELECT * FROM items -- s']
|
|
3603
3156
|
end
|
|
3604
3157
|
end
|
|
3605
3158
|
|
|
@@ -3649,23 +3202,23 @@ end
|
|
|
3649
3202
|
|
|
3650
3203
|
describe "Sequel::Dataset#qualify" do
|
|
3651
3204
|
specify "should qualify to the given table" do
|
|
3652
|
-
|
|
3205
|
+
Sequel::Dataset.new(nil).from(:t).filter{a<b}.qualify(:e).sql.should == 'SELECT e.* FROM t WHERE (e.a < e.b)'
|
|
3653
3206
|
end
|
|
3654
3207
|
|
|
3655
3208
|
specify "should qualify to the first source if no table if given" do
|
|
3656
|
-
|
|
3209
|
+
Sequel::Dataset.new(nil).from(:t).filter{a<b}.qualify.sql.should == 'SELECT t.* FROM t WHERE (t.a < t.b)'
|
|
3657
3210
|
end
|
|
3658
3211
|
end
|
|
3659
3212
|
|
|
3660
3213
|
describe "Sequel::Dataset#qualify_to" do
|
|
3661
3214
|
specify "should qualify to the given table" do
|
|
3662
|
-
|
|
3215
|
+
Sequel::Dataset.new(nil).from(:t).filter{a<b}.qualify_to(:e).sql.should == 'SELECT e.* FROM t WHERE (e.a < e.b)'
|
|
3663
3216
|
end
|
|
3664
3217
|
end
|
|
3665
3218
|
|
|
3666
3219
|
describe "Sequel::Dataset#qualify_to_first_source" do
|
|
3667
3220
|
before do
|
|
3668
|
-
@ds =
|
|
3221
|
+
@ds = Sequel::Database.new[:t]
|
|
3669
3222
|
end
|
|
3670
3223
|
|
|
3671
3224
|
specify "should qualify_to the first source" do
|
|
@@ -3675,13 +3228,11 @@ describe "Sequel::Dataset#qualify_to_first_source" do
|
|
|
3675
3228
|
end
|
|
3676
3229
|
|
|
3677
3230
|
specify "should handle the select, order, where, having, and group options/clauses" do
|
|
3678
|
-
@ds.select(:a).filter(:a=>1).order(:a).group(:a).having(:a).qualify_to_first_source.sql.should ==
|
|
3679
|
-
'SELECT t.a FROM t WHERE (t.a = 1) GROUP BY t.a HAVING t.a ORDER BY t.a'
|
|
3231
|
+
@ds.select(:a).filter(:a=>1).order(:a).group(:a).having(:a).qualify_to_first_source.sql.should == 'SELECT t.a FROM t WHERE (t.a = 1) GROUP BY t.a HAVING t.a ORDER BY t.a'
|
|
3680
3232
|
end
|
|
3681
3233
|
|
|
3682
3234
|
specify "should handle the select using a table.* if all columns are currently selected" do
|
|
3683
|
-
@ds.filter(:a=>1).order(:a).group(:a).having(:a).qualify_to_first_source.sql.should ==
|
|
3684
|
-
'SELECT t.* FROM t WHERE (t.a = 1) GROUP BY t.a HAVING t.a ORDER BY t.a'
|
|
3235
|
+
@ds.filter(:a=>1).order(:a).group(:a).having(:a).qualify_to_first_source.sql.should == 'SELECT t.* FROM t WHERE (t.a = 1) GROUP BY t.a HAVING t.a ORDER BY t.a'
|
|
3685
3236
|
end
|
|
3686
3237
|
|
|
3687
3238
|
specify "should handle hashes in select option" do
|
|
@@ -3750,14 +3301,13 @@ describe "Sequel::Dataset#qualify_to_first_source" do
|
|
|
3750
3301
|
end
|
|
3751
3302
|
|
|
3752
3303
|
specify "should handle all other objects by returning them unchanged" do
|
|
3753
|
-
@ds.select("a").filter{a(3)}.filter('blah').order('true'.lit).group('a > ?'.lit(1)).having(false).qualify_to_first_source.sql.should ==
|
|
3754
|
-
"SELECT 'a' FROM t WHERE (a(3) AND (blah)) GROUP BY a > 1 HAVING 'f' ORDER BY true"
|
|
3304
|
+
@ds.select("a").filter{a(3)}.filter('blah').order('true'.lit).group('a > ?'.lit(1)).having(false).qualify_to_first_source.sql.should == "SELECT 'a' FROM t WHERE (a(3) AND (blah)) GROUP BY a > 1 HAVING 'f' ORDER BY true"
|
|
3755
3305
|
end
|
|
3756
3306
|
end
|
|
3757
3307
|
|
|
3758
3308
|
describe "Sequel::Dataset#unbind" do
|
|
3759
3309
|
before do
|
|
3760
|
-
@ds =
|
|
3310
|
+
@ds = Sequel::Database.new[:t]
|
|
3761
3311
|
@u = proc{|ds| ds, bv = ds.unbind; [ds.sql, bv]}
|
|
3762
3312
|
end
|
|
3763
3313
|
|
|
@@ -3827,7 +3377,7 @@ end
|
|
|
3827
3377
|
|
|
3828
3378
|
describe "Sequel::Dataset #with and #with_recursive" do
|
|
3829
3379
|
before do
|
|
3830
|
-
@db =
|
|
3380
|
+
@db = Sequel::Database.new
|
|
3831
3381
|
@ds = @db[:t]
|
|
3832
3382
|
end
|
|
3833
3383
|
|
|
@@ -3868,11 +3418,18 @@ describe "Sequel::Dataset #with and #with_recursive" do
|
|
|
3868
3418
|
@ds.with(:t, @db[:x]).update_sql(:foo=>1).should == 'WITH t AS (SELECT * FROM x) UPDATE t SET foo = 1'
|
|
3869
3419
|
@ds.with(:t, @db[:x]).delete_sql.should == 'WITH t AS (SELECT * FROM x) DELETE FROM t'
|
|
3870
3420
|
end
|
|
3421
|
+
|
|
3422
|
+
specify "should hoist WITH clauses in given dataset(s) if dataset doesn't support WITH in subselect" do
|
|
3423
|
+
@ds.meta_def(:supports_cte?){true}
|
|
3424
|
+
@ds.meta_def(:supports_cte_in_subselect?){false}
|
|
3425
|
+
@ds.with(:t, @ds.from(:s).with(:s, @ds.from(:r))).sql.should == 'WITH s AS (SELECT * FROM r), t AS (SELECT * FROM s) SELECT * FROM t'
|
|
3426
|
+
@ds.with_recursive(:t, @ds.from(:s).with(:s, @ds.from(:r)), @ds.from(:q).with(:q, @ds.from(:p))).sql.should == 'WITH s AS (SELECT * FROM r), q AS (SELECT * FROM p), t AS (SELECT * FROM s UNION ALL SELECT * FROM q) SELECT * FROM t'
|
|
3427
|
+
end
|
|
3871
3428
|
end
|
|
3872
3429
|
|
|
3873
3430
|
describe Sequel::SQL::Constants do
|
|
3874
3431
|
before do
|
|
3875
|
-
@db =
|
|
3432
|
+
@db = Sequel::Database.new
|
|
3876
3433
|
end
|
|
3877
3434
|
|
|
3878
3435
|
it "should have CURRENT_DATE" do
|
|
@@ -3917,7 +3474,7 @@ end
|
|
|
3917
3474
|
|
|
3918
3475
|
describe "Sequel timezone support" do
|
|
3919
3476
|
before do
|
|
3920
|
-
@db =
|
|
3477
|
+
@db = Sequel::Database.new
|
|
3921
3478
|
@dataset = @db.dataset
|
|
3922
3479
|
@dataset.meta_def(:supports_timestamp_timezones?){true}
|
|
3923
3480
|
@dataset.meta_def(:supports_timestamp_usecs?){false}
|
|
@@ -3952,6 +3509,30 @@ describe "Sequel timezone support" do
|
|
|
3952
3509
|
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3953
3510
|
end
|
|
3954
3511
|
|
|
3512
|
+
specify "should have Database#timezone override Sequel.database_timezone" do
|
|
3513
|
+
Sequel.database_timezone = :local
|
|
3514
|
+
@db.timezone = :utc
|
|
3515
|
+
|
|
3516
|
+
t = Time.now
|
|
3517
|
+
s = t.getutc.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3518
|
+
@dataset.literal(t).should == "#{s}+0000'"
|
|
3519
|
+
|
|
3520
|
+
t = DateTime.now
|
|
3521
|
+
s = t.new_offset(0).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3522
|
+
@dataset.literal(t).should == "#{s}+0000'"
|
|
3523
|
+
|
|
3524
|
+
Sequel.database_timezone = :utc
|
|
3525
|
+
@db.timezone = :local
|
|
3526
|
+
|
|
3527
|
+
t = Time.now.utc
|
|
3528
|
+
s = t.getlocal.strftime("'%Y-%m-%d %H:%M:%S")
|
|
3529
|
+
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3530
|
+
|
|
3531
|
+
t = DateTime.now.new_offset(0)
|
|
3532
|
+
s = t.new_offset(DateTime.now.offset).strftime("'%Y-%m-%d %H:%M:%S")
|
|
3533
|
+
@dataset.literal(t).should == "#{s}#{@offset}'"
|
|
3534
|
+
end
|
|
3535
|
+
|
|
3955
3536
|
specify "should handle converting database timestamps into application timestamps" do
|
|
3956
3537
|
Sequel.database_timezone = :utc
|
|
3957
3538
|
Sequel.application_timezone = :local
|
|
@@ -4062,13 +3643,7 @@ end
|
|
|
4062
3643
|
|
|
4063
3644
|
describe "Sequel::Dataset#select_map" do
|
|
4064
3645
|
before do
|
|
4065
|
-
@ds =
|
|
4066
|
-
def @ds.fetch_rows(sql)
|
|
4067
|
-
db << sql
|
|
4068
|
-
yield({:c=>1})
|
|
4069
|
-
yield({:c=>2})
|
|
4070
|
-
end
|
|
4071
|
-
@ds.db.reset
|
|
3646
|
+
@ds = Sequel.mock(:fetch=>[{:c=>1}, {:c=>2}])[:t]
|
|
4072
3647
|
end
|
|
4073
3648
|
|
|
4074
3649
|
specify "should do select and map in one step" do
|
|
@@ -4099,21 +3674,19 @@ describe "Sequel::Dataset#select_map" do
|
|
|
4099
3674
|
specify "should handle an array of columns" do
|
|
4100
3675
|
@ds.select_map([:c, :c]).should == [[1, 1], [2, 2]]
|
|
4101
3676
|
@ds.db.sqls.should == ['SELECT c, c FROM t']
|
|
4102
|
-
@ds.
|
|
4103
|
-
@ds.
|
|
4104
|
-
|
|
3677
|
+
@ds.select_map([:d.as(:c), :c.qualify(:b), :c.identifier, :c.identifier.qualify(:b), :a__c, :a__d___c]).should == [[1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2]]
|
|
3678
|
+
@ds.db.sqls.should == ['SELECT d AS c, b.c, c, b.c, a.c, a.d AS c FROM t']
|
|
3679
|
+
end
|
|
3680
|
+
|
|
3681
|
+
specify "should handle an array with a single element" do
|
|
3682
|
+
@ds.select_map([:c]).should == [[1], [2]]
|
|
3683
|
+
@ds.db.sqls.should == ['SELECT c FROM t']
|
|
4105
3684
|
end
|
|
4106
3685
|
end
|
|
4107
3686
|
|
|
4108
3687
|
describe "Sequel::Dataset#select_order_map" do
|
|
4109
3688
|
before do
|
|
4110
|
-
@ds =
|
|
4111
|
-
def @ds.fetch_rows(sql)
|
|
4112
|
-
db << sql
|
|
4113
|
-
yield({:c=>1})
|
|
4114
|
-
yield({:c=>2})
|
|
4115
|
-
end
|
|
4116
|
-
@ds.db.reset
|
|
3689
|
+
@ds = Sequel.mock(:fetch=>[{:c=>1}, {:c=>2}])[:t]
|
|
4117
3690
|
end
|
|
4118
3691
|
|
|
4119
3692
|
specify "should do select and map in one step" do
|
|
@@ -4154,73 +3727,65 @@ describe "Sequel::Dataset#select_order_map" do
|
|
|
4154
3727
|
specify "should handle an array of columns" do
|
|
4155
3728
|
@ds.select_order_map([:c, :c]).should == [[1, 1], [2, 2]]
|
|
4156
3729
|
@ds.db.sqls.should == ['SELECT c, c FROM t ORDER BY c, c']
|
|
4157
|
-
@ds.db.reset
|
|
4158
3730
|
@ds.select_order_map([:d.as(:c), :c.qualify(:b), :c.identifier, :c.identifier.qualify(:b), :c.identifier.qualify(:b).desc, :a__c, :a__d___c.desc]).should == [[1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2]]
|
|
4159
3731
|
@ds.db.sqls.should == ['SELECT d AS c, b.c, c, b.c, b.c, a.c, a.d AS c FROM t ORDER BY d, b.c, c, b.c, b.c DESC, a.c, a.d DESC']
|
|
4160
3732
|
end
|
|
3733
|
+
|
|
3734
|
+
specify "should handle an array with a single element" do
|
|
3735
|
+
@ds.select_order_map([:c]).should == [[1], [2]]
|
|
3736
|
+
@ds.db.sqls.should == ['SELECT c FROM t ORDER BY c']
|
|
3737
|
+
end
|
|
4161
3738
|
end
|
|
4162
3739
|
|
|
4163
3740
|
describe "Sequel::Dataset#select_hash" do
|
|
4164
3741
|
before do
|
|
4165
|
-
@
|
|
4166
|
-
|
|
4167
|
-
@hs = hs
|
|
4168
|
-
end
|
|
4169
|
-
def @ds.fetch_rows(sql)
|
|
4170
|
-
db << sql
|
|
4171
|
-
@hs.each{|h| yield h}
|
|
4172
|
-
end
|
|
4173
|
-
@ds.db.reset
|
|
3742
|
+
@db = Sequel.mock(:fetch=>[{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
3743
|
+
@ds = @db[:t]
|
|
4174
3744
|
end
|
|
4175
3745
|
|
|
4176
3746
|
specify "should do select and to_hash in one step" do
|
|
4177
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4178
3747
|
@ds.select_hash(:a, :b).should == {1=>2, 3=>4}
|
|
4179
3748
|
@ds.db.sqls.should == ['SELECT a, b FROM t']
|
|
4180
3749
|
end
|
|
4181
3750
|
|
|
4182
3751
|
specify "should handle implicit qualifiers in arguments" do
|
|
4183
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4184
3752
|
@ds.select_hash(:t__a, :t__b).should == {1=>2, 3=>4}
|
|
4185
3753
|
@ds.db.sqls.should == ['SELECT t.a, t.b FROM t']
|
|
4186
3754
|
end
|
|
4187
3755
|
|
|
4188
3756
|
specify "should handle implicit aliases in arguments" do
|
|
4189
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4190
3757
|
@ds.select_hash(:c___a, :d___b).should == {1=>2, 3=>4}
|
|
4191
3758
|
@ds.db.sqls.should == ['SELECT c AS a, d AS b FROM t']
|
|
4192
3759
|
end
|
|
4193
3760
|
|
|
4194
3761
|
specify "should handle implicit qualifiers and aliases in arguments" do
|
|
4195
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4196
3762
|
@ds.select_hash(:t__c___a, :t__d___b).should == {1=>2, 3=>4}
|
|
4197
3763
|
@ds.db.sqls.should == ['SELECT t.c AS a, t.d AS b FROM t']
|
|
4198
3764
|
end
|
|
4199
3765
|
|
|
4200
3766
|
specify "should handle SQL::Identifiers in arguments" do
|
|
4201
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4202
3767
|
@ds.select_hash(:a.identifier, :b.identifier).should == {1=>2, 3=>4}
|
|
4203
3768
|
@ds.db.sqls.should == ['SELECT a, b FROM t']
|
|
4204
3769
|
end
|
|
4205
3770
|
|
|
4206
3771
|
specify "should handle SQL::QualifiedIdentifiers in arguments" do
|
|
4207
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4208
3772
|
@ds.select_hash(:a.qualify(:t), :b.identifier.qualify(:t)).should == {1=>2, 3=>4}
|
|
4209
3773
|
@ds.db.sqls.should == ['SELECT t.a, t.b FROM t']
|
|
4210
3774
|
end
|
|
4211
3775
|
|
|
4212
3776
|
specify "should handle SQL::AliasedExpressions in arguments" do
|
|
4213
|
-
@ds.set_fr_yield([{:a=>1, :b=>2}, {:a=>3, :b=>4}])
|
|
4214
3777
|
@ds.select_hash(:c.as(:a), :t.as(:b)).should == {1=>2, 3=>4}
|
|
4215
3778
|
@ds.db.sqls.should == ['SELECT c AS a, t AS b FROM t']
|
|
4216
3779
|
end
|
|
4217
3780
|
|
|
4218
3781
|
specify "should work with arrays of columns" do
|
|
4219
|
-
@
|
|
3782
|
+
@db.fetch = [{:a=>1, :b=>2, :c=>3}, {:a=>4, :b=>5, :c=>6}]
|
|
4220
3783
|
@ds.select_hash([:a, :c], :b).should == {[1, 3]=>2, [4, 6]=>5}
|
|
4221
3784
|
@ds.db.sqls.should == ['SELECT a, c, b FROM t']
|
|
4222
3785
|
@ds.select_hash(:a, [:b, :c]).should == {1=>[2, 3], 4=>[5, 6]}
|
|
3786
|
+
@ds.db.sqls.should == ['SELECT a, b, c FROM t']
|
|
4223
3787
|
@ds.select_hash([:a, :b], [:b, :c]).should == {[1, 2]=>[2, 3], [4, 5]=>[5, 6]}
|
|
3788
|
+
@ds.db.sqls.should == ['SELECT a, b, b, c FROM t']
|
|
4224
3789
|
end
|
|
4225
3790
|
|
|
4226
3791
|
specify "should raise an error if the resulting symbol cannot be determined" do
|
|
@@ -4230,9 +3795,8 @@ end
|
|
|
4230
3795
|
|
|
4231
3796
|
describe "Modifying joined datasets" do
|
|
4232
3797
|
before do
|
|
4233
|
-
@ds =
|
|
3798
|
+
@ds = Sequel.mock.from(:b, :c).join(:d, [:id]).where(:id => 2)
|
|
4234
3799
|
@ds.meta_def(:supports_modifying_joins?){true}
|
|
4235
|
-
@ds.db.reset
|
|
4236
3800
|
end
|
|
4237
3801
|
|
|
4238
3802
|
specify "should allow deleting from joined datasets" do
|
|
@@ -4248,7 +3812,7 @@ end
|
|
|
4248
3812
|
|
|
4249
3813
|
describe "Dataset#lock_style and for_update" do
|
|
4250
3814
|
before do
|
|
4251
|
-
@ds =
|
|
3815
|
+
@ds = Sequel::Dataset.new(nil).from(:t)
|
|
4252
3816
|
end
|
|
4253
3817
|
|
|
4254
3818
|
specify "#for_update should use FOR UPDATE" do
|
|
@@ -4271,16 +3835,15 @@ describe "Custom ASTTransformer" do
|
|
|
4271
3835
|
(s.is_a?(Symbol) || s.is_a?(String)) ? :"#{s}#{s}" : super
|
|
4272
3836
|
end
|
|
4273
3837
|
end.new
|
|
4274
|
-
ds =
|
|
3838
|
+
ds = Sequel::Dataset.new(nil).from(:t).cross_join(:a___g).join(:b___h, [:c]).join(:d___i, :e=>:f)
|
|
4275
3839
|
ds.sql.should == 'SELECT * FROM t CROSS JOIN a AS g INNER JOIN b AS h USING (c) INNER JOIN d AS i ON (i.e = h.f)'
|
|
4276
|
-
ds.clone(:from=>c.transform(ds.opts[:from]), :join=>c.transform(ds.opts[:join])).sql.should ==
|
|
4277
|
-
'SELECT * FROM tt CROSS JOIN aa AS gg INNER JOIN bb AS hh USING (cc) INNER JOIN dd AS ii ON (ii.ee = hh.ff)'
|
|
3840
|
+
ds.clone(:from=>c.transform(ds.opts[:from]), :join=>c.transform(ds.opts[:join])).sql.should == 'SELECT * FROM tt CROSS JOIN aa AS gg INNER JOIN bb AS hh USING (cc) INNER JOIN dd AS ii ON (ii.ee = hh.ff)'
|
|
4278
3841
|
end
|
|
4279
3842
|
end
|
|
4280
3843
|
|
|
4281
3844
|
describe "Dataset#returning" do
|
|
4282
3845
|
before do
|
|
4283
|
-
@ds = Sequel
|
|
3846
|
+
@ds = Sequel.mock(:fetch=>proc{|s| {:foo=>s}})[:t].returning(:foo)
|
|
4284
3847
|
@pr = proc do
|
|
4285
3848
|
[:insert, :update, :delete].each do |m|
|
|
4286
3849
|
@ds.meta_def(:"#{m}_clause_methods"){super() + [:"#{m}_returning_sql"]}
|
|
@@ -4303,9 +3866,6 @@ describe "Dataset#returning" do
|
|
|
4303
3866
|
|
|
4304
3867
|
specify "should have insert, update, and delete yield to blocks if RETURNING is used" do
|
|
4305
3868
|
@pr.call
|
|
4306
|
-
def @ds.fetch_rows(sql)
|
|
4307
|
-
yield(:foo=>sql)
|
|
4308
|
-
end
|
|
4309
3869
|
h = {}
|
|
4310
3870
|
@ds.delete{|r| h = r}
|
|
4311
3871
|
h.should == {:foo=>"DELETE FROM t RETURNING foo"}
|
|
@@ -4317,12 +3877,39 @@ describe "Dataset#returning" do
|
|
|
4317
3877
|
|
|
4318
3878
|
specify "should have insert, update, and delete return arrays of hashes if RETURNING is used and a block is not given" do
|
|
4319
3879
|
@pr.call
|
|
4320
|
-
def @ds.fetch_rows(sql)
|
|
4321
|
-
yield(:foo=>sql)
|
|
4322
|
-
end
|
|
4323
3880
|
h = {}
|
|
4324
3881
|
@ds.delete.should == [{:foo=>"DELETE FROM t RETURNING foo"}]
|
|
4325
3882
|
@ds.insert(1).should == [{:foo=>"INSERT INTO t VALUES (1) RETURNING foo"}]
|
|
4326
3883
|
@ds.update(:foo=>1).should == [{:foo=>"UPDATE t SET foo = 1 RETURNING foo"}]
|
|
4327
3884
|
end
|
|
4328
3885
|
end
|
|
3886
|
+
|
|
3887
|
+
describe "Dataset emulating bitwise operator support" do
|
|
3888
|
+
before do
|
|
3889
|
+
@ds = Sequel::Database.new.dataset
|
|
3890
|
+
@ds.quote_identifiers = true
|
|
3891
|
+
def @ds.complex_expression_sql(op, args)
|
|
3892
|
+
complex_expression_arg_pairs(args){|a, b| "bitand(#{literal(a)}, #{literal(b)})"}
|
|
3893
|
+
end
|
|
3894
|
+
end
|
|
3895
|
+
|
|
3896
|
+
it "should work with any numbers of arguments for operators" do
|
|
3897
|
+
@ds.select(Sequel::SQL::ComplexExpression.new(:&, :x)).sql.should == 'SELECT "x"'
|
|
3898
|
+
@ds.select(:x & 1).sql.should == 'SELECT bitand("x", 1)'
|
|
3899
|
+
@ds.select(:x & 1 & 2).sql.should == 'SELECT bitand(bitand("x", 1), 2)'
|
|
3900
|
+
end
|
|
3901
|
+
end
|
|
3902
|
+
|
|
3903
|
+
describe "Dataset feature defaults" do
|
|
3904
|
+
it "should not require aliases for recursive CTEs by default" do
|
|
3905
|
+
Sequel::Database.new.dataset.recursive_cte_requires_column_aliases?.should be_false
|
|
3906
|
+
end
|
|
3907
|
+
|
|
3908
|
+
it "should not require placeholder type specifiers by default" do
|
|
3909
|
+
Sequel::Database.new.dataset.requires_placeholder_type_specifiers?.should be_false
|
|
3910
|
+
end
|
|
3911
|
+
|
|
3912
|
+
it "offset use should be returning a separate row number column by default" do
|
|
3913
|
+
Sequel::Database.new.dataset.send(:offset_returns_row_number_column?).should be_false
|
|
3914
|
+
end
|
|
3915
|
+
end
|