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.
Files changed (40) hide show
  1. data/CHANGELOG +50 -0
  2. data/README +1 -2
  3. data/Rakefile +1 -1
  4. data/bin/sequel +26 -11
  5. data/doc/dataset_filtering.rdoc +9 -2
  6. data/lib/sequel_core/adapters/adapter_skeleton.rb +0 -2
  7. data/lib/sequel_core/adapters/mysql.rb +11 -97
  8. data/lib/sequel_core/adapters/odbc_mssql.rb +1 -1
  9. data/lib/sequel_core/adapters/oracle.rb +1 -1
  10. data/lib/sequel_core/adapters/postgres.rb +33 -17
  11. data/lib/sequel_core/adapters/sqlite.rb +1 -1
  12. data/lib/sequel_core/connection_pool.rb +12 -35
  13. data/lib/sequel_core/core_ext.rb +5 -19
  14. data/lib/sequel_core/core_sql.rb +17 -6
  15. data/lib/sequel_core/database.rb +14 -2
  16. data/lib/sequel_core/dataset/callback.rb +0 -3
  17. data/lib/sequel_core/dataset/convenience.rb +4 -3
  18. data/lib/sequel_core/dataset/parse_tree_sequelizer.rb +0 -21
  19. data/lib/sequel_core/dataset/sequelizer.rb +42 -43
  20. data/lib/sequel_core/dataset/sql.rb +121 -62
  21. data/lib/sequel_core/dataset.rb +20 -4
  22. data/lib/sequel_core/deprecated.rb +0 -6
  23. data/lib/sequel_core/migration.rb +4 -0
  24. data/lib/sequel_core/object_graph.rb +8 -6
  25. data/lib/sequel_core/pretty_table.rb +1 -1
  26. data/lib/sequel_core/schema/sql.rb +2 -0
  27. data/lib/sequel_core/sql.rb +393 -153
  28. data/lib/sequel_core.rb +22 -7
  29. data/spec/adapters/mysql_spec.rb +11 -7
  30. data/spec/adapters/postgres_spec.rb +32 -4
  31. data/spec/blockless_filters_spec.rb +33 -6
  32. data/spec/connection_pool_spec.rb +18 -16
  33. data/spec/core_ext_spec.rb +0 -13
  34. data/spec/core_sql_spec.rb +59 -13
  35. data/spec/database_spec.rb +5 -5
  36. data/spec/dataset_spec.rb +167 -55
  37. data/spec/object_graph_spec.rb +9 -4
  38. data/spec/sequelizer_spec.rb +8 -17
  39. data/spec/spec_helper.rb +4 -3
  40. metadata +2 -2
@@ -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 {:id == (6...12)}.sql.should ==
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
- @dataset = Sequel::Dataset.new(nil).from(:test).select(:name)
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 an inner join" do
1257
- @d.join_table(nil, :categories, :category_id).sql.should ==
1258
- 'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
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
- @d.join(:categories, :category_id).sql.should ==
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
 
@@ -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 accept a :select_option" do
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})
@@ -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
- module Kernel
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
- module Kernel
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 converting proc to SQL" do
28
- proc {proc {:x > 1}.to_sql(@ds)}.should raise_error(Sequel::Error)
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