sequel 3.21.0 → 3.36.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 (311) hide show
  1. data/CHANGELOG +855 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +23 -7
  4. data/Rakefile +42 -24
  5. data/bin/sequel +26 -8
  6. data/doc/active_record.rdoc +1 -0
  7. data/doc/advanced_associations.rdoc +171 -11
  8. data/doc/association_basics.rdoc +293 -43
  9. data/doc/dataset_basics.rdoc +5 -5
  10. data/doc/dataset_filtering.rdoc +8 -0
  11. data/doc/mass_assignment.rdoc +56 -0
  12. data/doc/migration.rdoc +85 -552
  13. data/doc/model_hooks.rdoc +78 -27
  14. data/doc/object_model.rdoc +541 -0
  15. data/doc/opening_databases.rdoc +97 -50
  16. data/doc/prepared_statements.rdoc +40 -14
  17. data/doc/querying.rdoc +28 -4
  18. data/doc/reflection.rdoc +30 -4
  19. data/doc/release_notes/3.22.0.txt +39 -0
  20. data/doc/release_notes/3.23.0.txt +172 -0
  21. data/doc/release_notes/3.24.0.txt +420 -0
  22. data/doc/release_notes/3.25.0.txt +88 -0
  23. data/doc/release_notes/3.26.0.txt +88 -0
  24. data/doc/release_notes/3.27.0.txt +82 -0
  25. data/doc/release_notes/3.28.0.txt +304 -0
  26. data/doc/release_notes/3.29.0.txt +459 -0
  27. data/doc/release_notes/3.30.0.txt +135 -0
  28. data/doc/release_notes/3.31.0.txt +146 -0
  29. data/doc/release_notes/3.32.0.txt +202 -0
  30. data/doc/release_notes/3.33.0.txt +157 -0
  31. data/doc/release_notes/3.34.0.txt +671 -0
  32. data/doc/release_notes/3.35.0.txt +144 -0
  33. data/doc/release_notes/3.36.0.txt +245 -0
  34. data/doc/schema_modification.rdoc +572 -0
  35. data/doc/sharding.rdoc +95 -3
  36. data/doc/testing.rdoc +129 -0
  37. data/doc/thread_safety.rdoc +17 -0
  38. data/doc/transactions.rdoc +137 -0
  39. data/doc/virtual_rows.rdoc +51 -2
  40. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  41. data/lib/sequel/adapters/ado.rb +40 -18
  42. data/lib/sequel/adapters/amalgalite.rb +17 -9
  43. data/lib/sequel/adapters/db2.rb +175 -86
  44. data/lib/sequel/adapters/dbi.rb +15 -15
  45. data/lib/sequel/adapters/do/mysql.rb +17 -11
  46. data/lib/sequel/adapters/do/postgres.rb +1 -57
  47. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  48. data/lib/sequel/adapters/do.rb +18 -36
  49. data/lib/sequel/adapters/firebird.rb +27 -208
  50. data/lib/sequel/adapters/ibmdb.rb +453 -0
  51. data/lib/sequel/adapters/informix.rb +6 -23
  52. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  53. data/lib/sequel/adapters/jdbc/db2.rb +47 -0
  54. data/lib/sequel/adapters/jdbc/derby.rb +287 -0
  55. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  56. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  57. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  58. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  59. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  61. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  62. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
  64. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  65. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  66. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  67. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  68. data/lib/sequel/adapters/jdbc.rb +265 -94
  69. data/lib/sequel/adapters/mock.rb +361 -0
  70. data/lib/sequel/adapters/mysql.rb +118 -222
  71. data/lib/sequel/adapters/mysql2.rb +58 -57
  72. data/lib/sequel/adapters/odbc/mssql.rb +15 -7
  73. data/lib/sequel/adapters/odbc.rb +28 -9
  74. data/lib/sequel/adapters/openbase.rb +3 -5
  75. data/lib/sequel/adapters/oracle.rb +349 -53
  76. data/lib/sequel/adapters/postgres.rb +356 -107
  77. data/lib/sequel/adapters/shared/access.rb +32 -9
  78. data/lib/sequel/adapters/shared/db2.rb +342 -0
  79. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  80. data/lib/sequel/adapters/shared/informix.rb +53 -0
  81. data/lib/sequel/adapters/shared/mssql.rb +335 -118
  82. data/lib/sequel/adapters/shared/mysql.rb +340 -76
  83. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  84. data/lib/sequel/adapters/shared/oracle.rb +243 -45
  85. data/lib/sequel/adapters/shared/postgres.rb +524 -279
  86. data/lib/sequel/adapters/shared/progress.rb +5 -8
  87. data/lib/sequel/adapters/shared/sqlite.rb +265 -89
  88. data/lib/sequel/adapters/sqlite.rb +101 -39
  89. data/lib/sequel/adapters/swift/mysql.rb +9 -12
  90. data/lib/sequel/adapters/swift/postgres.rb +9 -74
  91. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  92. data/lib/sequel/adapters/swift.rb +8 -7
  93. data/lib/sequel/adapters/tinytds.rb +161 -21
  94. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  95. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  96. data/lib/sequel/ast_transformer.rb +194 -0
  97. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  98. data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
  99. data/lib/sequel/connection_pool/single.rb +5 -0
  100. data/lib/sequel/connection_pool/threaded.rb +38 -14
  101. data/lib/sequel/connection_pool.rb +10 -2
  102. data/lib/sequel/core.rb +118 -11
  103. data/lib/sequel/database/connecting.rb +38 -28
  104. data/lib/sequel/database/dataset.rb +4 -4
  105. data/lib/sequel/database/dataset_defaults.rb +63 -2
  106. data/lib/sequel/database/logging.rb +7 -2
  107. data/lib/sequel/database/misc.rb +150 -46
  108. data/lib/sequel/database/query.rb +215 -65
  109. data/lib/sequel/database/schema_generator.rb +64 -20
  110. data/lib/sequel/database/schema_methods.rb +212 -54
  111. data/lib/sequel/dataset/actions.rb +322 -85
  112. data/lib/sequel/dataset/features.rb +96 -8
  113. data/lib/sequel/dataset/graph.rb +38 -11
  114. data/lib/sequel/dataset/misc.rb +50 -23
  115. data/lib/sequel/dataset/mutation.rb +12 -7
  116. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  117. data/lib/sequel/dataset/query.rb +237 -44
  118. data/lib/sequel/dataset/sql.rb +698 -278
  119. data/lib/sequel/dataset.rb +8 -0
  120. data/lib/sequel/exceptions.rb +4 -0
  121. data/lib/sequel/extensions/_pretty_table.rb +79 -0
  122. data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
  123. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  124. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
  125. data/lib/sequel/extensions/migration.rb +97 -11
  126. data/lib/sequel/extensions/named_timezones.rb +5 -0
  127. data/lib/sequel/extensions/null_dataset.rb +90 -0
  128. data/lib/sequel/extensions/pg_array.rb +460 -0
  129. data/lib/sequel/extensions/pg_array_ops.rb +220 -0
  130. data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
  131. data/lib/sequel/extensions/pg_hstore.rb +296 -0
  132. data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
  133. data/lib/sequel/extensions/pg_inet.rb +89 -0
  134. data/lib/sequel/extensions/pg_json.rb +178 -0
  135. data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
  136. data/lib/sequel/extensions/pretty_table.rb +5 -71
  137. data/lib/sequel/extensions/query.rb +1 -1
  138. data/lib/sequel/extensions/query_literals.rb +79 -0
  139. data/lib/sequel/extensions/schema_caching.rb +76 -0
  140. data/lib/sequel/extensions/schema_dumper.rb +251 -37
  141. data/lib/sequel/extensions/select_remove.rb +35 -0
  142. data/lib/sequel/extensions/server_block.rb +139 -0
  143. data/lib/sequel/extensions/sql_expr.rb +4 -110
  144. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  145. data/lib/sequel/extensions/to_dot.rb +95 -83
  146. data/lib/sequel/model/associations.rb +1187 -393
  147. data/lib/sequel/model/base.rb +578 -170
  148. data/lib/sequel/model/errors.rb +1 -1
  149. data/lib/sequel/model/exceptions.rb +5 -1
  150. data/lib/sequel/model/inflections.rb +1 -1
  151. data/lib/sequel/model.rb +30 -11
  152. data/lib/sequel/no_core_ext.rb +2 -0
  153. data/lib/sequel/plugins/active_model.rb +13 -1
  154. data/lib/sequel/plugins/association_pks.rb +22 -4
  155. data/lib/sequel/plugins/caching.rb +25 -18
  156. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  157. data/lib/sequel/plugins/composition.rb +44 -12
  158. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  159. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  160. data/lib/sequel/plugins/dirty.rb +214 -0
  161. data/lib/sequel/plugins/eager_each.rb +59 -0
  162. data/lib/sequel/plugins/force_encoding.rb +6 -6
  163. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  164. data/lib/sequel/plugins/identity_map.rb +123 -8
  165. data/lib/sequel/plugins/instance_filters.rb +10 -0
  166. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  167. data/lib/sequel/plugins/json_serializer.rb +58 -6
  168. data/lib/sequel/plugins/list.rb +12 -2
  169. data/lib/sequel/plugins/many_through_many.rb +79 -28
  170. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  171. data/lib/sequel/plugins/nested_attributes.rb +139 -63
  172. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  173. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  174. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  175. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  176. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  177. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  178. data/lib/sequel/plugins/schema.rb +7 -2
  179. data/lib/sequel/plugins/serialization.rb +98 -49
  180. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  181. data/lib/sequel/plugins/sharding.rb +21 -54
  182. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  183. data/lib/sequel/plugins/static_cache.rb +99 -0
  184. data/lib/sequel/plugins/subclasses.rb +10 -2
  185. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  186. data/lib/sequel/plugins/timestamps.rb +1 -1
  187. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  188. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  189. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  190. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  191. data/lib/sequel/sql.rb +526 -59
  192. data/lib/sequel/timezones.rb +57 -38
  193. data/lib/sequel/version.rb +1 -1
  194. data/spec/adapters/db2_spec.rb +146 -0
  195. data/spec/adapters/firebird_spec.rb +1 -1
  196. data/spec/adapters/mssql_spec.rb +142 -40
  197. data/spec/adapters/mysql_spec.rb +380 -234
  198. data/spec/adapters/oracle_spec.rb +67 -77
  199. data/spec/adapters/postgres_spec.rb +1050 -212
  200. data/spec/adapters/spec_helper.rb +8 -5
  201. data/spec/adapters/sqlite_spec.rb +139 -27
  202. data/spec/core/connection_pool_spec.rb +196 -93
  203. data/spec/core/database_spec.rb +879 -510
  204. data/spec/core/dataset_spec.rb +1415 -1086
  205. data/spec/core/expression_filters_spec.rb +554 -109
  206. data/spec/core/mock_adapter_spec.rb +449 -0
  207. data/spec/core/object_graph_spec.rb +86 -114
  208. data/spec/core/schema_generator_spec.rb +4 -4
  209. data/spec/core/schema_spec.rb +482 -38
  210. data/spec/core/spec_helper.rb +6 -48
  211. data/spec/extensions/active_model_spec.rb +13 -0
  212. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  213. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  214. data/spec/extensions/association_dependencies_spec.rb +15 -25
  215. data/spec/extensions/association_pks_spec.rb +66 -32
  216. data/spec/extensions/association_proxies_spec.rb +4 -4
  217. data/spec/extensions/caching_spec.rb +47 -51
  218. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  219. data/spec/extensions/columns_introspection_spec.rb +91 -0
  220. data/spec/extensions/composition_spec.rb +18 -13
  221. data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
  222. data/spec/extensions/dataset_associations_spec.rb +199 -0
  223. data/spec/extensions/defaults_setter_spec.rb +64 -0
  224. data/spec/extensions/dirty_spec.rb +155 -0
  225. data/spec/extensions/eager_each_spec.rb +34 -0
  226. data/spec/extensions/force_encoding_spec.rb +4 -2
  227. data/spec/extensions/hook_class_methods_spec.rb +69 -92
  228. data/spec/extensions/identity_map_spec.rb +131 -22
  229. data/spec/extensions/inflector_spec.rb +0 -4
  230. data/spec/extensions/instance_filters_spec.rb +11 -21
  231. data/spec/extensions/instance_hooks_spec.rb +72 -0
  232. data/spec/extensions/json_serializer_spec.rb +49 -6
  233. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  234. data/spec/extensions/list_spec.rb +48 -39
  235. data/spec/extensions/many_through_many_spec.rb +283 -250
  236. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  237. data/spec/extensions/migration_spec.rb +140 -35
  238. data/spec/extensions/named_timezones_spec.rb +29 -11
  239. data/spec/extensions/nested_attributes_spec.rb +251 -89
  240. data/spec/extensions/null_dataset_spec.rb +85 -0
  241. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  242. data/spec/extensions/pg_array_ops_spec.rb +105 -0
  243. data/spec/extensions/pg_array_spec.rb +196 -0
  244. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  245. data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
  246. data/spec/extensions/pg_hstore_spec.rb +195 -0
  247. data/spec/extensions/pg_inet_spec.rb +44 -0
  248. data/spec/extensions/pg_json_spec.rb +101 -0
  249. data/spec/extensions/pg_statement_cache_spec.rb +209 -0
  250. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  251. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  252. data/spec/extensions/prepared_statements_spec.rb +87 -0
  253. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  254. data/spec/extensions/pretty_table_spec.rb +7 -6
  255. data/spec/extensions/query_literals_spec.rb +168 -0
  256. data/spec/extensions/query_spec.rb +6 -0
  257. data/spec/extensions/rcte_tree_spec.rb +50 -43
  258. data/spec/extensions/schema_caching_spec.rb +41 -0
  259. data/spec/extensions/schema_dumper_spec.rb +429 -22
  260. data/spec/extensions/schema_spec.rb +25 -21
  261. data/spec/extensions/select_remove_spec.rb +38 -0
  262. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  263. data/spec/extensions/serialization_spec.rb +85 -43
  264. data/spec/extensions/server_block_spec.rb +90 -0
  265. data/spec/extensions/sharding_spec.rb +69 -143
  266. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  267. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  268. data/spec/extensions/spec_helper.rb +22 -61
  269. data/spec/extensions/sql_expr_spec.rb +29 -60
  270. data/spec/extensions/static_cache_spec.rb +145 -0
  271. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  272. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  273. data/spec/extensions/timestamps_spec.rb +6 -6
  274. data/spec/extensions/to_dot_spec.rb +4 -7
  275. data/spec/extensions/touch_spec.rb +13 -14
  276. data/spec/extensions/tree_spec.rb +11 -26
  277. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  278. data/spec/extensions/update_primary_key_spec.rb +30 -24
  279. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  280. data/spec/extensions/validation_helpers_spec.rb +16 -35
  281. data/spec/extensions/xml_serializer_spec.rb +29 -4
  282. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  283. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  284. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  285. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  286. data/spec/integration/associations_test.rb +659 -21
  287. data/spec/integration/database_test.rb +9 -3
  288. data/spec/integration/dataset_test.rb +605 -91
  289. data/spec/integration/eager_loader_test.rb +19 -21
  290. data/spec/integration/migrator_test.rb +2 -3
  291. data/spec/integration/model_test.rb +81 -2
  292. data/spec/integration/plugin_test.rb +454 -143
  293. data/spec/integration/prepared_statement_test.rb +263 -128
  294. data/spec/integration/schema_test.rb +309 -43
  295. data/spec/integration/spec_helper.rb +40 -30
  296. data/spec/integration/timezone_test.rb +38 -12
  297. data/spec/integration/transaction_test.rb +183 -8
  298. data/spec/integration/type_test.rb +18 -4
  299. data/spec/model/association_reflection_spec.rb +201 -7
  300. data/spec/model/associations_spec.rb +1067 -661
  301. data/spec/model/base_spec.rb +329 -95
  302. data/spec/model/dataset_methods_spec.rb +7 -27
  303. data/spec/model/eager_loading_spec.rb +677 -676
  304. data/spec/model/hooks_spec.rb +349 -67
  305. data/spec/model/model_spec.rb +240 -168
  306. data/spec/model/plugins_spec.rb +24 -13
  307. data/spec/model/record_spec.rb +490 -232
  308. data/spec/model/spec_helper.rb +14 -71
  309. data/spec/model/validations_spec.rb +11 -0
  310. data/spec/rcov.opts +2 -0
  311. metadata +178 -80
