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
@@ -123,8 +123,10 @@ describe "Composition plugin" do
123
123
  end
124
124
 
125
125
  it "should not clear compositions cache when saving with insert_select" do
126
- def (@c.instance_dataset).supports_insert_select?() true end
127
- def (@c.instance_dataset).insert_select(*) {:id=>1} end
126
+ @c.dataset = @c.dataset.with_extend do
127
+ def supports_insert_select?; true end
128
+ def insert_select(*) {:id=>1} end
129
+ end
128
130
  @c.composition :date, :composer=>proc{}, :decomposer=>proc{}
129
131
  @c.create(:date=>Date.new(3, 4, 5)).compositions.must_equal(:date=>Date.new(3, 4, 5))
130
132
  end
@@ -201,7 +203,7 @@ describe "Composition plugin" do
201
203
 
202
204
  it ":mapping option :composer should return nil if all values are nil" do
203
205
  @c.composition :date, :mapping=>[:year, :month, :day]
204
- @c.new.date.must_equal nil
206
+ @c.new.date.must_be_nil
205
207
  end
206
208
 
207
209
  it ":mapping option :decomposer should set all related fields to nil if nil" do
@@ -19,9 +19,9 @@ describe "Sequel::Plugins::ConstraintValidations" do
19
19
  @db = Sequel.mock
20
20
  set_fetch({})
21
21
  @ds = @db[:items]
22
- @ds.instance_variable_set(:@columns, [:name])
22
+ @ds.send(:columns=, [:name])
23
23
  @ds2 = Sequel.mock[:items2]
24
- @ds2.instance_variable_set(:@columns, [:name])
24
+ @ds2.send(:columns=, [:name])
25
25
  end
26
26
 
27
27
  it "should load the validation_helpers plugin into the class" do
@@ -234,7 +234,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
234
234
  c.plugin :constraint_validations, :validation_options=>{:unique=>{:message=>'is bad'}}
235
235
  c.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad'}]]
236
236
  c.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad'}]])
237
- c.dataset._fetch = {:count=>1}
237
+ c.dataset = c.dataset.with_fetch(:count=>1)
238
238
  o = c.new(:name=>'a')
239
239
  o.valid?.must_equal false
240
240
  o.errors.full_messages.must_equal ['name is bad']
@@ -245,7 +245,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
245
245
  c.plugin :constraint_validations, :validation_options=>{:unique=>{:message=>'is bad'}}
246
246
  c.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad', :allow_nil=>true}]]
247
247
  c.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad', :allow_nil=>true}]])
248
- c.dataset._fetch = {:count=>1}
248
+ c.dataset = c.dataset.with_fetch(:count=>1)
249
249
  o = c.new(:name=>'a')
250
250
  o.valid?.must_equal false
251
251
  o.errors.full_messages.must_equal ['name is bad']
@@ -258,7 +258,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
258
258
  sc.plugin :constraint_validations, :validation_options=>{:unique=>{:allow_missing=>true, :allow_nil=>false}}
259
259
  sc.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad', :allow_missing=>true, :allow_nil=>false}]]
260
260
  sc.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad', :allow_missing=>true, :allow_nil=>false}]])
261
- sc.dataset._fetch = {:count=>1}
261
+ sc.dataset = sc.dataset.with_fetch(:count=>1)
262
262
  o = sc.new(:name=>'a')
263
263
  o.valid?.must_equal false
264
264
  o.errors.full_messages.must_equal ['name is bad']
@@ -2,8 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "constraint_validations extension" do
4
4
  def parse_insert(s)
