sequel 4.41.0 → 4.42.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +98 -0
  3. data/README.rdoc +23 -10
  4. data/doc/active_record.rdoc +4 -4
  5. data/doc/advanced_associations.rdoc +2 -2
  6. data/doc/association_basics.rdoc +5 -2
  7. data/doc/cheat_sheet.rdoc +3 -3
  8. data/doc/core_extensions.rdoc +2 -2
  9. data/doc/dataset_basics.rdoc +4 -4
  10. data/doc/dataset_filtering.rdoc +1 -1
  11. data/doc/migration.rdoc +19 -1
  12. data/doc/prepared_statements.rdoc +2 -2
  13. data/doc/release_notes/4.42.0.txt +221 -0
  14. data/doc/testing.rdoc +3 -1
  15. data/lib/sequel/adapters/ado/access.rb +0 -1
  16. data/lib/sequel/adapters/ado/mssql.rb +0 -1
  17. data/lib/sequel/adapters/do/mysql.rb +0 -1
  18. data/lib/sequel/adapters/do/postgres.rb +0 -1
  19. data/lib/sequel/adapters/do/sqlite3.rb +0 -1
  20. data/lib/sequel/adapters/ibmdb.rb +21 -25
  21. data/lib/sequel/adapters/jdbc.rb +8 -16
  22. data/lib/sequel/adapters/jdbc/as400.rb +0 -1
  23. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
  24. data/lib/sequel/adapters/jdbc/db2.rb +0 -1
  25. data/lib/sequel/adapters/jdbc/derby.rb +0 -1
  26. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
  27. data/lib/sequel/adapters/jdbc/h2.rb +0 -1
  28. data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
  29. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
  30. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
  31. data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
  32. data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
  34. data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
  36. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
  37. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
  38. data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
  39. data/lib/sequel/adapters/mock.rb +54 -12
  40. data/lib/sequel/adapters/mysql.rb +1 -1
  41. data/lib/sequel/adapters/mysql2.rb +11 -17
  42. data/lib/sequel/adapters/odbc/mssql.rb +0 -1
  43. data/lib/sequel/adapters/oracle.rb +8 -20
  44. data/lib/sequel/adapters/postgres.rb +11 -29
  45. data/lib/sequel/adapters/shared/access.rb +5 -12
  46. data/lib/sequel/adapters/shared/cubrid.rb +4 -13
  47. data/lib/sequel/adapters/shared/db2.rb +4 -2
  48. data/lib/sequel/adapters/shared/firebird.rb +2 -4
  49. data/lib/sequel/adapters/shared/informix.rb +4 -2
  50. data/lib/sequel/adapters/shared/mssql.rb +3 -5
  51. data/lib/sequel/adapters/shared/mysql.rb +4 -14
  52. data/lib/sequel/adapters/shared/oracle.rb +1 -3
  53. data/lib/sequel/adapters/shared/postgres.rb +16 -38
  54. data/lib/sequel/adapters/shared/progress.rb +0 -2
  55. data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
  56. data/lib/sequel/adapters/shared/sqlite.rb +20 -16
  57. data/lib/sequel/adapters/sqlite.rb +8 -20
  58. data/lib/sequel/adapters/swift/mysql.rb +0 -1
  59. data/lib/sequel/adapters/swift/postgres.rb +0 -1
  60. data/lib/sequel/adapters/swift/sqlite.rb +0 -1
  61. data/lib/sequel/adapters/tinytds.rb +4 -12
  62. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  63. data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
  64. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
  65. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  66. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
  67. data/lib/sequel/ast_transformer.rb +2 -2
  68. data/lib/sequel/database/dataset.rb +1 -1
  69. data/lib/sequel/database/dataset_defaults.rb +0 -66
  70. data/lib/sequel/database/features.rb +6 -0
  71. data/lib/sequel/database/misc.rb +31 -17
  72. data/lib/sequel/database/query.rb +7 -4
  73. data/lib/sequel/database/schema_methods.rb +1 -1
  74. data/lib/sequel/dataset.rb +8 -8
  75. data/lib/sequel/dataset/actions.rb +140 -46
  76. data/lib/sequel/dataset/features.rb +1 -5
  77. data/lib/sequel/dataset/graph.rb +7 -8
  78. data/lib/sequel/dataset/misc.rb +127 -56
  79. data/lib/sequel/dataset/mutation.rb +9 -20
  80. data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
  81. data/lib/sequel/dataset/prepared_statements.rb +102 -46
  82. data/lib/sequel/dataset/query.rb +155 -72
  83. data/lib/sequel/dataset/sql.rb +26 -9
  84. data/lib/sequel/extensions/columns_introspection.rb +3 -1
  85. data/lib/sequel/extensions/core_extensions.rb +5 -5
  86. data/lib/sequel/extensions/core_refinements.rb +5 -5
  87. data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
  88. data/lib/sequel/extensions/freeze_datasets.rb +69 -0
  89. data/lib/sequel/extensions/identifier_mangling.rb +196 -0
  90. data/lib/sequel/extensions/looser_typecasting.rb +11 -7
  91. data/lib/sequel/extensions/migration.rb +1 -1
  92. data/lib/sequel/extensions/null_dataset.rb +5 -2
  93. data/lib/sequel/extensions/pagination.rb +42 -23
  94. data/lib/sequel/extensions/pg_enum.rb +3 -3
  95. data/lib/sequel/extensions/query.rb +3 -3
  96. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
  97. data/lib/sequel/model/associations.rb +25 -8
  98. data/lib/sequel/model/base.rb +88 -29
  99. data/lib/sequel/model/dataset_module.rb +37 -0
  100. data/lib/sequel/plugins/association_pks.rb +4 -4
  101. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  102. data/lib/sequel/plugins/constraint_validations.rb +1 -2
  103. data/lib/sequel/plugins/csv_serializer.rb +2 -2
  104. data/lib/sequel/plugins/dataset_associations.rb +8 -8
  105. data/lib/sequel/plugins/eager_each.rb +2 -2
  106. data/lib/sequel/plugins/instance_filters.rb +1 -1
  107. data/lib/sequel/plugins/json_serializer.rb +2 -2
  108. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  109. data/lib/sequel/plugins/list.rb +4 -4
  110. data/lib/sequel/plugins/prepared_statements.rb +2 -4
  111. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
  112. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  113. data/lib/sequel/plugins/rcte_tree.rb +13 -13
  114. data/lib/sequel/plugins/sharding.rb +1 -1
  115. data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
  116. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  117. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  118. data/lib/sequel/plugins/validation_helpers.rb +1 -1
  119. data/lib/sequel/plugins/xml_serializer.rb +2 -2
  120. data/lib/sequel/sql.rb +69 -36
  121. data/lib/sequel/version.rb +1 -1
  122. data/spec/adapters/db2_spec.rb +10 -0
  123. data/spec/adapters/firebird_spec.rb +1 -1
  124. data/spec/adapters/mssql_spec.rb +4 -5
  125. data/spec/adapters/mysql_spec.rb +9 -9
  126. data/spec/adapters/postgres_spec.rb +67 -68
  127. data/spec/adapters/spec_helper.rb +6 -1
  128. data/spec/adapters/sqlite_spec.rb +29 -15
  129. data/spec/core/connection_pool_spec.rb +14 -14
  130. data/spec/core/database_spec.rb +38 -180
  131. data/spec/core/dataset_mutation_spec.rb +253 -0
  132. data/spec/core/dataset_spec.rb +394 -537
  133. data/spec/core/expression_filters_spec.rb +34 -32
  134. data/spec/core/mock_adapter_spec.rb +27 -35
  135. data/spec/core/placeholder_literalizer_spec.rb +2 -4
  136. data/spec/core/schema_generator_spec.rb +4 -4
  137. data/spec/core/schema_spec.rb +1 -2
  138. data/spec/core_extensions_spec.rb +22 -29
  139. data/spec/extensions/active_model_spec.rb +6 -6
  140. data/spec/extensions/association_dependencies_spec.rb +2 -2
  141. data/spec/extensions/blacklist_security_spec.rb +3 -3
  142. data/spec/extensions/boolean_readers_spec.rb +12 -12
  143. data/spec/extensions/caching_spec.rb +13 -10
  144. data/spec/extensions/class_table_inheritance_spec.rb +38 -43
  145. data/spec/extensions/column_conflicts_spec.rb +1 -3
  146. data/spec/extensions/columns_introspection_spec.rb +2 -3
  147. data/spec/extensions/composition_spec.rb +5 -3
  148. data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
  149. data/spec/extensions/constraint_validations_spec.rb +14 -8
  150. data/spec/extensions/core_refinements_spec.rb +22 -29
  151. data/spec/extensions/csv_serializer_spec.rb +7 -6
  152. data/spec/extensions/date_arithmetic_spec.rb +15 -15
  153. data/spec/extensions/defaults_setter_spec.rb +2 -2
  154. data/spec/extensions/delay_add_association_spec.rb +1 -1
  155. data/spec/extensions/dirty_spec.rb +19 -10
  156. data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
  157. data/spec/extensions/eager_each_spec.rb +12 -16
  158. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  159. data/spec/extensions/eval_inspect_spec.rb +4 -3
  160. data/spec/extensions/force_encoding_spec.rb +12 -12
  161. data/spec/extensions/freeze_datasets_spec.rb +31 -0
  162. data/spec/extensions/graph_each_spec.rb +6 -18
  163. data/spec/extensions/hook_class_methods_spec.rb +7 -7
  164. data/spec/extensions/identifier_mangling_spec.rb +307 -0
  165. data/spec/extensions/instance_filters_spec.rb +5 -6
  166. data/spec/extensions/instance_hooks_spec.rb +12 -12
  167. data/spec/extensions/json_serializer_spec.rb +12 -15
  168. data/spec/extensions/lazy_attributes_spec.rb +4 -4
  169. data/spec/extensions/list_spec.rb +19 -21
  170. data/spec/extensions/many_through_many_spec.rb +108 -163
  171. data/spec/extensions/meta_def_spec.rb +7 -2
  172. data/spec/extensions/migration_spec.rb +10 -12
  173. data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
  174. data/spec/extensions/named_timezones_spec.rb +4 -3
  175. data/spec/extensions/nested_attributes_spec.rb +2 -2
  176. data/spec/extensions/null_dataset_spec.rb +17 -12
  177. data/spec/extensions/optimistic_locking_spec.rb +4 -5
  178. data/spec/extensions/pagination_spec.rb +8 -10
  179. data/spec/extensions/pg_array_associations_spec.rb +28 -27
  180. data/spec/extensions/pg_array_ops_spec.rb +2 -1
  181. data/spec/extensions/pg_array_spec.rb +6 -2
  182. data/spec/extensions/pg_enum_spec.rb +5 -3
  183. data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
  184. data/spec/extensions/pg_hstore_spec.rb +7 -6
  185. data/spec/extensions/pg_inet_ops_spec.rb +2 -1
  186. data/spec/extensions/pg_inet_spec.rb +2 -1
  187. data/spec/extensions/pg_interval_spec.rb +2 -1
  188. data/spec/extensions/pg_json_ops_spec.rb +2 -1
  189. data/spec/extensions/pg_json_spec.rb +6 -3
  190. data/spec/extensions/pg_loose_count_spec.rb +1 -0
  191. data/spec/extensions/pg_range_ops_spec.rb +3 -1
  192. data/spec/extensions/pg_range_spec.rb +9 -5
  193. data/spec/extensions/pg_row_ops_spec.rb +2 -1
  194. data/spec/extensions/pg_row_plugin_spec.rb +4 -6
  195. data/spec/extensions/pg_row_spec.rb +5 -3
  196. data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
  197. data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
  198. data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
  199. data/spec/extensions/prepared_statements_spec.rb +12 -11
  200. data/spec/extensions/pretty_table_spec.rb +1 -1
  201. data/spec/extensions/query_spec.rb +8 -5
  202. data/spec/extensions/rcte_tree_spec.rb +39 -39
  203. data/spec/extensions/round_timestamps_spec.rb +2 -2
  204. data/spec/extensions/schema_dumper_spec.rb +3 -2
  205. data/spec/extensions/schema_spec.rb +2 -2
  206. data/spec/extensions/scissors_spec.rb +1 -2
  207. data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
  208. data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
  209. data/spec/extensions/serialization_spec.rb +15 -13
  210. data/spec/extensions/set_overrides_spec.rb +14 -8
  211. data/spec/extensions/sharding_spec.rb +9 -18
  212. data/spec/extensions/shared_caching_spec.rb +3 -4
  213. data/spec/extensions/single_table_inheritance_spec.rb +11 -11
  214. data/spec/extensions/skip_create_refresh_spec.rb +2 -1
  215. data/spec/extensions/spec_helper.rb +1 -1
  216. data/spec/extensions/split_values_spec.rb +2 -2
  217. data/spec/extensions/sql_comments_spec.rb +6 -0
  218. data/spec/extensions/static_cache_spec.rb +7 -9
  219. data/spec/extensions/string_agg_spec.rb +30 -29
  220. data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
  221. data/spec/extensions/thread_local_timezones_spec.rb +2 -2
  222. data/spec/extensions/timestamps_spec.rb +28 -3
  223. data/spec/extensions/to_dot_spec.rb +1 -2
  224. data/spec/extensions/tree_spec.rb +33 -29
  225. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  226. data/spec/extensions/unlimited_update_spec.rb +1 -0
  227. data/spec/extensions/update_primary_key_spec.rb +11 -7
  228. data/spec/extensions/update_refresh_spec.rb +1 -1
  229. data/spec/extensions/uuid_spec.rb +0 -1
  230. data/spec/extensions/validate_associated_spec.rb +1 -1
  231. data/spec/extensions/validation_class_methods_spec.rb +10 -10
  232. data/spec/extensions/validation_helpers_spec.rb +10 -10
  233. data/spec/extensions/xml_serializer_spec.rb +7 -3
  234. data/spec/integration/associations_test.rb +31 -31
  235. data/spec/integration/dataset_test.rb +17 -19
  236. data/spec/integration/eager_loader_test.rb +24 -24
  237. data/spec/integration/model_test.rb +6 -6
  238. data/spec/integration/plugin_test.rb +43 -43
  239. data/spec/integration/prepared_statement_test.rb +6 -6
  240. data/spec/integration/schema_test.rb +63 -52
  241. data/spec/integration/spec_helper.rb +6 -1
  242. data/spec/integration/transaction_test.rb +13 -13
  243. data/spec/model/association_reflection_spec.rb +17 -17
  244. data/spec/model/associations_spec.rb +101 -96
  245. data/spec/model/base_spec.rb +175 -49
  246. data/spec/model/class_dataset_methods_spec.rb +5 -9
  247. data/spec/model/dataset_methods_spec.rb +5 -5
  248. data/spec/model/eager_loading_spec.rb +209 -235
  249. data/spec/model/hooks_spec.rb +15 -15
  250. data/spec/model/model_spec.rb +28 -21
  251. data/spec/model/plugins_spec.rb +4 -5
  252. data/spec/model/record_spec.rb +59 -57
  253. data/spec/model/spec_helper.rb +1 -1
  254. data/spec/model/validations_spec.rb +6 -6
  255. data/spec/spec_config.rb +1 -1
  256. metadata +10 -2
