sequel_core 2.0.1 → 2.1.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 +50 -0
- data/README +1 -2
- data/Rakefile +1 -1
- data/bin/sequel +26 -11
- data/doc/dataset_filtering.rdoc +9 -2
- data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -2
- data/lib/sequel_core/adapters/mysql.rb +11 -97
- data/lib/sequel_core/adapters/odbc_mssql.rb +1 -1
- data/lib/sequel_core/adapters/oracle.rb +1 -1
- data/lib/sequel_core/adapters/postgres.rb +33 -17
- data/lib/sequel_core/adapters/sqlite.rb +1 -1
- data/lib/sequel_core/connection_pool.rb +12 -35
- data/lib/sequel_core/core_ext.rb +5 -19
- data/lib/sequel_core/core_sql.rb +17 -6
- data/lib/sequel_core/database.rb +14 -2
- data/lib/sequel_core/dataset/callback.rb +0 -3
- data/lib/sequel_core/dataset/convenience.rb +4 -3
- data/lib/sequel_core/dataset/parse_tree_sequelizer.rb +0 -21
- data/lib/sequel_core/dataset/sequelizer.rb +42 -43
- data/lib/sequel_core/dataset/sql.rb +121 -62
- data/lib/sequel_core/dataset.rb +20 -4
- data/lib/sequel_core/deprecated.rb +0 -6
- data/lib/sequel_core/migration.rb +4 -0
- data/lib/sequel_core/object_graph.rb +8 -6
- data/lib/sequel_core/pretty_table.rb +1 -1
- data/lib/sequel_core/schema/sql.rb +2 -0
- data/lib/sequel_core/sql.rb +393 -153
- data/lib/sequel_core.rb +22 -7
- data/spec/adapters/mysql_spec.rb +11 -7
- data/spec/adapters/postgres_spec.rb +32 -4
- data/spec/blockless_filters_spec.rb +33 -6
- data/spec/connection_pool_spec.rb +18 -16
- data/spec/core_ext_spec.rb +0 -13
- data/spec/core_sql_spec.rb +59 -13
- data/spec/database_spec.rb +5 -5
- data/spec/dataset_spec.rb +167 -55
- data/spec/object_graph_spec.rb +9 -4
- data/spec/sequelizer_spec.rb +8 -17
- data/spec/spec_helper.rb +4 -3
- metadata +2 -2
data/spec/database_spec.rb
CHANGED
@@ -23,7 +23,7 @@ context "A new Database" do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
specify "should create a connection pool" do
|
26
|
-
@db.pool.should be_a_kind_of(ConnectionPool)
|
26
|
+
@db.pool.should be_a_kind_of(Sequel::ConnectionPool)
|
27
27
|
@db.pool.max_size.should == 4
|
28
28
|
|
29
29
|
Sequel::Database.new(:max_connections => 10).pool.max_size.should == 10
|
@@ -645,24 +645,24 @@ context "A single threaded database" do
|
|
645
645
|
|
646
646
|
specify "should use a SingleThreadedPool instead of a ConnectionPool" do
|
647
647
|
db = Sequel::Database.new(:single_threaded => true)
|
648
|
-
db.pool.should be_a_kind_of(SingleThreadedPool)
|
648
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
649
649
|
end
|
650
650
|
|
651
651
|
specify "should be constructable using :single_threaded => true option" do
|
652
652
|
db = Sequel::Database.new(:single_threaded => true)
|
653
|
-
db.pool.should be_a_kind_of(SingleThreadedPool)
|
653
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
654
654
|
end
|
655
655
|
|
656
656
|
specify "should be constructable using Database.single_threaded = true" do
|
657
657
|
Sequel::Database.single_threaded = true
|
658
658
|
db = Sequel::Database.new
|
659
|
-
db.pool.should be_a_kind_of(SingleThreadedPool)
|
659
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
660
660
|
end
|
661
661
|
|
662
662
|
specify "should be constructable using Sequel.single_threaded = true" do
|
663
663
|
Sequel.single_threaded = true
|
664
664
|
db = Sequel::Database.new
|
665
|
-
db.pool.should be_a_kind_of(SingleThreadedPool)
|
665
|
+
db.pool.should be_a_kind_of(Sequel::SingleThreadedPool)
|
666
666
|
end
|
667
667
|
end
|
668
668
|
|
data/spec/dataset_spec.rb
CHANGED
@@ -317,7 +317,6 @@ context "Dataset#where" do
|
|
317
317
|
end
|
318
318
|
|
319
319
|
specify "should accept a subquery" do
|
320
|
-
# select all countries that have GDP greater than the average for Asia
|
321
320
|
@dataset.filter('gdp > ?', @d1.select(:avg[:gdp])).sql.should ==
|
322
321
|
"SELECT * FROM test WHERE (gdp > (SELECT avg(gdp) FROM test WHERE (region = 'Asia')))"
|
323
322
|
|
@@ -364,18 +363,22 @@ context "Dataset#where" do
|
|
364
363
|
"SELECT * FROM test WHERE ((c LIKE 'ABC%') OR (c LIKE '%XYZ'))"
|
365
364
|
end
|
366
365
|
|
367
|
-
specify "should raise if receiving a single boolean value" do
|
368
|
-
# the result of erroneous use of comparison not in a block
|
369
|
-
# so instead of filter{:x == y} someone writes filter(:x == y)
|
370
|
-
|
371
|
-
proc {@dataset.filter(:a == 1)}.should raise_error(Sequel::Error::InvalidFilter)
|
372
|
-
proc {@dataset.filter(:a != 1)}.should raise_error(Sequel::Error::InvalidFilter)
|
373
|
-
end
|
374
|
-
|
375
366
|
specify "should work for grouped datasets" do
|
376
367
|
@dataset.group(:a).filter(:b => 1).sql.should ==
|
377
368
|
'SELECT * FROM test WHERE (b = 1) GROUP BY a'
|
378
369
|
end
|
370
|
+
|
371
|
+
specify "should accept true and false as arguments" do
|
372
|
+
@dataset.filter(true).sql.should ==
|
373
|
+
"SELECT * FROM test WHERE 't'"
|
374
|
+
@dataset.filter(false).sql.should ==
|
375
|
+
"SELECT * FROM test WHERE 'f'"
|
376
|
+
end
|
377
|
+
|
378
|
+
pt_specify "should allow the use of blocks and arguments simultaneously" do
|
379
|
+
@dataset.filter(:zz < 3){:yy > 3}.sql.should ==
|
380
|
+
'SELECT * FROM test WHERE ((zz < 3) AND (yy > 3))'
|
381
|
+
end
|
379
382
|
end
|
380
383
|
|
381
384
|
context "Dataset#or" do
|
@@ -412,6 +415,11 @@ context "Dataset#or" do
|
|
412
415
|
@d1.or(:y => 2).filter(:z => 3).sql.should ==
|
413
416
|
'SELECT * FROM test WHERE (((x = 1) OR (y = 2)) AND (z = 3))'
|
414
417
|
end
|
418
|
+
|
419
|
+
pt_specify "should allow the use of blocks and arguments simultaneously" do
|
420
|
+
@d1.or(:zz < 3){:yy > 3}.sql.should ==
|
421
|
+
'SELECT * FROM test WHERE ((x = 1) OR ((zz < 3) AND (yy > 3)))'
|
422
|
+
end
|
415
423
|
end
|
416
424
|
|
417
425
|
context "Dataset#and" do
|
@@ -486,9 +494,14 @@ context "Dataset#exclude" do
|
|
486
494
|
end
|
487
495
|
|
488
496
|
pt_specify "should support proc expressions" do
|
489
|
-
@dataset.exclude
|
497
|
+
@dataset.exclude{:id == (6...12)}.sql.should ==
|
490
498
|
'SELECT * FROM test WHERE NOT (id >= 6 AND id < 12)'
|
491
499
|
end
|
500
|
+
|
501
|
+
pt_specify "should allow the use of blocks and arguments simultaneously" do
|
502
|
+
@dataset.exclude(:id => (7..11)){:id == (6...12)}.sql.should ==
|
503
|
+
'SELECT * FROM test WHERE (((id < 7) OR (id > 11)) OR NOT (id >= 6 AND id < 12))'
|
504
|
+
end
|
492
505
|
end
|
493
506
|
|
494
507
|
context "Dataset#invert" do
|
@@ -712,12 +725,6 @@ context "Dataset#from" do
|
|
712
725
|
|
713
726
|
@dataset.from(:a[:i]).select_sql.should ==
|
714
727
|
"SELECT * FROM a(i)"
|
715
|
-
|
716
|
-
@dataset.from(:generate_series[1, 2].as(:a[:i])).select_sql.should ==
|
717
|
-
"SELECT * FROM generate_series(1, 2) AS a(i)"
|
718
|
-
|
719
|
-
@dataset.from(:generate_series[1, 2] => :a[:i]).select_sql.should ==
|
720
|
-
"SELECT * FROM generate_series(1, 2) a(i)"
|
721
728
|
end
|
722
729
|
end
|
723
730
|
|
@@ -914,7 +921,7 @@ context "Dataset#reverse_order" do
|
|
914
921
|
|
915
922
|
specify "should invert the order given" do
|
916
923
|
@dataset.reverse_order(:name.desc).sql.should ==
|
917
|
-
'SELECT * FROM test ORDER BY name'
|
924
|
+
'SELECT * FROM test ORDER BY name ASC'
|
918
925
|
end
|
919
926
|
|
920
927
|
specify "should invert the order for ASC expressions" do
|
@@ -924,14 +931,14 @@ context "Dataset#reverse_order" do
|
|
924
931
|
|
925
932
|
specify "should accept multiple arguments" do
|
926
933
|
@dataset.reverse_order(:name, :price.desc).sql.should ==
|
927
|
-
'SELECT * FROM test ORDER BY name DESC, price'
|
934
|
+
'SELECT * FROM test ORDER BY name DESC, price ASC'
|
928
935
|
end
|
929
936
|
|
930
937
|
specify "should reverse a previous ordering if no arguments are given" do
|
931
938
|
@dataset.order(:name).reverse_order.sql.should ==
|
932
939
|
'SELECT * FROM test ORDER BY name DESC'
|
933
940
|
@dataset.order(:clumsy.desc, :fool).reverse_order.sql.should ==
|
934
|
-
'SELECT * FROM test ORDER BY clumsy, fool DESC'
|
941
|
+
'SELECT * FROM test ORDER BY clumsy ASC, fool DESC'
|
935
942
|
end
|
936
943
|
|
937
944
|
specify "should return an unordered dataset for a dataset with no order" do
|
@@ -1059,11 +1066,17 @@ context "Dataset#to_hash" do
|
|
1059
1066
|
@d.to_hash(:a, :b).should == {1 => 2, 3 => 4, 5 => 6}
|
1060
1067
|
@d.to_hash(:b, :a).should == {2 => 1, 4 => 3, 6 => 5}
|
1061
1068
|
end
|
1069
|
+
|
1070
|
+
specify "should provide a hash with the first column as key and the entire hash as value if the value column is blank or nil" do
|
1071
|
+
@d.to_hash(:a).should == {1 => {:a => 1, :b => 2}, 3 => {:a => 3, :b => 4}, 5 => {:a => 5, :b => 6}}
|
1072
|
+
@d.to_hash(:b).should == {2 => {:a => 1, :b => 2}, 4 => {:a => 3, :b => 4}, 6 => {:a => 5, :b => 6}}
|
1073
|
+
end
|
1062
1074
|
end
|
1063
1075
|
|
1064
1076
|
context "Dataset#uniq" do
|
1065
1077
|
setup do
|
1066
|
-
@
|
1078
|
+
@db = MockDatabase.new
|
1079
|
+
@dataset = @db[:test].select(:name)
|
1067
1080
|
end
|
1068
1081
|
|
1069
1082
|
specify "should include DISTINCT clause in statement" do
|
@@ -1079,6 +1092,11 @@ context "Dataset#uniq" do
|
|
1079
1092
|
|
1080
1093
|
@dataset.uniq(:stamp.cast_as(:integer), :node_id).sql.should == 'SELECT DISTINCT ON (cast(stamp AS integer), node_id) name FROM test'
|
1081
1094
|
end
|
1095
|
+
|
1096
|
+
specify "should do a subselect for count" do
|
1097
|
+
@dataset.uniq.count
|
1098
|
+
@db.sqls.should == ['SELECT COUNT(*) FROM (SELECT DISTINCT name FROM test) t1 LIMIT 1']
|
1099
|
+
end
|
1082
1100
|
end
|
1083
1101
|
|
1084
1102
|
context "Dataset#count" do
|
@@ -1208,66 +1226,55 @@ context "Dataset#join_table" do
|
|
1208
1226
|
end
|
1209
1227
|
|
1210
1228
|
specify "should support multiple joins" do
|
1211
|
-
@d.join_table(:inner, :b, :items_id).join_table(:left_outer, :c, :b_id => :b__id).sql.should ==
|
1229
|
+
@d.join_table(:inner, :b, :items_id=>:id).join_table(:left_outer, :c, :b_id => :b__id).sql.should ==
|
1212
1230
|
'SELECT * FROM "items" INNER JOIN "b" ON ("b"."items_id" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")'
|
1213
1231
|
end
|
1214
1232
|
|
1215
|
-
specify "should use id as implicit relation primary key if omitted" do
|
1216
|
-
@d.join_table(:left_outer, :categories, :category_id).sql.should ==
|
1217
|
-
@d.join_table(:left_outer, :categories, :category_id => :id).sql
|
1218
|
-
|
1219
|
-
# when doing multiple joins, id should be qualified using the last joined table
|
1220
|
-
@d.join_table(:right_outer, :b, :items_id).join_table(:full_outer, :c, :b_id).sql.should ==
|
1221
|
-
'SELECT * FROM "items" RIGHT OUTER JOIN "b" ON ("b"."items_id" = "items"."id") FULL OUTER JOIN "c" ON ("c"."b_id" = "b"."id")'
|
1222
|
-
end
|
1223
|
-
|
1224
1233
|
specify "should support left outer joins" do
|
1225
|
-
@d.join_table(:left_outer, :categories, :category_id).sql.should ==
|
1234
|
+
@d.join_table(:left_outer, :categories, :category_id=>:id).sql.should ==
|
1226
1235
|
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1227
1236
|
|
1228
|
-
@d.left_outer_join(:categories, :category_id).sql.should ==
|
1237
|
+
@d.left_outer_join(:categories, :category_id=>:id).sql.should ==
|
1229
1238
|
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1230
1239
|
end
|
1231
1240
|
|
1232
1241
|
specify "should support right outer joins" do
|
1233
|
-
@d.join_table(:right_outer, :categories, :category_id).sql.should ==
|
1242
|
+
@d.join_table(:right_outer, :categories, :category_id=>:id).sql.should ==
|
1234
1243
|
'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1235
1244
|
|
1236
|
-
@d.right_outer_join(:categories, :category_id).sql.should ==
|
1245
|
+
@d.right_outer_join(:categories, :category_id=>:id).sql.should ==
|
1237
1246
|
'SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1238
1247
|
end
|
1239
1248
|
|
1240
1249
|
specify "should support full outer joins" do
|
1241
|
-
@d.join_table(:full_outer, :categories, :category_id).sql.should ==
|
1250
|
+
@d.join_table(:full_outer, :categories, :category_id=>:id).sql.should ==
|
1242
1251
|
'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1243
1252
|
|
1244
|
-
@d.full_outer_join(:categories, :category_id).sql.should ==
|
1253
|
+
@d.full_outer_join(:categories, :category_id=>:id).sql.should ==
|
1245
1254
|
'SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1246
1255
|
end
|
1247
1256
|
|
1248
1257
|
specify "should support inner joins" do
|
1249
|
-
@d.join_table(:inner, :categories, :category_id).sql.should ==
|
1258
|
+
@d.join_table(:inner, :categories, :category_id=>:id).sql.should ==
|
1250
1259
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1251
1260
|
|
1252
|
-
@d.inner_join(:categories, :category_id).sql.should ==
|
1261
|
+
@d.inner_join(:categories, :category_id=>:id).sql.should ==
|
1253
1262
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1254
1263
|
end
|
1255
1264
|
|
1256
|
-
specify "should default to
|
1257
|
-
@d.join_table(nil, :categories, :category_id).sql.should ==
|
1258
|
-
'SELECT * FROM "items"
|
1265
|
+
specify "should default to a plain join if nil is used for the type" do
|
1266
|
+
@d.join_table(nil, :categories, :category_id=>:id).sql.should ==
|
1267
|
+
'SELECT * FROM "items" JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1268
|
+
end
|
1259
1269
|
|
1260
|
-
|
1270
|
+
specify "should use an inner join for Dataset#join" do
|
1271
|
+
@d.join(:categories, :category_id=>:id).sql.should ==
|
1261
1272
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1262
1273
|
end
|
1263
1274
|
|
1264
|
-
specify "should raise if an invalid join type is specified" do
|
1265
|
-
proc {@d.join_table(:invalid, :a, :b)}.should raise_error(Sequel::Error)
|
1266
|
-
end
|
1267
|
-
|
1268
1275
|
specify "should support aliased tables" do
|
1269
1276
|
@d.from('stats').join('players', {:id => :player_id}, 'p').sql.should ==
|
1270
|
-
'SELECT * FROM "stats" INNER JOIN "players" "p" ON ("p"."id" = "stats"."player_id")'
|
1277
|
+
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
1271
1278
|
|
1272
1279
|
ds = MockDataset.new(nil).from(:foo => :f)
|
1273
1280
|
ds.quote_identifiers = true
|
@@ -1295,23 +1302,30 @@ context "Dataset#join_table" do
|
|
1295
1302
|
ds = Sequel::Dataset.new(nil).from(:categories)
|
1296
1303
|
|
1297
1304
|
@d.join_table(:left_outer, ds, :item_id => :id).sql.should ==
|
1298
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) "t1" ON ("t1"."item_id" = "items"."id")'
|
1305
|
+
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
1299
1306
|
|
1300
1307
|
ds.filter!(:active => true)
|
1301
1308
|
|
1302
1309
|
@d.join_table(:left_outer, ds, :item_id => :id).sql.should ==
|
1303
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active = \'t\')) "t1" ON ("t1"."item_id" = "items"."id")'
|
1310
|
+
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories WHERE (active = \'t\')) AS "t1" ON ("t1"."item_id" = "items"."id")'
|
1304
1311
|
end
|
1305
|
-
|
1312
|
+
|
1313
|
+
specify "should support joining datasets and aliasing the join" do
|
1314
|
+
ds = Sequel::Dataset.new(nil).from(:categories)
|
1315
|
+
|
1316
|
+
@d.join_table(:left_outer, ds, {:ds__item_id => :id}, :ds).sql.should ==
|
1317
|
+
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "ds" ON ("ds"."item_id" = "items"."id")'
|
1318
|
+
end
|
1319
|
+
|
1306
1320
|
specify "should support joining multiple datasets" do
|
1307
1321
|
ds = Sequel::Dataset.new(nil).from(:categories)
|
1308
1322
|
ds2 = Sequel::Dataset.new(nil).from(:nodes).select(:name)
|
1309
1323
|
ds3 = Sequel::Dataset.new(nil).from(:attributes).filter("name = 'blah'")
|
1310
1324
|
|
1311
1325
|
@d.join_table(:left_outer, ds, :item_id => :id).join_table(:inner, ds2, :node_id=>:id).join_table(:right_outer, ds3, :attribute_id=>:id).sql.should ==
|
1312
|
-
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) "t1" ON ("t1"."item_id" = "items"."id") ' \
|
1313
|
-
'INNER JOIN (SELECT name FROM nodes) "t2" ON ("t2"."node_id" = "t1"."id") ' \
|
1314
|
-
'RIGHT OUTER JOIN (SELECT * FROM attributes WHERE (name = \'blah\')) "t3" ON ("t3"."attribute_id" = "t2"."id")'
|
1326
|
+
'SELECT * FROM "items" LEFT OUTER JOIN (SELECT * FROM categories) AS "t1" ON ("t1"."item_id" = "items"."id") ' \
|
1327
|
+
'INNER JOIN (SELECT name FROM nodes) AS "t2" ON ("t2"."node_id" = "t1"."id") ' \
|
1328
|
+
'RIGHT OUTER JOIN (SELECT * FROM attributes WHERE (name = \'blah\')) AS "t3" ON ("t3"."attribute_id" = "t2"."id")'
|
1315
1329
|
end
|
1316
1330
|
|
1317
1331
|
specify "should support joining objects that respond to :table_name" do
|
@@ -1321,6 +1335,104 @@ context "Dataset#join_table" do
|
|
1321
1335
|
@d.join(ds, :item_id => :id).sql.should ==
|
1322
1336
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."item_id" = "items"."id")'
|
1323
1337
|
end
|
1338
|
+
|
1339
|
+
specify "should support using a SQL String as the join condition" do
|
1340
|
+
@d.join(:categories, %{c.item_id = items.id}, :c).sql.should ==
|
1341
|
+
'SELECT * FROM "items" INNER JOIN "categories" AS "c" ON (c.item_id = items.id)'
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
specify "should support using a boolean column as the join condition" do
|
1345
|
+
@d.join(:categories, :active).sql.should ==
|
1346
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON "active"'
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
specify "should support using an expression as the join condition" do
|
1350
|
+
@d.join(:categories, :number > 10).sql.should ==
|
1351
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON ("number" > 10)'
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
specify "should support natural and cross joins using nil" do
|
1355
|
+
@d.join_table(:natural, :categories).sql.should ==
|
1356
|
+
'SELECT * FROM "items" NATURAL JOIN "categories"'
|
1357
|
+
@d.join_table(:cross, :categories, nil).sql.should ==
|
1358
|
+
'SELECT * FROM "items" CROSS JOIN "categories"'
|
1359
|
+
@d.join_table(:natural, :categories, nil, :c).sql.should ==
|
1360
|
+
'SELECT * FROM "items" NATURAL JOIN "categories" AS "c"'
|
1361
|
+
end
|
1362
|
+
|
1363
|
+
specify "should support joins with a USING clause if an array of symbols is used" do
|
1364
|
+
@d.join(:categories, [:id]).sql.should ==
|
1365
|
+
'SELECT * FROM "items" INNER JOIN "categories" USING ("id")'
|
1366
|
+
@d.join(:categories, [:id1, :id2]).sql.should ==
|
1367
|
+
'SELECT * FROM "items" INNER JOIN "categories" USING ("id1", "id2")'
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
specify "should raise an error if using an array of symbols with a block" do
|
1371
|
+
proc{@d.join(:categories, [:id]){|j,lj,js|}}.should raise_error(Sequel::Error)
|
1372
|
+
end
|
1373
|
+
|
1374
|
+
specify "should support using a block that receieves the join table/alias, last join table/alias, and array of previous joins" do
|
1375
|
+
@d.join(:categories) do |join_alias, last_join_alias, joins|
|
1376
|
+
join_alias.should == :categories
|
1377
|
+
last_join_alias.should == :items
|
1378
|
+
joins.should == []
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
@d.from(:items=>:i).join(:categories, nil, :c) do |join_alias, last_join_alias, joins|
|
1382
|
+
join_alias.should == :c
|
1383
|
+
last_join_alias.should == :i
|
1384
|
+
joins.should == []
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
@d.from(:items___i).join(:categories, nil, :c) do |join_alias, last_join_alias, joins|
|
1388
|
+
join_alias.should == :c
|
1389
|
+
last_join_alias.should == :i
|
1390
|
+
joins.should == []
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
@d.join(:blah).join(:categories, nil, :c) do |join_alias, last_join_alias, joins|
|
1394
|
+
join_alias.should == :c
|
1395
|
+
last_join_alias.should == :blah
|
1396
|
+
joins.should be_a_kind_of(Array)
|
1397
|
+
joins.length.should == 1
|
1398
|
+
joins.first.should be_a_kind_of(Sequel::SQL::JoinClause)
|
1399
|
+
joins.first.join_type.should == :inner
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
@d.join_table(:natural, :blah, nil, :b).join(:categories, nil, :c) do |join_alias, last_join_alias, joins|
|
1403
|
+
join_alias.should == :c
|
1404
|
+
last_join_alias.should == :b
|
1405
|
+
joins.should be_a_kind_of(Array)
|
1406
|
+
joins.length.should == 1
|
1407
|
+
joins.first.should be_a_kind_of(Sequel::SQL::JoinClause)
|
1408
|
+
joins.first.join_type.should == :natural
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
@d.join(:blah).join(:categories).join(:blah2) do |join_alias, last_join_alias, joins|
|
1412
|
+
join_alias.should == :blah2
|
1413
|
+
last_join_alias.should == :categories
|
1414
|
+
joins.should be_a_kind_of(Array)
|
1415
|
+
joins.length.should == 2
|
1416
|
+
joins.first.should be_a_kind_of(Sequel::SQL::JoinClause)
|
1417
|
+
joins.first.table.should == :blah
|
1418
|
+
joins.last.should be_a_kind_of(Sequel::SQL::JoinClause)
|
1419
|
+
joins.last.table.should == :categories
|
1420
|
+
end
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
specify "should use the block result as the only condition if no condition is given" do
|
1424
|
+
@d.join(:categories){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should ==
|
1425
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."b" = "items"."c")'
|
1426
|
+
@d.join(:categories){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should ==
|
1427
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."b" > "items"."c")'
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
specify "should combine the block conditions and argument conditions if both given" do
|
1431
|
+
@d.join(:categories, :a=>:d){|j,lj,js| {:b.qualify(j)=>:c.qualify(lj)}}.sql.should ==
|
1432
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" = "items"."c"))'
|
1433
|
+
@d.join(:categories, :a=>:d){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should ==
|
1434
|
+
'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" > "items"."c"))'
|
1435
|
+
end
|
1324
1436
|
end
|
1325
1437
|
|
1326
1438
|
context "Dataset#[]=" do
|
@@ -1543,9 +1655,9 @@ context "Dataset #first and #last" do
|
|
1543
1655
|
|
1544
1656
|
specify "#last should invert the order" do
|
1545
1657
|
@d.order(:a).last.pop.should == 'SELECT * FROM test ORDER BY a DESC LIMIT 1'
|
1546
|
-
@d.order(:b.desc).last.pop.should == 'SELECT * FROM test ORDER BY b LIMIT 1'
|
1658
|
+
@d.order(:b.desc).last.pop.should == 'SELECT * FROM test ORDER BY b ASC LIMIT 1'
|
1547
1659
|
@d.order(:c, :d).last.pop.should == 'SELECT * FROM test ORDER BY c DESC, d DESC LIMIT 1'
|
1548
|
-
@d.order(:e.desc, :f).last.pop.should == 'SELECT * FROM test ORDER BY e, f DESC LIMIT 1'
|
1660
|
+
@d.order(:e.desc, :f).last.pop.should == 'SELECT * FROM test ORDER BY e ASC, f DESC LIMIT 1'
|
1549
1661
|
end
|
1550
1662
|
end
|
1551
1663
|
|
data/spec/object_graph_spec.rb
CHANGED
@@ -48,7 +48,7 @@ describe Sequel::Dataset, " graphing" do
|
|
48
48
|
|
49
49
|
it "#graph should accept a :table_alias option" do
|
50
50
|
ds = @ds1.graph(:lines, {:x=>:id}, :table_alias=>:planes)
|
51
|
-
ds.sql.should == 'SELECT points.id, points.x, points.y, planes.id AS planes_id, planes.x AS planes_x, planes.y AS planes_y, planes.graph_id FROM points LEFT OUTER JOIN lines planes ON (planes.x = points.id)'
|
51
|
+
ds.sql.should == 'SELECT points.id, points.x, points.y, planes.id AS planes_id, planes.x AS planes_x, planes.y AS planes_y, planes.graph_id FROM points LEFT OUTER JOIN lines AS planes ON (planes.x = points.id)'
|
52
52
|
end
|
53
53
|
|
54
54
|
it "#graph should accept a :join_type option" do
|
@@ -56,11 +56,16 @@ describe Sequel::Dataset, " graphing" do
|
|
56
56
|
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points INNER JOIN lines ON (lines.x = points.id)'
|
57
57
|
end
|
58
58
|
|
59
|
-
it "#graph should
|
59
|
+
it "#graph should not select any columns from the graphed table if :select option is false" do
|
60
60
|
ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
|
61
61
|
ds.sql.should == 'SELECT points.id, points.x, points.y, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
|
62
62
|
end
|
63
63
|
|
64
|
+
it "#graph should use the given columns if :select option is used" do
|
65
|
+
ds = @ds1.graph(:lines, {:x=>:id}, :select=>[:x, :graph_id]).graph(:graphs, :id=>:graph_id)
|
66
|
+
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.x AS lines_x, lines.graph_id, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x AS graphs_lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
|
67
|
+
end
|
68
|
+
|
64
69
|
it "#graph should pass all join_conditions to join_table" do
|
65
70
|
ds = @ds1.graph(@ds2, [[:x, :id], [:y, :id]])
|
66
71
|
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
|
@@ -80,7 +85,7 @@ describe Sequel::Dataset, " graphing" do
|
|
80
85
|
|
81
86
|
it "#graph should allow graphing of the same dataset multiple times" do
|
82
87
|
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
|
83
|
-
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graph.id AS graph_id_0, graph.x AS graph_x, graph.y AS graph_y, graph.graph_id AS graph_graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN lines graph ON (graph.y = points.id)'
|
88
|
+
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graph.id AS graph_id_0, graph.x AS graph_x, graph.y AS graph_y, graph.graph_id AS graph_graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN lines AS graph ON (graph.y = points.id)'
|
84
89
|
end
|
85
90
|
|
86
91
|
it "#graph should raise an error if the table/table alias has already been used" do
|
@@ -170,7 +175,7 @@ describe Sequel::Dataset, " graphing" do
|
|
170
175
|
results[3].should == {:points=>{:id=>3, :x=>5, :y=>6}, :lines=>{:id=>7, :x=>5, :y=>8, :graph_id=>9}, :graphs=>{:id=>9, :name=>10, :x=>10, :y=>11, :lines_x=>12}}
|
171
176
|
end
|
172
177
|
|
173
|
-
it "#graph_each should not included tables graphed with the :select option in the result set" do
|
178
|
+
it "#graph_each should not included tables graphed with the :select => false option in the result set" do
|
174
179
|
ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
|
175
180
|
def ds.fetch_rows(sql, &block)
|
176
181
|
yield({:id=>1,:x=>2,:y=>3,:graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :lines_x=>12})
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -2,30 +2,21 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
3
3
|
context "Sequelizer without ParseTree" do
|
4
4
|
setup do
|
5
|
-
|
6
|
-
alias_method :orig_sq_require, :require
|
7
|
-
def require(*args); raise LoadError; end
|
8
|
-
end
|
9
|
-
old_verbose = $VERBOSE
|
10
|
-
$VERBOSE = nil
|
11
|
-
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
12
|
-
$VERBOSE = old_verbose
|
5
|
+
Sequel.use_parse_tree = false
|
13
6
|
@db = Sequel::Database.new
|
14
7
|
@ds = @db[:items]
|
15
8
|
end
|
16
9
|
|
17
10
|
teardown do
|
18
|
-
|
19
|
-
alias_method :require, :orig_sq_require
|
20
|
-
end
|
21
|
-
old_verbose = $VERBOSE
|
22
|
-
$VERBOSE = nil
|
23
|
-
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
24
|
-
$VERBOSE = old_verbose
|
11
|
+
Sequel.use_parse_tree = true
|
25
12
|
end
|
26
13
|
|
27
|
-
specify "should raise error when
|
28
|
-
proc {
|
14
|
+
specify "should raise error when using ParseTree specific syntax without ParseTree" do
|
15
|
+
proc {@ds.filter{:x << 1}}.should raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should allow expression syntax inside block raise error when converting ParseTree proc to SQL" do
|
19
|
+
proc {@ds.filter{:x > 1}}.should_not raise_error(Sequel::Error)
|
29
20
|
end
|
30
21
|
end
|
31
22
|
|