@@ -1,55 +1,47 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Model#after_initialize" do
4
- specify "should be called after initialization" do
5
- $values1 = nil
6
- $reached_after_initialized = false
4
+ specify "should be called after initialization for both new object and objects retrieved from the database" do
7
5
 
8
- a = Class.new(Sequel::Model)
9
- a.class_eval do
6
+ a = Class.new(Sequel::Model) do
7
+ self::Foo = []
10
8
  columns :x, :y
11
9
  def after_initialize
12
- $values1 = @values.clone
13
- $reached_after_initialized = true
10
+ model::Foo << @values.clone
14
11
  end
15
12
  end
16
13
 
17
14
  a.new(:x => 1, :y => 2)
18
- $values1.should == {:x => 1, :y => 2}
19
- $reached_after_initialized.should == true
15
+ a.call(:x => 1, :y => 3)
16
+ a::Foo.should == [{:x => 1, :y => 2}, {:x => 1, :y => 3}]
20
17
  end
21
18
  end
22
19
 
23
20
  describe "Model#before_create && Model#after_create" do
24
21
  before do
25
- MODEL_DB.reset
26
-
27
- @c = Class.new(Sequel::Model(:items))
28
- @c.class_eval do
22
+ @c = Class.new(Sequel::Model(:items)) do
29
23
  columns :x
