sequel 4.22.0 → 4.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +22 -0
  3. data/README.rdoc +6 -0
  4. data/Rakefile +59 -81
  5. data/doc/migration.rdoc +2 -0
  6. data/doc/release_notes/4.23.0.txt +65 -0
  7. data/doc/sharding.rdoc +16 -14
  8. data/doc/testing.rdoc +61 -77
  9. data/lib/sequel/adapters/jdbc.rb +1 -0
  10. data/lib/sequel/adapters/mock.rb +0 -1
  11. data/lib/sequel/adapters/postgres.rb +1 -0
  12. data/lib/sequel/adapters/postgresql.rb +1 -0
  13. data/lib/sequel/adapters/shared/postgres.rb +3 -3
  14. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
  15. data/lib/sequel/connection_pool/threaded.rb +9 -1
  16. data/lib/sequel/database/connecting.rb +1 -1
  17. data/lib/sequel/database/transactions.rb +2 -1
  18. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  19. data/lib/sequel/extensions/constraint_validations.rb +12 -12
  20. data/lib/sequel/extensions/date_arithmetic.rb +0 -4
  21. data/lib/sequel/extensions/pagination.rb +14 -2
  22. data/lib/sequel/extensions/pg_enum.rb +2 -2
  23. data/lib/sequel/extensions/pg_hstore.rb +1 -1
  24. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  25. data/lib/sequel/plugins/csv_serializer.rb +2 -0
  26. data/lib/sequel/plugins/delay_add_association.rb +50 -0
  27. data/lib/sequel/plugins/list.rb +2 -2
  28. data/lib/sequel/plugins/nested_attributes.rb +8 -28
  29. data/lib/sequel/plugins/update_refresh.rb +50 -0
  30. data/lib/sequel/plugins/validate_associated.rb +55 -0
  31. data/lib/sequel/version.rb +1 -1
  32. data/spec/adapters/db2_spec.rb +29 -29
  33. data/spec/adapters/firebird_spec.rb +97 -103
  34. data/spec/adapters/informix_spec.rb +25 -25
  35. data/spec/adapters/mssql_spec.rb +156 -172
  36. data/spec/adapters/mysql_spec.rb +334 -359
  37. data/spec/adapters/oracle_spec.rb +67 -69
  38. data/spec/adapters/postgres_spec.rb +1298 -1249
  39. data/spec/adapters/spec_helper.rb +2 -35
  40. data/spec/adapters/sqlanywhere_spec.rb +39 -39
  41. data/spec/adapters/sqlite_spec.rb +203 -200
  42. data/spec/bin_spec.rb +57 -59
  43. data/spec/core/connection_pool_spec.rb +402 -401
  44. data/spec/core/database_spec.rb +953 -944
  45. data/spec/core/dataset_spec.rb +2178 -2168
  46. data/spec/core/deprecated_spec.rb +19 -19
  47. data/spec/core/expression_filters_spec.rb +415 -415
  48. data/spec/core/mock_adapter_spec.rb +212 -212
  49. data/spec/core/object_graph_spec.rb +73 -73
  50. data/spec/core/placeholder_literalizer_spec.rb +71 -71
  51. data/spec/core/schema_generator_spec.rb +44 -44
  52. data/spec/core/schema_spec.rb +470 -472
  53. data/spec/core/spec_helper.rb +5 -20
  54. data/spec/core/version_spec.rb +2 -2
  55. data/spec/core_extensions_spec.rb +320 -320
  56. data/spec/extensions/accessed_columns_spec.rb +12 -12
  57. data/spec/extensions/active_model_spec.rb +3 -3
  58. data/spec/extensions/after_initialize_spec.rb +2 -2
  59. data/spec/extensions/arbitrary_servers_spec.rb +23 -23
  60. data/spec/extensions/association_dependencies_spec.rb +34 -34
  61. data/spec/extensions/association_pks_spec.rb +98 -98
  62. data/spec/extensions/association_proxies_spec.rb +33 -33
  63. data/spec/extensions/auto_validations_spec.rb +46 -46
  64. data/spec/extensions/blacklist_security_spec.rb +19 -18
  65. data/spec/extensions/blank_spec.rb +36 -36
  66. data/spec/extensions/boolean_readers_spec.rb +36 -36
  67. data/spec/extensions/caching_spec.rb +82 -82
  68. data/spec/extensions/class_table_inheritance_spec.rb +72 -72
  69. data/spec/extensions/column_conflicts_spec.rb +19 -14
  70. data/spec/extensions/column_select_spec.rb +19 -19
  71. data/spec/extensions/columns_introspection_spec.rb +43 -43
  72. data/spec/extensions/composition_spec.rb +64 -64
  73. data/spec/extensions/connection_validator_spec.rb +92 -90
  74. data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
  75. data/spec/extensions/constraint_validations_spec.rb +80 -80
  76. data/spec/extensions/core_refinements_spec.rb +220 -220
  77. data/spec/extensions/csv_serializer_spec.rb +44 -44
  78. data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
  79. data/spec/extensions/dataset_associations_spec.rb +65 -65
  80. data/spec/extensions/dataset_source_alias_spec.rb +16 -16
  81. data/spec/extensions/date_arithmetic_spec.rb +51 -58
  82. data/spec/extensions/defaults_setter_spec.rb +19 -19
  83. data/spec/extensions/delay_add_association_spec.rb +52 -0
  84. data/spec/extensions/dirty_spec.rb +51 -51
  85. data/spec/extensions/eager_each_spec.rb +8 -8
  86. data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
  87. data/spec/extensions/error_splitter_spec.rb +2 -2
  88. data/spec/extensions/error_sql_spec.rb +4 -4
  89. data/spec/extensions/eval_inspect_spec.rb +3 -3
  90. data/spec/extensions/filter_having_spec.rb +8 -8
  91. data/spec/extensions/force_encoding_spec.rb +30 -30
  92. data/spec/extensions/from_block_spec.rb +7 -7
  93. data/spec/extensions/graph_each_spec.rb +19 -19
  94. data/spec/extensions/hash_aliases_spec.rb +5 -5
  95. data/spec/extensions/hook_class_methods_spec.rb +100 -100
  96. data/spec/extensions/inflector_spec.rb +54 -54
  97. data/spec/extensions/input_transformer_spec.rb +10 -10
  98. data/spec/extensions/insert_returning_select_spec.rb +8 -8
  99. data/spec/extensions/instance_filters_spec.rb +26 -26
  100. data/spec/extensions/instance_hooks_spec.rb +85 -85
  101. data/spec/extensions/json_serializer_spec.rb +68 -68
  102. data/spec/extensions/lazy_attributes_spec.rb +49 -49
  103. data/spec/extensions/list_spec.rb +77 -75
  104. data/spec/extensions/looser_typecasting_spec.rb +16 -16
  105. data/spec/extensions/many_through_many_spec.rb +627 -627
  106. data/spec/extensions/meta_def_spec.rb +7 -7
  107. data/spec/extensions/migration_spec.rb +217 -217
  108. data/spec/extensions/modification_detection_spec.rb +20 -20
  109. data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
  110. data/spec/extensions/named_timezones_spec.rb +18 -18
  111. data/spec/extensions/nested_attributes_spec.rb +107 -107
  112. data/spec/extensions/null_dataset_spec.rb +24 -24
  113. data/spec/extensions/optimistic_locking_spec.rb +21 -21
  114. data/spec/extensions/pagination_spec.rb +52 -52
  115. data/spec/extensions/pg_array_associations_spec.rb +273 -273
  116. data/spec/extensions/pg_array_ops_spec.rb +52 -52
  117. data/spec/extensions/pg_array_spec.rb +152 -152
  118. data/spec/extensions/pg_enum_spec.rb +13 -13
  119. data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
  120. data/spec/extensions/pg_hstore_spec.rb +84 -84
  121. data/spec/extensions/pg_inet_spec.rb +15 -15
  122. data/spec/extensions/pg_interval_spec.rb +29 -29
  123. data/spec/extensions/pg_json_ops_spec.rb +86 -84
  124. data/spec/extensions/pg_json_spec.rb +104 -104
  125. data/spec/extensions/pg_loose_count_spec.rb +6 -6
  126. data/spec/extensions/pg_range_ops_spec.rb +24 -24
  127. data/spec/extensions/pg_range_spec.rb +143 -143
  128. data/spec/extensions/pg_row_ops_spec.rb +14 -14
  129. data/spec/extensions/pg_row_plugin_spec.rb +12 -12
  130. data/spec/extensions/pg_row_spec.rb +118 -118
  131. data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
  132. data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
  133. data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
  134. data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
  135. data/spec/extensions/prepared_statements_spec.rb +28 -28
  136. data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
  137. data/spec/extensions/pretty_table_spec.rb +16 -16
  138. data/spec/extensions/query_literals_spec.rb +37 -37
  139. data/spec/extensions/query_spec.rb +32 -32
  140. data/spec/extensions/rcte_tree_spec.rb +141 -141
  141. data/spec/extensions/round_timestamps_spec.rb +21 -21
  142. data/spec/extensions/schema_caching_spec.rb +8 -8
  143. data/spec/extensions/schema_dumper_spec.rb +78 -78
  144. data/spec/extensions/schema_spec.rb +31 -27
  145. data/spec/extensions/scissors_spec.rb +3 -3
  146. data/spec/extensions/select_remove_spec.rb +14 -14
  147. data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
  148. data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
  149. data/spec/extensions/serialization_spec.rb +79 -78
  150. data/spec/extensions/server_block_spec.rb +17 -17
  151. data/spec/extensions/set_overrides_spec.rb +30 -30
  152. data/spec/extensions/sharding_spec.rb +65 -65
  153. data/spec/extensions/shared_caching_spec.rb +29 -29
  154. data/spec/extensions/single_table_inheritance_spec.rb +79 -79
  155. data/spec/extensions/skip_create_refresh_spec.rb +3 -3
  156. data/spec/extensions/spec_helper.rb +4 -29
  157. data/spec/extensions/split_array_nil_spec.rb +9 -9
  158. data/spec/extensions/split_values_spec.rb +7 -7
  159. data/spec/extensions/sql_expr_spec.rb +32 -32
  160. data/spec/extensions/static_cache_spec.rb +123 -123
  161. data/spec/extensions/string_date_time_spec.rb +34 -34
  162. data/spec/extensions/string_stripper_spec.rb +15 -15
  163. data/spec/extensions/subclasses_spec.rb +31 -31
  164. data/spec/extensions/table_select_spec.rb +15 -15
  165. data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
  166. data/spec/extensions/thread_local_timezones_spec.rb +13 -13
  167. data/spec/extensions/timestamps_spec.rb +40 -40
  168. data/spec/extensions/to_dot_spec.rb +34 -34
  169. data/spec/extensions/touch_spec.rb +52 -52
  170. data/spec/extensions/tree_spec.rb +72 -72
  171. data/spec/extensions/typecast_on_load_spec.rb +25 -25
  172. data/spec/extensions/unlimited_update_spec.rb +2 -2
  173. data/spec/extensions/update_or_create_spec.rb +36 -36
  174. data/spec/extensions/update_primary_key_spec.rb +35 -35
  175. data/spec/extensions/update_refresh_spec.rb +41 -0
  176. data/spec/extensions/validate_associated_spec.rb +52 -0
  177. data/spec/extensions/validation_class_methods_spec.rb +314 -317
  178. data/spec/extensions/validation_helpers_spec.rb +195 -195
  179. data/spec/extensions/xml_serializer_spec.rb +48 -48
  180. data/spec/guards_helper.rb +55 -0
  181. data/spec/integration/associations_test.rb +1089 -1088
  182. data/spec/integration/database_test.rb +29 -29
  183. data/spec/integration/dataset_test.rb +661 -661
  184. data/spec/integration/eager_loader_test.rb +147 -147
  185. data/spec/integration/migrator_test.rb +122 -122
  186. data/spec/integration/model_test.rb +70 -70
  187. data/spec/integration/plugin_test.rb +682 -640
  188. data/spec/integration/prepared_statement_test.rb +172 -172
  189. data/spec/integration/schema_test.rb +245 -245
  190. data/spec/integration/spec_helper.rb +1 -64
  191. data/spec/integration/timezone_test.rb +17 -17
  192. data/spec/integration/transaction_test.rb +87 -87
  193. data/spec/integration/type_test.rb +33 -33
  194. data/spec/model/association_reflection_spec.rb +130 -121
  195. data/spec/model/associations_spec.rb +1112 -1113
  196. data/spec/model/base_spec.rb +197 -196
  197. data/spec/model/class_dataset_methods_spec.rb +118 -118
  198. data/spec/model/dataset_methods_spec.rb +49 -49
  199. data/spec/model/eager_loading_spec.rb +705 -702
  200. data/spec/model/hooks_spec.rb +169 -168
  201. data/spec/model/inflector_spec.rb +5 -5
  202. data/spec/model/model_spec.rb +287 -297
  203. data/spec/model/plugins_spec.rb +47 -47
  204. data/spec/model/record_spec.rb +534 -535
  205. data/spec/model/spec_helper.rb +3 -21
  206. data/spec/model/validations_spec.rb +72 -70
  207. data/spec/spec_config.rb +8 -0
  208. metadata +41 -9
  209. data/lib/sequel/adapters/fdbsql.rb +0 -286
  210. data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
  211. data/lib/sequel/adapters/openbase.rb +0 -54
  212. data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
  213. data/spec/adapters/fdbsql_spec.rb +0 -429
  214. data/spec/rspec_helper.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7bcc145a56d7aca254c6a4298678e07ea3cbd4f0