5
- m = /\AINSERT INTO sequel_constraint_validations \((.*)\) VALUES \((.*)\)\z/.match(s)
6
- Hash[*m[1].split(', ').map{|v| v.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten]
5
+ m = /\AINSERT INTO "?sequel_constraint_validations"? \("?(.*)"?\) VALUES \((.*)\)\z/.match(s)
6
+ Hash[*m[1].split(/"?, "?/).map{|v| v.to_sym}.zip(m[2].split(/"?, "?/).map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten]
7
7
  end
8
8
 
9
9
  def parse_insert_value(s)
@@ -130,13 +130,17 @@ describe "constraint_validations extension" do
130
130
 
131
131
  it "should handle presence validation on Oracle with IS NOT NULL instead of != ''" do
132
132
  @db = Sequel.mock(:host=>'oracle')
133
+ @db.extend_datasets do
134
+ def quote_identifiers?; false end
135
+ def input_identifier(v) v.to_s end
136
+ end
133
137
  @db.extension(:constraint_validations)
134
138
  @db.create_table(:foo){String :name; validate{presence :name}}
135
139
  sqls = @db.sqls
136
- s = sqls.slice!(1)
137
- m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z/.match(s)
138
- Hash[*m[1].split(', ').map{|v| v.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten].must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
139
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) IS NOT NULL)))"]
140
+ s = sqls.slice!(1).upcase
141
+ m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z/i.match(s)
142
+ Hash[*m[1].split(', ').map{|v| v.downcase.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v.downcase.gsub('null', 'NULL'))}).reject{|k, v| v.nil?}.flatten].must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
143
+ sqls.must_equal ["BEGIN", "COMMIT", 'CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) IS NOT NULL)))']
140
144
  end
141
145
 
142
146
  it "should assume column is not a String if it can't determine the type" do
@@ -194,20 +198,22 @@ describe "constraint_validations extension" do
194
198
 
195
199
  it "should support :format constraint validation" do
196
200
  @db = Sequel.mock(:host=>'postgres')
201
+ @db.extend_datasets{def quote_identifiers?; false end}
197
202
  @db.extension(:constraint_validations)
198
203
  @db.create_table(:foo){String :name; validate{format(/^foo.*/, :name)}}
199
204
  sqls = @db.sqls
200
205
  parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"format", :column=>"name", :table=>"foo", :argument=>'^foo.*')
201
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~ '^foo.*')))"]
206
+ sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~ '^foo.*')))]]
202
207
  end
203
208
 
204
209
  it "should support :format constraint validation with case insensitive format" do
205
210
  @db = Sequel.mock(:host=>'postgres')
211
+ @db.extend_datasets{def quote_identifiers?; false end}
206
212
  @db.extension(:constraint_validations)
207
213
  @db.create_table(:foo){String :name; validate{format(/^foo.*/i, :name)}}
208
214
  sqls = @db.sqls
209
215
  parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"iformat", :column=>"name", :table=>"foo", :argument=>'^foo.*')
210
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~* '^foo.*')))"]
216
+ sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~* '^foo.*')))]]
211
217
  end
212
218
 
213
219
  it "should support :includes constraint validation with an array of strings" do
@@ -6,14 +6,15 @@ using Sequel::CoreRefinements
6
6
 
7
7
  describe "Core refinements" do
8
8
  before do
9
- db = Sequel::Database.new
10
- @d = db[:items]
11
- def @d.supports_regexp?; true end
12
- def @d.l(*args, &block)
13
- literal(filter_expr(*args, &block))
14
- end
15
- def @d.lit(*args)
16
- literal(*args)
9
+ db = Sequel.mock
10
+ @d = db[:items].with_extend do
11
+ def supports_regexp?; true end
12
+ def l(*args, &block)
13
+ literal(filter_expr(*args, &block))
14
+ end
15
+ def lit(*args)
16
+ literal(*args)
17
+ end
17
18
  end
18
19
  end
19
20
 
@@ -184,7 +185,7 @@ end
184
185
 
185
186
  describe "String#lit" do
186
187
  before do
187
- @ds = Sequel::Database.new[:t]
188
+ @ds = Sequel.mock[:t]
188
189
  end
189
190
 
190
191
  it "should return an LiteralString object" do
@@ -200,16 +201,14 @@ describe "String#lit" do
200
201
  a = 'DISTINCT ?'.lit(:a)
201
202
  a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
202
203
  @ds.literal(a).must_equal 'DISTINCT a'
203
- @ds.quote_identifiers = true
204
- @ds.literal(a).must_equal 'DISTINCT "a"'
204
+ @ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
205
205
  end
206
206
 
207
207
  it "should handle named placeholders if given a single argument hash" do
208
208
  a = 'DISTINCT :b'.lit(:b=>:a)
209
209
  a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
210
210
  @ds.literal(a).must_equal 'DISTINCT a'
211
- @ds.quote_identifiers = true
212
- @ds.literal(a).must_equal 'DISTINCT "a"'
211
+ @ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
213
212
  end
214
213
 