30
- no_primary_key
24
+ set_primary_key :x
25
+ unrestrict_primary_key
31
26
 
32
27
  def after_create
33
28
  MODEL_DB << "BLAH after"
34
29
  end
35
30
  end
31
+ MODEL_DB.reset
36
32
  end
37
33
 
38
34
  specify "should be called around new record creation" do
39
35
  @c.send(:define_method, :before_create){MODEL_DB << "BLAH before"}
40
36
  @c.create(:x => 2)
41
- MODEL_DB.sqls.should == [
42
- 'BLAH before',
43
- 'INSERT INTO items (x) VALUES (2)',
44
- 'BLAH after'
45
- ]
37
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after', 'SELECT * FROM items WHERE (x = 2) LIMIT 1']
46
38
  end
47
39
 
48
40
  specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
49
41
  @c.send(:define_method, :before_create){false}
50
- proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
51
42
  proc{@c.create(:x => 2)}.should raise_error(Sequel::BeforeHookFailed)
52
43
  MODEL_DB.sqls.should == []
44
+ proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
53
45
  end
54
46
 
55
47
  specify ".create should cancel the save and return nil if before_create returns false and raise_on_save_failure is false" do
@@ -62,24 +54,20 @@ end
62
54
 
63
55
  describe "Model#before_update && Model#after_update" do
