sequel 4.41.0 → 4.42.0

Sign up to get free protection for your applications and to get access to all the features.
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