sequel 3.47.0 → 3.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +230 -0
- data/README.rdoc +31 -40
- data/Rakefile +1 -14
- data/doc/active_record.rdoc +29 -29
- data/doc/association_basics.rdoc +4 -13
- data/doc/cheat_sheet.rdoc +8 -6
- data/doc/code_order.rdoc +89 -0
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_basics.rdoc +7 -8
- data/doc/dataset_filtering.rdoc +7 -2
- data/doc/mass_assignment.rdoc +2 -3
- data/doc/migration.rdoc +8 -8
- data/doc/model_hooks.rdoc +11 -7
- data/doc/object_model.rdoc +2 -2
- data/doc/opening_databases.rdoc +5 -14
- data/doc/prepared_statements.rdoc +5 -9
- data/doc/querying.rdoc +23 -28
- data/doc/reflection.rdoc +11 -0
- data/doc/release_notes/3.48.0.txt +477 -0
- data/doc/schema_modification.rdoc +12 -5
- data/doc/security.rdoc +2 -2
- data/doc/sharding.rdoc +1 -2
- data/doc/sql.rdoc +10 -13
- data/doc/testing.rdoc +8 -4
- data/doc/transactions.rdoc +2 -2
- data/doc/validations.rdoc +40 -17
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +25 -20
- data/lib/sequel/adapters/ado/access.rb +1 -0
- data/lib/sequel/adapters/ado/mssql.rb +1 -0
- data/lib/sequel/adapters/db2.rb +9 -7
- data/lib/sequel/adapters/dbi.rb +16 -16
- data/lib/sequel/adapters/do.rb +17 -18
- data/lib/sequel/adapters/do/mysql.rb +1 -0
- data/lib/sequel/adapters/do/postgres.rb +2 -0
- data/lib/sequel/adapters/do/sqlite.rb +1 -0
- data/lib/sequel/adapters/firebird.rb +5 -7
- data/lib/sequel/adapters/ibmdb.rb +23 -20
- data/lib/sequel/adapters/informix.rb +8 -2
- data/lib/sequel/adapters/jdbc.rb +39 -35
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
- data/lib/sequel/adapters/jdbc/db2.rb +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
- data/lib/sequel/adapters/jdbc/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
- data/lib/sequel/adapters/jdbc/progress.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
- data/lib/sequel/adapters/mock.rb +30 -31
- data/lib/sequel/adapters/mysql.rb +6 -7
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/odbc.rb +22 -20
- data/lib/sequel/adapters/odbc/mssql.rb +1 -0
- data/lib/sequel/adapters/openbase.rb +4 -1
- data/lib/sequel/adapters/oracle.rb +10 -8
- data/lib/sequel/adapters/postgres.rb +12 -10
- data/lib/sequel/adapters/shared/access.rb +6 -0
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +14 -8
- data/lib/sequel/adapters/shared/mysql.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +2 -0
- data/lib/sequel/adapters/shared/postgres.rb +14 -4
- data/lib/sequel/adapters/shared/progress.rb +1 -0
- data/lib/sequel/adapters/shared/sqlite.rb +4 -3
- data/lib/sequel/adapters/sqlite.rb +6 -7
- data/lib/sequel/adapters/swift.rb +20 -21
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +2 -0
- data/lib/sequel/adapters/swift/sqlite.rb +1 -0
- data/lib/sequel/adapters/tinytds.rb +5 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +57 -50
- data/lib/sequel/database/connecting.rb +9 -10
- data/lib/sequel/database/dataset.rb +11 -6
- data/lib/sequel/database/dataset_defaults.rb +61 -69
- data/lib/sequel/database/features.rb +21 -0
- data/lib/sequel/database/misc.rb +23 -3
- data/lib/sequel/database/query.rb +13 -7
- data/lib/sequel/database/schema_methods.rb +6 -6
- data/lib/sequel/database/transactions.rb +1 -0
- data/lib/sequel/dataset/actions.rb +51 -38
- data/lib/sequel/dataset/features.rb +1 -0
- data/lib/sequel/dataset/graph.rb +9 -33
- data/lib/sequel/dataset/misc.rb +30 -5
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +91 -27
- data/lib/sequel/dataset/sql.rb +40 -6
- data/lib/sequel/deprecated.rb +74 -0
- data/lib/sequel/deprecated_core_extensions.rb +135 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -5
- data/lib/sequel/extensions/core_extensions.rb +10 -3
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
- data/lib/sequel/extensions/filter_having.rb +58 -0
- data/lib/sequel/extensions/graph_each.rb +63 -0
- data/lib/sequel/extensions/hash_aliases.rb +44 -0
- data/lib/sequel/extensions/looser_typecasting.rb +14 -3
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/extensions/named_timezones.rb +14 -1
- data/lib/sequel/extensions/null_dataset.rb +7 -1
- data/lib/sequel/extensions/pagination.rb +15 -5
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
- data/lib/sequel/extensions/pg_json.rb +7 -7
- data/lib/sequel/extensions/pg_range_ops.rb +8 -2
- data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +13 -4
- data/lib/sequel/extensions/query.rb +21 -4
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -7
- data/lib/sequel/extensions/schema_dumper.rb +35 -48
- data/lib/sequel/extensions/select_remove.rb +13 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
- data/lib/sequel/extensions/set_overrides.rb +43 -0
- data/lib/sequel/extensions/to_dot.rb +6 -0
- data/lib/sequel/model.rb +12 -6
- data/lib/sequel/model/associations.rb +80 -38
- data/lib/sequel/model/base.rb +137 -52
- data/lib/sequel/model/errors.rb +7 -2
- data/lib/sequel/plugins/active_model.rb +13 -0
- data/lib/sequel/plugins/after_initialize.rb +43 -0
- data/lib/sequel/plugins/association_proxies.rb +63 -7
- data/lib/sequel/plugins/auto_validations.rb +56 -16
- data/lib/sequel/plugins/blacklist_security.rb +63 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
- data/lib/sequel/plugins/constraint_validations.rb +50 -8
- data/lib/sequel/plugins/dataset_associations.rb +2 -0
- data/lib/sequel/plugins/hook_class_methods.rb +7 -1
- data/lib/sequel/plugins/identity_map.rb +4 -0
- data/lib/sequel/plugins/json_serializer.rb +32 -13
- data/lib/sequel/plugins/optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/scissors.rb +33 -0
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
- data/lib/sequel/plugins/tree.rb +5 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +15 -11
- data/lib/sequel/plugins/xml_serializer.rb +12 -3
- data/lib/sequel/sql.rb +12 -2
- data/lib/sequel/timezones.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/mssql_spec.rb +24 -57
- data/spec/adapters/postgres_spec.rb +27 -55
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/bin_spec.rb +251 -0
- data/spec/core/database_spec.rb +46 -32
- data/spec/core/dataset_spec.rb +233 -181
- data/spec/core/deprecated_spec.rb +78 -0
- data/spec/core/expression_filters_spec.rb +3 -4
- data/spec/core/mock_adapter_spec.rb +9 -9
- data/spec/core/object_graph_spec.rb +9 -19
- data/spec/core/schema_spec.rb +3 -1
- data/spec/core/spec_helper.rb +19 -0
- data/spec/core_extensions_spec.rb +80 -30
- data/spec/extensions/after_initialize_spec.rb +24 -0
- data/spec/extensions/association_proxies_spec.rb +37 -1
- data/spec/extensions/auto_validations_spec.rb +20 -4
- data/spec/extensions/blacklist_security_spec.rb +87 -0
- data/spec/extensions/boolean_readers_spec.rb +2 -1
- data/spec/extensions/class_table_inheritance_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
- data/spec/extensions/core_refinements_spec.rb +7 -7
- data/spec/extensions/dataset_associations_spec.rb +2 -2
- data/spec/extensions/date_arithmetic_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -1
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
- data/spec/extensions/filter_having_spec.rb +40 -0
- data/spec/extensions/graph_each_spec.rb +109 -0
- data/spec/extensions/hash_aliases_spec.rb +16 -0
- data/spec/extensions/hook_class_methods_spec.rb +2 -2
- data/spec/extensions/identity_map_spec.rb +3 -3
- data/spec/extensions/json_serializer_spec.rb +19 -19
- data/spec/extensions/lazy_attributes_spec.rb +1 -0
- data/spec/extensions/list_spec.rb +13 -13
- data/spec/extensions/looser_typecasting_spec.rb +10 -3
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +7 -7
- data/spec/extensions/named_timezones_spec.rb +6 -0
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
- data/spec/extensions/pg_range_ops_spec.rb +4 -2
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_caching_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +27 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +26 -0
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
- data/spec/extensions/set_overrides_spec.rb +45 -0
- data/spec/extensions/single_table_inheritance_spec.rb +10 -0
- data/spec/extensions/spec_helper.rb +24 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +2 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +3 -2
- data/spec/extensions/update_primary_key_spec.rb +2 -2
- data/spec/extensions/validation_class_methods_spec.rb +19 -19
- data/spec/extensions/validation_helpers_spec.rb +30 -21
- data/spec/extensions/xml_serializer_spec.rb +5 -5
- data/spec/integration/associations_test.rb +10 -30
- data/spec/integration/dataset_test.rb +20 -24
- data/spec/integration/eager_loader_test.rb +5 -5
- data/spec/integration/model_test.rb +3 -3
- data/spec/integration/plugin_test.rb +7 -39
- data/spec/integration/schema_test.rb +4 -38
- data/spec/integration/spec_helper.rb +2 -1
- data/spec/model/association_reflection_spec.rb +70 -5
- data/spec/model/associations_spec.rb +11 -11
- data/spec/model/base_spec.rb +25 -8
- data/spec/model/class_dataset_methods_spec.rb +143 -0
- data/spec/model/dataset_methods_spec.rb +1 -1
- data/spec/model/eager_loading_spec.rb +25 -25
- data/spec/model/hooks_spec.rb +1 -1
- data/spec/model/model_spec.rb +22 -7
- data/spec/model/plugins_spec.rb +1 -6
- data/spec/model/record_spec.rb +37 -29
- data/spec/model/spec_helper.rb +23 -1
- data/spec/model/validations_spec.rb +15 -17
- metadata +32 -3
data/spec/model/base_spec.rb
CHANGED
@@ -462,7 +462,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
462
462
|
@c.allowed_columns.should == [:x, :y]
|
463
463
|
end
|
464
464
|
|
465
|
-
|
465
|
+
qspecify "should set the restricted columns correctly" do
|
466
466
|
@c.restricted_columns.should == nil
|
467
467
|
@c.set_restricted_columns :x
|
468
468
|
@c.restricted_columns.should == [:x]
|
@@ -484,7 +484,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
484
484
|
MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
485
485
|
end
|
486
486
|
|
487
|
-
|
487
|
+
qspecify "should not set restricted columns by default" do
|
488
488
|
@c.set_restricted_columns :z
|
489
489
|
i = @c.new(:x => 1, :y => 2, :z => 3)
|
490
490
|
i.values.should == {:x => 1, :y => 2}
|
@@ -498,7 +498,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
498
498
|
MODEL_DB.sqls.should == ["INSERT INTO blahblah (x) VALUES (7)", "SELECT * FROM blahblah WHERE (id = 10) LIMIT 1"]
|
499
499
|
end
|
500
500
|
|
501
|
-
|
501
|
+
qspecify "should have allowed take precedence over restricted" do
|
502
502
|
@c.set_allowed_columns :x, :y
|
503
503
|
@c.set_restricted_columns :y, :z
|
504
504
|
i = @c.new(:x => 1, :y => 2, :z => 3)
|
@@ -556,7 +556,7 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
556
556
|
before do
|
557
557
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
558
558
|
columns :x, :y, :z, :id
|
559
|
-
|
559
|
+
set_allowed_columns :x, :y
|
560
560
|
end
|
561
561
|
end
|
562
562
|
|
@@ -571,10 +571,14 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
571
571
|
proc{c.set(:z=>1)}.should raise_error(Sequel::Error)
|
572
572
|
proc{c.set_all(:id=>1)}.should raise_error(Sequel::Error)
|
573
573
|
proc{c.set_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
|
574
|
-
proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
|
575
574
|
proc{c.update(:z=>1)}.should raise_error(Sequel::Error)
|
576
575
|
proc{c.update_all(:id=>1)}.should raise_error(Sequel::Error)
|
577
576
|
proc{c.update_only({:x=>1}, :y)}.should raise_error(Sequel::Error)
|
577
|
+
end
|
578
|
+
|
579
|
+
qspecify "should raise an error if a missing/restricted column/method is accessed by *_except" do
|
580
|
+
c = @c.new
|
581
|
+
proc{c.set_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
|
578
582
|
proc{c.update_except({:x=>1}, :x)}.should raise_error(Sequel::Error)
|
579
583
|
end
|
580
584
|
|
@@ -631,8 +635,6 @@ describe Sequel::Model, ".[] optimization" do
|
|
631
635
|
it "should have simple_pk be blank if compound or no primary key" do
|
632
636
|
@c.no_primary_key
|
633
637
|
@c.simple_pk.should == nil
|
634
|
-
@c.set_primary_key :b, :a
|
635
|
-
@c.simple_pk.should == nil
|
636
638
|
@c.set_primary_key [:b, :a]
|
637
639
|
@c.simple_pk.should == nil
|
638
640
|
end
|
@@ -701,6 +703,13 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
701
703
|
MODEL_DB.reset
|
702
704
|
end
|
703
705
|
|
706
|
+
it "should be callable on the model class with optimized SQL" do
|
707
|
+
@c.with_pk(1).should == @c.load(:id=>1)
|
708
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
709
|
+
@c.with_pk!(1).should == @c.load(:id=>1)
|
710
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
711
|
+
end
|
712
|
+
|
704
713
|
it "should return the first record where the primary key matches" do
|
705
714
|
@ds.with_pk(1).should == @c.load(:id=>1)
|
706
715
|
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
@@ -723,7 +732,7 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
723
732
|
end
|
724
733
|
|
725
734
|
it "should handle an array for composite primary keys" do
|
726
|
-
@c.set_primary_key :id1, :id2
|
735
|
+
@c.set_primary_key [:id1, :id2]
|
727
736
|
@ds.with_pk([1, 2])
|
728
737
|
sqls = MODEL_DB.sqls
|
729
738
|
["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
|
@@ -745,6 +754,14 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
745
754
|
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
746
755
|
end
|
747
756
|
|
757
|
+
it "should have with_pk return nil and with_pk! raise if no rows match when calling the class method" do
|
758
|
+
@ds._fetch = []
|
759
|
+
@c.with_pk(1).should == nil
|
760
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
761
|
+
proc{@c.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
|
762
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE id = 1"]
|
763
|
+
end
|
764
|
+
|
748
765
|
it "should have #[] consider an integer as a primary key lookup" do
|
749
766
|
@ds[1].should == @c.load(:id=>1)
|
750
767
|
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe Sequel::Model, "class dataset methods" do
|
4
|
+
before do
|
5
|
+
@db = Sequel.mock
|
6
|
+
@c = Class.new(Sequel::Model(@db[:items]))
|
7
|
+
@d = @c.dataset
|
8
|
+
@d._fetch = {:id=>1}
|
9
|
+
@d.autoid = 1
|
10
|
+
@d.numrows = 0
|
11
|
+
@db.sqls
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should call the dataset method of the same name with the same args" do
|
15
|
+
@c.<<({}).should == @d
|
16
|
+
@db.sqls.should == ["INSERT INTO items DEFAULT VALUES"]
|
17
|
+
@c.all.should == [@c.load(:id=>1)]
|
18
|
+
@db.sqls.should == ["SELECT * FROM items"]
|
19
|
+
@c.avg(:id).should == 1
|
20
|
+
@db.sqls.should == ["SELECT avg(id) AS avg FROM items LIMIT 1"]
|
21
|
+
@c.count.should == 1
|
22
|
+
@db.sqls.should == ["SELECT count(*) AS count FROM items LIMIT 1"]
|
23
|
+
@c.cross_join(@c).sql.should == "SELECT * FROM items CROSS JOIN items"
|
24
|
+
@c.distinct.sql.should == "SELECT DISTINCT * FROM items"
|
25
|
+
@c.each{|r| r.should == @c.load(:id=>1)}.should == @d
|
26
|
+
@db.sqls.should == ["SELECT * FROM items"]
|
27
|
+
@c.each_server{|r| r.opts[:server].should == :default}
|
28
|
+
@c.empty?.should be_false
|
29
|
+
@db.sqls.should == ["SELECT 1 AS one FROM items LIMIT 1"]
|
30
|
+
@c.except(@d, :from_self=>false).sql.should == "SELECT * FROM items EXCEPT SELECT * FROM items"
|
31
|
+
@c.exclude(:a).sql.should == "SELECT * FROM items WHERE NOT a"
|
32
|
+
@c.exclude_having(:a).sql.should == "SELECT * FROM items HAVING NOT a"
|
33
|
+
@c.exclude_where(:a).sql.should == "SELECT * FROM items WHERE NOT a"
|
34
|
+
@c.fetch_rows("S"){|r| r.should == {:id=>1}}
|
35
|
+
@db.sqls.should == ["S"]
|
36
|
+
@c.filter(:a).sql.should == "SELECT * FROM items WHERE a"
|
37
|
+
@c.first.should == @c.load(:id=>1)
|
38
|
+
@db.sqls.should == ["SELECT * FROM items LIMIT 1"]
|
39
|
+
@c.first!.should == @c.load(:id=>1)
|
40
|
+
@db.sqls.should == ["SELECT * FROM items LIMIT 1"]
|
41
|
+
@c.for_update.sql.should == "SELECT * FROM items FOR UPDATE"
|
42
|
+
@c.from.sql.should == "SELECT *"
|
43
|
+
@c.from_self.sql.should == "SELECT * FROM (SELECT * FROM items) AS t1"
|
44
|
+
@c.full_join(@c).sql.should == "SELECT * FROM items FULL JOIN items"
|
45
|
+
@c.full_outer_join(@c).sql.should == "SELECT * FROM items FULL OUTER JOIN items"
|
46
|
+
@c.get(:a).should == 1
|
47
|
+
@db.sqls.should == ["SELECT a FROM items LIMIT 1"]
|
48
|
+
@c.graph(@c, nil, :table_alias=>:a).sql.should == "SELECT * FROM items LEFT OUTER JOIN items AS a"
|
49
|
+
@db.sqls
|
50
|
+
@c.grep(:id, 'a%').sql.should == "SELECT * FROM items WHERE ((id LIKE 'a%' ESCAPE '\\'))"
|
51
|
+
@c.group(:a).sql.should == "SELECT * FROM items GROUP BY a"
|
52
|
+
@c.group_and_count(:a).sql.should == "SELECT a, count(*) AS count FROM items GROUP BY a"
|
53
|
+
@c.group_by(:a).sql.should == "SELECT * FROM items GROUP BY a"
|
54
|
+
@c.having(:a).sql.should == "SELECT * FROM items HAVING a"
|
55
|
+
@c.import([:id], [[1]])
|
56
|
+
@db.sqls.should == ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
57
|
+
@c.inner_join(@c).sql.should == "SELECT * FROM items INNER JOIN items"
|
58
|
+
@c.insert.should == 2
|
59
|
+
@db.sqls.should == ["INSERT INTO items DEFAULT VALUES"]
|
60
|
+
@c.intersect(@d, :from_self=>false).sql.should == "SELECT * FROM items INTERSECT SELECT * FROM items"
|
61
|
+
@c.interval(:id).should == 1
|
62
|
+
@db.sqls.should == ["SELECT (max(id) - min(id)) AS interval FROM items LIMIT 1"]
|
63
|
+
@c.join(@c).sql.should == "SELECT * FROM items INNER JOIN items"
|
64
|
+
@c.join_table(:inner, @c).sql.should == "SELECT * FROM items INNER JOIN items"
|
65
|
+
@c.last.should == @c.load(:id=>1)
|
66
|
+
@db.sqls.should == ["SELECT * FROM items ORDER BY id DESC LIMIT 1"]
|
67
|
+
@c.left_join(@c).sql.should == "SELECT * FROM items LEFT JOIN items"
|
68
|
+
@c.left_outer_join(@c).sql.should == "SELECT * FROM items LEFT OUTER JOIN items"
|
69
|
+
@c.limit(2).sql.should == "SELECT * FROM items LIMIT 2"
|
70
|
+
@c.lock_style(:update).sql.should == "SELECT * FROM items FOR UPDATE"
|
71
|
+
@c.map(:id).should == [1]
|
72
|
+
@db.sqls.should == ["SELECT * FROM items"]
|
73
|
+
@c.max(:id).should == 1
|
74
|
+
@db.sqls.should == ["SELECT max(id) AS max FROM items LIMIT 1"]
|
75
|
+
@c.min(:id).should == 1
|
76
|
+
@db.sqls.should == ["SELECT min(id) AS min FROM items LIMIT 1"]
|
77
|
+
@c.multi_insert([{:id=>1}])
|
78
|
+
@db.sqls.should == ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
79
|
+
@c.naked.row_proc.should == nil
|
80
|
+
@c.natural_full_join(@c).sql.should == "SELECT * FROM items NATURAL FULL JOIN items"
|
81
|
+
@c.natural_join(@c).sql.should == "SELECT * FROM items NATURAL JOIN items"
|
82
|
+
@c.natural_left_join(@c).sql.should == "SELECT * FROM items NATURAL LEFT JOIN items"
|
83
|
+
@c.natural_right_join(@c).sql.should == "SELECT * FROM items NATURAL RIGHT JOIN items"
|
84
|
+
@c.order(:a).sql.should == "SELECT * FROM items ORDER BY a"
|
85
|
+
@c.order_append(:a).sql.should == "SELECT * FROM items ORDER BY a"
|
86
|
+
@c.order_by(:a).sql.should == "SELECT * FROM items ORDER BY a"
|
87
|
+
@c.order_more(:a).sql.should == "SELECT * FROM items ORDER BY a"
|
88
|
+
@c.order_prepend(:a).sql.should == "SELECT * FROM items ORDER BY a"
|
89
|
+
@c.paged_each{|r| r.should == @c.load(:id=>1)}
|
90
|
+
@db.sqls.should == ["BEGIN", "SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0", "COMMIT"]
|
91
|
+
@c.qualify.sql.should == 'SELECT items.* FROM items'
|
92
|
+
@c.right_join(@c).sql.should == "SELECT * FROM items RIGHT JOIN items"
|
93
|
+
@c.right_outer_join(@c).sql.should == "SELECT * FROM items RIGHT OUTER JOIN items"
|
94
|
+
@c.select(:a).sql.should == "SELECT a FROM items"
|
95
|
+
@c.select_all(:items).sql.should == "SELECT items.* FROM items"
|
96
|
+
@c.select_append(:a).sql.should == "SELECT *, a FROM items"
|
97
|
+
@c.select_group(:a).sql.should == "SELECT a FROM items GROUP BY a"
|
98
|
+
@c.select_hash(:id, :id).should == {1=>1}
|
99
|
+
@db.sqls.should == ["SELECT id, id FROM items"]
|
100
|
+
@c.select_hash_groups(:id, :id).should == {1=>[1]}
|
101
|
+
@db.sqls.should == ["SELECT id, id FROM items"]
|
102
|
+
@c.select_map(:id).should == [1]
|
103
|
+
@db.sqls.should == ["SELECT id FROM items"]
|
104
|
+
@c.select_order_map(:id).should == [1]
|
105
|
+
@db.sqls.should == ["SELECT id FROM items ORDER BY id"]
|
106
|
+
@c.server(:a).opts[:server].should == :a
|
107
|
+
@c.set_graph_aliases(:a=>:b).opts[:graph_aliases].should == {:a=>[:b, :a]}
|
108
|
+
@c.single_record.should == @c.load(:id=>1)
|
109
|
+
@db.sqls.should == ["SELECT * FROM items LIMIT 1"]
|
110
|
+
@c.single_value.should == 1
|
111
|
+
@db.sqls.should == ["SELECT * FROM items LIMIT 1"]
|
112
|
+
@c.sum(:id).should == 1
|
113
|
+
@db.sqls.should == ["SELECT sum(id) AS sum FROM items LIMIT 1"]
|
114
|
+
@c.to_hash(:id, :id).should == {1=>1}
|
115
|
+
@db.sqls.should == ["SELECT * FROM items"]
|
116
|
+
@c.to_hash_groups(:id, :id).should == {1=>[1]}
|
117
|
+
@db.sqls.should == ["SELECT * FROM items"]
|
118
|
+
@c.truncate
|
119
|
+
@db.sqls.should == ["TRUNCATE TABLE items"]
|
120
|
+
@c.union(@d, :from_self=>false).sql.should == "SELECT * FROM items UNION SELECT * FROM items"
|
121
|
+
@c.where(:a).sql.should == "SELECT * FROM items WHERE a"
|
122
|
+
@c.with(:a, @d).sql.should == "WITH a AS (SELECT * FROM items) SELECT * FROM items"
|
123
|
+
@c.with_recursive(:a, @d, @d).sql.should == "WITH a AS (SELECT * FROM items UNION ALL SELECT * FROM items) SELECT * FROM items"
|
124
|
+
@c.with_sql('S').sql.should == "S"
|
125
|
+
|
126
|
+
sc = Class.new(@c)
|
127
|
+
sc.set_dataset(@d.where(:a).order(:a).select(:a).group(:a).limit(2))
|
128
|
+
@db.sqls
|
129
|
+
sc.invert.sql.should == 'SELECT a FROM items WHERE NOT a GROUP BY a ORDER BY a LIMIT 2'
|
130
|
+
sc.dataset._fetch = {:v1=>1, :v2=>2}
|
131
|
+
sc.range(:a).should == (1..2)
|
132
|
+
@db.sqls.should == ["SELECT min(a) AS v1, max(a) AS v2 FROM (SELECT a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2) AS t1 LIMIT 1"]
|
133
|
+
sc.reverse.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
|
134
|
+
sc.reverse_order.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
|
135
|
+
sc.select_more(:a).sql.should == 'SELECT a, a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2'
|
136
|
+
sc.unfiltered.sql.should == 'SELECT a FROM items GROUP BY a ORDER BY a LIMIT 2'
|
137
|
+
sc.ungrouped.sql.should == 'SELECT a FROM items WHERE a ORDER BY a LIMIT 2'
|
138
|
+
sc.unordered.sql.should == 'SELECT a FROM items WHERE a GROUP BY a LIMIT 2'
|
139
|
+
sc.unlimited.sql.should == 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a'
|
140
|
+
sc.dataset.graph!(:a)
|
141
|
+
sc.dataset.ungraphed.opts[:graph].should == nil
|
142
|
+
end
|
143
|
+
end
|
@@ -92,7 +92,7 @@ describe Sequel::Model::DatasetMethods do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
specify "#insert_sql should handle a single model instance as an argument" do
|
95
|
-
@c.insert_sql(@c.load(:id=>1)).should == 'INSERT INTO items (id) VALUES (1)'
|
95
|
+
@c.dataset.insert_sql(@c.load(:id=>1)).should == 'INSERT INTO items (id) VALUES (1)'
|
96
96
|
end
|
97
97
|
|
98
98
|
specify "#first should handle no primary key" do
|
@@ -7,7 +7,7 @@ describe Sequel::Model, "#eager" do
|
|
7
7
|
many_to_one :band, :class=>'EagerBand', :key=>:band_id
|
8
8
|
one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id
|
9
9
|
many_to_many :genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag
|
10
|
-
one_to_many :good_tracks, :class=>'EagerTrack', :key=>:album_id do |ds|
|
10
|
+
one_to_many :good_tracks, :class=>'EagerTrack', :reciprocal=>nil, :key=>:album_id do |ds|
|
11
11
|
ds.filter(:name=>'Good')
|
12
12
|
end
|
13
13
|
many_to_one :band_name, :class=>'EagerBand', :key=>:band_id, :select=>[:id, :name]
|
@@ -21,11 +21,11 @@ describe Sequel::Model, "#eager" do
|
|
21
21
|
|
22
22
|
class ::EagerBand < Sequel::Model(:bands)
|
23
23
|
columns :id, :p_k
|
24
|
-
one_to_many :albums, :class=>'EagerAlbum', :key=>:band_id, :eager=>:tracks
|
25
|
-
one_to_many :graph_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_graph=>:tracks
|
24
|
+
one_to_many :albums, :class=>'EagerAlbum', :key=>:band_id, :eager=>:tracks, :reciprocal=>:band
|
25
|
+
one_to_many :graph_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_graph=>:tracks, :reciprocal=>nil
|
26
26
|
many_to_many :members, :class=>'EagerBandMember', :left_key=>:band_id, :right_key=>:member_id, :join_table=>:bm
|
27
27
|
many_to_many :graph_members, :clone=>:members, :eager_graph=>:bands
|
28
|
-
one_to_many :good_albums, :class=>'EagerAlbum', :key=>:band_id, :eager_block=>proc{|ds| ds.filter(:name=>'good')} do |ds|
|
28
|
+
one_to_many :good_albums, :class=>'EagerAlbum', :key=>:band_id, :reciprocal=>nil, :eager_block=>proc{|ds| ds.filter(:name=>'good')} do |ds|
|
29
29
|
ds.filter(:name=>'Good')
|
30
30
|
end
|
31
31
|
one_to_many :self_titled_albums, :class=>'EagerAlbum', :key=>:band_id, :allow_eager=>false do |ds|
|
@@ -169,7 +169,7 @@ describe Sequel::Model, "#eager" do
|
|
169
169
|
MODEL_DB.sqls.should == []
|
170
170
|
end
|
171
171
|
|
172
|
-
|
172
|
+
qspecify "should eagerly load a single one_to_one association using the :correlated_subquery strategy" do
|
173
173
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name
|
174
174
|
a = EagerAlbum.eager(:track).all
|
175
175
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -178,7 +178,7 @@ describe Sequel::Model, "#eager" do
|
|
178
178
|
MODEL_DB.sqls.should == []
|
179
179
|
end
|
180
180
|
|
181
|
-
|
181
|
+
qspecify "should handle qualified order clauses when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
|
182
182
|
EagerAlbum.one_to_one :track, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>[:tracks__name, Sequel.desc(:tracks__name), Sequel.qualify(:tracks, :name), Sequel.qualify(:t, :name), 1]
|
183
183
|
a = EagerAlbum.eager(:track).all
|
184
184
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -187,7 +187,7 @@ describe Sequel::Model, "#eager" do
|
|
187
187
|
MODEL_DB.sqls.should == []
|
188
188
|
end
|
189
189
|
|
190
|
-
|
190
|
+
qspecify "should handle qualified composite keys when eagerly loading a single one_to_one association using the :correlated_subquery strategy" do
|
191
191
|
c1 = Class.new(EagerAlbum)
|
192
192
|
c2 = Class.new(EagerTrack)
|
193
193
|
c1.set_primary_key [:id, :band_id]
|
@@ -228,7 +228,7 @@ describe Sequel::Model, "#eager" do
|
|
228
228
|
end
|
229
229
|
|
230
230
|
it "should support using a custom :primary_key option when eager loading one_to_many associations" do
|
231
|
-
EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil
|
231
|
+
EagerBand.one_to_many :salbums, :clone=>:albums, :primary_key=>:id3, :eager=>nil, :reciprocal=>nil
|
232
232
|
EagerBand.dataset._fetch = {:id=>6}
|
233
233
|
a = EagerBand.eager(:salbums).all
|
234
234
|
MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE (albums.band_id IN (2))']
|
@@ -258,7 +258,7 @@ describe Sequel::Model, "#eager" do
|
|
258
258
|
end
|
259
259
|
|
260
260
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
|
261
|
-
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil
|
261
|
+
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
|
262
262
|
EagerBand.dataset._fetch = {:id=>6}
|
263
263
|
a = EagerBand.eager(:salbums).all
|
264
264
|
MODEL_DB.sqls.should == ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
|
@@ -501,7 +501,7 @@ describe Sequel::Model, "#eager" do
|
|
501
501
|
as.length.should == 1
|
502
502
|
as.first.special_band.should == EagerBand.load(:p_k=>2, :id=>1)
|
503
503
|
|
504
|
-
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id
|
504
|
+
EagerAlbum.one_to_many :special_tracks, :class=>:EagerTrack, :primary_key=>:band_id, :key=>:album_id, :reciprocal=>nil
|
505
505
|
EagerTrack.dataset._fetch = {:album_id=>2, :id=>1}
|
506
506
|
as = EagerAlbum.eager(:special_tracks).all
|
507
507
|
MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT * FROM tracks WHERE (tracks.album_id IN (2))"]
|
@@ -581,7 +581,7 @@ describe Sequel::Model, "#eager" do
|
|
581
581
|
MODEL_DB.sqls.should == []
|
582
582
|
end
|
583
583
|
|
584
|
-
|
584
|
+
qspecify "should respect the :limit option on a one_to_many association using the :correlated_subquery strategy" do
|
585
585
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>2
|
586
586
|
a = EagerAlbum.eager(:tracks).all
|
587
587
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -590,7 +590,7 @@ describe Sequel::Model, "#eager" do
|
|
590
590
|
MODEL_DB.sqls.should == []
|
591
591
|
end
|
592
592
|
|
593
|
-
|
593
|
+
qspecify "should respect the :limit option with an offset on a one_to_many association using the :correlated_subquery strategy" do
|
594
594
|
EagerAlbum.one_to_many :tracks, :class=>'EagerTrack', :key=>:album_id, :eager_limit_strategy=>:correlated_subquery, :order=>:name, :limit=>[2, 1]
|
595
595
|
a = EagerAlbum.eager(:tracks).all
|
596
596
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -632,7 +632,7 @@ describe Sequel::Model, "#eager" do
|
|
632
632
|
as.first.first_two_genres.should == [EagerGenre.load(:id=>5), EagerGenre.load(:id=>6)]
|
633
633
|
end
|
634
634
|
|
635
|
-
|
635
|
+
qspecify "should respect the limit option on a many_to_many association using the :correlated_subquery strategy" do
|
636
636
|
EagerAlbum.many_to_many :first_two_genres, :class=>:EagerGenre, :left_primary_key=>:band_id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :eager_limit_strategy=>:correlated_subquery, :limit=>2, :order=>:name
|
637
637
|
EagerGenre.dataset._fetch = [{:x_foreign_key_x=>2, :id=>5}, {:x_foreign_key_x=>2, :id=>6}]
|
638
638
|
as = EagerAlbum.eager(:first_two_genres).all
|
@@ -649,17 +649,17 @@ describe Sequel::Model, "#eager" do
|
|
649
649
|
end
|
650
650
|
|
651
651
|
it "should use the :eager_loader association option when eager loading" do
|
652
|
-
EagerAlbum.many_to_one :special_band, :key=>:band_id, :eager_loader=>(proc do |
|
653
|
-
item = EagerBand.filter(:album_id=>
|
654
|
-
|
652
|
+
EagerAlbum.many_to_one :special_band, :key=>:band_id, :eager_loader=>(proc do |eo|
|
653
|
+
item = EagerBand.filter(:album_id=>eo[:rows].collect{|r| [r.pk, r.pk*2]}.flatten).order(:name).first
|
654
|
+
eo[:rows].each{|r| r.associations[:special_band] = item}
|
655
655
|
end)
|
656
656
|
EagerAlbum.one_to_many :special_tracks, :eager_loader=>(proc do |eo|
|
657
657
|
items = EagerTrack.filter(:album_id=>eo[:rows].collect{|r| [r.pk, r.pk*2]}.flatten).all
|
658
658
|
eo[:rows].each{|r| r.associations[:special_tracks] = items}
|
659
659
|
end)
|
660
|
-
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :eager_loader=>(proc do |
|
661
|
-
items = EagerGenre.inner_join(:ag, [:genre_id]).filter(:album_id=>
|
662
|
-
|
660
|
+
EagerAlbum.many_to_many :special_genres, :class=>:EagerGenre, :eager_loader=>(proc do |eo|
|
661
|
+
items = EagerGenre.inner_join(:ag, [:genre_id]).filter(:album_id=>eo[:rows].collect{|r| r.pk}).all
|
662
|
+
eo[:rows].each{|r| r.associations[:special_genres] = items}
|
663
663
|
end)
|
664
664
|
a = EagerAlbum.eager(:special_genres, :special_tracks, :special_band).all
|
665
665
|
a.should == [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -1166,7 +1166,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1166
1166
|
as.should == [GraphAlbum.load(:id=>3, :band_id=>2)]
|
1167
1167
|
as.first.inner_band.should == GraphBand.load(:id=>5, :vocalist_id=>2)
|
1168
1168
|
|
1169
|
-
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id
|
1169
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :primary_key=>:band_id, :reciprocal=>nil
|
1170
1170
|
ds = GraphAlbum.eager_graph(:right_tracks)
|
1171
1171
|
ds.sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON (right_tracks.album_id = albums.band_id)'
|
1172
1172
|
ds._fetch = [{:id=>3, :band_id=>2, :right_tracks_id=>5, :album_id=>2}, {:id=>3, :band_id=>2, :right_tracks_id=>6, :album_id=>2}]
|
@@ -1276,7 +1276,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1276
1276
|
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :conditions=>{:active=>true}
|
1277
1277
|
GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums LEFT OUTER JOIN bands AS active_band ON ((active_band.id = albums.band_id) AND (active_band.active IS TRUE))"
|
1278
1278
|
|
1279
|
-
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}
|
1279
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :conditions=>{:id=>(0..100)}, :reciprocal=>nil
|
1280
1280
|
GraphAlbum.eager_graph(:right_tracks).sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums LEFT OUTER JOIN tracks AS right_tracks ON ((right_tracks.album_id = albums.id) AND (right_tracks.id >= 0) AND (right_tracks.id <= 100))'
|
1281
1281
|
|
1282
1282
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :conditions=>{true=>:active}
|
@@ -1322,13 +1322,13 @@ describe Sequel::Model, "#eager_graph" do
|
|
1322
1322
|
end
|
1323
1323
|
|
1324
1324
|
it "should respect the association's :eager_grapher option" do
|
1325
|
-
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|
|
1325
|
+
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphBand, {:active=>true}, :table_alias=>eo[:table_alias], :join_type=>:inner)}
|
1326
1326
|
GraphAlbum.eager_graph(:active_band).sql.should == "SELECT albums.id, albums.band_id, active_band.id AS active_band_id, active_band.vocalist_id FROM albums INNER JOIN bands AS active_band ON (active_band.active IS TRUE)"
|
1327
1327
|
|
1328
1328
|
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphTrack, nil, :join_type=>:natural, :table_alias=>eo[:table_alias])}
|
1329
1329
|
GraphAlbum.eager_graph(:right_tracks).sql.should == 'SELECT albums.id, albums.band_id, right_tracks.id AS right_tracks_id, right_tracks.album_id FROM albums NATURAL JOIN tracks AS right_tracks'
|
1330
1330
|
|
1331
|
-
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :eager_grapher=>proc{|
|
1331
|
+
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :eager_grapher=>proc{|eo| eo[:self].graph(:ag, {:album_id=>:id}, :table_alias=>:a123, :implicit_qualifier=>eo[:implicit_qualifier]).graph(GraphGenre, [:album_id], :table_alias=>eo[:table_alias])}
|
1332
1332
|
GraphAlbum.eager_graph(:active_genres).sql.should == "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag AS a123 ON (a123.album_id = albums.id) LEFT OUTER JOIN genres AS active_genres USING (album_id)"
|
1333
1333
|
end
|
1334
1334
|
|
@@ -1380,7 +1380,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1380
1380
|
end
|
1381
1381
|
|
1382
1382
|
it "should add the association's :order for cascading associations" do
|
1383
|
-
GraphBand.one_to_many :a_albums, :class=>'GraphAlbum', :key=>:band_id, :order=>:name
|
1383
|
+
GraphBand.one_to_many :a_albums, :class=>'GraphAlbum', :key=>:band_id, :order=>:name, :reciprocal=>nil
|
1384
1384
|
GraphAlbum.one_to_many :b_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[:id, :album_id]
|
1385
1385
|
GraphBand.eager_graph(:a_albums=>:b_tracks).sql.should == 'SELECT bands.id, bands.vocalist_id, a_albums.id AS a_albums_id, a_albums.band_id, b_tracks.id AS b_tracks_id, b_tracks.album_id FROM bands LEFT OUTER JOIN albums AS a_albums ON (a_albums.band_id = bands.id) LEFT OUTER JOIN tracks AS b_tracks ON (b_tracks.album_id = a_albums.id) ORDER BY a_albums.name, b_tracks.id, b_tracks.album_id'
|
1386
1386
|
GraphAlbum.one_to_many :albums, :class=>'GraphAlbum', :key=>:band_id, :order=>[:band_id, :id]
|
@@ -1417,7 +1417,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1417
1417
|
GraphAlbum.eager_graph(:band).join(:s__genres, [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1418
1418
|
GraphAlbum.eager_graph(:band).join(Sequel.qualify(:s, :genres), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1419
1419
|
GraphAlbum.eager_graph(:band).join(Sequel.expr(:s__b).as('genres'), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1420
|
-
GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], Sequel.identifier(:genres)).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1420
|
+
GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN s.b AS genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1421
1421
|
GraphAlbum.eager_graph(:band).join(Sequel.identifier(:genres), [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1422
1422
|
GraphAlbum.eager_graph(:band).join('genres', [:b_id]).eager_graph(:genres).sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id, genres_0.id AS genres_0_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) INNER JOIN genres USING (b_id) LEFT OUTER JOIN ag ON (ag.album_id = albums.id) LEFT OUTER JOIN genres AS genres_0 ON (genres_0.id = ag.genre_id)'
|
1423
1423
|
end
|
data/spec/model/hooks_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
3
|
describe "Model#after_initialize" do
|
4
|
-
|
4
|
+
qspecify "should be called after initialization for both new object and objects retrieved from the database" do
|
5
5
|
|
6
6
|
a = Class.new(Sequel::Model) do
|
7
7
|
self::Foo = []
|
data/spec/model/model_spec.rb
CHANGED
@@ -55,7 +55,7 @@ describe "Sequel::Model()" do
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should return a model subclass associated to the given database if given a database" do
|
58
|
-
db = Sequel
|
58
|
+
db = Sequel.mock
|
59
59
|
c = Sequel::Model(db)
|
60
60
|
c.superclass.should == Sequel::Model
|
61
61
|
c.db.should == db
|
@@ -68,10 +68,10 @@ describe "Sequel::Model()" do
|
|
68
68
|
|
69
69
|
describe "reloading" do
|
70
70
|
before do
|
71
|
-
Sequel
|
71
|
+
Sequel.cache_anonymous_models = true
|
72
72
|
end
|
73
73
|
after do
|
74
|
-
Sequel
|
74
|
+
Sequel.cache_anonymous_models = false
|
75
75
|
Object.send(:remove_const, :Album) if defined?(::Album)
|
76
76
|
end
|
77
77
|
|
@@ -132,7 +132,7 @@ describe "Sequel::Model()" do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
it "should raise an exception if anonymous model caching is disabled" do
|
135
|
-
Sequel
|
135
|
+
Sequel.cache_anonymous_models = false
|
136
136
|
proc do
|
137
137
|
class ::Album < Sequel::Model(@db[Sequel.identifier(:table)]); end
|
138
138
|
class ::Album < Sequel::Model(@db[Sequel.identifier(:table)]); end
|
@@ -308,7 +308,7 @@ describe Sequel::Model, "constructors" do
|
|
308
308
|
end
|
309
309
|
|
310
310
|
it "should have dataset row_proc create an existing object" do
|
311
|
-
@m.dataset = Sequel
|
311
|
+
@m.dataset = Sequel.mock.dataset
|
312
312
|
o = @m.dataset.row_proc.call(:a=>1)
|
313
313
|
o.should be_a_kind_of(@m)
|
314
314
|
o.values.should == {:a=>1}
|
@@ -329,7 +329,7 @@ describe Sequel::Model, "constructors" do
|
|
329
329
|
o.new?.should be_false
|
330
330
|
end
|
331
331
|
|
332
|
-
|
332
|
+
qspecify "should have .new with a second true argument create an existing object" do
|
333
333
|
o = @m.new({:a=>1}, true)
|
334
334
|
o.should be_a_kind_of(@m)
|
335
335
|
o.values.should == {:a=>1}
|
@@ -520,6 +520,7 @@ end
|
|
520
520
|
describe Sequel::Model, "attribute accessors" do
|
521
521
|
before do
|
522
522
|
db = Sequel.mock
|
523
|
+
def db.supports_schema_parsing?() true end
|
523
524
|
def db.schema(*)
|
524
525
|
[[:x, {:type=>:integer}], [:z, {:type=>:integer}]]
|
525
526
|
end
|
@@ -616,7 +617,7 @@ describe Sequel::Model, ".[]" do
|
|
616
617
|
sqls.first.should =~ /^SELECT \* FROM items WHERE \((\(node_id = 3921\) AND \(kind = 201\))|(\(kind = 201\) AND \(node_id = 3921\))\) LIMIT 1$/
|
617
618
|
end
|
618
619
|
|
619
|
-
|
620
|
+
qspecify "should work correctly for composite primary key specified as separate arguments" do
|
620
621
|
@c.set_primary_key :node_id, :kind
|
621
622
|
@c[3921, 201].should be_a_kind_of(@c)
|
622
623
|
sqls = MODEL_DB.sqls
|
@@ -637,9 +638,23 @@ describe "Model.db_schema" do
|
|
637
638
|
def self.columns; orig_columns; end
|
638
639
|
end
|
639
640
|
@db = Sequel.mock
|
641
|
+
def @db.supports_schema_parsing?() true end
|
640
642
|
@dataset = @db[:items]
|
641
643
|
end
|
642
644
|
|
645
|
+
specify "should not call database's schema if it isn't supported" do
|
646
|
+
def @db.supports_schema_parsing?() false end
|
647
|
+
def @db.schema(table, opts = {})
|
648
|
+
raise Sequel::Error
|
649
|
+
end
|
650
|
+
@dataset.instance_variable_set(:@columns, [:x, :y])
|
651
|
+
|
652
|
+
@c.dataset = @dataset
|
653
|
+
@c.db_schema.should == {:x=>{}, :y=>{}}
|
654
|
+
@c.columns.should == [:x, :y]
|
655
|
+
@c.dataset.instance_variable_get(:@columns).should == [:x, :y]
|
656
|
+
end
|
657
|
+
|
643
658
|
specify "should use the database's schema and set the columns and dataset columns" do
|
644
659
|
def @db.schema(table, opts = {})
|
645
660
|
[[:x, {:type=>:integer}], [:y, {:type=>:string}]]
|