4
- data.tar.gz: 8c90dbb6ef553ddb4995b70f9ac3d0cf03d4dd76
3
+ metadata.gz: b30c79c77e61381e85de13c0490b3e5cba437b25
4
+ data.tar.gz: daf911babab2bc31fb6e255d0a0219a4536f373f
5
5
  SHA512:
6
- metadata.gz: 5b0214c84c88c09f8c3130a75a1e0f3cacf55584f3f3fc310907cd4e08cfdc39147ea4fca90475917db55ac054bcfc8778ea8df2648b2edff8ca9282f4348c72
7
- data.tar.gz: b6efbc0bdd00bd6e5d668960b085e5fd26b6da7fa6592c4621c5f3505d221b1988243af9fbd27ba8075541de6d3a2c24a13c73f36240761416f2c7c7ba10db47
6
+ metadata.gz: b360c247c80f905380b13ac37ff319339127a09860ddcf13288378be326f8dea51c0e56b9880ae0f488253f32e46bf0752d5b4bf4abe4bd7f9200ddcbe563702
7
+ data.tar.gz: 15a84132c8caa90c4dad81998a6a060f931cd2bc77145345e5de5cadbf378c545b3e7f8bbab1a0900341be5a6dd1cf0e9121d35bfea5cfeb85f9ac45a6f42bf0
data/CHANGELOG CHANGED
@@ -1,3 +1,25 @@
1
+ === 4.23.0 (2015-06-01)
2
+
3
+ * Make dataset.call_sproc(:insert) work in the jdbc adapter (flash-gordon) (#1013)
4
+
5
+ * Add update_refresh plugin, for refreshing a model instance when updating (jeremyevans)
6
+
7
+ * Add delay_add_association plugin, for delaying add_* method calls on new objects until after saving the object (jeremyevans)
8
+
9
+ * Add validate_associated plugin, for validating associated objects when validating the current object (jeremyevans)
10
+
11
+ * Make Postgres::JSONBOp#[] and #get_text return JSONBOp instances (jeremyevans) (#1005)
12
+
13
+ * Remove the fdbsql, jdbc/fdbsql, and openbase adapters (jeremyevans)
14
+
15
+ * Database#transaction now returns block return value if :rollback=>:always is used (jeremyevans)
16
+
17
+ * Allow postgresql:// connection strings as aliases to postgres://, for compatibility with libpq (jeremyevans) (#1004)
18
+
19
+ * Make Model#move_to in the list plugin handle out-of-range targets without raising an exception (jeremyevans) (#1003)
20
+
21
+ * Make Database#add_named_conversion_proc on PostgreSQL handle conversion procs for enum types (celsworth) (#1002)
22
+
1
23
  === 4.22.0 (2015-05-01)
2
24
 
3
25
  * Deprecate the db2, dbi, fdbsql, firebird, jdbc/fdbsql, informix, and openbase adapters (jeremyevans)
@@ -430,6 +430,12 @@ You can then do anything you like with the dataset:
430
430
  # ON order_items.item_id = items.id
431
431
  # WHERE order_items.order_id = 1234
432
432
 
433
+ Note that the default selection in Sequel is <tt>*</tt>, which includes all columns
434
+ in all joined tables. Because Sequel returns results as a hash keyed by column name
435
+ symbols, if any tables have columns with the same name, this will clobber the columns
436
+ in the returned hash. So when joining you are usually going to want to change the
437
+ selection using +select+, +select_all+, and/or +select_append+.
438
+
433
439
  == Column references in Sequel
434
440
 
435
441
  Sequel expects column names to be specified using symbols. In addition, returned hashes always use symbols as their keys. This allows you to freely mix literal values and column references in many cases. For example, the two following lines produce equivalent SQL:
data/Rakefile CHANGED
@@ -82,98 +82,76 @@ end
82
82
 
83
83
  ### Specs
84
84
 
85
- begin
86
- begin
87
- raise LoadError if ENV['RSPEC1']
88
- # RSpec 2
89
- require "rspec/core/rake_task"
90
- spec_class = RSpec::Core::RakeTask
91
- spec_files_meth = :pattern=
92
- spec_opts_meth = :rspec_opts=
93
- rescue LoadError
94
- # RSpec 1
95
- require "spec/rake/spectask"
96
- spec_class = Spec::Rake::SpecTask
97
- spec_files_meth = :spec_files=
98
- spec_opts_meth = :spec_opts=
85
+ run_spec = proc do |patterns|
86
+ lib_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'lib')
87
+ rubylib = ENV['RUBYLIB']
88
+ ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
89
+ if RUBY_PLATFORM =~ /mingw32/
90
+ patterns = patterns.split.map{|pat| Dir[pat].to_a}.flatten.join(' ')
99
91
  end