@@ -3,24 +3,24 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  mod = shared_description do
4
4
  it "should take action depending on :on_duplicate_columns if 2 or more columns have the same name" do
5
5
  check(nil, @cols)
6
- @warned.must_equal nil
6
+ @warned.must_be_nil
7
7
 
8
8
  check(:ignore, @cols)
9
- @warned.must_equal nil
9
+ @warned.must_be_nil
10
10
 
11
11
  check(:warn, @cols)
12
- @warned.must_equal("One or more duplicate columns present in #{@cols.inspect}")
12
+ @warned.must_include("One or more duplicate columns present in #{@cols.inspect}")
13
13
 
14
14
  proc{check(:raise, @cols)}.must_raise(Sequel::DuplicateColumnError)
15
15
 
16
16
  cols = nil
17
17
  check(proc{|cs| cols = cs; nil}, @cols)
18
- @warned.must_equal nil
18
+ @warned.must_be_nil
19
19
  cols.must_equal @cols
20
20
 
21
21
  cols = nil
22
22
  check(proc{|cs| cols = cs; :ignore}, @cols)
23
- @warned.must_equal nil
23
+ @warned.must_be_nil
24
24
  cols.must_equal @cols
25
25
 
26
26
  cols = nil
@@ -29,17 +29,17 @@ mod = shared_description do
29
29
 