215
214
  it "should treat placeholder literal strings as generic expressions" do
@@ -285,11 +284,7 @@ end
285
284
 
286
285
  describe "Column references" do
287
286
  before do
288
- @ds = Sequel::Database.new.dataset
289
- def @ds.quoted_identifier_append(sql, c)
290
- sql << "`#{c}`"
291
- end
292
- @ds.quote_identifiers = true
287
+ @ds = Sequel.mock.dataset.with_quote_identifiers(true).with_extend{def quoted_identifier_append(sql, c) sql << "`#{c}`" end}
293
288
  end
294
289
 
295
290
  it "should be quoted properly" do
@@ -349,30 +344,28 @@ end
349
344
 
350
345
  describe "Symbol" do
351
346
  before do
352
- @ds = Sequel.mock.dataset
353
- @ds.quote_identifiers = true
354
- @ds.identifier_input_method = :upcase
347
+ @ds = Sequel.mock.dataset.with_quote_identifiers(true)
355
348
  end
356
349
 
357
350
  it "#identifier should format an identifier" do
358
- @ds.literal(:xyz__abc.identifier).must_equal '"XYZ__ABC"'
351
+ @ds.literal(:xyz__abc.identifier).must_equal '"xyz__abc"'
359
352
  end
360
353
 
361
354
  it "#qualify should format a qualified column" do
362
- @ds.literal(:xyz.qualify(:abc)).must_equal '"ABC"."XYZ"'
355
+ @ds.literal(:xyz.qualify(:abc)).must_equal '"abc"."xyz"'
363
356
  end
364
357
 
365
358
  it "#qualify should work on QualifiedIdentifiers" do
366
- @ds.literal(:xyz.qualify(:abc).qualify(:def)).must_equal '"DEF"."ABC"."XYZ"'
359
+ @ds.literal(:xyz.qualify(:abc).qualify(:def)).must_equal '"def"."abc"."xyz"'
367
360
  end
368
361
 
369
362
  it "should be able to qualify an identifier" do
370
- @ds.literal(:xyz.identifier.qualify(:xyz__abc)).must_equal '"XYZ"."ABC"."XYZ"'
363
+ @ds.literal(:xyz.identifier.qualify(:xyz__abc)).must_equal '"xyz"."abc"."xyz"'
371
364
  end
372
365
 
373
366
  it "should be able to specify a schema.table.column" do
374
- @ds.literal(:column.qualify(:table.qualify(:schema))).must_equal '"SCHEMA"."TABLE"."COLUMN"'
375
- @ds.literal(:column.qualify(:table__name.identifier.qualify(:schema))).must_equal '"SCHEMA"."TABLE__NAME"."COLUMN"'
367
+ @ds.literal(:column.qualify(:table.qualify(:schema))).must_equal '"schema"."table"."column"'
368
+ @ds.literal(:column.qualify(:table__name.identifier.qualify(:schema))).must_equal '"schema"."table__name"."column"'
376
369
  end
377
370
 
378
371
  it "should be able to specify order" do
@@ -387,13 +380,13 @@ describe "Symbol" do
387
380
  it "should work correctly with objects" do
388
381
  o = Object.new
389
382
  def o.sql_literal(ds) "(foo)" end
390
- @ds.literal(:column.qualify(o)).must_equal '(foo)."COLUMN"'
383
+ @ds.literal(:column.qualify(o)).must_equal '(foo)."column"'
391
384
  end
392
385
  end
393
386
 
394
387
  describe "Symbol" do
395
388
  before do
396
- @ds = Sequel::Database.new.dataset
389
+ @ds = Sequel.mock.dataset
397
390
  end
398
391
 
399
392
  it "should support sql_function method" do
@@ -95,7 +95,7 @@ describe "Sequel::Plugins::CsvSerializer" do
95
95
 
96
96
  @album = @Album.from_csv('2,AS', :headers=>[nil, 'name'])
97
97
  @album.name.must_equal 'AS'
98
- @album.artist_id.must_equal nil
98
+ @album.artist_id.must_be_nil
99
99
  end
100
100
 
101
101
  it "#from_csv should support :headers to specify headers" do
@@ -109,8 +109,10 @@ describe "Sequel::Plugins::CsvSerializer" do
109
109
  end
110
110
 
111
111
  it "should support a to_csv class and dataset method" do