64
56
  before do
65
- MODEL_DB.reset
66
-
67
- @c = Class.new(Sequel::Model(:items))
68
- @c.class_eval do
57
+ @c = Class.new(Sequel::Model(:items)) do
69
58
  columns :id, :x
70
- def after_update; MODEL_DB << "BLAH after" end
59
+ def after_update
60
+ MODEL_DB << "BLAH after"
61
+ end
71
62
  end
63
+ MODEL_DB.reset
72
64
  end
73
65
 
74
66
  specify "should be called around record update" do
75
67
  @c.send(:define_method, :before_update){MODEL_DB << "BLAH before"}
76
68
  m = @c.load(:id => 2233, :x=>123)
77
69
  m.save
78
- MODEL_DB.sqls.should == [
79
- 'BLAH before',
80
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
81
- 'BLAH after'
82
- ]
70
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
83
71
  end
84
72
 
85
73
  specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
@@ -107,35 +95,28 @@ end
107
95
 
108
96
  describe "Model#before_save && Model#after_save" do
109
97
  before do
110
- MODEL_DB.reset
111
-
112
- @c = Class.new(Sequel::Model(:items))
113
- @c.class_eval do
98
+ @c = Class.new(Sequel::Model(:items)) do
114
99
  columns :x
115
- def after_save; MODEL_DB << "BLAH after" end
100
+ def after_save
101
+ MODEL_DB << "BLAH after"
102
+ end
116
103
  end
