sequel 4.45.0 → 4.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +108 -0
- data/doc/release_notes/4.46.0.txt +404 -0
- data/doc/security.rdoc +9 -0
- data/doc/sql.rdoc +2 -2
- data/doc/testing.rdoc +1 -1
- data/doc/validations.rdoc +1 -2
- data/lib/sequel/adapters/ado.rb +8 -3
- data/lib/sequel/adapters/ado/access.rb +8 -4
- data/lib/sequel/adapters/ado/mssql.rb +3 -1
- data/lib/sequel/adapters/amalgalite.rb +5 -0
- data/lib/sequel/adapters/cubrid.rb +16 -7
- data/lib/sequel/adapters/do.rb +7 -1
- data/lib/sequel/adapters/do/mysql.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +10 -5
- data/lib/sequel/adapters/jdbc.rb +8 -2
- data/lib/sequel/adapters/jdbc/as400.rb +10 -3
- data/lib/sequel/adapters/jdbc/db2.rb +27 -16
- data/lib/sequel/adapters/jdbc/derby.rb +47 -20
- data/lib/sequel/adapters/jdbc/h2.rb +13 -7
- data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +6 -1
- data/lib/sequel/adapters/odbc.rb +20 -8
- data/lib/sequel/adapters/odbc/mssql.rb +6 -3
- data/lib/sequel/adapters/oracle.rb +12 -6
- data/lib/sequel/adapters/postgres.rb +20 -8
- data/lib/sequel/adapters/shared/access.rb +76 -47
- data/lib/sequel/adapters/shared/cubrid.rb +16 -11
- data/lib/sequel/adapters/shared/db2.rb +46 -19
- data/lib/sequel/adapters/shared/firebird.rb +20 -8
- data/lib/sequel/adapters/shared/informix.rb +6 -3
- data/lib/sequel/adapters/shared/mssql.rb +132 -72
- data/lib/sequel/adapters/shared/mysql.rb +112 -65
- data/lib/sequel/adapters/shared/oracle.rb +36 -21
- data/lib/sequel/adapters/shared/postgres.rb +91 -56
- data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
- data/lib/sequel/adapters/shared/sqlite.rb +67 -32
- data/lib/sequel/adapters/sqlanywhere.rb +9 -1
- data/lib/sequel/adapters/sqlite.rb +8 -1
- data/lib/sequel/adapters/swift.rb +5 -0
- data/lib/sequel/adapters/swift/mysql.rb +4 -2
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +10 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/adapters/utils/pg_types.rb +14 -6
- data/lib/sequel/adapters/utils/replace.rb +4 -2
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/core.rb +24 -11
- data/lib/sequel/database/connecting.rb +9 -3
- data/lib/sequel/database/dataset_defaults.rb +7 -1
- data/lib/sequel/database/logging.rb +1 -0
- data/lib/sequel/database/misc.rb +5 -2
- data/lib/sequel/database/query.rb +7 -5
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +50 -27
- data/lib/sequel/database/transactions.rb +19 -9
- data/lib/sequel/dataset/actions.rb +15 -6
- data/lib/sequel/dataset/graph.rb +15 -5
- data/lib/sequel/dataset/misc.rb +12 -4
- data/lib/sequel/dataset/mutation.rb +17 -8
- data/lib/sequel/dataset/prepared_statements.rb +3 -2
- data/lib/sequel/dataset/query.rb +84 -38
- data/lib/sequel/dataset/sql.rb +302 -191
- data/lib/sequel/deprecated.rb +26 -17
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/migration.rb +28 -4
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +4 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
- data/lib/sequel/extensions/set_overrides.rb +2 -0
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +11 -7
- data/lib/sequel/model/associations.rb +5 -7
- data/lib/sequel/model/base.rb +47 -45
- data/lib/sequel/model/dataset_module.rb +9 -14
- data/lib/sequel/model/plugins.rb +3 -0
- data/lib/sequel/no_core_ext.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -1
- data/lib/sequel/plugins/boolean_subsets.rb +7 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/finder.rb +240 -0
- data/lib/sequel/plugins/inverted_subsets.rb +19 -12
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
- data/lib/sequel/plugins/subset_conditions.rb +11 -3
- data/lib/sequel/plugins/whitelist_security.rb +118 -0
- data/lib/sequel/sql.rb +80 -36
- data/lib/sequel/timezones.rb +2 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +20 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +12 -8
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +36 -34
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +87 -9
- data/spec/core/dataset_spec.rb +501 -129
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +146 -60
- data/spec/core/mock_adapter_spec.rb +1 -1
- data/spec/core/object_graph_spec.rb +61 -9
- data/spec/core/placeholder_literalizer_spec.rb +20 -2
- data/spec/core/schema_generator_spec.rb +6 -6
- data/spec/core/schema_spec.rb +54 -5
- data/spec/core_extensions_spec.rb +122 -18
- data/spec/deprecation_helper.rb +27 -2
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
- data/spec/extensions/association_proxies_spec.rb +2 -2
- data/spec/extensions/auto_literal_strings_spec.rb +212 -0
- data/spec/extensions/blacklist_security_spec.rb +1 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
- data/spec/extensions/column_select_spec.rb +20 -8
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/core_refinements_spec.rb +29 -12
- data/spec/extensions/dataset_associations_spec.rb +12 -12
- data/spec/extensions/def_dataset_method_spec.rb +100 -0
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +260 -0
- data/spec/extensions/graph_each_spec.rb +2 -2
- data/spec/extensions/identifier_mangling_spec.rb +14 -8
- data/spec/extensions/inverted_subsets_spec.rb +4 -4
- data/spec/extensions/lazy_attributes_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +38 -14
- data/spec/extensions/nested_attributes_spec.rb +18 -6
- data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
- data/spec/extensions/pg_enum_spec.rb +16 -1
- data/spec/extensions/pg_interval_spec.rb +11 -2
- data/spec/extensions/pg_loose_count_spec.rb +5 -0
- data/spec/extensions/pg_row_spec.rb +25 -0
- data/spec/extensions/prepared_statements_spec.rb +10 -1
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/set_overrides_spec.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +0 -1
- data/spec/extensions/subset_conditions_spec.rb +6 -6
- data/spec/extensions/table_select_spec.rb +24 -12
- data/spec/extensions/to_dot_spec.rb +4 -4
- data/spec/extensions/whitelist_security_spec.rb +131 -0
- data/spec/integration/dataset_test.rb +9 -5
- data/spec/integration/model_test.rb +2 -0
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/model/associations_spec.rb +39 -11
- data/spec/model/base_spec.rb +44 -24
- data/spec/model/class_dataset_methods_spec.rb +18 -16
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +84 -24
- data/spec/model/model_spec.rb +97 -63
- data/spec/model/record_spec.rb +21 -13
- metadata +13 -2
@@ -26,7 +26,7 @@ Sequel::Model.cache_anonymous_models = false
|
|
26
26
|
|
27
27
|
require './spec/guards_helper'
|
28
28
|
|
29
|
-
IDENTIFIER_MANGLING =
|
29
|
+
IDENTIFIER_MANGLING = !!ENV['SEQUEL_IDENTIFIER_MANGLING'] unless defined?(IDENTIFIER_MANGLING)
|
30
30
|
|
31
31
|
unless defined?(DB)
|
32
32
|
# SEQUEL5: Remove :identifier_mangling=>false
|
@@ -2027,13 +2027,19 @@ describe Sequel::Model, "many_to_many" do
|
|
2027
2027
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.id, attributes.b FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)'
|
2028
2028
|
end
|
2029
2029
|
|
2030
|
-
|
2030
|
+
with_symbol_splitting "should not override a selection consisting completely of qualified columns using symbols" do
|
2031
2031
|
@c1.dataset = @c1.dataset.select(:attributes__id, :attributes__b)
|
2032
2032
|
@c2.many_to_many :attributes, :class => @c1
|
2033
2033
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.id, attributes.b FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)'
|
2034
2034
|
end
|
2035
2035
|
|
2036
2036
|
it "should not override a selection consisting completely of qualified columns using Sequel::SQL::AliasedExpression" do
|
2037
|
+
@c1.dataset = @c1.dataset.select(Sequel.qualify(:attributes, :id).as(:a), Sequel[:attributes][:b].as(:c))
|
2038
|
+
@c2.many_to_many :attributes, :class => @c1
|
2039
|
+
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.id AS a, attributes.b AS c FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)'
|
2040
|
+
end
|
2041
|
+
|
2042
|
+
with_symbol_splitting "should not override a selection consisting completely of qualified columns using Sequel::SQL::AliasedExpression with qualified symbol" do
|
2037
2043
|
@c1.dataset = @c1.dataset.select(Sequel.qualify(:attributes, :id).as(:a), Sequel.as(:attributes__b, :c))
|
2038
2044
|
@c2.many_to_many :attributes, :class => @c1
|
2039
2045
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.id AS a, attributes.b AS c FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)'
|
@@ -2046,7 +2052,7 @@ describe Sequel::Model, "many_to_many" do
|
|
2046
2052
|
end
|
2047
2053
|
|
2048
2054
|
it "should respect :eager_loader_predicate_key when lazily loading" do
|
2049
|
-
@c2.many_to_many :attributes, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(:
|
2055
|
+
@c2.many_to_many :attributes, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(Sequel[:attributes_nodes][:node_id], 0)
|
2050
2056
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id[0] = 1234)'
|
2051
2057
|
end
|
2052
2058
|
|
@@ -2059,7 +2065,7 @@ describe Sequel::Model, "many_to_many" do
|
|
2059
2065
|
@c2.many_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
2060
2066
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((a = 32) AND (attributes_nodes.node_id = 1234))'
|
2061
2067
|
|
2062
|
-
@c2.many_to_many :attributes, :class => @c1, :conditions =>
|
2068
|
+
@c2.many_to_many :attributes, :class => @c1, :conditions => Sequel.lit('a = ?', 32)
|
2063
2069
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((a = 32) AND (attributes_nodes.node_id = 1234))'
|
2064
2070
|
@c2.new(:id => 1234).attributes.must_equal [@c1.load({})]
|
2065
2071
|
end
|
@@ -2110,7 +2116,7 @@ describe Sequel::Model, "many_to_many" do
|
|
2110
2116
|
end
|
2111
2117
|
|
2112
2118
|
it "should support an array for the select option" do
|
2113
|
-
@c2.many_to_many :attributes, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), :
|
2119
|
+
@c2.many_to_many :attributes, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), Sequel[:attribute_nodes][:blah2]]
|
2114
2120
|
|
2115
2121
|
@c2.new(:id => 1234).attributes_dataset.sql.must_equal 'SELECT attributes.*, attribute_nodes.blah2 FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)'
|
2116
2122
|
end
|
@@ -2137,7 +2143,7 @@ describe Sequel::Model, "many_to_many" do
|
|
2137
2143
|
|
2138
2144
|
it "should support a :dataset option that is used instead of the default" do
|
2139
2145
|
c1 = @c1
|
2140
|
-
@c2.many_to_many :attributes, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(:
|
2146
|
+
@c2.many_to_many :attributes, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(Sequel[:an][:nodeid]=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
|
2141
2147
|
ds.filter(:xxx => @xxx)
|
2142
2148
|
end
|
2143
2149
|
|
@@ -2149,7 +2155,7 @@ describe Sequel::Model, "many_to_many" do
|
|
2149
2155
|
end
|
2150
2156
|
|
2151
2157
|
it "should support a :dataset option that accepts the reflection as an argument" do
|
2152
|
-
@c2.many_to_many :attributes, :class => @c1, :dataset=>lambda{|opts| opts.associated_class.natural_join(:an).filter(:
|
2158
|
+
@c2.many_to_many :attributes, :class => @c1, :dataset=>lambda{|opts| opts.associated_class.natural_join(:an).filter(Sequel[:an][:nodeid]=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
|
2153
2159
|
ds.filter(:xxx => @xxx)
|
2154
2160
|
end
|
2155
2161
|
|
@@ -2173,6 +2179,22 @@ describe Sequel::Model, "many_to_many" do
|
|
2173
2179
|
end
|
2174
2180
|
|
2175
2181
|
it "should handle an aliased join table" do
|
2182
|
+
@c2.many_to_many :attributes, :class => @c1, :join_table => Sequel[:attribute2node].as(:attributes_nodes)
|
2183
|
+
n = @c2.load(:id => 1234)
|
2184
|
+
a = @c1.load(:id => 2345)
|
2185
|
+
n.attributes_dataset.sql.must_equal "SELECT attributes.* FROM attributes INNER JOIN attribute2node AS attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234)"
|
2186
|
+
a.must_equal n.add_attribute(a)
|
2187
|
+
a.must_equal n.remove_attribute(a)
|
2188
|
+
n.remove_all_attributes
|
2189
|
+
sqls = DB.sqls
|
2190
|
+
['INSERT INTO attribute2node (node_id, attribute_id) VALUES (1234, 2345)',
|
2191
|
+
'INSERT INTO attribute2node (attribute_id, node_id) VALUES (2345, 1234)'].must_include(sqls.shift)
|
2192
|
+
["DELETE FROM attribute2node WHERE ((node_id = 1234) AND (attribute_id = 2345))",
|
2193
|
+
"DELETE FROM attribute2node WHERE ((attribute_id = 2345) AND (node_id = 1234))"].must_include(sqls.shift)
|
2194
|
+
sqls.must_equal ["DELETE FROM attribute2node WHERE (node_id = 1234)"]
|
2195
|
+
end
|
2196
|
+
|
2197
|
+
with_symbol_splitting "should handle an aliased symbol join table" do
|
2176
2198
|
@c2.many_to_many :attributes, :class => @c1, :join_table => :attribute2node___attributes_nodes
|
2177
2199
|
n = @c2.load(:id => 1234)
|
2178
2200
|
a = @c1.load(:id => 2345)
|
@@ -2861,7 +2883,7 @@ describe Sequel::Model, "one_through_one" do
|
|
2861
2883
|
end
|
2862
2884
|
|
2863
2885
|
it "should respect :eager_loader_predicate_key when lazily loading" do
|
2864
|
-
@c2.one_through_one :attribute, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(:
|
2886
|
+
@c2.one_through_one :attribute, :class => @c1, :eager_loading_predicate_key=>Sequel.subscript(Sequel[:attributes_nodes][:node_id], 0)
|
2865
2887
|
@c2.new(:id => 1234).attribute_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id[0] = 1234) LIMIT 1'
|
2866
2888
|
end
|
2867
2889
|
|
@@ -2874,7 +2896,7 @@ describe Sequel::Model, "one_through_one" do
|
|
2874
2896
|
@c2.one_through_one :attribute, :class => @c1, :conditions => {:a=>32}
|
2875
2897
|
@c2.new(:id => 1234).attribute_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((a = 32) AND (attributes_nodes.node_id = 1234)) LIMIT 1'
|
2876
2898
|
|
2877
|
-
@c2.one_through_one :attribute, :class => @c1, :conditions =>
|
2899
|
+
@c2.one_through_one :attribute, :class => @c1, :conditions => Sequel.lit('a = ?', 32)
|
2878
2900
|
@c2.new(:id => 1234).attribute_dataset.sql.must_equal 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((a = 32) AND (attributes_nodes.node_id = 1234)) LIMIT 1'
|
2879
2901
|
@c2.new(:id => 1234).attribute.must_equal @c1.load({})
|
2880
2902
|
end
|
@@ -2925,7 +2947,7 @@ describe Sequel::Model, "one_through_one" do
|
|
2925
2947
|
end
|
2926
2948
|
|
2927
2949
|
it "should support an array for the select option" do
|
2928
|
-
@c2.one_through_one :attribute, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), :
|
2950
|
+
@c2.one_through_one :attribute, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), Sequel[:attribute_nodes][:blah2]]
|
2929
2951
|
|
2930
2952
|
@c2.new(:id => 1234).attribute_dataset.sql.must_equal 'SELECT attributes.*, attribute_nodes.blah2 FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234) LIMIT 1'
|
2931
2953
|
end
|
@@ -2952,7 +2974,7 @@ describe Sequel::Model, "one_through_one" do
|
|
2952
2974
|
|
2953
2975
|
it "should support a :dataset option that is used instead of the default" do
|
2954
2976
|
c1 = @c1
|
2955
|
-
@c2.one_through_one :attribute, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(:
|
2977
|
+
@c2.one_through_one :attribute, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(Sequel[:an][:nodeid]=>pk)}, :order=> :a, :select=>nil do |ds|
|
2956
2978
|
ds.filter(:xxx => @xxx)
|
2957
2979
|
end
|
2958
2980
|
|
@@ -2964,7 +2986,7 @@ describe Sequel::Model, "one_through_one" do
|
|
2964
2986
|
end
|
2965
2987
|
|
2966
2988
|
it "should support a :dataset option that accepts the reflection as an argument" do
|
2967
|
-
@c2.one_through_one :attribute, :class => @c1, :dataset=>lambda{|opts| opts.associated_class.natural_join(:an).filter(:
|
2989
|
+
@c2.one_through_one :attribute, :class => @c1, :dataset=>lambda{|opts| opts.associated_class.natural_join(:an).filter(Sequel[:an][:nodeid]=>pk)}, :order=> :a, :select=>nil do |ds|
|
2968
2990
|
ds.filter(:xxx => @xxx)
|
2969
2991
|
end
|
2970
2992
|
|
@@ -2986,6 +3008,12 @@ describe Sequel::Model, "one_through_one" do
|
|
2986
3008
|
end
|
2987
3009
|
|
2988
3010
|
it "should handle an aliased join table" do
|
3011
|
+
@c2.one_through_one :attribute, :class => @c1, :join_table => Sequel[:attribute2node].as(:attributes_nodes)
|
3012
|
+
n = @c2.load(:id => 1234)
|
3013
|
+
n.attribute_dataset.sql.must_equal "SELECT attributes.* FROM attributes INNER JOIN attribute2node AS attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234) LIMIT 1"
|
3014
|
+
end
|
3015
|
+
|
3016
|
+
with_symbol_splitting "should handle an aliased join table with splittable symbol" do
|
2989
3017
|
@c2.one_through_one :attribute, :class => @c1, :join_table => :attribute2node___attributes_nodes
|
2990
3018
|
n = @c2.load(:id => 1234)
|
2991
3019
|
n.attribute_dataset.sql.must_equal "SELECT attributes.* FROM attributes INNER JOIN attribute2node AS attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE (attributes_nodes.node_id = 1234) LIMIT 1"
|
data/spec/model/base_spec.rb
CHANGED
@@ -123,19 +123,19 @@ describe Sequel::Model, ".def_dataset_method" do
|
|
123
123
|
@c = Class.new(Sequel::Model(:items))
|
124
124
|
end
|
125
125
|
|
126
|
-
|
126
|
+
deprecated "should add a method to the dataset and model if called with a block argument" do
|
127
127
|
@c.def_dataset_method(:return_3){3}
|
128
128
|
@c.return_3.must_equal 3
|
129
129
|
@c.dataset.return_3.must_equal 3
|
130
130
|
end
|
131
131
|
|
132
|
-
|
132
|
+
deprecated "should handle weird method names" do
|
133
133
|
@c.def_dataset_method(:"return 3"){3}
|
134
134
|
@c.send(:"return 3").must_equal 3
|
135
135
|
@c.dataset.send(:"return 3").must_equal 3
|
136
136
|
end
|
137
137
|
|
138
|
-
|
138
|
+
deprecated "should not add a model method if the model already responds to the method" do
|
139
139
|
@c.instance_eval do
|
140
140
|
def foo
|
141
141
|
1
|
@@ -156,7 +156,7 @@ describe Sequel::Model, ".def_dataset_method" do
|
|
156
156
|
@c.dataset.bar.must_equal 4
|
157
157
|
end
|
158
158
|
|
159
|
-
|
159
|
+
deprecated "should add all passed methods to the model if called without a block argument" do
|
160
160
|
@c.def_dataset_method(:return_3, :return_4)
|
161
161
|
proc{@c.return_3}.must_raise(NoMethodError)
|
162
162
|
proc{@c.return_4}.must_raise(NoMethodError)
|
@@ -168,14 +168,14 @@ describe Sequel::Model, ".def_dataset_method" do
|
|
168
168
|
@c.return_4.must_equal 4
|
169
169
|
end
|
170
170
|
|
171
|
-
|
171
|
+
deprecated "should cache calls and readd methods if set_dataset is used" do
|
172
172
|
@c.def_dataset_method(:return_3){3}
|
173
173
|
@c.set_dataset :items
|
174
174
|
@c.return_3.must_equal 3
|
175
175
|
@c.dataset.return_3.must_equal 3
|
176
176
|
end
|
177
177
|
|
178
|
-
|
178
|
+
deprecated "should readd methods to subclasses, if set_dataset is used in a subclass" do
|
179
179
|
@c.def_dataset_method(:return_3){3}
|
180
180
|
c = Class.new(@c)
|
181
181
|
c.set_dataset :items
|
@@ -209,6 +209,13 @@ describe Sequel::Model, ".dataset_module" do
|
|
209
209
|
@c.return_3.must_equal 3
|
210
210
|
end
|
211
211
|
|
212
|
+
it "should not add private or protected methods defined in the module to the class" do
|
213
|
+
@c.dataset_module{private; def return_3() 3 end}
|
214
|
+
@c.dataset_module{protected; def return_4() 4 end}
|
215
|
+
@c.respond_to?(:return_3).must_equal false
|
216
|
+
@c.respond_to?(:return_4).must_equal false
|
217
|
+
end
|
218
|
+
|
212
219
|
it "should cache calls and readd methods if set_dataset is used" do
|
213
220
|
@c.dataset_module{def return_3() 3 end}
|
214
221
|
@c.set_dataset :items
|
@@ -562,25 +569,26 @@ describe "Model.db=" do
|
|
562
569
|
@m = Class.new(Sequel::Model(@db1[:blue].filter(:x=>1)))
|
563
570
|
end
|
564
571
|
|
565
|
-
|
572
|
+
deprecated "should affect the underlying dataset" do
|
566
573
|
@m.db = @db2
|
567
574
|
|
568
575
|
@m.dataset.db.must_equal @db2
|
569
576
|
@m.dataset.db.wont_equal @db1
|
570
577
|
end
|
571
578
|
|
572
|
-
|
579
|
+
deprecated "should keep the same dataset options" do
|
573
580
|
@m.db = @db2
|
574
581
|
@m.dataset.sql.must_equal 'SELECT * FROM blue WHERE (x = 1)'
|
575
582
|
end
|
576
583
|
|
577
584
|
it "should use the database for subclasses" do
|
585
|
+
@m = Class.new(Sequel::Model)
|
578
586
|
@m.db = @db2
|
579
587
|
Class.new(@m).db.must_equal @db2
|
580
588
|
end
|
581
589
|
end
|
582
590
|
|
583
|
-
describe Sequel::Model, ".
|
591
|
+
describe Sequel::Model, ".allowed_columns " do
|
584
592
|
before do
|
585
593
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
586
594
|
columns :x, :y, :z
|
@@ -590,7 +598,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
590
598
|
DB.reset
|
591
599
|
end
|
592
600
|
|
593
|
-
|
601
|
+
deprecated "should set the allowed columns correctly" do
|
594
602
|
@c.allowed_columns.must_be_nil
|
595
603
|
@c.set_allowed_columns :x
|
596
604
|
@c.allowed_columns.must_equal [:x]
|
@@ -598,7 +606,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
|
|
598
606
|
@c.allowed_columns.must_equal [:x, :y]
|
599
607
|
end
|
600
608
|
|
601
|
-
|
609
|
+
deprecated "should only set allowed columns by default" do
|
602
610
|
@c.set_allowed_columns :x, :y
|
603
611
|
i = @c.new(:x => 1, :y => 2, :z => 3)
|
604
612
|
i.values.must_equal(:x => 1, :y => 2)
|
@@ -655,7 +663,6 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
655
663
|
before do
|
656
664
|
@c = Class.new(Sequel::Model(:blahblah)) do
|
657
665
|
columns :x, :y, :z, :id
|
658
|
-
set_allowed_columns :x, :y
|
659
666
|
end
|
660
667
|
end
|
661
668
|
|
@@ -664,21 +671,24 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
664
671
|
end
|
665
672
|
|
666
673
|
it "should raise an error if a missing/restricted column/method is accessed" do
|
667
|
-
proc{@c.new(:
|
668
|
-
proc{@c.create(:
|
674
|
+
proc{@c.new(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
675
|
+
proc{@c.create(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
669
676
|
c = @c.new
|
670
|
-
proc{c.set(:
|
671
|
-
proc{c.
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
677
|
+
proc{c.set(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
678
|
+
proc{c.update(:a=>1)}.must_raise(Sequel::MassAssignmentRestriction)
|
679
|
+
deprecated do
|
680
|
+
@c.set_allowed_columns :x, :y
|
681
|
+
proc{c.set_all(:use_after_commit_rollback => false)}.must_raise(Sequel::MassAssignmentRestriction)
|
682
|
+
proc{c.set_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
683
|
+
proc{c.update_all(:use_after_commit_rollback=>false)}.must_raise(Sequel::MassAssignmentRestriction)
|
684
|
+
proc{c.update_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
|
685
|
+
end
|
676
686
|
end
|
677
687
|
|
678
688
|
it "should be disabled by strict_param_setting = false" do
|
679
689
|
@c.strict_param_setting = false
|
680
690
|
@c.strict_param_setting.must_equal false
|
681
|
-
@c.new(:
|
691
|
+
@c.new(:a=>1)
|
682
692
|
end
|
683
693
|
end
|
684
694
|
|
@@ -737,8 +747,6 @@ describe Sequel::Model, ".[] optimization" do
|
|
737
747
|
@c.simple_table.must_equal 'a'
|
738
748
|
@c.set_dataset :b
|
739
749
|
@c.simple_table.must_equal 'b'
|
740
|
-
@c.set_dataset :b__a
|
741
|
-
@c.simple_table.must_equal 'b.a'
|
742
750
|
end
|
743
751
|
|
744
752
|
it "should have simple_table set if passed a simple select all dataset to set_dataset" do
|
@@ -746,6 +754,13 @@ describe Sequel::Model, ".[] optimization" do
|
|
746
754
|
@c.simple_table.must_equal '"a"'
|
747
755
|
@c.set_dataset @ds.from(:b)
|
748
756
|
@c.simple_table.must_equal '"b"'
|
757
|
+
@c.set_dataset @ds.from(Sequel[:b][:a])
|
758
|
+
@c.simple_table.must_equal '"b"."a"'
|
759
|
+
end
|
760
|
+
|
761
|
+
with_symbol_splitting "should have simple_table set using qualified symbol" do
|
762
|
+
@c.set_dataset :b__a
|
763
|
+
@c.simple_table.must_equal 'b.a'
|
749
764
|
@c.set_dataset @ds.from(:b__a)
|
750
765
|
@c.simple_table.must_equal '"b"."a"'
|
751
766
|
end
|
@@ -865,11 +880,16 @@ describe "Model datasets #with_pk with #with_pk!" do
|
|
865
880
|
DB.sqls.must_equal ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
|
866
881
|
end
|
867
882
|
|
868
|
-
|
883
|
+
deprecated "should not have #[] consider a string as a primary key lookup" do
|
869
884
|
@ds['foo'].must_equal @c.load(:id=>1)
|
870
885
|
DB.sqls.must_equal ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
871
886
|
end
|
872
887
|
|
888
|
+
it "should not have #[] consider a literal string as a primary key lookup" do
|
889
|
+
@ds[Sequel.lit('foo')].must_equal @c.load(:id=>1)
|
890
|
+
DB.sqls.must_equal ["SELECT * FROM a WHERE (foo) LIMIT 1"]
|
891
|
+
end
|
892
|
+
|
873
893
|
it "should raise Error if called on a dataset with no primary key" do
|
874
894
|
@c.no_primary_key
|
875
895
|
@ds.freeze
|
@@ -17,7 +17,7 @@ describe Sequel::Model, "class dataset methods" do
|
|
17
17
|
@db.sqls.must_equal ["SELECT avg(id) AS avg FROM items LIMIT 1"]
|
18
18
|
@c.count.must_equal 1
|
19
19
|
@db.sqls.must_equal ["SELECT count(*) AS count FROM items LIMIT 1"]
|
20
|
-
@c.cross_join(@c).sql.must_equal "SELECT * FROM items CROSS JOIN items"
|
20
|
+
@c.cross_join(@c.table_name).sql.must_equal "SELECT * FROM items CROSS JOIN items"
|
21
21
|
@c.distinct.sql.must_equal "SELECT DISTINCT * FROM items"
|
22
22
|
@c.each{|r| r.must_equal @c.load(:id=>1)}.must_equal @d
|
23
23
|
@db.sqls.must_equal ["SELECT * FROM items"]
|
@@ -38,11 +38,11 @@ describe Sequel::Model, "class dataset methods" do
|
|
38
38
|
@c.for_update.sql.must_equal "SELECT * FROM items FOR UPDATE"
|
39
39
|
@c.from.sql.must_equal "SELECT *"
|
40
40
|
@c.from_self.sql.must_equal "SELECT * FROM (SELECT * FROM items) AS t1"
|
41
|
-
@c.full_join(@c).sql.must_equal "SELECT * FROM items FULL JOIN items"
|
42
|
-
@c.full_outer_join(@c).sql.must_equal "SELECT * FROM items FULL OUTER JOIN items"
|
41
|
+
@c.full_join(@c.table_name).sql.must_equal "SELECT * FROM items FULL JOIN items"
|
42
|
+
@c.full_outer_join(@c.table_name).sql.must_equal "SELECT * FROM items FULL OUTER JOIN items"
|
43
43
|
@c.get(:a).must_equal 1
|
44
44
|
@db.sqls.must_equal ["SELECT a FROM items LIMIT 1"]
|
45
|
-
@c.graph(@c, nil, :table_alias=>:a).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items AS a"
|
45
|
+
@c.graph(@c.table_name, nil, :table_alias=>:a).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items AS a"
|
46
46
|
@db.sqls
|
47
47
|
@c.grep(:id, 'a%').sql.must_equal "SELECT * FROM items WHERE ((id LIKE 'a%' ESCAPE '\\'))"
|
48
48
|
@c.group(:a).sql.must_equal "SELECT * FROM items GROUP BY a"
|
@@ -52,18 +52,18 @@ describe Sequel::Model, "class dataset methods" do
|
|
52
52
|
@c.having(:a).sql.must_equal "SELECT * FROM items HAVING a"
|
53
53
|
@c.import([:id], [[1]])
|
54
54
|
@db.sqls.must_equal ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
55
|
-
@c.inner_join(@c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
55
|
+
@c.inner_join(@c.table_name).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
56
56
|
@c.insert.must_equal 2
|
57
57
|
@db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES"]
|
58
58
|
@c.intersect(@d, :from_self=>false).sql.must_equal "SELECT * FROM items INTERSECT SELECT * FROM items"
|
59
59
|
@c.interval(:id).must_equal 1
|
60
60
|
@db.sqls.must_equal ["SELECT (max(id) - min(id)) AS interval FROM items LIMIT 1"]
|
61
|
-
@c.join(@c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
62
|
-
@c.join_table(:inner, @c).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
61
|
+
@c.join(@c.table_name).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
62
|
+
@c.join_table(:inner, @c.table_name).sql.must_equal "SELECT * FROM items INNER JOIN items"
|
63
63
|
@c.last.must_equal @c.load(:id=>1)
|
64
64
|
@db.sqls.must_equal ["SELECT * FROM items ORDER BY id DESC LIMIT 1"]
|
65
|
-
@c.left_join(@c).sql.must_equal "SELECT * FROM items LEFT JOIN items"
|
66
|
-
@c.left_outer_join(@c).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items"
|
65
|
+
@c.left_join(@c.table_name).sql.must_equal "SELECT * FROM items LEFT JOIN items"
|
66
|
+
@c.left_outer_join(@c.table_name).sql.must_equal "SELECT * FROM items LEFT OUTER JOIN items"
|
67
67
|
@c.limit(2).sql.must_equal "SELECT * FROM items LIMIT 2"
|
68
68
|
@c.lock_style(:update).sql.must_equal "SELECT * FROM items FOR UPDATE"
|
69
69
|
@c.map(:id).must_equal [1]
|
@@ -75,10 +75,10 @@ describe Sequel::Model, "class dataset methods" do
|
|
75
75
|
@c.multi_insert([{:id=>1}])
|
76
76
|
@db.sqls.must_equal ["BEGIN", "INSERT INTO items (id) VALUES (1)", "COMMIT"]
|
77
77
|
@c.naked.row_proc.must_be_nil
|
78
|
-
@c.natural_full_join(@c).sql.must_equal "SELECT * FROM items NATURAL FULL JOIN items"
|
79
|
-
@c.natural_join(@c).sql.must_equal "SELECT * FROM items NATURAL JOIN items"
|
80
|
-
@c.natural_left_join(@c).sql.must_equal "SELECT * FROM items NATURAL LEFT JOIN items"
|
81
|
-
@c.natural_right_join(@c).sql.must_equal "SELECT * FROM items NATURAL RIGHT JOIN items"
|
78
|
+
@c.natural_full_join(@c.table_name).sql.must_equal "SELECT * FROM items NATURAL FULL JOIN items"
|
79
|
+
@c.natural_join(@c.table_name).sql.must_equal "SELECT * FROM items NATURAL JOIN items"
|
80
|
+
@c.natural_left_join(@c.table_name).sql.must_equal "SELECT * FROM items NATURAL LEFT JOIN items"
|
81
|
+
@c.natural_right_join(@c.table_name).sql.must_equal "SELECT * FROM items NATURAL RIGHT JOIN items"
|
82
82
|
@c.offset(2).sql.must_equal "SELECT * FROM items OFFSET 2"
|
83
83
|
@c.order(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
84
84
|
@c.order_append(:a).sql.must_equal "SELECT * FROM items ORDER BY a"
|
@@ -88,8 +88,8 @@ describe Sequel::Model, "class dataset methods" do
|
|
88
88
|
@c.paged_each{|r| r.must_equal @c.load(:id=>1)}
|
89
89
|
@db.sqls.must_equal ["BEGIN", "SELECT * FROM items ORDER BY id LIMIT 1000 OFFSET 0", "COMMIT"]
|
90
90
|
@c.qualify.sql.must_equal 'SELECT items.* FROM items'
|
91
|
-
@c.right_join(@c).sql.must_equal "SELECT * FROM items RIGHT JOIN items"
|
92
|
-
@c.right_outer_join(@c).sql.must_equal "SELECT * FROM items RIGHT OUTER JOIN items"
|
91
|
+
@c.right_join(@c.table_name).sql.must_equal "SELECT * FROM items RIGHT JOIN items"
|
92
|
+
@c.right_outer_join(@c.table_name).sql.must_equal "SELECT * FROM items RIGHT OUTER JOIN items"
|
93
93
|
@c.select(:a).sql.must_equal "SELECT a FROM items"
|
94
94
|
@c.select_all(:items).sql.must_equal "SELECT items.* FROM items"
|
95
95
|
@c.select_append(:a).sql.must_equal "SELECT *, a FROM items"
|
@@ -103,7 +103,9 @@ describe Sequel::Model, "class dataset methods" do
|
|
103
103
|
@c.select_order_map(:id).must_equal [1]
|
104
104
|
@db.sqls.must_equal ["SELECT id FROM items ORDER BY id"]
|
105
105
|
@c.server(:a).opts[:server].must_equal :a
|
106
|
-
|
106
|
+
deprecated do
|
107
|
+
@c.set_graph_aliases(:a=>:b).opts[:graph_aliases].must_equal(:a=>[:b, :a])
|
108
|
+
end
|
107
109
|
@c.single_record.must_equal @c.load(:id=>1)
|
108
110
|
@db.sqls.must_equal ["SELECT * FROM items LIMIT 1"]
|
109
111
|
@c.single_record!.must_equal @c.load(:id=>1)
|
@@ -77,21 +77,21 @@ describe Sequel::Model::DatasetMethods do
|
|
77
77
|
@c.db.reset
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
deprecated "#join_table should allow use to use a model class when joining" do
|
81
81
|
@c.join(Class.new(Sequel::Model(:categories)), :item_id => :id).sql.must_equal 'SELECT * FROM items INNER JOIN categories ON (categories.item_id = items.id)'
|
82
82
|
end
|
83
83
|
|
84
|
-
|
84
|
+
deprecated "#join_table should handle model classes that aren't simple selects using a subselect" do
|
85
85
|
@c.join(Class.new(Sequel::Model(DB[:categories].where(:foo=>1))), :item_id => :id).sql.must_equal 'SELECT * FROM items INNER JOIN (SELECT * FROM categories WHERE (foo = 1)) AS t1 ON (t1.item_id = items.id)'
|
86
86
|
end
|
87
87
|
|
88
|
-
|
88
|
+
deprecated "#graph should allow use to use a model class when joining" do
|
89
89
|
c = Class.new(Sequel::Model(:categories))
|
90
90
|
c.columns :id
|
91
91
|
@c.graph(c, :item_id => :id).sql.must_equal 'SELECT items.id, categories.id AS categories_id FROM items LEFT OUTER JOIN categories ON (categories.item_id = items.id)'
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
deprecated "#insert_sql should handle a single model instance as an argument" do
|
95
95
|
@c.dataset.insert_sql(@c.load(:id=>1)).must_equal 'INSERT INTO items (id) VALUES (1)'
|
96
96
|
end
|
97
97
|
|
@@ -381,7 +381,7 @@ describe Sequel::Model, "#eager" do
|
|
381
381
|
end
|
382
382
|
|
383
383
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_one associations" do
|
384
|
-
EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>Sequel
|
384
|
+
EagerAlbum.many_to_one :sband, :clone=>:band, :eager_loading_predicate_key=>(Sequel[:bands][:id] / 3), :primary_key_method=>:id3
|
385
385
|
EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
|
386
386
|
a = EagerAlbum.eager(:sband).all
|
387
387
|
DB.sqls.must_equal ['SELECT * FROM albums', 'SELECT * FROM bands WHERE ((bands.id / 3) IN (2))']
|
@@ -391,7 +391,7 @@ describe Sequel::Model, "#eager" do
|
|
391
391
|
end
|
392
392
|
|
393
393
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_to_many associations" do
|
394
|
-
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>Sequel
|
394
|
+
EagerBand.one_to_many :salbums, :clone=>:albums, :eager_loading_predicate_key=>(Sequel[:albums][:band_id] * 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
|
395
395
|
EagerBand.dataset = EagerBand.dataset.with_fetch(:id=>6)
|
396
396
|
a = EagerBand.eager(:salbums).all
|
397
397
|
DB.sqls.must_equal ['SELECT * FROM bands', 'SELECT * FROM albums WHERE ((albums.band_id * 3) IN (6))']
|
@@ -401,7 +401,7 @@ describe Sequel::Model, "#eager" do
|
|
401
401
|
end
|
402
402
|
|
403
403
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for many_to_many associations" do
|
404
|
-
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>Sequel
|
404
|
+
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :eager_loading_predicate_key=>(Sequel[:ag][:album_id] * 1)
|
405
405
|
a = EagerAlbum.eager(:sgenres).all
|
406
406
|
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
407
407
|
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE ((ag.album_id * 1) IN (1))"]
|
@@ -410,7 +410,7 @@ describe Sequel::Model, "#eager" do
|
|
410
410
|
end
|
411
411
|
|
412
412
|
it "should handle a :eager_loading_predicate_key option to change the SQL used in the lookup, for one_through_one associations" do
|
413
|
-
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :eager_loading_predicate_key=>Sequel
|
413
|
+
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :eager_loading_predicate_key=>(Sequel[:ag][:album_id] * 1)
|
414
414
|
a = EagerAlbum.eager(:sgenre).all
|
415
415
|
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
416
416
|
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, (ag.album_id * 1) AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE ((ag.album_id * 1) IN (1))"]
|
@@ -445,18 +445,30 @@ describe Sequel::Model, "#eager" do
|
|
445
445
|
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT *, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON (ag.genre_id = genres.id) WHERE (ag.album_id IN (1))"]
|
446
446
|
end
|
447
447
|
|
448
|
-
|
448
|
+
with_symbol_splitting "should correctly handle an aliased join table symbol in many_to_many" do
|
449
449
|
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>:ag___ga
|
450
450
|
EagerAlbum.eager(:sgenres).all
|
451
451
|
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (ga.genre_id = genres.id) WHERE (ga.album_id IN (1))"]
|
452
452
|
end
|
453
453
|
|
454
|
-
|
454
|
+
with_symbol_splitting "should correctly handle an aliased join table symbol in one_through_one" do
|
455
455
|
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :join_table=>:ag___ga
|
456
456
|
EagerAlbum.eager(:sgenre).all
|
457
457
|
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (ga.genre_id = genres.id) WHERE (ga.album_id IN (1))"]
|
458
458
|
end
|
459
459
|
|
460
|
+
it "should correctly handle an aliased join table in many_to_many" do
|
461
|
+
EagerAlbum.many_to_many :sgenres, :clone=>:genres, :join_table=>Sequel[:ag].as(:ga)
|
462
|
+
EagerAlbum.eager(:sgenres).all
|
463
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (ga.genre_id = genres.id) WHERE (ga.album_id IN (1))"]
|
464
|
+
end
|
465
|
+
|
466
|
+
it "should correctly handle an aliased join table in one_through_one" do
|
467
|
+
EagerAlbum.one_through_one :sgenre, :clone=>:genre, :join_table=>Sequel[:ag].as(:ga)
|
468
|
+
EagerAlbum.eager(:sgenre).all
|
469
|
+
DB.sqls.must_equal ['SELECT * FROM albums', "SELECT genres.*, ga.album_id AS x_foreign_key_x FROM genres INNER JOIN ag AS ga ON (ga.genre_id = genres.id) WHERE (ga.album_id IN (1))"]
|
470
|
+
end
|
471
|
+
|
460
472
|
it "should eagerly load multiple associations in a single call" do
|
461
473
|
a = EagerAlbum.eager(:genres, :tracks, :band).all
|
462
474
|
a.must_equal [EagerAlbum.load(:id => 1, :band_id => 2)]
|
@@ -629,7 +641,7 @@ describe Sequel::Model, "#eager" do
|
|
629
641
|
a.first.good_bands.must_equal [EagerBand.load(:id => 2)]
|
630
642
|
DB.sqls.must_equal []
|
631
643
|
|
632
|
-
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>"x = 1"
|
644
|
+
EagerBandMember.many_to_many :good_bands, :clone=>:bands, :conditions=>Sequel.lit("x = 1")
|
633
645
|
a = EagerBandMember.eager(:good_bands).all
|
634
646
|
DB.sqls.must_equal ['SELECT * FROM members', 'SELECT bands.*, bm.member_id AS x_foreign_key_x FROM bands INNER JOIN bm ON (bm.band_id = bands.id) WHERE ((x = 1) AND (bm.member_id IN (5))) ORDER BY id']
|
635
647
|
end
|
@@ -661,7 +673,7 @@ describe Sequel::Model, "#eager" do
|
|
661
673
|
end
|
662
674
|
|
663
675
|
it "should cache the negative lookup when eagerly loading a *_to_many associations" do
|
664
|
-
a = EagerBand.eager(:albums).
|
676
|
+
a = EagerBand.eager(:albums).where{id > 100}.all
|
665
677
|
a.must_equal [EagerBand.load(:id => 101), EagerBand.load(:id =>102)]
|
666
678
|
sqls = DB.sqls
|
667
679
|
['SELECT * FROM albums WHERE (albums.band_id IN (101, 102))', 'SELECT * FROM albums WHERE (albums.band_id IN (102, 101))'].must_include(sqls.delete_at(1))
|
@@ -1238,14 +1250,14 @@ describe Sequel::Model, "#eager_graph" do
|
|
1238
1250
|
|
1239
1251
|
it "should work correctly with select_map" do
|
1240
1252
|
ds = GraphAlbum.eager_graph(:band)
|
1241
|
-
ds.with_fetch([{:id=>1}, {:id=>2}]).select_map(:
|
1253
|
+
ds.with_fetch([{:id=>1}, {:id=>2}]).select_map(Sequel[:albums][:id]).must_equal [1, 2]
|
1242
1254
|
DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
|
1243
|
-
ds.with_fetch([{:id=>1}, {:id=>2}]).select_map([:
|
1255
|
+
ds.with_fetch([{:id=>1}, {:id=>2}]).select_map([Sequel[:albums][:id], Sequel[:albums][:id]]).must_equal [[1, 1], [2, 2]]
|
1244
1256
|
DB.sqls.must_equal ['SELECT albums.id, albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)']
|
1245
1257
|
end
|
1246
1258
|
|
1247
1259
|
it "should work correctly with single_value" do
|
1248
|
-
ds = GraphAlbum.eager_graph(:band).select(:
|
1260
|
+
ds = GraphAlbum.eager_graph(:band).select(Sequel[:albums][:id])
|
1249
1261
|
ds.with_fetch([{:id=>1}]).single_value.must_equal 1
|
1250
1262
|
DB.sqls.must_equal ['SELECT albums.id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id) LIMIT 1']
|
1251
1263
|
end
|
@@ -1471,7 +1483,15 @@ describe Sequel::Model, "#eager_graph" do
|
|
1471
1483
|
a.first.lgenre.must_equal sub.load(:id => 4)
|
1472
1484
|
end
|
1473
1485
|
|
1474
|
-
it "should correctly handle an aliased join table in many_to_many and one_through_one" do
|
1486
|
+
it "should correctly handle an aliased join table in many_to_many and one_through_one with conditions" do
|
1487
|
+
c = Class.new(GraphAlbum)
|
1488
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>Sequel[:ag].as(:ga), :conditions=>'true', :ignore_conditions_warning=> true
|
1489
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
1490
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>Sequel[:ag].as(:ga), :conditions=>'true', :graph_block => proc{true}
|
1491
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON ((genres.id = ga.genre_id) AND \'t\')'
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
with_symbol_splitting "should correctly handle an aliased join table symbol in many_to_many and one_through_one with conditions" do
|
1475
1495
|
c = Class.new(GraphAlbum)
|
1476
1496
|
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga, :conditions=>'true', :ignore_conditions_warning=> true
|
1477
1497
|
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
@@ -1479,7 +1499,7 @@ describe Sequel::Model, "#eager_graph" do
|
|
1479
1499
|
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON ((genres.id = ga.genre_id) AND \'t\')'
|
1480
1500
|
end
|
1481
1501
|
|
1482
|
-
|
1502
|
+
with_symbol_splitting "should correctly handle an aliased join table symbol in many_to_many and one_through_one" do
|
1483
1503
|
c = Class.new(GraphAlbum)
|
1484
1504
|
c.many_to_many :genres, :clone=>:genres, :join_table=>:ag___ga
|
1485
1505
|
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
@@ -1494,6 +1514,21 @@ describe Sequel::Model, "#eager_graph" do
|
|
1494
1514
|
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS genres_0 ON (genres_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = genres_0.genre_id)'
|
1495
1515
|
end
|
1496
1516
|
|
1517
|
+
it "should correctly handle an aliased join table in many_to_many and one_through_one" do
|
1518
|
+
c = Class.new(GraphAlbum)
|
1519
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>Sequel[:ag].as(:ga)
|
1520
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = ga.genre_id)'
|
1521
|
+
|
1522
|
+
c.many_to_many :genre, :clone=>:genre, :join_table=>Sequel[:ag].as(:ga)
|
1523
|
+
c.eager_graph(:genre).sql.must_equal 'SELECT albums.id, albums.band_id, genre.id AS genre_id FROM albums LEFT OUTER JOIN ag AS ga ON (ga.album_id = albums.id) LEFT OUTER JOIN genres AS genre ON (genre.id = ga.genre_id)'
|
1524
|
+
|
1525
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>Sequel[:ag].as(:albums)
|
1526
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS albums_0 ON (albums_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = albums_0.genre_id)'
|
1527
|
+
|
1528
|
+
c.many_to_many :genres, :clone=>:genres, :join_table=>Sequel[:ag].as(:genres)
|
1529
|
+
c.eager_graph(:genres).sql.must_equal 'SELECT albums.id, albums.band_id, genres.id AS genres_id FROM albums LEFT OUTER JOIN ag AS genres_0 ON (genres_0.album_id = albums.id) LEFT OUTER JOIN genres ON (genres.id = genres_0.genre_id)'
|
1530
|
+
end
|
1531
|
+
|
1497
1532
|
it "should handle multiple associations in a single call to association_join" do
|
1498
1533
|
GraphAlbum.association_join(:genres, :tracks, :band).sql.must_equal 'SELECT * FROM albums INNER JOIN ag ON (ag.album_id = albums.id) INNER JOIN genres ON (genres.id = ag.genre_id) INNER JOIN tracks ON (tracks.album_id = albums.id) INNER JOIN bands AS band ON (band.id = albums.band_id)'
|
1499
1534
|
end
|
@@ -1891,13 +1926,13 @@ describe Sequel::Model, "#eager_graph" do
|
|
1891
1926
|
end
|
1892
1927
|
|
1893
1928
|
it "should respect the association's :eager_grapher option" do
|
1894
|
-
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)}
|
1929
|
+
GraphAlbum.many_to_one :active_band, :class=>'GraphBand', :key=>:band_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphBand.dataset, {:active=>true}, :table_alias=>eo[:table_alias], :join_type=>:inner)}
|
1895
1930
|
GraphAlbum.eager_graph(:active_band).sql.must_equal "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)"
|
1896
1931
|
|
1897
|
-
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])}
|
1932
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :eager_grapher=>proc{|eo| eo[:self].graph(GraphTrack.dataset, nil, :join_type=>:natural, :table_alias=>eo[:table_alias])}
|
1898
1933
|
GraphAlbum.eager_graph(:right_tracks).sql.must_equal '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'
|
1899
1934
|
|
1900
|
-
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])}
|
1935
|
+
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.dataset, [:album_id], :table_alias=>eo[:table_alias])}
|
1901
1936
|
GraphAlbum.eager_graph(:active_genres).sql.must_equal "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)"
|
1902
1937
|
end
|
1903
1938
|
|
@@ -1916,8 +1951,8 @@ describe Sequel::Model, "#eager_graph" do
|
|
1916
1951
|
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_join_table_only_conditions=>{:active=>true}
|
1917
1952
|
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON (ag.active IS TRUE) LEFT OUTER JOIN genres AS active_genres ON (active_genres.id = ag.genre_id)"
|
1918
1953
|
|
1919
|
-
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_only_conditions=>(Sequel.expr(:price) + 2 > 100), :graph_join_table_only_conditions=>"active"
|
1920
|
-
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON
|
1954
|
+
GraphAlbum.many_to_many :active_genres, :class=>'GraphGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :graph_only_conditions=>(Sequel.expr(:price) + 2 > 100), :graph_join_table_only_conditions=>Sequel.identifier("active")
|
1955
|
+
GraphAlbum.eager_graph(:active_genres).sql.must_equal "SELECT albums.id, albums.band_id, active_genres.id AS active_genres_id FROM albums LEFT OUTER JOIN ag ON active LEFT OUTER JOIN genres AS active_genres ON ((price + 2) > 100)"
|
1921
1956
|
end
|
1922
1957
|
|
1923
1958
|
it "should create unique table aliases for all associations" do
|
@@ -1929,8 +1964,13 @@ describe Sequel::Model, "#eager_graph" do
|
|
1929
1964
|
GraphAlbum.eager_graph(:right_tracks).sql.must_equal '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) ORDER BY right_tracks.id, right_tracks.album_id'
|
1930
1965
|
end
|
1931
1966
|
|
1967
|
+
with_symbol_splitting "should not qualify qualified symbols in association's :order" do
|
1968
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[Sequel.desc(:blah__id), :blah__id]
|
1969
|
+
GraphAlbum.eager_graph(:right_tracks).sql.must_equal '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) ORDER BY blah.id DESC, blah.id'
|
1970
|
+
end
|
1971
|
+
|
1932
1972
|
it "should only qualify unqualified symbols, identifiers, or ordered versions in association's :order" do
|
1933
|
-
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel.desc
|
1973
|
+
GraphAlbum.one_to_many :right_tracks, :class=>'GraphTrack', :key=>:album_id, :order=>[Sequel.identifier(:blah__id), Sequel.identifier(:blah__id).desc, Sequel[:blah][:id].desc, Sequel[:blah][:id], :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
|
1934
1974
|
GraphAlbum.eager_graph(:right_tracks).sql.must_equal '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) ORDER BY right_tracks.blah__id, right_tracks.blah__id DESC, blah.id DESC, blah.id, right_tracks.album_id, right_tracks.album_id DESC, 1, RANDOM(), b.a'
|
1935
1975
|
end
|
1936
1976
|
|
@@ -1983,20 +2023,40 @@ describe Sequel::Model, "#eager_graph" do
|
|
1983
2023
|
end
|
1984
2024
|
|
1985
2025
|
it "should handle eager loading with schemas and aliases of different types" do
|
1986
|
-
GraphAlbum.eager_graph(:band).join(:
|
2026
|
+
GraphAlbum.eager_graph(:band).join(Sequel[:s][:genres], [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
1987
2027
|
GraphAlbum.eager_graph(:band).join(Sequel.qualify(:s, :genres), [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
1988
|
-
GraphAlbum.eager_graph(:band).join(Sequel
|
1989
|
-
GraphAlbum.eager_graph(:band).join(:
|
2028
|
+
GraphAlbum.eager_graph(:band).join(Sequel[:s][:b].as('genres'), [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
2029
|
+
GraphAlbum.eager_graph(:band).join(Sequel[:s][:b], [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.must_equal '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)'
|
1990
2030
|
GraphAlbum.eager_graph(:band).join(Sequel.identifier(:genres), [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
1991
2031
|
GraphAlbum.eager_graph(:band).join('genres', [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
1992
2032
|
end
|
1993
2033
|
|
2034
|
+
with_symbol_splitting "should handle eager loading with splittable symbols" do
|
2035
|
+
GraphAlbum.eager_graph(:band).join(:s__genres, [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
2036
|
+
GraphAlbum.eager_graph(:band).join(Sequel.expr(:s__b).as('genres'), [:b_id]).eager_graph(:genres).sql.must_equal '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)'
|
2037
|
+
GraphAlbum.eager_graph(:band).join(:s__b, [:b_id], :table_alias=>Sequel.identifier(:genres)).eager_graph(:genres).sql.must_equal '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)'
|
2038
|
+
end
|
2039
|
+
|
1994
2040
|
it "should raise errors if invalid aliases or table styles are used" do
|
1995
2041
|
proc{GraphAlbum.from_self(:alias=>Sequel.qualify(:s, :bands)).eager_graph(:band)}.must_raise(Sequel::Error)
|
1996
2042
|
proc{GraphAlbum.from(Sequel.lit('?', :bands)).eager_graph(:band)}.must_raise(Sequel::Error)
|
1997
2043
|
end
|
1998
2044
|
|
1999
2045
|
it "should eagerly load schema qualified tables correctly with joins" do
|
2046
|
+
c1 = Class.new(GraphAlbum)
|
2047
|
+
c2 = Class.new(GraphGenre)
|
2048
|
+
ds = c1.dataset.from(Sequel[:s][:a]).with_extend{def columns; [:id] end}
|
2049
|
+
c1.dataset = ds
|
2050
|
+
ds = c1.dataset
|
2051
|
+
c2.dataset = c2.dataset.from(Sequel[:s][:g])
|
2052
|
+
c1.many_to_many :a_genres, :class=>c2, :left_primary_key=>:id, :left_key=>:album_id, :right_key=>:genre_id, :join_table=>Sequel[:s][:ag]
|
2053
|
+
ds = c1.join(Sequel[:s][:t], [:b_id]).eager_graph(:a_genres)
|
2054
|
+
ds.sql.must_equal 'SELECT a.id, a_genres.id AS a_genres_id FROM (SELECT * FROM s.a INNER JOIN s.t USING (b_id)) AS a LEFT OUTER JOIN s.ag AS ag ON (ag.album_id = a.id) LEFT OUTER JOIN s.g AS a_genres ON (a_genres.id = ag.genre_id)'
|
2055
|
+
ds = c1.eager_graph(:a_genres)
|
2056
|
+
ds.sql.must_equal 'SELECT s.a.id, a_genres.id AS a_genres_id FROM s.a LEFT OUTER JOIN s.ag AS ag ON (ag.album_id = s.a.id) LEFT OUTER JOIN s.g AS a_genres ON (a_genres.id = ag.genre_id)'
|
2057
|
+
end
|
2058
|
+
|
2059
|
+
with_symbol_splitting "should eagerly load schema qualified table symbols correctly with joins" do
|
2000
2060
|
c1 = Class.new(GraphAlbum)
|
2001
2061
|
c2 = Class.new(GraphGenre)
|
2002
2062
|
ds = c1.dataset.from(:s__a).with_extend{def columns; [:id] end}
|
@@ -2152,7 +2212,7 @@ describe "Sequel::Models with double underscores in table names" do
|
|
2152
2212
|
it "should have working eager_graph implementations" do
|
2153
2213
|
@db.fetch = {:id=>1, :foo_id=>1, :foos_id=>1, :foos_foo_id=>1}
|
2154
2214
|
foos = @Foo.eager_graph(:foos).all
|
2155
|
-
@db.sqls.must_equal ["SELECT fo__os.id, fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM fo__os LEFT OUTER JOIN
|
2215
|
+
@db.sqls.must_equal ["SELECT fo__os.id, fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM fo__os LEFT OUTER JOIN fo__os AS foos ON (foos._id = fo__os.id)"]
|
2156
2216
|
foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
2157
2217
|
foos.first.foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
2158
2218
|
end
|
@@ -2163,7 +2223,7 @@ describe "Sequel::Models with double underscores in table names" do
|
|
2163
2223
|
@db.sqls
|
2164
2224
|
@db.fetch = {:id=>1, :foo_id=>1, :foos_id=>1, :foos_foo_id=>1}
|
2165
2225
|
foos = @Foo.eager_graph(:foos).all
|
2166
|
-
@db.sqls.must_equal ["SELECT s.fo__os.id, s.fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM s.fo__os LEFT OUTER JOIN
|
2226
|
+
@db.sqls.must_equal ["SELECT s.fo__os.id, s.fo__os.foo_id, foos.id AS foos_id, foos.foo_id AS foos_foo_id FROM s.fo__os LEFT OUTER JOIN s.fo__os AS foos ON (foos._id = s.fo__os.id)"]
|
2167
2227
|
foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
2168
2228
|
foos.first.foos.must_equal [@Foo.load(:id=>1, :foo_id=>1)]
|
2169
2229
|
end
|