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