104
+ MODEL_DB.reset
117
105
  end
118
106
 
119
107
  specify "should be called around record update" do
120
108
  @c.send(:define_method, :before_save){MODEL_DB << "BLAH before"}
121
109
  m = @c.load(:id => 2233, :x=>123)
122
110
  m.save
123
- MODEL_DB.sqls.should == [
124
- 'BLAH before',
125
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
126
- 'BLAH after'
127
- ]
111
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
128
112
  end
129
113
 
130
114
  specify "should be called around record creation" do
131
115
  @c.send(:define_method, :before_save){MODEL_DB << "BLAH before"}
132
- @c.no_primary_key
116
+ @c.set_primary_key :x
117
+ @c.unrestrict_primary_key
133
118
  @c.create(:x => 2)
134
- MODEL_DB.sqls.should == [
135
- 'BLAH before',
136
- 'INSERT INTO items (x) VALUES (2)',
137
- 'BLAH after'
138
- ]
119
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after', 'SELECT * FROM items WHERE (x = 2) LIMIT 1']
139
120
  end
140
121
 
141
122
  specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
@@ -163,27 +144,19 @@ end
163
144
 
164
145
  describe "Model#before_destroy && Model#after_destroy" do
165
146
  before do
166
- MODEL_DB.reset
167
-
168
- @c = Class.new(Sequel::Model(:items))
169
- @c.class_eval do
170
- def after_destroy; MODEL_DB << "BLAH after"; end
171
-
172
- def delete
173
- MODEL_DB << "DELETE BLAH"
147
+ @c = Class.new(Sequel::Model(:items)) do
148
+ def after_destroy
149
+ MODEL_DB << "BLAH after"
174
150
  end
175
151
  end
152
+ MODEL_DB.reset
176
153
  end
177
154
 
178
155
  specify "should be called around record destruction" do
179
156
  @c.send(:define_method, :before_destroy){MODEL_DB << "BLAH before"}
180
157
  m = @c.load(:id => 2233)
181
158
  m.destroy
182
- MODEL_DB.sqls.should == [
183
- 'BLAH before',
184
- 'DELETE BLAH',
185
- 'BLAH after'
186
- ]
159
+ MODEL_DB.sqls.should == ['BLAH before', 'DELETE FROM items WHERE id = 2233', 'BLAH after']
187
160
  end
