sequel 3.47.0 → 3.48.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.
- 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}]]
|