112
- @Album.dataset._fetch = {:id=>1, :name=>'RF', :artist_id=>2}
113
- @Artist.dataset._fetch = {:id=>2, :name=>'YJM'}
112
+ @Album.dataset = @Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
113
+ @Artist.dataset = @Artist.dataset.with_fetch(:id=>2, :name=>'YJM')
114
+ @Album.columns(:id, :name, :artist_id)
115
+ @Album.db_schema.replace(:id=>{:type=>:integer}, :artist_id=>{:type=>:integer})
114
116
  @Album.array_from_csv(@Album.to_csv).must_equal [@album]
115
117
  @Album.array_from_csv(@Album.dataset.to_csv(:only=>:name), :only=>:name).must_equal [@Album.load(:name=>@album.name)]
116
118
  end
@@ -166,9 +168,8 @@ describe "Sequel::Plugins::CsvSerializer" do
166
168
  it "should use a dataset's selected columns" do
167
169
  columns = [:id]
168
170
  ds = @Artist.select(*columns).limit(1)
169
- ds.instance_variable_set(:@columns, columns)
170
- ds._fetch = [:id => 10]
171
- ds.to_csv(:write_headers => true).must_equal "id\n10\n"
171
+ ds.send(:columns=, columns)
172
+ ds.with_fetch(:id => 10).to_csv(:write_headers => true).must_equal "id\n10\n"
172
173
  end
173
174
 
174
175
  it "should pass all the examples from the documentation" do
@@ -83,21 +83,21 @@ describe "date_arithmetic extension" do
83
83
  end
84
84
 
85
85
  it "should correctly literalize on Postgres" do
86
- db = dbf.call(:postgres)
86
+ db = dbf.call(:postgres).dataset.with_quote_identifiers(false)
87
87
  db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
88
88
  db.literal(Sequel.date_add(:a, @h1)).must_equal "(CAST(a AS timestamp) + CAST('1 days ' AS interval))"
89
89
  db.literal(Sequel.date_add(:a, @h2)).must_equal "(CAST(a AS timestamp) + CAST('1 years 1 months 1 days 1 hours 1 minutes 1 seconds ' AS interval))"
90
90
  end
91
91
 
92
92
  it "should correctly literalize on SQLite" do
93
- db = dbf.call(:sqlite)
93
+ db = dbf.call(:sqlite).dataset.with_quote_identifiers(false)
94
94
  db.literal(Sequel.date_add(:a, @h0)).must_equal "datetime(a)"
95
95
  db.literal(Sequel.date_add(:a, @h1)).must_equal "datetime(a, '1 days')"
96
96
  db.literal(Sequel.date_add(:a, @h2)).must_equal "datetime(a, '1 years', '1 months', '1 days', '1 hours', '1 minutes', '1 seconds')"
97
97
  end
98
98
 
99
99
  it "should correctly literalize on MySQL" do
100
- db = dbf.call(:mysql)
100
+ db = dbf.call(:mysql).dataset.with_quote_identifiers(false)
101
101
  db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS DATETIME)"
102
102
  db.literal(Sequel.date_add(:a, @h1)).must_equal "DATE_ADD(a, INTERVAL 1 DAY)"
103
103
  db.literal(Sequel.date_add(:a, @h2)).must_equal "DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(a, INTERVAL 1 YEAR), INTERVAL 1 MONTH), INTERVAL 1 DAY), INTERVAL 1 HOUR), INTERVAL 1 MINUTE), INTERVAL 1 SECOND)"
@@ -113,10 +113,10 @@ describe "date_arithmetic extension" do
113
113
  end
114
114
 
115
115
  it "should correctly literalize on MSSQL" do
116
- db = dbf.call(:mssql)
117
- db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS datetime)"
118
- db.literal(Sequel.date_add(:a, @h1)).must_equal "DATEADD(day, 1, a)"
119
- db.literal(Sequel.date_add(:a, @h2)).must_equal "DATEADD(second, 1, DATEADD(minute, 1, DATEADD(hour, 1, DATEADD(day, 1, DATEADD(month, 1, DATEADD(year, 1, a))))))"
116
+ db = dbf.call(:mssql).dataset.with_quote_identifiers(false)
117
+ db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS datetime)"
118
+ db.literal(Sequel.date_add(:A, @h1)).must_equal "DATEADD(day, 1, A)"
119
+ db.literal(Sequel.date_add(:A, @h2)).must_equal "DATEADD(second, 1, DATEADD(minute, 1, DATEADD(hour, 1, DATEADD(day, 1, DATEADD(month, 1, DATEADD(year, 1, A))))))"
120
120
  end