92
+ sh "#{FileUtils::RUBY} -e \"ARGV.each{|f| require f}\" #{patterns}"
93
+ ENV['RUBYLIB'] = rubylib
94
+ end
100
95
 
101
- spec = lambda do |name, files, d|
102
- lib_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'lib')
103
- ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
104
-
105
- desc "#{d} with -w, some warnings filtered"
106
- task "#{name}_w" do
107
- ENV['RUBYOPT'] ? (ENV['RUBYOPT'] += " -w") : (ENV['RUBYOPT'] = '-w')
108
- rake = ENV['RAKE'] || "#{FileUtils::RUBY} -S rake"
109
- sh "#{rake} #{name} 2>&1 | egrep -v \"(spec/.*: warning: (possibly )?useless use of == in void context|: warning: instance variable @.* not initialized|: warning: method redefined; discarding old|: warning: previous definition of)|rspec\""
110
- end
111
-
112
- desc d
113
- spec_class.new(name) do |t|
114
- t.send spec_files_meth, files
115
- t.send spec_opts_meth, ENV['SEQUEL_SPEC_OPTS'].split if ENV['SEQUEL_SPEC_OPTS']
116
- end
96
+ spec_task = proc do |description, name, files|
97
+ desc description
98
+ task name do
99
+ run_spec.call(files)
117
100
  end
