sequel 3.36.1 → 3.37.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +84 -0
- data/Rakefile +13 -0
- data/bin/sequel +12 -16
- data/doc/advanced_associations.rdoc +36 -67
- data/doc/association_basics.rdoc +11 -16
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/schema_modification.rdoc +4 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +26 -8
- data/lib/sequel/adapters/mysql2.rb +4 -3
- data/lib/sequel/adapters/odbc/mssql.rb +2 -2
- data/lib/sequel/adapters/postgres.rb +4 -60
- data/lib/sequel/adapters/shared/mssql.rb +2 -1
- data/lib/sequel/adapters/shared/mysql.rb +0 -5
- data/lib/sequel/adapters/shared/postgres.rb +68 -2
- data/lib/sequel/adapters/shared/sqlite.rb +17 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +12 -1
- data/lib/sequel/adapters/utils/pg_types.rb +76 -0
- data/lib/sequel/core.rb +13 -0
- data/lib/sequel/database/misc.rb +41 -1
- data/lib/sequel/database/schema_generator.rb +23 -10
- data/lib/sequel/database/schema_methods.rb +26 -4
- data/lib/sequel/dataset/graph.rb +2 -1
- data/lib/sequel/dataset/query.rb +62 -2
- data/lib/sequel/extensions/_pretty_table.rb +7 -3
- data/lib/sequel/extensions/arbitrary_servers.rb +5 -4
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +13 -2
- data/lib/sequel/extensions/core_extensions.rb +6 -0
- data/lib/sequel/extensions/eval_inspect.rb +158 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +4 -1
- data/lib/sequel/extensions/named_timezones.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +4 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +219 -168
- data/lib/sequel/extensions/pg_array_ops.rb +7 -2
- data/lib/sequel/extensions/pg_auto_parameterize.rb +10 -4
- data/lib/sequel/extensions/pg_hstore.rb +3 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +7 -2
- data/lib/sequel/extensions/pg_inet.rb +28 -3
- data/lib/sequel/extensions/pg_interval.rb +192 -0
- data/lib/sequel/extensions/pg_json.rb +21 -9
- data/lib/sequel/extensions/pg_range.rb +487 -0
- data/lib/sequel/extensions/pg_range_ops.rb +122 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +3 -2
- data/lib/sequel/extensions/pretty_table.rb +12 -1
- data/lib/sequel/extensions/query.rb +4 -0
- data/lib/sequel/extensions/query_literals.rb +6 -6
- data/lib/sequel/extensions/schema_dumper.rb +39 -38
- data/lib/sequel/extensions/select_remove.rb +4 -0
- data/lib/sequel/extensions/server_block.rb +3 -2
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -0
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +9 -3
- data/lib/sequel/extensions/to_dot.rb +4 -0
- data/lib/sequel/model/associations.rb +150 -91
- data/lib/sequel/plugins/identity_map.rb +2 -2
- data/lib/sequel/plugins/list.rb +1 -0
- data/lib/sequel/plugins/many_through_many.rb +33 -32
- data/lib/sequel/plugins/nested_attributes.rb +11 -3
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/sql.rb +14 -14
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/mysql_spec.rb +25 -0
- data/spec/adapters/postgres_spec.rb +572 -28
- data/spec/adapters/sqlite_spec.rb +16 -1
- data/spec/core/database_spec.rb +61 -2
- data/spec/core/dataset_spec.rb +92 -0
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/eval_inspect_spec.rb +58 -0
- data/spec/extensions/json_serializer_spec.rb +0 -6
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +81 -0
- data/spec/extensions/nested_attributes_spec.rb +21 -4
- data/spec/extensions/pg_array_ops_spec.rb +1 -11
- data/spec/extensions/pg_array_spec.rb +181 -90
- data/spec/extensions/pg_auto_parameterize_spec.rb +3 -3
- data/spec/extensions/pg_hstore_spec.rb +1 -3
- data/spec/extensions/pg_inet_spec.rb +6 -1
- data/spec/extensions/pg_interval_spec.rb +73 -0
- data/spec/extensions/pg_json_spec.rb +5 -9
- data/spec/extensions/pg_range_ops_spec.rb +49 -0
- data/spec/extensions/pg_range_spec.rb +372 -0
- data/spec/extensions/pg_statement_cache_spec.rb +1 -2
- data/spec/extensions/query_literals_spec.rb +1 -2
- data/spec/extensions/schema_dumper_spec.rb +48 -89
- data/spec/extensions/serialization_spec.rb +1 -5
- data/spec/extensions/server_block_spec.rb +2 -2
- data/spec/extensions/spec_helper.rb +12 -2
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/integration/associations_test.rb +4 -4
- data/spec/integration/database_test.rb +2 -2
- data/spec/integration/dataset_test.rb +4 -4
- data/spec/integration/eager_loader_test.rb +6 -6
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +2 -2
- data/spec/model/association_reflection_spec.rb +5 -0
- data/spec/model/associations_spec.rb +156 -49
- data/spec/model/eager_loading_spec.rb +137 -2
- data/spec/model/model_spec.rb +10 -10
- metadata +15 -2
@@ -887,11 +887,11 @@ describe "Sequel::Model Associations with clashing column names" do
|
|
887
887
|
@Bar = Class.new(Sequel::Model(:bars))
|
888
888
|
@Foo.def_column_alias(:obj_id, :object_id)
|
889
889
|
@Bar.def_column_alias(:obj_id, :object_id)
|
890
|
-
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :
|
891
|
-
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :
|
890
|
+
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
891
|
+
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
892
892
|
@Bar.many_to_one :foo, :key=>:obj_id, :key_column=>:object_id, :primary_key=>:object_id, :primary_key_method=>:obj_id, :class=>@Foo
|
893
|
-
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:foo_id, :right_key=>:object_id, :
|
894
|
-
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:object_id, :right_key=>:foo_id, :
|
893
|
+
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:foo_id, :right_key=>:object_id, :class=>@Bar
|
894
|
+
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:object_id, :right_key=>:foo_id, :class=>@Foo
|
895
895
|
@foo = @Foo.create(:obj_id=>2)
|
896
896
|
@bar = @Bar.create(:obj_id=>2)
|
897
897
|
@Foo.db[:bars_foos].insert(2, 2)
|
@@ -2,10 +2,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
2
|
|
3
3
|
describe Sequel::Database do
|
4
4
|
specify "should provide disconnect functionality" do
|
5
|
-
INTEGRATION_DB.test_connection
|
6
|
-
INTEGRATION_DB.pool.size.should == 1
|
7
5
|
INTEGRATION_DB.disconnect
|
8
6
|
INTEGRATION_DB.pool.size.should == 0
|
7
|
+
INTEGRATION_DB.test_connection
|
8
|
+
INTEGRATION_DB.pool.size.should == 1
|
9
9
|
end
|
10
10
|
|
11
11
|
specify "should provide disconnect functionality after preparing a statement" do
|
@@ -150,7 +150,7 @@ describe "Simple Dataset operations" do
|
|
150
150
|
@db.drop_table(:items2)
|
151
151
|
end
|
152
152
|
|
153
|
-
|
153
|
+
specify "should fetch correctly with a limit and offset without an order" do
|
154
154
|
@ds.limit(2, 1).all.should == []
|
155
155
|
end
|
156
156
|
|
@@ -301,11 +301,11 @@ describe Sequel::Database do
|
|
301
301
|
"\\'dingo",
|
302
302
|
"\\\\''dingo",
|
303
303
|
].each do |str|
|
304
|
-
INTEGRATION_DB.get(str.
|
304
|
+
INTEGRATION_DB.get(str.cast(String)).should == str
|
305
305
|
str = "1#{str}1"
|
306
|
-
INTEGRATION_DB.get(str.
|
306
|
+
INTEGRATION_DB.get(str.cast(String)).should == str
|
307
307
|
str = "#{str}#{str}"
|
308
|
-
INTEGRATION_DB.get(str.
|
308
|
+
INTEGRATION_DB.get(str.cast(String)).should == str
|
309
309
|
end
|
310
310
|
end
|
311
311
|
|
@@ -12,7 +12,7 @@ describe "Eagerly loading a tree structure" do
|
|
12
12
|
one_to_many :children, :key=>:parent_id
|
13
13
|
|
14
14
|
# Only useful when eager loading
|
15
|
-
many_to_one :ancestors, :eager_loader=>(proc do |eo|
|
15
|
+
many_to_one :ancestors, :eager_loader_key=>nil, :eager_loader=>(proc do |eo|
|
16
16
|
# Handle cases where the root node has the same parent_id as primary_key
|
17
17
|
# and also when it is NULL
|
18
18
|
non_root_nodes = eo[:rows].reject do |n|
|
@@ -36,7 +36,7 @@ describe "Eagerly loading a tree structure" do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end)
|
39
|
-
many_to_one :descendants, :eager_loader=>(proc do |eo|
|
39
|
+
many_to_one :descendants, :eager_loader_key=>nil, :eager_loader=>(proc do |eo|
|
40
40
|
id_map = {}
|
41
41
|
eo[:rows].each do |n|
|
42
42
|
# Initialize an empty array of child associations for each parent node
|
@@ -185,7 +185,7 @@ describe "has_many :through has_many and has_one :through belongs_to" do
|
|
185
185
|
end
|
186
186
|
end), \
|
187
187
|
:eager_loader=>(proc do |eo|
|
188
|
-
id_map = eo[:
|
188
|
+
id_map = eo[:id_map]
|
189
189
|
eo[:rows].each{|firm| firm.associations[:invoices] = []}
|
190
190
|
Invoice.eager_graph(:client).filter(:client__firm_id=>id_map.keys).all do |inv|
|
191
191
|
id_map[inv.client.firm_id].each do |firm|
|
@@ -526,7 +526,7 @@ describe "many_to_one/one_to_many not referencing primary key" do
|
|
526
526
|
many_to_one :client, :key=>:client_name, \
|
527
527
|
:dataset=>proc{Client.filter(:name=>client_name)}, \
|
528
528
|
:eager_loader=>(proc do |eo|
|
529
|
-
id_map = eo[:
|
529
|
+
id_map = eo[:id_map]
|
530
530
|
eo[:rows].each{|inv| inv.associations[:client] = nil}
|
531
531
|
Client.filter(:name=>id_map.keys).all do |client|
|
532
532
|
id_map[client.name].each{|inv| inv.associations[:client] = client}
|
@@ -629,11 +629,11 @@ describe "statistics associations" do
|
|
629
629
|
:dataset=>proc{Ticket.filter(:project_id=>id).select{sum(hours).as(hours)}},
|
630
630
|
:eager_loader=>(proc do |eo|
|
631
631
|
eo[:rows].each{|p| p.associations[:ticket_hours] = nil}
|
632
|
-
Ticket.filter(:project_id=>eo[:
|
632
|
+
Ticket.filter(:project_id=>eo[:id_map].keys).
|
633
633
|
group(:project_id).
|
634
634
|
select{[project_id.as(project_id), sum(hours).as(hours)]}.
|
635
635
|
all do |t|
|
636
|
-
p = eo[:
|
636
|
+
p = eo[:id_map][t.values.delete(:project_id)].first
|
637
637
|
p.associations[:ticket_hours] = t
|
638
638
|
end
|
639
639
|
end)
|
@@ -100,7 +100,7 @@ describe "Class Table Inheritance Plugin" do
|
|
100
100
|
Employee.filter(:id=>@i2).all.first.manager.id.should == @i4
|
101
101
|
end
|
102
102
|
|
103
|
-
cspecify "should insert rows into all tables", [
|
103
|
+
cspecify "should insert rows into all tables", [proc{|db| db.sqlite_version < 30709}, :sqlite] do
|
104
104
|
e = Executive.create(:name=>'Ex2', :num_managers=>8, :num_staff=>9)
|
105
105
|
i = e.id
|
106
106
|
@db[:employees][:id=>i].should == {:id=>i, :name=>'Ex2', :kind=>'Executive'}
|
@@ -139,7 +139,7 @@ describe "Class Table Inheritance Plugin" do
|
|
139
139
|
Executive.limit(1).eager(:staff_members).first.staff_members.should == [Staff[@i2]]
|
140
140
|
end
|
141
141
|
|
142
|
-
cspecify "should handle eagerly graphing one_to_many relationships", [
|
142
|
+
cspecify "should handle eagerly graphing one_to_many relationships", [proc{|db| db.sqlite_version < 30709}, :sqlite] do
|
143
143
|
es = Executive.limit(1).eager_graph(:staff_members).all
|
144
144
|
es.should == [Executive[@i4]]
|
145
145
|
es.map{|x| x.staff_members}.should == [[Staff[@i2]]]
|
@@ -42,7 +42,7 @@ def Sequel.guarded?(*checked)
|
|
42
42
|
return c if c.first == INTEGRATION_DB.adapter_scheme
|
43
43
|
when 2
|
44
44
|
if c.first.is_a?(Proc)
|
45
|
-
return c if c.
|
45
|
+
return c if c.last == INTEGRATION_DB.database_type && c.first.call(INTEGRATION_DB)
|
46
46
|
elsif c.last.is_a?(Proc)
|
47
47
|
return c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
|
48
48
|
else
|
@@ -69,7 +69,7 @@ end
|
|
69
69
|
|
70
70
|
def self.cspecify(message, *checked, &block)
|
71
71
|
if pending = Sequel.guarded?(*checked)
|
72
|
-
specify(message){pending("Not yet working on #{Array(pending).join(', ')}", &block)}
|
72
|
+
specify(message){pending("Not yet working on #{Array(pending).map{|x| x.is_a?(Proc) ? :proc : x}.join(', ')}", &block)}
|
73
73
|
else
|
74
74
|
specify(message, &block)
|
75
75
|
end
|
@@ -193,6 +193,11 @@ describe Sequel::Model::Associations::AssociationReflection do
|
|
193
193
|
@c.meta_def(:name){"C"}
|
194
194
|
end
|
195
195
|
|
196
|
+
it "#eager_loading_predicate_key should be an alias of predicate_key for backwards compatibility" do
|
197
|
+
@c.one_to_many :cs, :class=>@c
|
198
|
+
@c.dataset.literal(@c.association_reflection(:cs).eager_loading_predicate_key).should == 'foo.c_id'
|
199
|
+
end
|
200
|
+
|
196
201
|
it "one_to_many #qualified_primary_key should be a qualified version of the primary key" do
|
197
202
|
@c.one_to_many :cs, :class=>@c
|
198
203
|
@c.dataset.literal(@c.association_reflection(:cs).qualified_primary_key).should == 'foo.id'
|
@@ -125,6 +125,18 @@ describe Sequel::Model, "associate" do
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
+
it "should raise an error if attempting to clone an association of differing type" do
|
129
|
+
c = Class.new(Sequel::Model(:c))
|
130
|
+
c.many_to_one :c
|
131
|
+
proc{c.one_to_many :cs, :clone=>:c}.should raise_error(Sequel::Error)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should allow cloning of one_to_many to one_to_one associations and vice-versa" do
|
135
|
+
c = Class.new(Sequel::Model(:c))
|
136
|
+
c.one_to_one :c
|
137
|
+
proc{c.one_to_many :cs, :clone=>:c}.should_not raise_error(Sequel::Error)
|
138
|
+
proc{c.one_to_one :c2, :clone=>:cs}.should_not raise_error(Sequel::Error)
|
139
|
+
end
|
128
140
|
end
|
129
141
|
|
130
142
|
describe Sequel::Model, "many_to_one" do
|
@@ -672,7 +684,7 @@ describe Sequel::Model, "one_to_one" do
|
|
672
684
|
sqls = MODEL_DB.sqls
|
673
685
|
['INSERT INTO attributes (node_id, id) VALUES (1234, 3)',
|
674
686
|
'INSERT INTO attributes (id, node_id) VALUES (3, 1234)'].should(include(sqls.slice! 1))
|
675
|
-
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (
|
687
|
+
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
676
688
|
|
677
689
|
@c2.new(:id => 1234).attribute.should == attrib
|
678
690
|
attrib = @c1.load(:id=>3)
|
@@ -711,7 +723,7 @@ describe Sequel::Model, "one_to_one" do
|
|
711
723
|
sqls = MODEL_DB.sqls
|
712
724
|
['INSERT INTO attributes (node_id, id) VALUES (5, 3)',
|
713
725
|
'INSERT INTO attributes (id, node_id) VALUES (3, 5)'].should(include(sqls.slice! 1))
|
714
|
-
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (
|
726
|
+
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 5)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
715
727
|
|
716
728
|
@c2.new(:id => 321, :xxx=>5).attribute.should == attrib
|
717
729
|
attrib = @c1.load(:id=>3)
|
@@ -845,38 +857,6 @@ describe Sequel::Model, "one_to_one" do
|
|
845
857
|
MODEL_DB.sqls.should == []
|
846
858
|
end
|
847
859
|
|
848
|
-
it "should define a setter method" do
|
849
|
-
@c2.one_to_one :parent, :class => @c2
|
850
|
-
|
851
|
-
d = @c2.new(:id => 1)
|
852
|
-
f = @c2.new(:id => 3, :node_id=> 4321)
|
853
|
-
@c2.dataset._fetch = @c2.instance_dataset._fetch = {:id => 3, :node_id=>1}
|
854
|
-
d.parent = f
|
855
|
-
f.values.should == {:id => 3, :node_id=>1}
|
856
|
-
d.parent.should == f
|
857
|
-
sqls = MODEL_DB.sqls
|
858
|
-
["INSERT INTO nodes (node_id, id) VALUES (1, 3)",
|
859
|
-
"INSERT INTO nodes (id, node_id) VALUES (3, 1)"].should include(sqls.slice! 1)
|
860
|
-
sqls.should == ["UPDATE nodes SET node_id = NULL WHERE ((node_id = 1) AND (id != 3))", "SELECT * FROM nodes WHERE (id = 3) LIMIT 1"]
|
861
|
-
|
862
|
-
d.parent = nil
|
863
|
-
d.parent.should == nil
|
864
|
-
MODEL_DB.sqls.should == ["UPDATE nodes SET node_id = NULL WHERE (node_id = 1)"]
|
865
|
-
end
|
866
|
-
|
867
|
-
it "should have the setter method respect the :primary_key option" do
|
868
|
-
@c2.one_to_one :parent, :class => @c2, :primary_key=>:blah
|
869
|
-
d = @c2.new(:id => 1, :blah => 3)
|
870
|
-
e = @c2.new(:id => 4321, :node_id=>444)
|
871
|
-
@c2.dataset._fetch = @c2.instance_dataset._fetch = {:id => 4321, :node_id => 3}
|
872
|
-
d.parent = e
|
873
|
-
e.values.should == {:id => 4321, :node_id => 3}
|
874
|
-
sqls = MODEL_DB.sqls
|
875
|
-
["INSERT INTO nodes (node_id, id) VALUES (3, 4321)",
|
876
|
-
"INSERT INTO nodes (id, node_id) VALUES (4321, 3)"].should include(sqls.slice! 1)
|
877
|
-
sqls.should == ["UPDATE nodes SET node_id = NULL WHERE ((node_id = 3) AND (id != 4321))", "SELECT * FROM nodes WHERE (id = 4321) LIMIT 1"]
|
878
|
-
end
|
879
|
-
|
880
860
|
it "should have the setter method respect the :key option" do
|
881
861
|
@c2.one_to_one :parent, :class => @c2, :key=>:blah
|
882
862
|
d = @c2.new(:id => 3)
|
@@ -887,7 +867,7 @@ describe Sequel::Model, "one_to_one" do
|
|
887
867
|
sqls = MODEL_DB.sqls
|
888
868
|
["INSERT INTO nodes (blah, id) VALUES (3, 4321)",
|
889
869
|
"INSERT INTO nodes (id, blah) VALUES (4321, 3)"].should include(sqls.slice! 1)
|
890
|
-
sqls.should == ["UPDATE nodes SET blah = NULL WHERE (
|
870
|
+
sqls.should == ["UPDATE nodes SET blah = NULL WHERE (blah = 3)", "SELECT * FROM nodes WHERE (id = 4321) LIMIT 1"]
|
891
871
|
end
|
892
872
|
|
893
873
|
it "should persist changes to associated object when the setter is called" do
|
@@ -1796,7 +1776,7 @@ describe Sequel::Model, "many_to_many" do
|
|
1796
1776
|
attr_accessor :yyy
|
1797
1777
|
def self.name; 'Attribute'; end
|
1798
1778
|
def self.to_s; 'Attribute'; end
|
1799
|
-
columns :id, :y
|
1779
|
+
columns :id, :y, :z
|
1800
1780
|
end
|
1801
1781
|
|
1802
1782
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
@@ -1841,6 +1821,11 @@ describe Sequel::Model, "many_to_many" do
|
|
1841
1821
|
end
|
1842
1822
|
end
|
1843
1823
|
|
1824
|
+
it "should respect :eager_loader_predicate_key when lazily loading" do
|
1825
|
+
@c2.many_to_many :attributes, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(:attributes_nodes__node_id, 0)
|
1826
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id[0] = 1234))'
|
1827
|
+
end
|
1828
|
+
|
1844
1829
|
it "should use explicit key values and join table if given" do
|
1845
1830
|
@c2.many_to_many :attributes, :class => @c1, :left_key => :nodeid, :right_key => :attributeid, :join_table => :attribute2node
|
1846
1831
|
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attribute2node ON ((attribute2node.attributeid = attributes.id) AND (attribute2node.nodeid = 1234))'
|
@@ -2058,9 +2043,9 @@ describe Sequel::Model, "many_to_many" do
|
|
2058
2043
|
end
|
2059
2044
|
|
2060
2045
|
it "should have the add_ method respect composite keys" do
|
2061
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
2046
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
2062
2047
|
n = @c2.load(:id => 1234, :x=>5)
|
2063
|
-
a = @c1.load(:id => 2345, :
|
2048
|
+
a = @c1.load(:id => 2345, :z=>8)
|
2064
2049
|
a.should == n.add_attribute(a)
|
2065
2050
|
sqls = MODEL_DB.sqls
|
2066
2051
|
m = /INSERT INTO attributes_nodes \((\w+), (\w+), (\w+), (\w+)\) VALUES \((\d+), (\d+), (\d+), (\d+)\)/.match(sqls.pop)
|
@@ -2080,14 +2065,14 @@ describe Sequel::Model, "many_to_many" do
|
|
2080
2065
|
end
|
2081
2066
|
|
2082
2067
|
it "should have the add_ method respect composite keys" do
|
2083
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
2084
|
-
@c1.set_primary_key [:id, :
|
2068
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
2069
|
+
@c1.set_primary_key [:id, :z]
|
2085
2070
|
n = @c2.load(:id => 1234, :x=>5)
|
2086
|
-
a = @c1.load(:id => 2345, :
|
2087
|
-
@c1.dataset._fetch = {:id => 2345, :
|
2071
|
+
a = @c1.load(:id => 2345, :z=>8)
|
2072
|
+
@c1.dataset._fetch = {:id => 2345, :z=>8}
|
2088
2073
|
n.add_attribute([2345, 8]).should == a
|
2089
2074
|
sqls = MODEL_DB.sqls
|
2090
|
-
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|
|
2075
|
+
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|z) = (8|2345)\) AND \((id|z) = (8|2345)\)\) LIMIT 1/
|
2091
2076
|
sqls.pop.should =~ /INSERT INTO attributes_nodes \([lr][12], [lr][12], [lr][12], [lr][12]\) VALUES \((1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8)\)/
|
2092
2077
|
sqls.should == []
|
2093
2078
|
end
|
@@ -2102,9 +2087,9 @@ describe Sequel::Model, "many_to_many" do
|
|
2102
2087
|
end
|
2103
2088
|
|
2104
2089
|
it "should have the remove_ method respect composite keys" do
|
2105
|
-
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :
|
2090
|
+
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
|
2106
2091
|
n = @c2.load(:id => 1234, :x=>5)
|
2107
|
-
a = @c1.load(:id => 2345, :
|
2092
|
+
a = @c1.load(:id => 2345, :z=>8)
|
2108
2093
|
a.should == n.remove_attribute(a)
|
2109
2094
|
MODEL_DB.sqls.should == ["DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5) AND (r1 = 2345) AND (r2 = 8))"]
|
2110
2095
|
end
|
@@ -2964,11 +2949,11 @@ describe "Sequel::Model Associations with clashing column names" do
|
|
2964
2949
|
@Bar.columns :id, :object_id
|
2965
2950
|
@Foo.def_column_alias(:obj_id, :object_id)
|
2966
2951
|
@Bar.def_column_alias(:obj_id, :object_id)
|
2967
|
-
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id,
|
2968
|
-
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :
|
2952
|
+
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
2953
|
+
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>:object_id, :key=>:object_id, :key_method=>:obj_id, :class=>@Bar
|
2969
2954
|
@Bar.many_to_one :foo, :key=>:obj_id, :key_column=>:object_id, :primary_key=>:object_id, :primary_key_method=>:obj_id, :class=>@Foo
|
2970
|
-
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:foo_id, :right_key=>:object_id, :
|
2971
|
-
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:object_id, :right_key=>:foo_id, :
|
2955
|
+
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:foo_id, :right_key=>:object_id, :class=>@Bar
|
2956
|
+
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>:object_id, :right_primary_key=>:object_id, :right_primary_key_method=>:obj_id, :left_key=>:object_id, :right_key=>:foo_id, :class=>@Foo
|
2972
2957
|
@foo = @Foo.load(:id=>1, :object_id=>2)
|
2973
2958
|
@bar = @Bar.load(:id=>1, :object_id=>2)
|
2974
2959
|
@db.sqls
|
@@ -2976,33 +2961,61 @@ describe "Sequel::Model Associations with clashing column names" do
|
|
2976
2961
|
|
2977
2962
|
it "should have working regular association methods" do
|
2978
2963
|
@Bar.first.foo.should == @foo
|
2964
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
2979
2965
|
@Foo.first.bars.should == [@bar]
|
2966
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_id = 2)"]
|
2980
2967
|
@Foo.first.bar.should == @bar
|
2968
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_id = 2) LIMIT 1"]
|
2981
2969
|
@Foo.first.mtmbars.should == [@bar]
|
2970
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT bars.* FROM bars INNER JOIN bars_foos ON ((bars_foos.object_id = bars.object_id) AND (bars_foos.foo_id = 2))"]
|
2982
2971
|
@Bar.first.mtmfoos.should == [@foo]
|
2972
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT foos.* FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_id = foos.object_id) AND (bars_foos.object_id = 2))"]
|
2983
2973
|
end
|
2984
2974
|
|
2985
2975
|
it "should have working eager loading methods" do
|
2986
2976
|
@Bar.eager(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
2977
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT * FROM foos WHERE (foos.object_id IN (2))"]
|
2987
2978
|
@Foo.eager(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
2979
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_id IN (2))"]
|
2988
2980
|
@Foo.eager(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
2981
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_id IN (2))"]
|
2989
2982
|
@db.fetch = [[{:id=>1, :object_id=>2}], [{:id=>1, :object_id=>2, :x_foreign_key_x=>2}]]
|
2990
2983
|
@Foo.eager(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
2984
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT bars.*, bars_foos.foo_id AS x_foreign_key_x FROM bars INNER JOIN bars_foos ON ((bars_foos.object_id = bars.object_id) AND (bars_foos.foo_id IN (2)))"]
|
2991
2985
|
@db.fetch = [[{:id=>1, :object_id=>2}], [{:id=>1, :object_id=>2, :x_foreign_key_x=>2}]]
|
2992
2986
|
@Bar.eager(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
2987
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT foos.*, bars_foos.object_id AS x_foreign_key_x FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_id = foos.object_id) AND (bars_foos.object_id IN (2)))"]
|
2993
2988
|
end
|
2994
2989
|
|
2995
2990
|
it "should have working eager graphing methods" do
|
2996
2991
|
@db.fetch = {:id=>1, :object_id=>2, :foo_id=>1, :foo_object_id=>2}
|
2997
2992
|
@Bar.eager_graph(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
2993
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_id, foo.id AS foo_id, foo.object_id AS foo_object_id FROM bars LEFT OUTER JOIN foos AS foo ON (foo.object_id = bars.object_id)"]
|
2998
2994
|
@db.fetch = {:id=>1, :object_id=>2, :bars_id=>1, :bars_object_id=>2}
|
2999
2995
|
@Foo.eager_graph(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
2996
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, bars.id AS bars_id, bars.object_id AS bars_object_id FROM foos LEFT OUTER JOIN bars ON (bars.object_id = foos.object_id)"]
|
3000
2997
|
@db.fetch = {:id=>1, :object_id=>2, :bar_id=>1, :bar_object_id=>2}
|
3001
2998
|
@Foo.eager_graph(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
2999
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, bar.id AS bar_id, bar.object_id AS bar_object_id FROM foos LEFT OUTER JOIN bars AS bar ON (bar.object_id = foos.object_id)"]
|
3002
3000
|
@db.fetch = {:id=>1, :object_id=>2, :mtmfoos_id=>1, :mtmfoos_object_id=>2}
|
3003
3001
|
@Bar.eager_graph(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
3002
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_id, mtmfoos.id AS mtmfoos_id, mtmfoos.object_id AS mtmfoos_object_id FROM bars LEFT OUTER JOIN bars_foos ON (bars_foos.object_id = bars.object_id) LEFT OUTER JOIN foos AS mtmfoos ON (mtmfoos.object_id = bars_foos.foo_id)"]
|
3004
3003
|
@db.fetch = {:id=>1, :object_id=>2, :mtmbars_id=>1, :mtmbars_object_id=>2}
|
3005
3004
|
@Foo.eager_graph(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
3005
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_id, mtmbars.id AS mtmbars_id, mtmbars.object_id AS mtmbars_object_id FROM foos LEFT OUTER JOIN bars_foos ON (bars_foos.foo_id = foos.object_id) LEFT OUTER JOIN bars AS mtmbars ON (mtmbars.object_id = bars_foos.object_id)"]
|
3006
|
+
end
|
3007
|
+
|
3008
|
+
it "should have working filter by associations with model instances" do
|
3009
|
+
@Bar.first(:foo=>@foo).should == @bar
|
3010
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_id = 2) LIMIT 1"]
|
3011
|
+
@Foo.first(:bars=>@bar).should == @foo
|
3012
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
3013
|
+
@Foo.first(:bar=>@bar).should == @foo
|
3014
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id = 2) LIMIT 1"]
|
3015
|
+
@Foo.first(:mtmbars=>@bar).should == @foo
|
3016
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_id IN (SELECT bars_foos.foo_id FROM bars_foos WHERE ((bars_foos.object_id = 2) AND (bars_foos.foo_id IS NOT NULL)))) LIMIT 1"]
|
3017
|
+
@Bar.first(:mtmfoos=>@foo).should == @bar
|
3018
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_id IN (SELECT bars_foos.object_id FROM bars_foos WHERE ((bars_foos.foo_id = 2) AND (bars_foos.object_id IS NOT NULL)))) LIMIT 1"]
|
3006
3019
|
end
|
3007
3020
|
|
3008
3021
|
it "should have working modification methods" do
|
@@ -3045,6 +3058,100 @@ describe "Sequel::Model Associations with clashing column names" do
|
|
3045
3058
|
end
|
3046
3059
|
end
|
3047
3060
|
|
3061
|
+
describe "Sequel::Model Associations with non-column expression keys" do
|
3062
|
+
before do
|
3063
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :object_ids=>[2]})
|
3064
|
+
@Foo = Class.new(Sequel::Model(@db[:foos]))
|
3065
|
+
@Bar = Class.new(Sequel::Model(@db[:bars]))
|
3066
|
+
@Foo.columns :id, :object_ids
|
3067
|
+
@Bar.columns :id, :object_ids
|
3068
|
+
m = Module.new{def obj_id; object_ids[0]; end}
|
3069
|
+
@Foo.include m
|
3070
|
+
@Bar.include m
|
3071
|
+
|
3072
|
+
@Foo.one_to_many :bars, :primary_key=>:obj_id, :primary_key_column=>Sequel.subscript(:object_ids, 0), :key=>Sequel.subscript(:object_ids, 0), :key_method=>:obj_id, :class=>@Bar
|
3073
|
+
@Foo.one_to_one :bar, :primary_key=>:obj_id, :primary_key_column=>Sequel.subscript(:object_ids, 0), :key=>Sequel.subscript(:object_ids, 0), :key_method=>:obj_id, :class=>@Bar
|
3074
|
+
@Bar.many_to_one :foo, :key=>:obj_id, :key_column=>Sequel.subscript(:object_ids, 0), :primary_key=>Sequel.subscript(:object_ids, 0), :primary_key_method=>:obj_id, :class=>@Foo
|
3075
|
+
@Foo.many_to_many :mtmbars, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:foo_ids, 0), :right_key=>Sequel.subscript(:bar_ids, 0), :class=>@Bar
|
3076
|
+
@Bar.many_to_many :mtmfoos, :join_table=>:bars_foos, :left_primary_key=>:obj_id, :left_primary_key_column=>Sequel.subscript(:object_ids, 0), :right_primary_key=>Sequel.subscript(:object_ids, 0), :right_primary_key_method=>:obj_id, :left_key=>Sequel.subscript(:bar_ids, 0), :right_key=>Sequel.subscript(:foo_ids, 0), :class=>@Foo
|
3077
|
+
@foo = @Foo.load(:id=>1, :object_ids=>[2])
|
3078
|
+
@bar = @Bar.load(:id=>1, :object_ids=>[2])
|
3079
|
+
@db.sqls
|
3080
|
+
end
|
3081
|
+
|
3082
|
+
it "should have working regular association methods" do
|
3083
|
+
@Bar.first.foo.should == @foo
|
3084
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
3085
|
+
@Foo.first.bars.should == [@bar]
|
3086
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_ids[0] = 2)"]
|
3087
|
+
@Foo.first.bar.should == @bar
|
3088
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT * FROM bars WHERE (bars.object_ids[0] = 2) LIMIT 1"]
|
3089
|
+
@Foo.first.mtmbars.should == [@bar]
|
3090
|
+
@db.sqls.should == ["SELECT * FROM foos LIMIT 1", "SELECT bars.* FROM bars INNER JOIN bars_foos ON ((bars_foos.bar_ids[0] = bars.object_ids[0]) AND (bars_foos.foo_ids[0] = 2))"]
|
3091
|
+
@Bar.first.mtmfoos.should == [@foo]
|
3092
|
+
@db.sqls.should == ["SELECT * FROM bars LIMIT 1", "SELECT foos.* FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_ids[0] = foos.object_ids[0]) AND (bars_foos.bar_ids[0] = 2))"]
|
3093
|
+
end
|
3094
|
+
|
3095
|
+
it "should have working eager loading methods" do
|
3096
|
+
@Bar.eager(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
3097
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT * FROM foos WHERE (foos.object_ids[0] IN (2))"]
|
3098
|
+
@Foo.eager(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
3099
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_ids[0] IN (2))"]
|
3100
|
+
@Foo.eager(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
3101
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT * FROM bars WHERE (bars.object_ids[0] IN (2))"]
|
3102
|
+
@db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
|
3103
|
+
@Foo.eager(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
3104
|
+
@db.sqls.should == ["SELECT * FROM foos", "SELECT bars.*, bars_foos.foo_ids[0] AS x_foreign_key_x FROM bars INNER JOIN bars_foos ON ((bars_foos.bar_ids[0] = bars.object_ids[0]) AND (bars_foos.foo_ids[0] IN (2)))"]
|
3105
|
+
@db.fetch = [[{:id=>1, :object_ids=>[2]}], [{:id=>1, :object_ids=>[2], :x_foreign_key_x=>2}]]
|
3106
|
+
@Bar.eager(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
3107
|
+
@db.sqls.should == ["SELECT * FROM bars", "SELECT foos.*, bars_foos.bar_ids[0] AS x_foreign_key_x FROM foos INNER JOIN bars_foos ON ((bars_foos.foo_ids[0] = foos.object_ids[0]) AND (bars_foos.bar_ids[0] IN (2)))"]
|
3108
|
+
end
|
3109
|
+
|
3110
|
+
it "should have working eager graphing methods" do
|
3111
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :foo_id=>1, :foo_object_ids=>[2]}
|
3112
|
+
@Bar.eager_graph(:foo).all.map{|o| [o, o.foo]}.should == [[@bar, @foo]]
|
3113
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_ids, foo.id AS foo_id, foo.object_ids AS foo_object_ids FROM bars LEFT OUTER JOIN foos AS foo ON (foo.object_ids[0] = bars.object_ids[0])"]
|
3114
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :bars_id=>1, :bars_object_ids=>[2]}
|
3115
|
+
@Foo.eager_graph(:bars).all.map{|o| [o, o.bars]}.should == [[@foo, [@bar]]]
|
3116
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, bars.id AS bars_id, bars.object_ids AS bars_object_ids FROM foos LEFT OUTER JOIN bars ON (bars.object_ids[0] = foos.object_ids[0])"]
|
3117
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :bar_id=>1, :bar_object_ids=>[2]}
|
3118
|
+
@Foo.eager_graph(:bar).all.map{|o| [o, o.bar]}.should == [[@foo, @bar]]
|
3119
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, bar.id AS bar_id, bar.object_ids AS bar_object_ids FROM foos LEFT OUTER JOIN bars AS bar ON (bar.object_ids[0] = foos.object_ids[0])"]
|
3120
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :mtmfoos_id=>1, :mtmfoos_object_ids=>[2]}
|
3121
|
+
@Bar.eager_graph(:mtmfoos).all.map{|o| [o, o.mtmfoos]}.should == [[@bar, [@foo]]]
|
3122
|
+
@db.sqls.should == ["SELECT bars.id, bars.object_ids, mtmfoos.id AS mtmfoos_id, mtmfoos.object_ids AS mtmfoos_object_ids FROM bars LEFT OUTER JOIN bars_foos ON (bars_foos.bar_ids[0] = bars.object_ids[0]) LEFT OUTER JOIN foos AS mtmfoos ON (mtmfoos.object_ids[0] = bars_foos.foo_ids[0])"]
|
3123
|
+
@db.fetch = {:id=>1, :object_ids=>[2], :mtmbars_id=>1, :mtmbars_object_ids=>[2]}
|
3124
|
+
@Foo.eager_graph(:mtmbars).all.map{|o| [o, o.mtmbars]}.should == [[@foo, [@bar]]]
|
3125
|
+
@db.sqls.should == ["SELECT foos.id, foos.object_ids, mtmbars.id AS mtmbars_id, mtmbars.object_ids AS mtmbars_object_ids FROM foos LEFT OUTER JOIN bars_foos ON (bars_foos.foo_ids[0] = foos.object_ids[0]) LEFT OUTER JOIN bars AS mtmbars ON (mtmbars.object_ids[0] = bars_foos.bar_ids[0])"]
|
3126
|
+
end
|
3127
|
+
|
3128
|
+
it "should have working filter by associations with model instances" do
|
3129
|
+
@Bar.first(:foo=>@foo).should == @bar
|
3130
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] = 2) LIMIT 1"]
|
3131
|
+
@Foo.first(:bars=>@bar).should == @foo
|
3132
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
3133
|
+
@Foo.first(:bar=>@bar).should == @foo
|
3134
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] = 2) LIMIT 1"]
|
3135
|
+
@Foo.first(:mtmbars=>@bar).should == @foo
|
3136
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars_foos.foo_ids[0] FROM bars_foos WHERE ((bars_foos.bar_ids[0] = 2) AND (bars_foos.foo_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3137
|
+
@Bar.first(:mtmfoos=>@foo).should == @bar
|
3138
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT bars_foos.bar_ids[0] FROM bars_foos WHERE ((bars_foos.foo_ids[0] = 2) AND (bars_foos.bar_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3139
|
+
end
|
3140
|
+
|
3141
|
+
it "should have working filter by associations with model datasets" do
|
3142
|
+
@Bar.first(:foo=>@Foo.where(:id=>@foo.id)).should == @bar
|
3143
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3144
|
+
@Foo.first(:bars=>@Bar.where(:id=>@bar.id)).should == @foo
|
3145
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3146
|
+
@Foo.first(:bar=>@Bar.where(:id=>@bar.id)).should == @foo
|
3147
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3148
|
+
@Foo.first(:mtmbars=>@Bar.where(:id=>@bar.id)).should == @foo
|
3149
|
+
@db.sqls.should == ["SELECT * FROM foos WHERE (foos.object_ids[0] IN (SELECT bars_foos.foo_ids[0] FROM bars_foos WHERE ((bars_foos.bar_ids[0] IN (SELECT bars.object_ids[0] FROM bars WHERE ((id = 1) AND (bars.object_ids[0] IS NOT NULL)))) AND (bars_foos.foo_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3150
|
+
@Bar.first(:mtmfoos=>@Foo.where(:id=>@foo.id)).should == @bar
|
3151
|
+
@db.sqls.should == ["SELECT * FROM bars WHERE (bars.object_ids[0] IN (SELECT bars_foos.bar_ids[0] FROM bars_foos WHERE ((bars_foos.foo_ids[0] IN (SELECT foos.object_ids[0] FROM foos WHERE ((id = 1) AND (foos.object_ids[0] IS NOT NULL)))) AND (bars_foos.bar_ids[0] IS NOT NULL)))) LIMIT 1"]
|
3152
|
+
end
|
3153
|
+
end
|
3154
|
+
|
3048
3155
|
describe "Model#pk_or_nil" do
|
3049
3156
|
before do
|
3050
3157
|
@m = Class.new(Sequel::Model)
|