121
121
 
122
122
  it "should correctly literalize on H2" do
@@ -129,7 +129,7 @@ describe "date_arithmetic extension" do
129
129
  end
130
130
 
131
131
  it "should correctly literalize on access" do
132
- db = dbf.call(:access)
132
+ db = dbf.call(:access).dataset.with_quote_identifiers(false)
133
133
  db.literal(Sequel.date_add(:a, @h0)).must_equal "CDate(a)"
134
134
  db.literal(Sequel.date_add(:a, @h1)).must_equal "DATEADD('d', 1, a)"
135
135
  db.literal(Sequel.date_add(:a, @h2)).must_equal "DATEADD('s', 1, DATEADD('n', 1, DATEADD('h', 1, DATEADD('d', 1, DATEADD('m', 1, DATEADD('yyyy', 1, a))))))"
@@ -146,17 +146,17 @@ describe "date_arithmetic extension" do
146
146
  end
147
147
 
148
148
  it "should correctly literalize on Oracle" do
149
- db = dbf.call(:oracle)
150
- db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
151
- db.literal(Sequel.date_add(:a, @h1)).must_equal "(a + INTERVAL '1' DAY)"
152
- db.literal(Sequel.date_add(:a, @h2)).must_equal "(a + INTERVAL '1' YEAR + INTERVAL '1' MONTH + INTERVAL '1' DAY + INTERVAL '1' HOUR + INTERVAL '1' MINUTE + INTERVAL '1' SECOND)"
149
+ db = dbf.call(:oracle).dataset.with_quote_identifiers(false)
150
+ db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS timestamp)"
151
+ db.literal(Sequel.date_add(:A, @h1)).must_equal "(A + INTERVAL '1' DAY)"
152
+ db.literal(Sequel.date_add(:A, @h2)).must_equal "(A + INTERVAL '1' YEAR + INTERVAL '1' MONTH + INTERVAL '1' DAY + INTERVAL '1' HOUR + INTERVAL '1' MINUTE + INTERVAL '1' SECOND)"
153
153
  end
154
154
 
155
155
  it "should correctly literalize on DB2" do
156
156
  db = dbf.call(:db2)
157
- db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
158
- db.literal(Sequel.date_add(:a, @h1)).must_equal "(CAST(a AS timestamp) + 1 days)"
159
- db.literal(Sequel.date_add(:a, @h2)).must_equal "(CAST(a AS timestamp) + 1 years + 1 months + 1 days + 1 hours + 1 minutes + 1 seconds)"
157
+ db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS timestamp)"
158
+ db.literal(Sequel.date_add(:A, @h1)).must_equal "(CAST(A AS timestamp) + 1 days)"
159
+ db.literal(Sequel.date_add(:A, @h2)).must_equal "(CAST(A AS timestamp) + 1 years + 1 months + 1 days + 1 hours + 1 minutes + 1 seconds)"
160
160
  end
161
161
 
162
162
  it "should raise error if literalizing on an unsupported database" do
@@ -63,7 +63,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
63
63
  it "should not override a given value" do
64
64
  @pr.call(2)
65
65
  @c.new('a'=>3).a.must_equal 3
66
- @c.new('a'=>nil).a.must_equal nil
66
+ @c.new('a'=>nil).a.must_be_nil
67
67
  end
68
68
 
69
69
  it "should work correctly when subclassing" do
@@ -90,7 +90,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
90
90
  it "should have procs that set default values set them to nil" do
91
91
  @pr.call(2)
92
92
  @c.default_values[:a] = proc{nil}
93
- @c.new.a.must_equal nil
93
+ @c.new.a.must_be_nil
94
94
  end
95
95
 
96
96
  it "should work correctly on a model without a dataset" do
@@ -45,7 +45,7 @@ describe "Sequel::Plugins::DelayAddAssociation" do
45
45
  @c.send(:define_method, :validate){|*| errors.add(:name, 'is b') if name == 'b'}
46
46
  @o = @c.new(:name=>'a')