118
101
 
119
- spec_with_cov = lambda do |name, files, d, &b|
120
- spec.call(name, files, d)
121
- if RUBY_VERSION < '1.9'
122
- t = spec.call("#{name}_cov", files, "#{d} with coverage")
123
- t.rcov = true
124
- t.rcov_opts = File.file?("spec/rcov.opts") ? File.read("spec/rcov.opts").split("\n") : []
125
- b.call(t) if b
126
- else
127
- desc "#{d} with coverage"
128
- task "#{name}_cov" do
129
- ENV['COVERAGE'] = '1'
130
- Rake::Task[name].invoke
131
- end
132
- end
133
- t
102
+ desc "#{description} with warnings, some warnings filtered"
103
+ task :"#{name}_w" do
104
+ ENV['RUBYOPT'] ? (ENV['RUBYOPT'] += " -w") : (ENV['RUBYOPT'] = '-w')
105
+ rake = ENV['RAKE'] || "#{FileUtils::RUBY} -S rake"
106
+ sh "#{rake} #{name} 2>&1 | egrep -v \"(: warning: instance variable @.* not initialized|: warning: method redefined; discarding old|: warning: previous definition of)\""
134
107
  end
135
108
 
136
- desc "Run the core, model, and extension/plugin specs"
137
- task :default => [:spec, :spec_plugin]
109
+ desc "#{description} with coverage"
110
+ task :"#{name}_cov" do
111
+ ENV['COVERAGE'] = '1'
112
+ run_spec.call(files)
113
+ ENV.delete('COVERAGE')
114
+ end
115
+ end
138
116
 
