sequel 4.45.0 → 4.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +108 -0
  3. data/doc/release_notes/4.46.0.txt +404 -0
  4. data/doc/security.rdoc +9 -0
  5. data/doc/sql.rdoc +2 -2
  6. data/doc/testing.rdoc +1 -1
  7. data/doc/validations.rdoc +1 -2
  8. data/lib/sequel/adapters/ado.rb +8 -3
  9. data/lib/sequel/adapters/ado/access.rb +8 -4
  10. data/lib/sequel/adapters/ado/mssql.rb +3 -1
  11. data/lib/sequel/adapters/amalgalite.rb +5 -0
  12. data/lib/sequel/adapters/cubrid.rb +16 -7
  13. data/lib/sequel/adapters/do.rb +7 -1
  14. data/lib/sequel/adapters/do/mysql.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +10 -5
  16. data/lib/sequel/adapters/jdbc.rb +8 -2
  17. data/lib/sequel/adapters/jdbc/as400.rb +10 -3
  18. data/lib/sequel/adapters/jdbc/db2.rb +27 -16
  19. data/lib/sequel/adapters/jdbc/derby.rb +47 -20
  20. data/lib/sequel/adapters/jdbc/h2.rb +13 -7
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
  22. data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
  24. data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
  26. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
  29. data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
  30. data/lib/sequel/adapters/mock.rb +5 -0
  31. data/lib/sequel/adapters/mysql.rb +8 -1
  32. data/lib/sequel/adapters/mysql2.rb +6 -1
  33. data/lib/sequel/adapters/odbc.rb +20 -8
  34. data/lib/sequel/adapters/odbc/mssql.rb +6 -3
  35. data/lib/sequel/adapters/oracle.rb +12 -6
  36. data/lib/sequel/adapters/postgres.rb +20 -8
  37. data/lib/sequel/adapters/shared/access.rb +76 -47
  38. data/lib/sequel/adapters/shared/cubrid.rb +16 -11
  39. data/lib/sequel/adapters/shared/db2.rb +46 -19
  40. data/lib/sequel/adapters/shared/firebird.rb +20 -8
  41. data/lib/sequel/adapters/shared/informix.rb +6 -3
  42. data/lib/sequel/adapters/shared/mssql.rb +132 -72
  43. data/lib/sequel/adapters/shared/mysql.rb +112 -65
  44. data/lib/sequel/adapters/shared/oracle.rb +36 -21
  45. data/lib/sequel/adapters/shared/postgres.rb +91 -56
  46. data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
  47. data/lib/sequel/adapters/shared/sqlite.rb +67 -32
  48. data/lib/sequel/adapters/sqlanywhere.rb +9 -1
  49. data/lib/sequel/adapters/sqlite.rb +8 -1
  50. data/lib/sequel/adapters/swift.rb +5 -0
  51. data/lib/sequel/adapters/swift/mysql.rb +4 -2
  52. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  53. data/lib/sequel/adapters/tinytds.rb +10 -3
  54. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  55. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  56. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  57. data/lib/sequel/adapters/utils/pg_types.rb +14 -6
  58. data/lib/sequel/adapters/utils/replace.rb +4 -2
  59. data/lib/sequel/connection_pool/single.rb +2 -2
  60. data/lib/sequel/core.rb +24 -11
  61. data/lib/sequel/database/connecting.rb +9 -3
  62. data/lib/sequel/database/dataset_defaults.rb +7 -1
  63. data/lib/sequel/database/logging.rb +1 -0
  64. data/lib/sequel/database/misc.rb +5 -2
  65. data/lib/sequel/database/query.rb +7 -5
  66. data/lib/sequel/database/schema_generator.rb +1 -0
  67. data/lib/sequel/database/schema_methods.rb +50 -27
  68. data/lib/sequel/database/transactions.rb +19 -9
  69. data/lib/sequel/dataset/actions.rb +15 -6
  70. data/lib/sequel/dataset/graph.rb +15 -5
  71. data/lib/sequel/dataset/misc.rb +12 -4
  72. data/lib/sequel/dataset/mutation.rb +17 -8
  73. data/lib/sequel/dataset/prepared_statements.rb +3 -2
  74. data/lib/sequel/dataset/query.rb +84 -38
  75. data/lib/sequel/dataset/sql.rb +302 -191
  76. data/lib/sequel/deprecated.rb +26 -17
  77. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
  78. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  79. data/lib/sequel/extensions/from_block.rb +1 -0
  80. data/lib/sequel/extensions/graph_each.rb +1 -1
  81. data/lib/sequel/extensions/identifier_mangling.rb +2 -2
  82. data/lib/sequel/extensions/migration.rb +28 -4
  83. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
  84. data/lib/sequel/extensions/schema_dumper.rb +4 -4
  85. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
  86. data/lib/sequel/extensions/set_overrides.rb +2 -0
  87. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  88. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  89. data/lib/sequel/model.rb +11 -7
  90. data/lib/sequel/model/associations.rb +5 -7
  91. data/lib/sequel/model/base.rb +47 -45
  92. data/lib/sequel/model/dataset_module.rb +9 -14
  93. data/lib/sequel/model/plugins.rb +3 -0
  94. data/lib/sequel/no_core_ext.rb +1 -0
  95. data/lib/sequel/plugins/blacklist_security.rb +1 -1
  96. data/lib/sequel/plugins/boolean_subsets.rb +7 -5
  97. data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
  98. data/lib/sequel/plugins/dataset_associations.rb +1 -1
  99. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  100. data/lib/sequel/plugins/finder.rb +240 -0
  101. data/lib/sequel/plugins/inverted_subsets.rb +19 -12
  102. data/lib/sequel/plugins/many_through_many.rb +1 -1
  103. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  104. data/lib/sequel/plugins/schema.rb +1 -1
  105. data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
  106. data/lib/sequel/plugins/subset_conditions.rb +11 -3
  107. data/lib/sequel/plugins/whitelist_security.rb +118 -0
  108. data/lib/sequel/sql.rb +80 -36
  109. data/lib/sequel/timezones.rb +2 -0
  110. data/lib/sequel/version.rb +1 -1
  111. data/spec/adapters/mssql_spec.rb +20 -0
  112. data/spec/adapters/mysql_spec.rb +1 -1
  113. data/spec/adapters/oracle_spec.rb +12 -8
  114. data/spec/adapters/postgres_spec.rb +1 -1
  115. data/spec/adapters/spec_helper.rb +1 -1
  116. data/spec/adapters/sqlite_spec.rb +36 -34
  117. data/spec/core/connection_pool_spec.rb +2 -1
  118. data/spec/core/database_spec.rb +87 -9
  119. data/spec/core/dataset_spec.rb +501 -129
  120. data/spec/core/deprecated_spec.rb +1 -1
  121. data/spec/core/expression_filters_spec.rb +146 -60
  122. data/spec/core/mock_adapter_spec.rb +1 -1
  123. data/spec/core/object_graph_spec.rb +61 -9
  124. data/spec/core/placeholder_literalizer_spec.rb +20 -2
  125. data/spec/core/schema_generator_spec.rb +6 -6
  126. data/spec/core/schema_spec.rb +54 -5
  127. data/spec/core_extensions_spec.rb +122 -18
  128. data/spec/deprecation_helper.rb +27 -2
  129. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
  130. data/spec/extensions/association_proxies_spec.rb +2 -2
  131. data/spec/extensions/auto_literal_strings_spec.rb +212 -0
  132. data/spec/extensions/blacklist_security_spec.rb +1 -0
  133. data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
  134. data/spec/extensions/column_select_spec.rb +20 -8
  135. data/spec/extensions/columns_introspection_spec.rb +3 -3
  136. data/spec/extensions/core_refinements_spec.rb +29 -12
  137. data/spec/extensions/dataset_associations_spec.rb +12 -12
  138. data/spec/extensions/def_dataset_method_spec.rb +100 -0
  139. data/spec/extensions/error_sql_spec.rb +1 -1
  140. data/spec/extensions/finder_spec.rb +260 -0
  141. data/spec/extensions/graph_each_spec.rb +2 -2
  142. data/spec/extensions/identifier_mangling_spec.rb +14 -8
  143. data/spec/extensions/inverted_subsets_spec.rb +4 -4
  144. data/spec/extensions/lazy_attributes_spec.rb +7 -0
  145. data/spec/extensions/many_through_many_spec.rb +38 -14
  146. data/spec/extensions/nested_attributes_spec.rb +18 -6
  147. data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
  148. data/spec/extensions/pg_enum_spec.rb +16 -1
  149. data/spec/extensions/pg_interval_spec.rb +11 -2
  150. data/spec/extensions/pg_loose_count_spec.rb +5 -0
  151. data/spec/extensions/pg_row_spec.rb +25 -0
  152. data/spec/extensions/prepared_statements_spec.rb +10 -1
  153. data/spec/extensions/query_spec.rb +2 -2
  154. data/spec/extensions/schema_dumper_spec.rb +2 -2
  155. data/spec/extensions/schema_spec.rb +2 -2
  156. data/spec/extensions/set_overrides_spec.rb +7 -3
  157. data/spec/extensions/sql_expr_spec.rb +0 -1
  158. data/spec/extensions/subset_conditions_spec.rb +6 -6
  159. data/spec/extensions/table_select_spec.rb +24 -12
  160. data/spec/extensions/to_dot_spec.rb +4 -4
  161. data/spec/extensions/whitelist_security_spec.rb +131 -0
  162. data/spec/integration/dataset_test.rb +9 -5
  163. data/spec/integration/model_test.rb +2 -0
  164. data/spec/integration/plugin_test.rb +2 -2
  165. data/spec/integration/spec_helper.rb +1 -1
  166. data/spec/model/associations_spec.rb +39 -11
  167. data/spec/model/base_spec.rb +44 -24
  168. data/spec/model/class_dataset_methods_spec.rb +18 -16
  169. data/spec/model/dataset_methods_spec.rb +4 -4
  170. data/spec/model/eager_loading_spec.rb +84 -24
  171. data/spec/model/model_spec.rb +97 -63
  172. data/spec/model/record_spec.rb +21 -13
  173. 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 = !ENV['SEQUEL_NO_MANGLE'] unless defined?(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
- it "should not override a selection consisting completely of qualified columns using symbols" do
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(:attributes_nodes__node_id, 0)
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 => ['a = ?', 32]
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), :attribute_nodes__blah2]
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(:an__nodeid=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
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(:an__nodeid=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
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(:attributes_nodes__node_id, 0)
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 => ['a = ?', 32]
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), :attribute_nodes__blah2]
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(:an__nodeid=>pk)}, :order=> :a, :select=>nil do |ds|
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(:an__nodeid=>pk)}, :order=> :a, :select=>nil do |ds|
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"
@@ -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
- it "should add a method to the dataset and model if called with a block argument" do
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
- it "should handle weird method names" do
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
- it "should not add a model method if the model already responds to the method" do
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
- it "should add all passed methods to the model if called without a block argument" do
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
- it "should cache calls and readd methods if set_dataset is used" do
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
- it "should readd methods to subclasses, if set_dataset is used in a subclass" do
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
- it "should affect the underlying dataset" do
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
- it "should keep the same dataset options" do
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, ".(allowed|restricted)_columns " do
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
- it "should set the allowed columns correctly" do
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
- it "should only set allowed columns by default" do
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(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
668
- proc{@c.create(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
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(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
671
- proc{c.set_all(:use_after_commit_rollback => false)}.must_raise(Sequel::MassAssignmentRestriction)
672
- proc{c.set_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
673
- proc{c.update(:z=>1)}.must_raise(Sequel::MassAssignmentRestriction)
674
- proc{c.update_all(:use_after_commit_rollback=>false)}.must_raise(Sequel::MassAssignmentRestriction)
675
- proc{c.update_only({:x=>1}, :y)}.must_raise(Sequel::MassAssignmentRestriction)
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(:z=>1)
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
- it "should not have #[] consider a string as a primary key lookup" do
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
- @c.set_graph_aliases(:a=>:b).opts[:graph_aliases].must_equal(:a=>[:b, :a])
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
- it "#join_table should allow use to use a model class when joining" do
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
- it "#join_table should handle model classes that aren't simple selects using a subselect" do
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
- it "#graph should allow use to use a model class when joining" do
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
- it "#insert_sql should handle a single model instance as an argument" do
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./(:bands__id, 3), :primary_key_method=>:id3
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.*(:albums__band_id, 3), :key_method=>:band_id3, :eager=>nil, :reciprocal=>nil
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.*(:ag__album_id, 1)
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.*(:ag__album_id, 1)
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
- it "should correctly handle an aliased join table in many_to_many" do
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
- it "should correctly handle an aliased join table in one_through_one" do
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).filter('id > 100').all
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(:albums__id).must_equal [1, 2]
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([:albums__id, :albums__id]).must_equal [[1, 1], [2, 2]]
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(:albums__id)
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
- it "should correctly handle an aliased join table in many_to_many and one_through_one" do
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 (active) LEFT OUTER JOIN genres AS active_genres ON ((price + 2) > 100)"
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(:blah__id), :blah__id, :album_id, Sequel.desc(:album_id), 1, Sequel.lit('RANDOM()'), Sequel.qualify(:b, :a)]
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(: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)'
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.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)'
1989
- 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)'
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 (SELECT * FROM fo__os) AS foos ON (foos._id = fo__os.id)"]
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 (SELECT * FROM s.fo__os) AS foos ON (foos._id = s.fo__os.id)"]
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