sequel 4.45.0 → 4.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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