139
- spec_with_cov.call("spec", Dir["spec/{core,model}/*_spec.rb"], "Run core and model specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/(adapters/([a-ln-z]|m[a-np-z])|extensions/core_extensions)"')}
140
- spec.call("spec_bin", ["spec/bin_spec.rb"], "Run bin/sequel specs")
141
- spec.call("spec_core", Dir["spec/core/*_spec.rb"], "Run core specs")
142
- spec.call("spec_model", Dir["spec/model/*_spec.rb"], "Run model specs")
143
- spec.call("_spec_model_no_assoc", Dir["spec/model/*_spec.rb"].delete_if{|f| f =~ /association|eager_loading/}, '')
144
- spec_with_cov.call("spec_core_ext", ["spec/core_extensions_spec.rb"], "Run core extensions specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|adapters|connection_pool|database|dataset|model)"')}
145
- spec_with_cov.call("spec_plugin", Dir["spec/extensions/*_spec.rb"].sort_by{rand}, "Run extension/plugin specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|adapters|connection_pool|database|dataset|model)"')}
146
- spec_with_cov.call("spec_integration", Dir["spec/integration/*_test.rb"], "Run integration tests")
117
+ desc "Run the core, model, and extension/plugin specs"
118
+ task :default => :spec
119
+ desc "Run the core, model, and extension/plugin specs"
120
+ task :spec => [:spec_core, :spec_model, :spec_plugin]
121
+
122
+ spec_task.call("Run core and model specs together", :spec_core_model, './spec/core/*_spec.rb ./spec/model/*_spec.rb')
123
+ spec_task.call("Run core specs", :spec_core, './spec/core/*_spec.rb')
124
+ spec_task.call("Run model specs", :spec_model, './spec/model/*_spec.rb')
125
+ spec_task.call("Run plugin/extension specs", :spec_plugin, './spec/extensions/*_spec.rb')
126
+ spec_task.call("Run bin/sequel specs", :spec_bin, './spec/bin_spec.rb')
127
+ spec_task.call("Run core extensions specs", :spec_core_ext, './spec/core_extensions_spec.rb')
128
+ spec_task.call("Run integration tests", :spec_integration, './spec/integration/*_test.rb')
129
+
130
+ %w'postgres sqlite mysql informix oracle firebird mssql db2 sqlanywhere'.each do |adapter|
131
+ spec_task.call("Run #{adapter} tests", :"spec_#{adapter}", "./spec/adapters/#{adapter}_spec.rb ./spec/integration/*_test.rb")
132
+ end
147
133
 
148
- %w'postgres sqlite mysql informix oracle fdbsql firebird mssql db2 sqlanywhere'.each do |adapter|
149
- spec_with_cov.call("spec_#{adapter}", ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"], "Run #{adapter} specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|connection_pool|database|dataset|model|extensions|plugins)"')}
150
- end
134
+ spec_task.call("Run model specs without the associations code", :_spec_model_no_assoc, Dir["./spec/model/*_spec.rb"].delete_if{|f| f =~ /association|eager_loading/}.join(' '))
135
+ desc "Run model specs without the associations code"
136
+ task :spec_model_no_assoc do
137
+ ENV['SEQUEL_NO_ASSOCIATIONS'] = '1'
138
+ Rake::Task['_spec_model_no_assoc'].invoke
139
+ end
151
140
 
152
- task :spec_travis=>[:spec, :spec_plugin, :spec_core_ext] do
153
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
154
- ENV['SEQUEL_SQLITE_URL'] = "jdbc:sqlite::memory:"
155
- ENV['SEQUEL_POSTGRES_URL'] = "jdbc:postgresql://localhost/sequel_test?user=postgres"
156
- ENV['SEQUEL_MYSQL_URL'] = "jdbc:mysql://localhost/sequel_test?user=root"
157
- else
158
- ENV['SEQUEL_SQLITE_URL'] = "sqlite:/"
159
- ENV['SEQUEL_POSTGRES_URL'] = "postgres://localhost/sequel_test?user=postgres"
160
- ENV['SEQUEL_MYSQL_URL'] = "mysql2://localhost/sequel_test?user=root"
161
- end
162
-
163
- Rake::Task['spec_sqlite'].invoke
164
- Rake::Task['spec_postgres'].invoke
165
- Rake::Task['spec_mysql'].invoke
141
+ task :spec_travis=>[:spec_core, :spec_model, :spec_plugin, :spec_core_ext] do
142
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
143
+ ENV['SEQUEL_SQLITE_URL'] = "jdbc:sqlite::memory:"
144
+ ENV['SEQUEL_POSTGRES_URL'] = "jdbc:postgresql://localhost/sequel_test?user=postgres"
145
+ ENV['SEQUEL_MYSQL_URL'] = "jdbc:mysql://localhost/sequel_test?user=root"
146
+ else
147
+ ENV['SEQUEL_SQLITE_URL'] = "sqlite:/"
148
+ ENV['SEQUEL_POSTGRES_URL'] = "postgres://localhost/sequel_test?user=postgres"
149
+ ENV['SEQUEL_MYSQL_URL'] = "mysql2://localhost/sequel_test?user=root"
166
150
  end
167
151
 
168
- desc "Run model specs without the associations code"
169
- task :spec_model_no_assoc do
170
- ENV['SEQUEL_NO_ASSOCIATIONS'] = '1'
171
- Rake::Task['_spec_model_no_assoc'].invoke
172
- end
173
- rescue LoadError
174
- task :default do
175
- puts "Must install rspec to run the default task (which runs specs)"
176
- end
152
+ Rake::Task['spec_sqlite'].invoke
153
+ Rake::Task['spec_postgres'].invoke
154
+ Rake::Task['spec_mysql'].invoke
177
155
  end
178
156
 
179
157
  desc "Print Sequel version"
@@ -72,6 +72,8 @@ reverse the given migration. The +change+ block can usually correctly reverse
72
72
  the following methods:
73
73
 
74
74
  * +create_table+
75
+ * +create_join_table+
76
+ * +create_view+
75
77
  * +add_column+
76
78
  * +add_index+
77
79
  * +rename_column+
@@ -0,0 +1,65 @@
1
+ = New Features
2
+
3
+ * An update_refresh plugin has been added, for refreshing a model
4
+ instance when updating. The default behavior is to only refresh
5
+ when inserting. However, if you have triggers on the model's table,
6
+ it's a good idea to refresh when updating to pick up the possibly
7
+ changed values. On databases that support UPDATE RETURNING, such as
8
+ PostgreSQL, the update and refresh are done in a single query.
9
+
10
+ * A delay_add_association plugin has been added, for delaying add_*
11
+ method calls for associations until after the receiver has been
12
+ saved, if the receiver is a new object. Example:
13
+
14
+ artist = Artist.new(:name=>'Foo')
15
+ artist.add_album(Album.new(:name=>'Bar'))
16
+ # No database queries yet
17
+
18
+ artist.save # Saves artist, then album
19
+
20
+ * A validate_associated plugin has been added, for validating
21
+ associated objects when validating the current object. This
22
+ was extracted from the nested_attributes plugin, and is also
23
+ used by the delay_add_association plugin. For example,
24
+ if you have an albums association and you want to validate all
25
+ associated objects before saving the current object, you can
26
+ cal validate_associated_object for each object:
27
+
28
+ def validate
29
+ super
30
+ reflection = association_reflection(:albums)
31
+ associations[:albums].each do |obj|
32
+ validate_associated_object(reflection, obj)
33
+ end
34
+ end
35
+
36
+ = Other Improvements
37
+
38
+ * Database#transaction now returns the block return value if
39
+ :rollback=>:always is used. Previously, it would return nil in
40
+ that case.
41
+
42
+ * Postgres::JSONBOp#[] and #get_text now return JSONBOp instances
43
+ instead of JSONOp instances.
44
+
45
+ * Model#move_to, #move_up, and #move_down in the list plugin now
46
+ automatically handle out-of-range targets by defaulting to the first
47
+ or last position in the list. Previously, using an out of range
48
+ target would raise an exception.
49
+
50
+ * Database#add_named_conversion_proc on PostgreSQL now works for enum
51
+ types.
52
+
53
+ * dataset.call_sproc(:insert, ...) now works correctly on JDBC.
54
+
55
+ * postgresql:// connection strings are now supported, since that is
56
+ the protocol name supported by libpq.
57
+
58
+ * Sequel has switched from rspec to minitest/spec for testing, and
59
+ now uses random test order when testing. During the conversion
60
+ process, many test order dependency bugs were fixed.
61
+
62
+ = Backwards Compatibility
63
+
64
+ * The deprecated fdbsql, jdbc/fdbsql, and openbase adapters have been
65
+ removed.
@@ -56,12 +56,13 @@ the symbol name defined in the connect options. For example:
56
56
  Let's say you have 4 slave database servers with names slave_server0,
57
57
  slave_server1, slave_server2, and slave_server3.
58
58
 
59
- DB=Sequel.connect('postgres://master_server/database', \
60
- :servers=>{:read_only=>proc{|db| {:host=>db.get_slave_host}}})
61
- def DB.get_slave_host
62
- @current_host ||= -1
63
- "slave_server#{(@current_host+=1)%4}"
59
+ num_read_only = 4
60
+ read_only_host = rand(num_read_only)
61
+ read_only_proc = proc do |db|
62
+ {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
64
63
  end
64
+ DB=Sequel.connect('postgres://master_server/database', \
65
+ :servers=>{:read_only=>read_only_proc})
65
66
 
66
67
  This will use one of the slave servers for SELECT queries and use the
67
68
  master_server for other queries. It's also possible to pick a random host
@@ -74,17 +75,18 @@ This involves the same basic idea as the multiple slaves, single master, but
74
75
  it shows that the master database is named :default. So for 4 masters and
75
76
  4 slaves:
76
77
 
77
- DB=Sequel.connect('postgres://master_server/database', \
78
- :servers=>{:read_only=>proc{|db| {:host=>db.get_slave_host}}, \
79
- :default=>proc{|db| {:host=>db.get_master_host}}})
80
- def DB.get_slave_host
81
- @current_slave_host ||= -1
82
- "slave_server#{(@current_slave_host+=1)%4}"
78
+ num_read_only = 4
79
+ read_only_host = rand(num_read_only)
80
+ read_only_proc = proc do |db|
81
+ {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
83
82
  end
84
- def DB.get_master_host
85
- @current_master_host ||= -1
86
- "master_server#{(@current_master_host+=1)%4}"
83
+ num_default = 4
84
+ default_host = rand(num_default)
85
+ default_proc = proc do |db|
86
+ {:host=>"master_server#{(default_host+=1) % num_default}"}
87
87
  end
88
+ DB=Sequel.connect('postgres://master_server/database', \
89
+ :servers=>{:default=>default_proc, :read_only=>read_only_proc})
88
90
 
89
91
  == Sharding
90
92
 
@@ -6,84 +6,39 @@ Whether or not you use Sequel in your application, you are usually going to want
6
6
 
7
7
  These run each test in its own transaction, the recommended way to test.
8
8
 
9
- === RSpec 1
9
+ === minitest/spec
10
10
 
11
- class Spec::Example::ExampleGroup
12
- def execute(*args, &block)
13
- result = nil
14
- Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){result = super(*args, &block)}
15
- result
16
- end
17
- end
18
-
19
- === RSpec 2, <2.8
20
-
21
- class RSpec::Core::ExampleGroup
22
- # Setting an around filter globally doesn't appear to work in <2.8,
23
- # so set one up for each subclass.
24
- def self.inherited(subclass)
25
- super
26
- subclass.around do |example|
27
- Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){example.call}
28
- end
29
- end
30
- end
31
-
32
- === RSpec >=2.8
33
-
34
- # Global around filters should work
35
- RSpec.configure do |c|
36
- c.around(:each) do |example|
37
- DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
38
- end
39
- end
40
-
41
- === Test::Unit
11
+ ==== with minitest-hooks
42
12
 
43
- # Must use this class as the base class for your tests
44
- class SequelTestCase < Test::Unit::TestCase
45
- def run(*args, &block)
46
- result = nil
47
- Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){result = super}
48
- result
13
+ require 'minitest/hooks/default'
14
+ class Minitest::HooksSpec
15
+ def around
16
+ Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){super}
49
17
  end
50
18
  end
51
19
 
52
- # Or you could override the base implementation like this
53
- class Test::Unit::TestCase
54
- alias_method :_original_run, :run
20
+ ==== without minitest-hooks
55
21
 
22
+ class Minitest::Spec
56
23
  def run(*args, &block)
57
- result = nil
58
- Sequel::Model.db.transaction(:rollback => :always, :auto_savepoint=>true) do
59
- result = _original_run(*args, &block)
60
- end
61
- result
24
+ Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){super}
62
25
  end
63
26
  end
64
27
 
65
- === MiniTest::Unit
28
+ === minitest/test
66
29
 
67
- # Add a subclass
68
- # Must use this class as the base class for your tests
69
- class SequelTestCase < MiniTest::Unit::TestCase
30
+ # Use this class as the base class for your tests
31
+ class SequelTestCase < Minitest::Test
70
32
  def run(*args, &block)
71
- result = nil
72
- Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){result = super}
73
- result
33
+ Sequel::Model.db.transaction(:rollback=>:always, :auto_savepoint=>true){super}
74
34
  end