188
161
 
189
162
  specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
@@ -209,16 +182,15 @@ end
209
182
 
210
183
  describe "Model#before_validation && Model#after_validation" do
211
184
  before do
212
- MODEL_DB.reset
213
-
214
- @c = Class.new(Sequel::Model(:items))
215
- @c.class_eval do
216
- def after_validation; MODEL_DB << "BLAH after" end
185
+ @c = Class.new(Sequel::Model(:items)) do
186
+ columns :id
187
+ def after_validation
188
+ MODEL_DB << "BLAH after"
189
+ end
217
190
 
218
191
  def validate
219
192
  errors.add(:id, 'not valid') unless id == 2233
220
193
  end
221
- columns :id
222
194
  end
223
195
  end
224
196
 
@@ -228,7 +200,6 @@ describe "Model#before_validation && Model#after_validation" do
228
200
  m.should be_valid
229
201
  MODEL_DB.sqls.should == ['BLAH before', 'BLAH after']
230
202
 
231
- MODEL_DB.sqls.clear
232
203
  m = @c.load(:id => 22)
233
204
  m.should_not be_valid
234
205
  MODEL_DB.sqls.should == ['BLAH before', 'BLAH after']
@@ -240,7 +211,6 @@ describe "Model#before_validation && Model#after_validation" do
240
211
  m.save.should == m
241
212
  MODEL_DB.sqls.should == ['BLAH before', 'BLAH after', 'UPDATE items SET x = 123 WHERE (id = 2233)']
242
213
 
243
- MODEL_DB.sqls.clear
244
214
  m = @c.load(:id => 22)
245
215
  m.raise_on_save_failure = false
246
216
  m.save.should == nil
@@ -268,4 +238,316 @@ describe "Model#before_validation && Model#after_validation" do
268
238
  @c.load(:id => 2233).save.should == nil
269
239
  MODEL_DB.sqls.should == []
270
240
  end