30
30
  cols = nil
31
31
  check(proc{|cs| cols = cs; :warn}, @cols)
32
- @warned.must_equal("One or more duplicate columns present in #{@cols.inspect}")
32
+ @warned.must_include("One or more duplicate columns present in #{@cols.inspect}")
33
33
  cols.must_equal @cols
34
34
 
35
35
  check(:raise, nil)
36
- @warned.must_equal nil
36
+ @warned.must_be_nil
37
37
  end
38
38
 
39
39
  it "should not raise error or warning if no columns have the same name" do
40
40
  [nil, :ignore, :raise, :warn, proc{|cs| :raise}].each do |handler|
41
41
  check(handler, @cols.uniq)
42
- @warned.must_equal nil
42
+ @warned.must_be_nil
43
43
  end
44
44
  end
45
45
  end
@@ -48,13 +48,10 @@ describe "Sequel::DuplicateColumnsHandler Database configuration" do
48
48
  before do
49
49
  @db = Sequel.mock
50
50
  @db.extension(:duplicate_columns_handler)
51
- @ds = @db[:things]
52
51
  @cols = [:id, :name, :id]
53
52
  @warned = nil
54
53
  set_warned = @set_warned = proc{|m| @warned = m}
55
- @ds.meta_def(:warn) do |message|
56
- set_warned.call(message)
57
- end
54
+ @ds = @db[:things].with_extend{define_method(:warn){|message| set_warned.call(message)}}
58
55
  end
59
56
 
60
57
  def check(handler, cols)
@@ -68,13 +65,10 @@ end
68
65
 
69
66
  describe "Sequel::DuplicateColumnsHandler Dataset configuration" do
70
67
  before do
71
- @ds = Sequel.mock[:things].extension!(:duplicate_columns_handler)
72
68
  @cols = [:id, :name, :id]
73
69
  @warned = nil
74
70
  set_warned = @set_warned = proc{|m| @warned = m}
75
- @ds.meta_def(:warn) do |message|
76
- set_warned.call(message)
77
- end
71
+ @ds = Sequel.mock[:things].extension(:duplicate_columns_handler).with_extend{define_method(:warn){|message| set_warned.call(message)}}
78
72
  end
79
73
 
80
74
  def check(handler, cols)
@@ -98,13 +92,13 @@ describe "Sequel::DuplicateColumnsHandler Dataset configuration" do
98
92
 
99
93
  it "should warn by defaul if there is no database or dataset handler" do
100
94
  @ds.send(:columns=, @cols)
101
- @warned.must_equal("One or more duplicate columns present in #{@cols.inspect}")
95
+ @warned.must_include("One or more duplicate columns present in #{@cols.inspect}")
102
96
  end
103
97
 
104
98
  it "should fallback to database setting if there is no dataset-level handler" do
105
99
  @ds.db.opts[:on_duplicate_columns] = :raise
106
100
  proc{@ds.send(:columns=, @cols)}.must_raise(Sequel::DuplicateColumnError)
107
101
  check(:ignore, @cols)
108
- @warned.must_equal nil
102
+ @warned.must_be_nil
109
103
  end
110
104
  end
@@ -11,9 +11,8 @@ describe "Sequel::Plugins::EagerEach" do
11
11
 
12
12
  it "should make #each on an eager dataset do eager loading" do
13
13
  a = []