75
35
  end
76
36
 
77
- # Or you could override the base implementation like this
78
- class MiniTest::Unit::TestCase
79
- alias_method :_original_run, :run
37
+ === rspec >= 2.8
80
38
 
81
- def run(*args, &block)
82
- result = nil
83
- Sequel::Model.db.transaction(:rollback => :always, :auto_savepoint=>true) do
84
- result = _original_run(*args, &block)
85
- end
86
- result
39
+ RSpec.configure do |c|
40
+ c.around(:each) do |example|
41
+ DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
87
42
  end
88
43
  end
89
44
 
@@ -97,15 +52,43 @@ Use Sequel.transaction with an array of databases:
97
52
 
98
53
  Sequel.transaction([DB1, DB2, DB3], :rollback=>:always)
99
54
 
55
+ == Transactional testing with savepoints
56
+
57
+ Using minitest/spec and minitest-hooks, and assuming your database supports it, you can use
58
+ transactions around entire test suites, using savepoints around each test. This can sigificantly
59
+ speed up any test suite where there is a lot of shared setup in a before all hook. By using
60
+ savepoints per test, each test is isolated from each other, rolling back changes after it
61
+ completes, and by using transactions per test suite, you only pay the cost to load the data once
62
+ for the test suite, and it is automatically rolled back after the test suite completes.
63
+
64
+ Example:
65
+
66
+ require 'minitest/hooks/default'
67
+ class Minitest::HooksSpec
68
+ def around
69
+ Sequel::Model.db.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true){super}
70
+ end
71
+
72
+ def around_all
73
+ Sequel::Model.db.transaction(:rollback=>:always){super}
74
+ end
75
+ end
76
+
77
+ describe "some large test suite" do
78
+ before(:all) do
79
+ DB[:table].import # Large number of rows
80
+ end
81
+ end
82
+
100
83
  == Nontransactional tests