241
+
242
+ specify "#valid? should return false if before_validation returns false" do
243
+ @c.send(:define_method, :before_validation){false}
244
+ @c.load(:id => 2233).valid?.should == false
245
+ end
246
+ end
247
+
248
+ describe "Model around filters" do
249
+ before do
250
+ @c = Class.new(Sequel::Model(:items)) do
251
+ columns :id, :x
252
+ end
253
+ MODEL_DB.reset
254
+ end
255
+
256
+ specify "around_create should be called around new record creation" do
257
+ @c.class_eval do
258
+ def around_create
259
+ MODEL_DB << 'ac_before'
260
+ super
261
+ MODEL_DB << 'ac_after'
262
+ end
263
+ end
264
+ @c.create(:x => 2)
265
+ MODEL_DB.sqls.should == ['ac_before', 'INSERT INTO items (x) VALUES (2)', 'ac_after', "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
266
+ end
267
+
268
+ specify "around_delete should be called around record destruction" do
269
+ @c.class_eval do
270
+ def around_destroy
271
+ MODEL_DB << 'ad_before'
272
+ super
273
+ MODEL_DB << 'ad_after'
274
+ end
275
+ end
276
+ @c.load(:id=>1, :x => 2).destroy
277
+ MODEL_DB.sqls.should == ['ad_before', 'DELETE FROM items WHERE id = 1', 'ad_after']
278
+ end
279
+
280
+ specify "around_update should be called around updating existing records" do
281
+ @c.class_eval do
282
+ def around_update
283
+ MODEL_DB << 'au_before'
284
+ super
285
+ MODEL_DB << 'au_after'
286
+ end
287
+ end
288
+ @c.load(:id=>1, :x => 2).save
289
+ MODEL_DB.sqls.should == ['au_before', 'UPDATE items SET x = 2 WHERE (id = 1)', 'au_after']
290
+ end
291
+
292
+ specify "around_save should be called around saving both new and existing records, around either after_create and after_update" do
293
+ @c.class_eval do
294
+ def around_update
295
+ MODEL_DB << 'au_before'
296
+ super
297
+ MODEL_DB << 'au_after'
298
+ end
299
+ def around_create
300
+ MODEL_DB << 'ac_before'
301
+ super
302
+ MODEL_DB << 'ac_after'
303
+ end
304
+ def around_save
305
+ MODEL_DB << 'as_before'
306
+ super
307
+ MODEL_DB << 'as_after'
308
+ end
309
+ end
310
+ @c.create(:x => 2)
311
+ MODEL_DB.sqls.should == ['as_before', 'ac_before', 'INSERT INTO items (x) VALUES (2)', 'ac_after', 'as_after', "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
312
+ @c.load(:id=>1, :x => 2).save
313
+ MODEL_DB.sqls.should == ['as_before', 'au_before', 'UPDATE items SET x = 2 WHERE (id = 1)', 'au_after', 'as_after']
314
+ end
315
+
316
+ specify "around_validation should be called around validating records" do
317
+ @c.class_eval do
318
+ def around_validation
319
+ MODEL_DB << 'av_before'
320
+ super
321
+ MODEL_DB << 'av_after'
322
+ end
323
+ def validate
324
+ MODEL_DB << 'validate'
325
+ end
326
+ end
327
+ @c.new(:x => 2).valid?.should == true
328
+ MODEL_DB.sqls.should == [ 'av_before', 'validate', 'av_after' ]
329
+ end
330
+
331
+ specify "around_validation should be able to catch validation errors and modify them" do
332
+ @c.class_eval do
333
+ def validate
334
+ errors.add(:x, 'foo')
335
+ end
336
+ end
337
+ @c.new(:x => 2).valid?.should == false
338
+ @c.class_eval do
339
+ def around_validation
340
+ super
341
+ errors.clear
342
+ end
343
+ end
344
+ @c.new(:x => 2).valid?.should == true
345
+ end
346
+
347
+ specify "around_create that doesn't call super should raise a HookFailed" do
348
+ @c.send(:define_method, :around_create){}
349
+ proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
350
+ end
351
+
352
+ specify "around_update that doesn't call super should raise a HookFailed" do
353
+ @c.send(:define_method, :around_update){}
354
+ proc{@c.load(:x => 2).save}.should raise_error(Sequel::HookFailed)
355
+ end
356
+
357
+ specify "around_save that doesn't call super should raise a HookFailed" do
358
+ @c.send(:define_method, :around_save){}
359
+ proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
360
+ proc{@c.load(:x => 2).save}.should raise_error(Sequel::HookFailed)
361
+ end
362
+
363
+ specify "around_destroy that doesn't call super should raise a HookFailed" do
364
+ @c.send(:define_method, :around_destroy){}
365
+ proc{@c.load(:x => 2).destroy}.should raise_error(Sequel::HookFailed)
366
+ end
367
+
368
+ specify "around_validation that doesn't call super should raise a HookFailed" do
369
+ @c.send(:define_method, :around_validation){}
370
+ proc{@c.new.save}.should raise_error(Sequel::HookFailed)
371
+ end
372
+
373
+ specify "around_validation that doesn't call super should have valid? return false" do
374
+ @c.send(:define_method, :around_validation){}
375
+ @c.new.valid?.should == false
376
+ end
377
+
378
+ specify "around_* that doesn't call super should return nil if raise_on_save_failure is false" do
379
+ @c.raise_on_save_failure = false
380
+
381
+ o = @c.load(:id => 1)
382
+ o.meta_def(:around_save){}
383
+ o.save.should == nil
384
+
385
+ o = @c.load(:id => 1)
386
+ o.meta_def(:around_update){}
387
+ o.save.should == nil
388
+
389
+ o = @c.new
390
+ o.meta_def(:around_create){}
391
+ o.save.should == nil
392
+
393
+ o = @c.new
394
+ o.meta_def(:around_validation){}
395
+ o.save.should == nil
396
+ end
397
+ end
398
+
399
+ describe "Model#after_commit and #after_rollback" do
400
+ before do
401
+ @db = Sequel.mock(:servers=>{:test=>{}})
402
+ @m = Class.new(Sequel::Model(@db[:items])) do
403
+ attr_accessor :rb
404
+ def _delete
405
+ end
406
+ def after_save
407
+ db.execute('as')
408
+ raise Sequel::Rollback if rb
409
+ end
410
+ def after_commit
411
+ db.execute('ac')
412
+ end
413
+ def after_rollback
414
+ db.execute('ar')
415
+ end
416
+ def after_destroy
417
+ db.execute('ad')
418
+ raise Sequel::Rollback if rb
419
+ end
420
+ def after_destroy_commit
421
+ db.execute('adc')
422
+ end
423
+ def after_destroy_rollback
424
+ db.execute('adr')
425
+ end
426
+ end
427
+ @m.use_transactions = true
428
+ @o = @m.load({})
429
+ @db.sqls
430
+ end
431
+
432
+ specify "should call after_commit for save after the transaction commits if it commits" do
433
+ @o.save
434
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT', 'ac']
435
+ end
436
+
437
+ specify "should call after_rollback for save after the transaction rolls back if it rolls back" do
438
+ @o.rb = true
439
+ @o.save
440
+ @db.sqls.should == ['BEGIN', 'as', 'ROLLBACK', 'ar']
441
+ end
442
+
443
+ specify "should have after_commit respect any surrounding transactions" do
444
+ @db.transaction do
445
+ @o.save
446
+ end
447
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT', 'ac']
448
+ end
449
+
450
+ specify "should have after_rollback respect any surrounding transactions" do
451
+ @db.transaction do
452
+ @o.rb = true
453
+ @o.save
454
+ end
455
+ @db.sqls.should == ['BEGIN', 'as', 'ROLLBACK', 'ar']
456
+ end
457
+
458
+ specify "should have after_commit work with surrounding transactions and sharding" do
459
+ @db.transaction(:server=>:test) do
460
+ @o.save
461
+ end
462
+ @db.sqls.should == ['BEGIN -- test', 'BEGIN', 'as', 'COMMIT', 'ac', 'COMMIT -- test']
463
+ end
464
+
465
+ specify "should have after_rollback work with surrounding transactions and sharding" do
466
+ @db.transaction(:server=>:test) do
467
+ @o.rb = true
468
+ @o.save
469
+ end
470
+ @db.sqls.should == ['BEGIN -- test', 'BEGIN', 'as', 'ROLLBACK', 'ar', 'COMMIT -- test']
471
+ end
472
+
473
+ specify "should call after_destroy_commit for destroy after the transaction commits if it commits" do
474
+ @o.destroy
475
+ @db.sqls.should == ['BEGIN', 'ad', 'COMMIT', 'adc']
476
+ end
477
+
478
+ specify "should call after_destroy_rollback for destroy after the transaction rolls back if it rolls back" do
479
+ @o.rb = true
480
+ @o.destroy
481
+ @db.sqls.should == ['BEGIN', 'ad', 'ROLLBACK', 'adr']
482
+ end
483
+
484
+ specify "should have after_destroy_commit respect any surrounding transactions" do
485
+ @db.transaction do
486
+ @o.destroy
487
+ end
488
+ @db.sqls.should == ['BEGIN', 'ad', 'COMMIT', 'adc']
489
+ end
490
+
491
+ specify "should have after_destroy_rollback respect any surrounding transactions" do
492
+ @db.transaction do
493
+ @o.rb = true
494
+ @o.destroy
495
+ end
496
+ @db.sqls.should == ['BEGIN', 'ad', 'ROLLBACK', 'adr']
497
+ end
498
+
499
+ specify "should have after_destroy commit work with surrounding transactions and sharding" do
500
+ @db.transaction(:server=>:test) do
501
+ @o.destroy
502
+ end
503
+ @db.sqls.should == ['BEGIN -- test', 'BEGIN', 'ad', 'COMMIT', 'adc', 'COMMIT -- test']
504
+ end
505
+
506
+ specify "should have after_destroy_rollback work with surrounding transactions and sharding" do
507
+ @db.transaction(:server=>:test) do
508
+ @o.rb = true
509
+ @o.destroy
510
+ end
511
+ @db.sqls.should == ['BEGIN -- test', 'BEGIN', 'ad', 'ROLLBACK', 'adr', 'COMMIT -- test']
512
+ end
513
+
514
+ specify "should not call after_commit if use_after_commit_rollback is false" do
515
+ @o.use_after_commit_rollback = false
516
+ @o.save
517
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT']
518
+ end
519
+
520
+ specify "should not call after_rollback if use_after_commit_rollback is false" do
521
+ @o.use_after_commit_rollback = false
522
+ @o.rb = true
523
+ @o.save
524
+ @db.sqls.should == ['BEGIN', 'as', 'ROLLBACK']
525
+ end
526
+
527
+ specify "should not call after_destroy_commit if use_after_commit_rollback is false" do
528
+ @o.use_after_commit_rollback = false
529
+ @o.destroy
530
+ @db.sqls.should == ['BEGIN', 'ad', 'COMMIT']
531
+ end
532
+
533
+ specify "should not call after_destroy_rollback for save if use_after_commit_rollback is false" do
534
+ @o.use_after_commit_rollback = false
535
+ @o.rb = true
536
+ @o.destroy
537
+ @db.sqls.should == ['BEGIN', 'ad', 'ROLLBACK']
538
+ end
539
+
540
+ specify "should handle use_after_commit_rollback at the class level" do
541
+ @m.use_after_commit_rollback = false
542
+ @o.save
543
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT']
544
+ end
545
+
546
+ specify "should handle use_after_commit_rollback when subclassing" do
547
+ @m.use_after_commit_rollback = false
548
+ o = Class.new(@m).load({})
549
+ @db.sqls
550
+ o.save
551
+ @db.sqls.should == ['BEGIN', 'as', 'COMMIT']
552
+ end
271
553
  end