47
47
  @o.add_c(@c.load(:id=>2, :name=>'b'))
48
- @o.save.must_equal nil
48
+ @o.save.must_be_nil
49
49
  @o.errors[:cs].must_equal ["name is b"]
50
50
  @o.cs.first.errors[:name].must_equal ['is b']
51
51
  end
@@ -11,19 +11,19 @@ describe "Sequel::Plugins::Dirty" do
11
11
  dirty_plugin_specs = shared_description do
12
12
  it "initial_value should be the current value if value has not changed" do
13
13
  @o.initial_value(:initial).must_equal 'i'
14
- @o.initial_value(:missing).must_equal nil
14
+ @o.initial_value(:missing).must_be_nil
15
15
  end
16
16
 
17
17
  it "initial_value should be the intial value if value has changed" do
18
18
  @o.initial_value(:initial_changed).must_equal 'ic'
19
- @o.initial_value(:missing_changed).must_equal nil
19
+ @o.initial_value(:missing_changed).must_be_nil
20
20
  end
21
21
 
22
22
  it "initial_value should handle case where initial value is reassigned later" do
23
23
  @o.initial_changed = 'ic'
24
24
  @o.initial_value(:initial_changed).must_equal 'ic'
25
25
  @o.missing_changed = nil
26
- @o.initial_value(:missing_changed).must_equal nil
26
+ @o.initial_value(:missing_changed).must_be_nil
27
27
  end
28
28
 
29
29
  it "changed_columns should handle case where initial value is reassigned later" do
@@ -40,8 +40,8 @@ describe "Sequel::Plugins::Dirty" do
40
40
  end
41
41
 
42
42
  it "column_change should be nil if no change has been made" do
43
- @o.column_change(:initial).must_equal nil
44
- @o.column_change(:missing).must_equal nil
43
+ @o.column_change(:initial).must_be_nil
44
+ @o.column_change(:missing).must_be_nil
45
45
  end
46
46
 
47
47
  it "column_changed? should return whether the column has changed" do
@@ -76,9 +76,9 @@ describe "Sequel::Plugins::Dirty" do
76
76
  @o.reset_column(:initial_changed)
77
77
  @o.initial_changed.must_equal 'ic'
78
78
  @o.reset_column(:missing)
79
- @o.missing.must_equal nil
79
+ @o.missing.must_be_nil
80
80
  @o.reset_column(:missing_changed)
81
- @o.missing_changed.must_equal nil
81
+ @o.missing_changed.must_be_nil
82
82
  end
83
83
 
84
84
  it "reset_column should remove missing values from the values" do
@@ -124,11 +124,18 @@ describe "Sequel::Plugins::Dirty" do
124
124
  end
125
125
 
126
126
  it "should have #dup duplicate structures" do
127
+ was_new = @o.new?
128
+ @o.update(:missing=>'m2')
127
129
  @o.dup.initial_values.must_equal @o.initial_values
128
130
  @o.dup.initial_values.wont_be_same_as(@o.initial_values)
129
131
  @o.dup.instance_variable_get(:@missing_initial_values).must_equal @o.instance_variable_get(:@missing_initial_values)
130
132
  @o.dup.instance_variable_get(:@missing_initial_values).wont_be_same_as(@o.instance_variable_get(:@missing_initial_values))
131
- @o.dup.previous_changes.must_equal @o.previous_changes
133
+ if was_new
134
+ @o.previous_changes.must_be_nil
135
+ @o.dup.previous_changes.must_be_nil
136
+ else
137
+ @o.dup.previous_changes.must_equal @o.previous_changes
138
+ end
132
139
  @o.dup.previous_changes.wont_be_same_as(@o.previous_changes) if @o.previous_changes
133
140
  end
134
141
  end
@@ -148,8 +155,10 @@ describe "Sequel::Plugins::Dirty" do
148
155
  end
149
156
 
150
157
  it "save_changes should clear the cached initial values" do
151
- def (@c.instance_dataset).supports_insert_select?() true end
152
- def (@c.instance_dataset).insert_select(*) {:id=>1} end
158
+ @c.dataset = @c.dataset.with_extend do
159
+ def supports_insert_select?; true end
160
+ def insert_select(*) {:id=>1} end
161
+ end
153
162
  @o.save
154
163
  @o.column_changes.must_equal({})
155
164
  end