101
84
 
102
85
  In some cases, it is not possible to use transactions. For example, if you are testing a web application that is running in a separate process, you don't have access to that process's database connections, so you can't run your examples in transactions. In that case, the best way to handle things is to cleanup after each test by deleting or truncating the database tables used in the test.
103
86
 
104
87
  The order in which you delete/truncate the tables is important if you are using referential integrity in your database (which you should be doing). If you are using referential integrity, you need to make sure to delete in tables referencing other tables before the tables that are being referenced. For example, if you have an +albums+ table with an +artist_id+ field referencing the +artists+ table, you want to delete/truncate the +albums+ table before the +artists+ table. Note that if you have cyclic references in your database, you will probably need to write your own custom cleaning code.
105
88
 
106
- === RSpec
89
+ === minitest/spec or rspec
107
90
 
108
- class Spec::Example::ExampleGroup
91
+ describe "some test suite" do
109
92
  after do
110
93
  [:table1, :table2].each{|x| Sequel::Model.db.from(x).truncate}
111
94
  # or
@@ -113,10 +96,9 @@ The order in which you delete/truncate the tables is important if you are using
113
96
  end
114
97
  end
115
98
 
116
- === Test::Unit
99
+ === minitest/test
117
100
 
118
- # Must use this class as the base class for your tests
119
- class SequelTestCase < Test::Unit::TestCase
101
+ class SomeTestClass < Minitest::Test
120
102
  def teardown