14
- ds = @c.eager(:children)
15
- ds._fetch = [{:id=>1, :parent_id=>nil}, {:id=>2, :parent_id=>nil}]
16
- @c.dataset._fetch = [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>2}, {:id=>6, :parent_id=>2}]
14
+ ds = @c.eager(:children).with_fetch([{:id=>1, :parent_id=>nil}, {:id=>2, :parent_id=>nil}])
15
+ @c.dataset = @c.dataset.with_fetch([{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>2}, {:id=>6, :parent_id=>2}])
17
16
  ds.each{|c| a << c}
18
17
  a.must_equal [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
19
18
  a.map{|c| c.associations[:children]}.must_equal [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
@@ -25,8 +24,7 @@ describe "Sequel::Plugins::EagerEach" do
25
24
 
26
25
  it "should make #each on an eager_graph dataset do eager loading" do
27
26
  a = []
28
- ds = @c.eager_graph(:children)
29
- ds._fetch = [{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}, {:id=>2, :parent_id=>nil, :children_id=>5, :children_parent_id=>2}, {:id=>2, :parent_id=>nil, :children_id=>6, :children_parent_id=>2}]
27
+ ds = @c.eager_graph(:children).with_fetch([{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}, {:id=>2, :parent_id=>nil, :children_id=>5, :children_parent_id=>2}, {:id=>2, :parent_id=>nil, :children_id=>6, :children_parent_id=>2}])
30
28
  ds.each{|c| a << c}
31
29
  a.must_equal [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
32
30
  a.map{|c| c.associations[:children]}.must_equal [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
@@ -34,9 +32,8 @@ describe "Sequel::Plugins::EagerEach" do
34
32
  end
35
33
 
36
34
  it "should make #first on an eager dataset do eager loading" do
37
- ds = @c.eager(:children)
38
- ds._fetch = [{:id=>1, :parent_id=>nil}]
39
- @c.dataset._fetch = [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}]
35
+ ds = @c.eager(:children).with_fetch([{:id=>1, :parent_id=>nil}])
36
+ @c.dataset = @c.dataset.with_fetch([{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}])
40
37
  a = ds.first
41
38
  a.values.must_equal(:id=>1, :parent_id=>nil)
42
39
  a.associations[:children].must_equal [@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)]
@@ -44,9 +41,7 @@ describe "Sequel::Plugins::EagerEach" do
44
41
  end
45
42
 
46
43
  it "should make #first on an eager_graph dataset do eager loading" do
47
- ds = @c.eager_graph(:children)
48
- ds._fetch = [[{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}], [{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}]]
49
- a = ds.first
44
+ a = @c.eager_graph(:children).with_fetch([[{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}], [{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}]]).first
50
45
  a.values.must_equal(:id=>1, :parent_id=>nil)
51
46
  a.associations[:children].must_equal [@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)]
52
47
  @c.db.sqls.must_equal ['SELECT items.id, items.parent_id, children.id AS children_id, children.parent_id AS children_parent_id FROM items LEFT OUTER JOIN items AS children ON (children.parent_id = items.id) LIMIT 1',
@@ -54,13 +49,14 @@ describe "Sequel::Plugins::EagerEach" do
54
49
  end
55
50
 
56
51
  it "should make #first on a non-eager dataset work correctly" do
57
- @c.dataset._fetch = [{:id=>1, :parent_id=>nil}]
58
- @c.first.must_equal @c.load(:id=>1, :parent_id=>nil)
52
+ @c.dataset.with_fetch([{:id=>1, :parent_id=>nil}]).first.must_equal @c.load(:id=>1, :parent_id=>nil)
53
+ end
54
+
55
+ it "should get columns normally columns" do
56
+ @c.dataset.columns!.must_equal [:id, :parent_id]
59
57
  end
60
58
 
61
59
  it "should not attempt to eager load when getting the columns" do
62
- ds = @c.eager(:children)
63
- def ds.all; raise; end
64
- ds.columns!
60
+ ds = @c.eager(:children).with_extend{def all; raise; end}.columns!.must_equal [:id, :parent_id]
65
61
  end
66
62
  end
@@ -13,9 +13,9 @@ describe "filter_having extension" do
13
13
  end
14
14
 
15
15
  it "should handle IN/NOT IN queries with multiple columns and an empty dataset where the database doesn't support it" do
16
- @dataset.meta_def(:supports_multiple_column_in?){false}
17
16
  db = Sequel.mock
18
17
  d1 = db[:test].select(:id1, :id2).filter(:region=>'Asia').columns(:id1, :id2)
18
+ @dataset = @dataset.with_extend{def supports_multiple_column_in?; false end}
19
19
  @dataset.filter([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE ((id1 != id1) AND (id2 != id2))"
20
20
  db.sqls.must_equal ["SELECT id1, id2 FROM test WHERE (region = 'Asia')"]
21
21
  @dataset.exclude([:id1, :id2] => d1).sql.must_equal "SELECT * FROM test WHERE ((id1 = id1) AND (id2 = id2))"
@@ -4,9 +4,10 @@ Sequel.extension :eval_inspect
4
4
 
5
5
  describe "eval_inspect extension" do
6
6
  before do
7
- @ds = Sequel.mock.dataset
8
- @ds.meta_def(:supports_window_functions?){true}
9
- @ds.meta_def(:literal_blob_append){|sql, s| sql << "X'#{s}'"}
7
+ @ds = Sequel.mock.dataset.with_extend do
8
+ def supports_window_functions?; true end
9
+ def literal_blob_append(sql, s) sql << "X'#{s}'" end
10
+ end
10
11
  end
11
12
 
12
13
  it "should make eval(obj.inspect) == obj for all Sequel::SQL::Expression subclasses" do
@@ -83,13 +83,13 @@ describe "force_encoding plugin" do
83
83
 
84
84
  it "should work when saving new model instances" do
85
85
  o = @c.new
86
- ds = DB[:a]
87
- def ds.first
88
- s = 'blah'.dup
89
- s.force_encoding('US-ASCII')
90
- {:id=>1, :x=>s}
86
+ @c.dataset = DB[:a].with_extend do
87
+ def first
88
+ s = 'blah'.dup
89
+ s.force_encoding('US-ASCII')
90
+ {:id=>1, :x=>s}
91
+ end
91
92
  end
92
- @c.dataset = ds
93
93
  o.save
94
94
  o.x.must_equal 'blah'
95
95
  o.x.encoding.must_equal @e1
@@ -97,13 +97,13 @@ describe "force_encoding plugin" do
97
97
 
98
98
  it "should work when refreshing model instances" do
99
99
  o = @c.load(:id=>1, :x=>'as'.dup)
100
- ds = DB[:a]
101
- def ds.first
102
- s = 'blah'.dup
103
- s.force_encoding('US-ASCII')
104
- {:id=>1, :x=>s}
100
+ @c.dataset = DB[:a].with_extend do
101
+ def first
102
+ s = 'blah'.dup
103
+ s.force_encoding('US-ASCII')
104
+ {:id=>1, :x=>s}
105
+ end
105
106
  end
106
- @c.dataset = ds
107
107
  o.refresh
108
108
  o.x.must_equal 'blah'
109
109
  o.x.encoding.must_equal @e1
@@ -0,0 +1,31 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "freeze_datasets extension" do
4
+ before do
5
+ @db = Sequel.mock.extension(:freeze_datasets)
6
+ end
7
+
8
+ it "should freeze datasets by default" do
9
+ @db.dataset.frozen?.must_equal true
10
+ @db.fetch('SQL').frozen?.must_equal true
11
+ @db.from(:table).frozen?.must_equal true
12
+ @db[:table].frozen?.must_equal true
13
+ end
14
+
15
+ it "should have dataset#dup return frozen dataset" do
16
+ @db.dataset.dup.frozen?.must_equal true
17
+ end
18
+
19
+ it "should cache Database#from calls with single symbol tables" do
20
+ @db.from(:foo).must_be_same_as @db.from(:foo)
21
+ @db.from(Sequel[:foo]).wont_be_same_as @db.from(Sequel[:foo])
22
+ end
23
+
24
+ it "should clear Database#from cache when modifying the schema" do
25
+ ds = @db.from(:foo)
26
+ ds.columns(:foo, :bar)
27
+ @db[:foo].columns.must_equal [:foo, :bar]
28
+ @db.create_table!(:foo){Integer :x}
29
+ @db[:foo].columns.wont_equal [:foo, :bar]
30
+ end
31
+ end
@@ -20,25 +20,15 @@ describe Sequel::Dataset, " graphing" do
20
20
  end
21
21
 
22
22
  it "#graph_each should handle graph using currently selected columns as the basis for the selected columns in a new graph" do
23
- ds = @ds1.select(:id).graph(@ds2, :x=>:id)
24
- ds._fetch = {:id=>1, :lines_id=>2, :x=>3, :y=>4, :graph_id=>5}
25
- ds.all.must_equal [{:points=>{:id=>1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
23
+ @ds1.select(:id).graph(@ds2, :x=>:id).with_fetch(:id=>1, :lines_id=>2, :x=>3, :y=>4, :graph_id=>5).all.must_equal [{:points=>{:id=>1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
26
24
 
27
- ds = @ds1.select(:id, :x).graph(@ds2, :x=>:id)
28
- ds._fetch = {:id=>1, :x=>-1, :lines_id=>2, :lines_x=>3, :y=>4, :graph_id=>5}
29
- ds.all.must_equal [{:points=>{:id=>1, :x=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
25
+ @ds1.select(:id, :x).graph(@ds2, :x=>:id).with_fetch(:id=>1, :x=>-1, :lines_id=>2, :lines_x=>3, :y=>4, :graph_id=>5).all.must_equal [{:points=>{:id=>1, :x=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
30
26
 
31
- ds = @ds1.select(Sequel.identifier(:id), Sequel.qualify(:points, :x)).graph(@ds2, :x=>:id)
32
- ds._fetch = {:id=>1, :x=>-1, :lines_id=>2, :lines_x=>3, :y=>4, :graph_id=>5}
33
- ds.all.must_equal [{:points=>{:id=>1, :x=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
27
+ @ds1.select(Sequel.identifier(:id), Sequel.qualify(:points, :x)).graph(@ds2, :x=>:id).with_fetch(:id=>1, :x=>-1, :lines_id=>2, :lines_x=>3, :y=>4, :graph_id=>5).all.must_equal [{:points=>{:id=>1, :x=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
34
28
 
35
- ds = @ds1.select(Sequel.identifier(:id).qualify(:points), Sequel.identifier(:x).as(:y)).graph(@ds2, :x=>:id)
36
- ds._fetch = {:id=>1, :y=>-1, :lines_id=>2, :x=>3, :lines_y=>4, :graph_id=>5}
37
- ds.all.must_equal [{:points=>{:id=>1, :y=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
29
+ @ds1.select(Sequel.identifier(:id).qualify(:points), Sequel.identifier(:x).as(:y)).graph(@ds2, :x=>:id).with_fetch(:id=>1, :y=>-1, :lines_id=>2, :x=>3, :lines_y=>4, :graph_id=>5).all.must_equal [{:points=>{:id=>1, :y=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
38
30
 
39
- ds = @ds1.select(:id, Sequel.identifier(:x).qualify(Sequel.identifier(:points)).as(Sequel.identifier(:y))).graph(@ds2, :x=>:id)
40
- ds._fetch = {:id=>1, :y=>-1, :lines_id=>2, :x=>3, :lines_y=>4, :graph_id=>5}
41
- ds.all.must_equal [{:points=>{:id=>1, :y=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
31
+ @ds1.select(:id, Sequel.identifier(:x).qualify(Sequel.identifier(:points)).as(Sequel.identifier(:y))).graph(@ds2, :x=>:id).with_fetch(:id=>1, :y=>-1, :lines_id=>2, :x=>3, :lines_y=>4, :graph_id=>5).all.must_equal [{:points=>{:id=>1, :y=>-1}, :lines=>{:id=>2, :x=>3, :y=>4, :graph_id=>5}}]
42
32
  end
43
33
 
44
34
  it "#graph_each should split the result set into component tables" do
@@ -111,10 +101,8 @@ describe Sequel::Dataset, " graphing" do
111
101
  end
112
102
 
113
103
  it "#graph_each should run the row_proc for graphed datasets" do
114
- @ds1.row_proc = proc{|h| h.keys.each{|k| h[k] *= 2}; h}
115
- @ds2.row_proc = proc{|h| h.keys.each{|k| h[k] *= 3}; h}
116
104
  @db.fetch = {:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7}
117
- @ds1.graph(@ds2, :x=>:id).all.must_equal [{:points=>{:id=>2, :x=>4, :y=>6}, :lines=>{:id=>12, :x=>15, :y=>18, :graph_id=>21}}]
105
+ @ds1.with_row_proc(proc{|h| h.keys.each{|k| h[k] *= 2}; h}).graph(@ds2.with_row_proc(proc{|h| h.keys.each{|k| h[k] *= 3}; h}), :x=>:id).all.must_equal [{:points=>{:id=>2, :x=>4, :y=>6}, :lines=>{:id=>12, :x=>15, :y=>18, :graph_id=>21}}]
118
106
  end
119
107
 
120
108
  it "#with_sql_each should work normally if the dataset is not graphed" do
@@ -197,14 +197,14 @@ describe "Model#before_create && Model#after_create" do
197
197
  it ".create should cancel the save and return nil if before_create returns false and raise_on_save_failure is false" do
198
198
  @c.before_create{false}
199
199
  @c.raise_on_save_failure = false
200
- @c.create(:x => 2).must_equal nil
200
+ @c.create(:x => 2).must_be_nil
201
201
  DB.sqls.must_equal []
202
202
  end
203
203
 
204
204
  it ".create should cancel the save and return nil if before_create calls cancel_action and raise_on_save_failure is false" do
205
205
  @c.before_create{cancel_action}
206
206
  @c.raise_on_save_failure = false
207
- @c.create(:x => 2).must_equal nil
207
+ @c.create(:x => 2).must_be_nil
208
208
  DB.sqls.must_equal []
209
209
  end
210
210
  end
@@ -234,7 +234,7 @@ describe "Model#before_update && Model#after_update" do
234
234
  it "#save should cancel the save and return nil if before_update returns false and raise_on_save_failure is false" do
235
235
  @c.before_update{false}
236
236
  @c.raise_on_save_failure = false
237
- @c.load(:id => 2233).save.must_equal nil
237
+ @c.load(:id => 2233).save.must_be_nil
238
238
  DB.sqls.must_equal []
239
239
  end
240
240
  end
@@ -272,7 +272,7 @@ describe "Model#before_save && Model#after_save" do
272
272
  it "#save should cancel the save and return nil if before_save returns false and raise_on_save_failure is false" do
273
273
  @c.before_save{false}
274
274
  @c.raise_on_save_failure = false
275
- @c.load(:id => 2233).save.must_equal nil
275
+ @c.load(:id => 2233).save.must_be_nil
276
276
  DB.sqls.must_equal []
277
277
  end
278
278
  end
@@ -302,7 +302,7 @@ describe "Model#before_destroy && Model#after_destroy" do
302
302
  it "#destroy should cancel the destroy and return nil if before_destroy returns false and raise_on_save_failure is false" do
303
303
  @c.before_destroy{false}
304
304
  @c.raise_on_save_failure = false
305
- @c.load(:id => 2233).destroy.must_equal nil
305
+ @c.load(:id => 2233).destroy.must_be_nil
306
306
  DB.sqls.must_equal []
307
307
  end
308
308
  end
@@ -343,7 +343,7 @@ describe "Model#before_validation && Model#after_validation" do
343
343
  DB.sqls.clear
344
344
  m = @c.load(:id => 22)
345
345
  m.raise_on_save_failure = false
346
- m.save.must_equal nil
346
+ m.save.must_be_nil
347
347
  DB.sqls.must_equal ['BLAH before', 'BLAH after']
348
348
  end
349
349
 
@@ -356,7 +356,7 @@ describe "Model#before_validation && Model#after_validation" do
356
356
  it "#save should cancel the save and return nil if before_validation returns false and raise_on_save_failure is false" do
357
357
  @c.before_validation{false}
358
358
  @c.raise_on_save_failure = false
359
- @c.load(:id => 2233).save.must_equal nil
359
+ @c.load(:id => 2233).save.must_be_nil
360
360
  DB.sqls.must_equal []
361
361
  end
362
362
  end
@@ -0,0 +1,307 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "identifier_mangling extension" do
4
+ after do
5
+ Sequel.quote_identifiers = false
6
+ Sequel.identifier_input_method = nil
7
+ Sequel.identifier_output_method = nil
8
+ end
9
+
10
+ it "should respect the :quote_identifiers option" do
11
+ db = Sequel::Database.new(:quote_identifiers=>false, :identifier_mangling=>true)
12
+ db.quote_identifiers?.must_equal false
13
+ db = Sequel::Database.new(:quote_identifiers=>true, :identifier_mangling=>true)
14
+ db.quote_identifiers?.must_equal true
15
+ end
16
+
17
+ it "should upcase on input and downcase on output by default" do
18
+ db = Sequel::Database.new(:identifier_mangling=>true)
19
+ db.send(:identifier_input_method_default).must_equal :upcase
20
+ db.send(:identifier_output_method_default).must_equal :downcase
21
+ end
22
+
23
+ it "should respect the :identifier_input_method option" do
24
+ Sequel.identifier_input_method = nil
25
+ Sequel::Database.identifier_input_method.must_equal false
26
+ db = Sequel::Database.new(:identifier_input_method=>nil, :identifier_mangling=>true)
27
+ db.identifier_input_method.must_be_nil
28
+ db.identifier_input_method = :downcase
29
+ db.identifier_input_method.must_equal :downcase
30
+ db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
31
+ db.identifier_input_method.must_equal :upcase
32
+ db.identifier_input_method = nil
33
+ db.identifier_input_method.must_be_nil
34
+ Sequel.identifier_input_method = :downcase
35
+ Sequel::Database.identifier_input_method.must_equal :downcase
36
+ db = Sequel::Database.new(:identifier_input_method=>nil, :identifier_mangling=>true)
37
+ db.identifier_input_method.must_be_nil
38
+ db.identifier_input_method = :upcase
39
+ db.identifier_input_method.must_equal :upcase
40
+ db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
41
+ db.identifier_input_method.must_equal :upcase
42
+ db.identifier_input_method = nil
43
+ db.identifier_input_method.must_be_nil
44
+ end
45
+
46
+ it "should respect the :identifier_output_method option" do
47
+ Sequel.identifier_output_method = nil
48
+ Sequel::Database.identifier_output_method.must_equal false
49
+ db = Sequel::Database.new(:identifier_output_method=>nil, :identifier_mangling=>true)
50
+ db.identifier_output_method.must_be_nil
51
+ db.identifier_output_method = :downcase
52
+ db.identifier_output_method.must_equal :downcase
53
+ db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
54
+ db.identifier_output_method.must_equal :upcase
55
+ db.identifier_output_method = nil
56
+ db.identifier_output_method.must_be_nil
57
+ Sequel.identifier_output_method = :downcase
58
+ Sequel::Database.identifier_output_method.must_equal :downcase
59
+ db = Sequel::Database.new(:identifier_output_method=>nil, :identifier_mangling=>true)
60
+ db.identifier_output_method.must_be_nil
61
+ db.identifier_output_method = :upcase
62
+ db.identifier_output_method.must_equal :upcase
63
+ db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
64
+ db.identifier_output_method.must_equal :upcase
65
+ db.identifier_output_method = nil
66
+ db.identifier_output_method.must_be_nil
67
+ end
68
+
69
+ it "should use the default Sequel.quote_identifiers value" do
70
+ Sequel.quote_identifiers = true
71
+ Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
72
+ Sequel.quote_identifiers = false
73
+ Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
74
+ Sequel::Database.quote_identifiers = true
75
+ Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
76
+ Sequel::Database.quote_identifiers = false
77
+ Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
78
+ end
79
+
80
+ it "should use the default Sequel.identifier_input_method value" do
81
+ Sequel.identifier_input_method = :downcase
82
+ Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
83
+ Sequel.identifier_input_method = :upcase
84
+ Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :upcase
85
+ Sequel::Database.identifier_input_method = :downcase
86
+ Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
87
+ Sequel::Database.identifier_input_method = :upcase
88
+ Sequel::Database.new(:identifier_mangling=>true).identifier_input_method.must_equal :upcase
89
+ end
90
+
91
+ it "should use the default Sequel.identifier_output_method value" do
92
+ Sequel.identifier_output_method = :downcase
93
+ Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :downcase
94
+ Sequel.identifier_output_method = :upcase
95
+ Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
96
+ Sequel::Database.identifier_output_method = :downcase
97
+ Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :downcase
98
+ Sequel::Database.identifier_output_method = :upcase
99
+ Sequel::Database.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
100
+ end
101
+
102
+ it "should respect the quote_indentifiers_default method if Sequel.quote_identifiers = nil" do
103
+ Sequel.quote_identifiers = nil
104
+ Sequel::Database.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
105
+ x = Class.new(Sequel::Database){def quote_identifiers_default; false end}
106
+ x.new(:identifier_mangling=>true).quote_identifiers?.must_equal false
107
+ y = Class.new(Sequel::Database){def quote_identifiers_default; true end}
108
+ y.new(:identifier_mangling=>true).quote_identifiers?.must_equal true
109
+ end
110
+
111
+ it "should respect the identifier_input_method_default method if Sequel.identifier_input_method is not called" do
112
+ class Sequel::Database
113
+ @identifier_input_method = nil
114
+ end
115
+ x = Class.new(Sequel::Database){def identifier_input_method_default; :downcase end}
116
+ x.new(:identifier_mangling=>true).identifier_input_method.must_equal :downcase
117
+ y = Class.new(Sequel::Database){def identifier_input_method_default; :camelize end}
118
+ y.new(:identifier_mangling=>true).identifier_input_method.must_equal :camelize
119
+ end
120
+
121
+ it "should respect the identifier_output_method_default method if Sequel.identifier_output_method is not called" do
122
+ class Sequel::Database
123
+ @identifier_output_method = nil
124
+ end
125
+ x = Class.new(Sequel::Database){def identifier_output_method_default; :upcase end}
126
+ x.new(:identifier_mangling=>true).identifier_output_method.must_equal :upcase
127
+ y = Class.new(Sequel::Database){def identifier_output_method_default; :underscore end}
128
+ y.new(:identifier_mangling=>true).identifier_output_method.must_equal :underscore
129
+ end
130
+ end
131
+
132
+ describe "Database#input_identifier_meth" do
133
+ it "should be the input_identifer method of a default dataset for this database" do
134
+ db = Sequel::Database.new(:identifier_mangling=>true)
135
+ db.send(:input_identifier_meth).call(:a).must_equal 'a'
136
+ db.identifier_input_method = :upcase
137
+ db.send(:input_identifier_meth).call(:a).must_equal 'A'
138
+ end
139
+ end
140
+
141
+ describe "Database#output_identifier_meth" do
142
+ it "should be the output_identifer method of a default dataset for this database" do
143
+ db = Sequel::Database.new(:identifier_mangling=>true)
144
+ db.send(:output_identifier_meth).call('A').must_equal :A
145
+ db.identifier_output_method = :downcase
146
+ db.send(:output_identifier_meth).call('A').must_equal :a
147
+ end
148
+ end
149
+
150
+ describe "Database#metadata_dataset" do
151
+ it "should be a dataset with the default settings for identifier_mangling" do
152
+ ds = Sequel::Database.new(:identifier_mangling=>true).send(:metadata_dataset)
153
+ ds.literal(:a).must_equal 'A'
154
+ ds.send(:output_identifier, 'A').must_equal :a
155
+ end
156
+ end
157
+
158
+ describe "Dataset" do
159
+ before do
160
+ @dataset = Sequel.mock(:identifier_mangling=>true).dataset
161
+ end
162
+
163
+ it "should get quote_identifiers default from database" do
164
+ db = Sequel::Database.new(:quote_identifiers=>true, :identifier_mangling=>true)
165
+ db[:a].quote_identifiers?.must_equal true
166
+ db = Sequel::Database.new(:quote_identifiers=>false, :identifier_mangling=>true)
167
+ db[:a].quote_identifiers?.must_equal false
168
+ end
169
+
170
+ it "should get identifier_input_method default from database" do
171
+ db = Sequel::Database.new(:identifier_input_method=>:upcase, :identifier_mangling=>true)
172
+ db[:a].identifier_input_method.must_equal :upcase
173
+ db = Sequel::Database.new(:identifier_input_method=>:downcase, :identifier_mangling=>true)
174
+ db[:a].identifier_input_method.must_equal :downcase
175
+ end
176
+
177
+ it "should get identifier_output_method default from database" do
178
+ db = Sequel::Database.new(:identifier_output_method=>:upcase, :identifier_mangling=>true)
179
+ db[:a].identifier_output_method.must_equal :upcase
180
+ db = Sequel::Database.new(:identifier_output_method=>:downcase, :identifier_mangling=>true)
181
+ db[:a].identifier_output_method.must_equal :downcase
182
+ end
183
+
184
+ # SEQUEL5: Remove
185
+ unless Sequel.mock(:identifier_mangling=>true).dataset.frozen?
186
+ it "should have quote_identifiers= method which changes literalization of identifiers" do
187
+ @dataset.quote_identifiers = true
188
+ @dataset.literal(:a).must_equal '"a"'
189
+ @dataset.quote_identifiers = false
190
+ @dataset.literal(:a).must_equal 'a'
191
+ end
192
+
193
+ it "should have identifier_input_method= method which changes literalization of identifiers" do
194
+ @dataset.identifier_input_method = :upcase
195
+ @dataset.literal(:a).must_equal 'A'
196
+ @dataset.identifier_input_method = :downcase
197
+ @dataset.literal(:A).must_equal 'a'
198
+ @dataset.identifier_input_method = :reverse
199
+ @dataset.literal(:at_b).must_equal 'b_ta'
200
+ end
201
+
202
+ it "should have identifier_output_method= method which changes identifiers returned from the database" do
203
+ @dataset.send(:output_identifier, "at_b_C").must_equal :at_b_C
204
+ @dataset.identifier_output_method = :upcase
205
+ @dataset.send(:output_identifier, "at_b_C").must_equal :AT_B_C
206
+ @dataset.identifier_output_method = :downcase
207
+ @dataset.send(:output_identifier, "at_b_C").must_equal :at_b_c
208
+ @dataset.identifier_output_method = :reverse
209
+ @dataset.send(:output_identifier, "at_b_C").must_equal :C_b_ta
210
+ end
211
+ end
212
+
213
+ it "should have with_quote_identifiers method which returns cloned dataset with changed literalization of identifiers" do
214
+ @dataset.with_quote_identifiers(true).literal(:a).must_equal '"a"'
215
+ @dataset.with_quote_identifiers(false).literal(:a).must_equal 'a'
216
+ ds = @dataset.freeze.with_quote_identifiers(false)
217
+ ds.literal(:a).must_equal 'a'
218
+ ds.frozen?.must_equal true
219
+ end
220
+
221
+ it "should have with_identifier_input_method method which returns cloned dataset with changed literalization of identifiers" do
222
+ @dataset.with_identifier_input_method(:upcase).literal(:a).must_equal 'A'
223
+ @dataset.with_identifier_input_method(:downcase).literal(:A).must_equal 'a'
224
+ @dataset.with_identifier_input_method(:reverse).literal(:at_b).must_equal 'b_ta'
225
+ ds = @dataset.freeze.with_identifier_input_method(:reverse)
226
+ ds.frozen?.must_equal true
227
+ ds.literal(:at_b).must_equal 'b_ta'
228
+ end
229
+
230
+ it "should have with_identifier_output_method method which returns cloned dataset with changed identifiers returned from the database" do
231
+ @dataset.send(:output_identifier, "at_b_C").must_equal :at_b_C
232
+ @dataset.with_identifier_output_method(:upcase).send(:output_identifier, "at_b_C").must_equal :AT_B_C
233
+ @dataset.with_identifier_output_method(:downcase).send(:output_identifier, "at_b_C").must_equal :at_b_c
234
+ @dataset.with_identifier_output_method(:reverse).send(:output_identifier, "at_b_C").must_equal :C_b_ta
235
+ ds = @dataset.freeze.with_identifier_output_method(:reverse)
236
+ ds.send(:output_identifier, "at_b_C").must_equal :C_b_ta
237
+ ds.frozen?.must_equal true
238
+ end
239
+
240
+ it "should have output_identifier handle empty identifiers" do
241
+ @dataset.send(:output_identifier, "").must_equal :untitled
242
+ @dataset.with_identifier_output_method(:upcase).send(:output_identifier, "").must_equal :UNTITLED
243
+ @dataset.with_identifier_output_method(:downcase).send(:output_identifier, "").must_equal :untitled
244
+ @dataset.with_identifier_output_method(:reverse).send(:output_identifier, "").must_equal :deltitnu
245
+ end
246
+ end
247
+
248
+ describe "Frozen Datasets" do
249
+ before do
250
+ @ds = Sequel.mock(:identifier_mangling=>true)[:test].freeze
251
+ end
252
+
253
+ it "should raise an error when calling mutation methods" do
254
+ proc{@ds.identifier_input_method = :a}.must_raise RuntimeError
255
+ proc{@ds.identifier_output_method = :a}.must_raise RuntimeError
256
+ proc{@ds.quote_identifiers = false}.must_raise RuntimeError
257
+ end
258
+ end
259
+
260
+ describe "identifier_mangling extension" do
261
+ it "should be able to load dialects based on the database name" do
262
+ begin
263
+ qi = class Sequel::Database; @quote_identifiers; end
264
+ ii = class Sequel::Database; @identifier_input_method; end
265
+ io = class Sequel::Database; @identifier_output_method; end
266
+ Sequel.quote_identifiers = nil
267
+ class Sequel::Database; @identifier_input_method=nil; end
268
+ class Sequel::Database; @identifier_output_method=nil; end
269
+ Sequel.mock(:host=>'access').select(Date.new(2011, 12, 13)).sql.must_equal 'SELECT #2011-12-13#'
270
+ Sequel.mock(:host=>'cubrid').from(:a).offset(1).sql.must_equal 'SELECT * FROM "a" LIMIT 1,4294967295'
271
+ Sequel.mock(:host=>'db2').select(1).sql.must_equal 'SELECT 1 FROM "SYSIBM"."SYSDUMMY1"'
272
+ Sequel.mock(:host=>'firebird')[:a].distinct.limit(1, 2).sql.must_equal 'SELECT DISTINCT FIRST 1 SKIP 2 * FROM "A"'
273
+ Sequel.mock(:host=>'informix')[:a].distinct.limit(1, 2).sql.must_equal 'SELECT SKIP 2 FIRST 1 DISTINCT * FROM A'
274
+ Sequel.mock(:host=>'mssql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM [A] WHERE (CONTAINS ([B], 'c'))"
275
+ Sequel.mock(:host=>'mysql')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM `a` WHERE (MATCH (`b`) AGAINST ('c'))"
276
+ Sequel.mock(:host=>'oracle')[:a].limit(1).sql.must_equal 'SELECT * FROM (SELECT * FROM "A") "T1" WHERE (ROWNUM <= 1)'
277
+ Sequel.mock(:host=>'postgres')[:a].full_text_search(:b, 'c').sql.must_equal "SELECT * FROM \"a\" WHERE (to_tsvector(CAST('simple' AS regconfig), (COALESCE(\"b\", ''))) @@ to_tsquery(CAST('simple' AS regconfig), 'c'))"
278
+ Sequel.mock(:host=>'sqlanywhere').from(:a).offset(1).sql.must_equal 'SELECT TOP 2147483647 START AT (1 + 1) * FROM "A"'
279
+ Sequel.mock(:host=>'sqlite')[:a___b].sql.must_equal "SELECT * FROM `a` AS 'b'"
280
+ ensure
281
+ Sequel.quote_identifiers = qi
282
+ Sequel::Database.send(:instance_variable_set, :@identifier_input_method, ii)
283
+ Sequel::Database.send(:instance_variable_set, :@identifier_output_method, io)
284
+ end
285
+ end
286
+ end
287
+
288
+ describe Sequel::Model, ".[] optimization" do
289
+ before do
290
+ @db = Sequel.mock(:identifier_mangling=>true, :quote_identifiers=>true)
291
+ def @db.schema(*) [[:id, {:primary_key=>true}]] end
292
+ def @db.supports_schema_parsing?() true end
293
+ @c = Class.new(Sequel::Model(@db))
294
+ @ds = @db.dataset.with_quote_identifiers(true)
295
+ end
296
+
297
+ it "should have simple_pk and simple_table respect dataset's identifier input methods" do
298
+ ds = @db.from(:ab).with_identifier_input_method(:reverse)
299
+ @c.set_dataset ds
300
+ @c.simple_table.must_equal '"ba"'
301
+ @c.set_primary_key :cd
302
+ @c.simple_pk.must_equal '"dc"'
303
+
304
+ @c.set_dataset ds.from(:ef__gh)
305
+ @c.simple_table.must_equal '"fe"."hg"'
306
+ end
307
+ end