121
103
  [:table1, :table2].each{|x| Sequel::Model.db.from(x).truncate}
122
104
  # or
@@ -126,15 +108,19 @@ The order in which you delete/truncate the tables is important if you are using
126
108
 
127
109
  = Testing Sequel Itself
128
110
 
129
- Sequel has multiple separate test suites. All test suites run under rspec >=1.3.
111
+ Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-shared_description extensions.
130
112
 
131
113
  == rake
132
114
 
133
- The default rake task runs Sequel's core, model, plugin, and extension specs, the same as <tt>rake spec spec_plugin</tt>.
115
+ The default rake task runs Sequel's core, model, plugin, and extension specs, the same as <tt>rake spec</tt> or <tt>rake spec_core spec_model spec_plugin</tt>.
116
+
117
+ == rake spec_core
118
+
119
+ The +spec_core+ rake task runs Sequel's core specs. These specs use a mocked database connection, and test for specific SQL used and for generally correct behavior.
134
120
 
135
- == rake spec
121
+ == rake spec_model
136
122
 
137
- The +spec+ rake task runs Sequel's core and model specs. These specs use a mocked database connection, and test for specific SQL used and for generally correct behavior.
123
+ The +spec_model+ rake task runs Sequel's model specs. These specs also use a mocked database connection, and operate similar to the core tests.
138
124
 
139
125
  == rake spec_plugin
140
126
 
@@ -152,13 +138,13 @@ The +spec_bin+ rake task runs the specs for bin/sequel. These use an SQLite3 da
152
138
 
153
139
  The <tt>spec_<i>adapter</i></tt> specs run against a real database connection with nothing mocked, and test for correct results. They are slower than the standard specs, but they will catch errors that are mocked out by the default specs, as well as show issues that only occur on a certain database, adapter, or a combination of the two.
154
140
 
155
- These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use rake spec_integration to just run the shared integration tests.
141
+ These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use <tt>rake spec_integration</tt> to just run the shared integration tests.
156
142
 
157
143
  == Environment variables
158
144
 
159
- Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying spec/spec_config.rb.example to spec/spec_config.rb and modifying it. See that file for details. It may be necessary to use spec_config.rb as opposed to an environment variable if your database connection cannot be specified by a connection string.
145
+ Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying <tt>spec/spec_config.rb.example</tt> to <tt>spec/spec_config.rb</tt> and modifying it. See that file for details. It may be necessary to use +spec_config.rb+ as opposed to an environment variable if your database connection cannot be specified by a connection string.
160
146
 
161
- Sequel does not create test databases automatically, except for file-based databases such as SQLite/H2/HSQLDB/Derby. It's up to the user to create the test databases manually and give Sequel a valid connection string in an environment variable (or setup the connection object in spec_config.rb).
147
+ Sequel does not create test databases automatically, except for file-based databases such as SQLite/H2/HSQLDB/Derby. It's up to the user to create the test databases manually and give Sequel a valid connection string in an environment variable (or setup the connection object in +spec_config.rb+).
162
148
 
163
149
  === Connection Strings
164
150
 
@@ -166,12 +152,10 @@ The SEQUEL_INTEGRATION_URL environment variable specifies the Database connectio
166
152
 
167
153
  === Other
168
154
 
169
- RSPEC1 :: Use RSpec 1 to run the tests even if a newer version is installed
170
155
  SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when running the specs
171
156
  SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
172
157
  SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
173
158
  SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
174
159
  SEQUEL_NO_CHECK_SQLS :: Don't check for specific SQL syntax when running the specs
175
- SEQUEL_NO_PENDING :: Don't mark any specs as pending, try running all specs (note, can cause lockups for some adapters)
176
- SEQUEL_NO_SKIP_PENDING :: On RSpec 3, run specs marked as pending, and fail the pending spec if it passes (note, can cause lockups for some adapters)
160
+ SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
177
161
  SKIPPED_TEST_WARN :: Warn when skipping any tests because libraries aren't available