sequel 4.49.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (484) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +130 -0
  3. data/README.rdoc +195 -136
  4. data/Rakefile +26 -42
  5. data/bin/sequel +6 -9
  6. data/doc/advanced_associations.rdoc +91 -168
  7. data/doc/association_basics.rdoc +197 -274
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +66 -43
  10. data/doc/code_order.rdoc +1 -8
  11. data/doc/core_extensions.rdoc +81 -56
  12. data/doc/dataset_basics.rdoc +8 -17
  13. data/doc/dataset_filtering.rdoc +81 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/mass_assignment.rdoc +73 -30
  16. data/doc/migration.rdoc +19 -36
  17. data/doc/model_dataset_method_design.rdoc +14 -17
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +10 -10
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +52 -70
  22. data/doc/opening_databases.rdoc +39 -32
  23. data/doc/postgresql.rdoc +48 -38
  24. data/doc/prepared_statements.rdoc +27 -22
  25. data/doc/querying.rdoc +173 -150
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.2.0.txt +33 -0
  30. data/doc/release_notes/5.3.0.txt +121 -0
  31. data/doc/schema_modification.rdoc +78 -64
  32. data/doc/security.rdoc +97 -88
  33. data/doc/sharding.rdoc +43 -30
  34. data/doc/sql.rdoc +53 -65
  35. data/doc/testing.rdoc +4 -5
  36. data/doc/thread_safety.rdoc +2 -4
  37. data/doc/transactions.rdoc +18 -17
  38. data/doc/validations.rdoc +48 -45
  39. data/doc/virtual_rows.rdoc +87 -115
  40. data/lib/sequel/adapters/ado/access.rb +7 -13
  41. data/lib/sequel/adapters/ado/mssql.rb +2 -9
  42. data/lib/sequel/adapters/ado.rb +9 -25
  43. data/lib/sequel/adapters/amalgalite.rb +3 -18
  44. data/lib/sequel/adapters/ibmdb.rb +9 -45
  45. data/lib/sequel/adapters/jdbc/db2.rb +8 -37
  46. data/lib/sequel/adapters/jdbc/derby.rb +4 -50
  47. data/lib/sequel/adapters/jdbc/h2.rb +6 -26
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -27
  49. data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
  50. data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
  51. data/lib/sequel/adapters/jdbc/mysql.rb +11 -15
  52. data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
  53. data/lib/sequel/adapters/jdbc/postgresql.rb +23 -33
  54. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
  55. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
  56. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
  57. data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
  58. data/lib/sequel/adapters/jdbc.rb +18 -74
  59. data/lib/sequel/adapters/mock.rb +4 -30
  60. data/lib/sequel/adapters/mysql.rb +7 -44
  61. data/lib/sequel/adapters/mysql2.rb +5 -23
  62. data/lib/sequel/adapters/odbc/db2.rb +1 -1
  63. data/lib/sequel/adapters/odbc/mssql.rb +4 -12
  64. data/lib/sequel/adapters/odbc/oracle.rb +1 -1
  65. data/lib/sequel/adapters/odbc.rb +0 -19
  66. data/lib/sequel/adapters/oracle.rb +8 -13
  67. data/lib/sequel/adapters/postgres.rb +28 -150
  68. data/lib/sequel/adapters/postgresql.rb +1 -1
  69. data/lib/sequel/adapters/shared/access.rb +11 -51
  70. data/lib/sequel/adapters/shared/db2.rb +3 -61
  71. data/lib/sequel/adapters/shared/mssql.rb +21 -157
  72. data/lib/sequel/adapters/shared/mysql.rb +61 -227
  73. data/lib/sequel/adapters/shared/oracle.rb +13 -41
  74. data/lib/sequel/adapters/shared/postgres.rb +58 -264
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
  76. data/lib/sequel/adapters/shared/sqlite.rb +22 -101
  77. data/lib/sequel/adapters/sqlanywhere.rb +4 -23
  78. data/lib/sequel/adapters/sqlite.rb +2 -19
  79. data/lib/sequel/adapters/tinytds.rb +5 -15
  80. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -4
  82. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
  83. data/lib/sequel/adapters/utils/replace.rb +0 -5
  84. data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
  85. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
  86. data/lib/sequel/ast_transformer.rb +3 -94
  87. data/lib/sequel/connection_pool/sharded_single.rb +1 -4
  88. data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
  89. data/lib/sequel/connection_pool/single.rb +0 -2
  90. data/lib/sequel/connection_pool/threaded.rb +94 -110
  91. data/lib/sequel/connection_pool.rb +38 -28
  92. data/lib/sequel/core.rb +42 -101
  93. data/lib/sequel/database/connecting.rb +23 -60
  94. data/lib/sequel/database/dataset.rb +6 -9
  95. data/lib/sequel/database/dataset_defaults.rb +4 -48
  96. data/lib/sequel/database/features.rb +5 -4
  97. data/lib/sequel/database/logging.rb +2 -9
  98. data/lib/sequel/database/misc.rb +36 -55
  99. data/lib/sequel/database/query.rb +8 -13
  100. data/lib/sequel/database/schema_generator.rb +93 -64
  101. data/lib/sequel/database/schema_methods.rb +61 -79
  102. data/lib/sequel/database/transactions.rb +4 -24
  103. data/lib/sequel/database.rb +12 -2
  104. data/lib/sequel/dataset/actions.rb +57 -107
  105. data/lib/sequel/dataset/dataset_module.rb +4 -16
  106. data/lib/sequel/dataset/features.rb +35 -30
  107. data/lib/sequel/dataset/graph.rb +40 -49
  108. data/lib/sequel/dataset/misc.rb +12 -37
  109. data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
  110. data/lib/sequel/dataset/prepared_statements.rb +23 -51
  111. data/lib/sequel/dataset/query.rb +91 -161
  112. data/lib/sequel/dataset/sql.rb +33 -225
  113. data/lib/sequel/dataset.rb +18 -10
  114. data/lib/sequel/deprecated.rb +18 -27
  115. data/lib/sequel/exceptions.rb +1 -17
  116. data/lib/sequel/extensions/_model_pg_row.rb +0 -7
  117. data/lib/sequel/extensions/_pretty_table.rb +1 -3
  118. data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
  119. data/lib/sequel/extensions/connection_expiration.rb +1 -1
  120. data/lib/sequel/extensions/connection_validator.rb +1 -1
  121. data/lib/sequel/extensions/constraint_validations.rb +11 -11
  122. data/lib/sequel/extensions/core_extensions.rb +39 -49
  123. data/lib/sequel/extensions/core_refinements.rb +39 -45
  124. data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
  125. data/lib/sequel/extensions/date_arithmetic.rb +7 -7
  126. data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
  127. data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
  128. data/lib/sequel/extensions/eval_inspect.rb +4 -11
  129. data/lib/sequel/extensions/freeze_datasets.rb +1 -69
  130. data/lib/sequel/extensions/from_block.rb +1 -35
  131. data/lib/sequel/extensions/graph_each.rb +2 -2
  132. data/lib/sequel/extensions/identifier_mangling.rb +9 -19
  133. data/lib/sequel/extensions/implicit_subquery.rb +2 -2
  134. data/lib/sequel/extensions/inflector.rb +4 -4
  135. data/lib/sequel/extensions/migration.rb +27 -43
  136. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
  137. data/lib/sequel/extensions/null_dataset.rb +2 -8
  138. data/lib/sequel/extensions/pagination.rb +1 -17
  139. data/lib/sequel/extensions/pg_array.rb +20 -189
  140. data/lib/sequel/extensions/pg_extended_date_support.rb +230 -0
  141. data/lib/sequel/extensions/pg_hstore.rb +11 -50
  142. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
  143. data/lib/sequel/extensions/pg_inet.rb +3 -16
  144. data/lib/sequel/extensions/pg_interval.rb +1 -20
  145. data/lib/sequel/extensions/pg_json.rb +7 -27
  146. data/lib/sequel/extensions/pg_loose_count.rb +1 -1
  147. data/lib/sequel/extensions/pg_range.rb +6 -121
  148. data/lib/sequel/extensions/pg_range_ops.rb +1 -3
  149. data/lib/sequel/extensions/pg_row.rb +5 -77
  150. data/lib/sequel/extensions/pg_row_ops.rb +2 -13
  151. data/lib/sequel/extensions/query.rb +3 -4
  152. data/lib/sequel/extensions/round_timestamps.rb +0 -6
  153. data/lib/sequel/extensions/schema_dumper.rb +13 -13
  154. data/lib/sequel/extensions/select_remove.rb +3 -3
  155. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  156. data/lib/sequel/extensions/sql_comments.rb +2 -2
  157. data/lib/sequel/extensions/string_agg.rb +11 -8
  158. data/lib/sequel/extensions/symbol_aref.rb +6 -20
  159. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  160. data/lib/sequel/model/associations.rb +129 -131
  161. data/lib/sequel/model/base.rb +133 -731
  162. data/lib/sequel/model/default_inflections.rb +1 -1
  163. data/lib/sequel/model/errors.rb +0 -3
  164. data/lib/sequel/model/exceptions.rb +2 -6
  165. data/lib/sequel/model/inflections.rb +1 -26
  166. data/lib/sequel/model/plugins.rb +1 -0
  167. data/lib/sequel/model.rb +27 -62
  168. data/lib/sequel/plugins/active_model.rb +2 -5
  169. data/lib/sequel/plugins/association_dependencies.rb +15 -15
  170. data/lib/sequel/plugins/association_pks.rb +14 -28
  171. data/lib/sequel/plugins/association_proxies.rb +6 -7
  172. data/lib/sequel/plugins/auto_validations.rb +4 -4
  173. data/lib/sequel/plugins/before_after_save.rb +0 -43
  174. data/lib/sequel/plugins/blacklist_security.rb +9 -8
  175. data/lib/sequel/plugins/boolean_readers.rb +3 -3
  176. data/lib/sequel/plugins/boolean_subsets.rb +2 -2
  177. data/lib/sequel/plugins/caching.rb +5 -5
  178. data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
  179. data/lib/sequel/plugins/column_conflicts.rb +2 -2
  180. data/lib/sequel/plugins/column_select.rb +2 -2
  181. data/lib/sequel/plugins/composition.rb +15 -24
  182. data/lib/sequel/plugins/constraint_validations.rb +4 -3
  183. data/lib/sequel/plugins/csv_serializer.rb +13 -20
  184. data/lib/sequel/plugins/dataset_associations.rb +2 -2
  185. data/lib/sequel/plugins/def_dataset_method.rb +5 -5
  186. data/lib/sequel/plugins/defaults_setter.rb +1 -1
  187. data/lib/sequel/plugins/delay_add_association.rb +1 -1
  188. data/lib/sequel/plugins/finder.rb +16 -10
  189. data/lib/sequel/plugins/force_encoding.rb +1 -7
  190. data/lib/sequel/plugins/hook_class_methods.rb +4 -106
  191. data/lib/sequel/plugins/input_transformer.rb +10 -11
  192. data/lib/sequel/plugins/insert_returning_select.rb +1 -9
  193. data/lib/sequel/plugins/instance_filters.rb +5 -5
  194. data/lib/sequel/plugins/instance_hooks.rb +7 -52
  195. data/lib/sequel/plugins/inverted_subsets.rb +3 -1
  196. data/lib/sequel/plugins/json_serializer.rb +19 -19
  197. data/lib/sequel/plugins/lazy_attributes.rb +1 -10
  198. data/lib/sequel/plugins/list.rb +6 -6
  199. data/lib/sequel/plugins/many_through_many.rb +11 -8
  200. data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
  201. data/lib/sequel/plugins/nested_attributes.rb +18 -31
  202. data/lib/sequel/plugins/optimistic_locking.rb +3 -3
  203. data/lib/sequel/plugins/pg_array_associations.rb +8 -2
  204. data/lib/sequel/plugins/pg_row.rb +2 -11
  205. data/lib/sequel/plugins/prepared_statements.rb +13 -66
  206. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
  207. data/lib/sequel/plugins/rcte_tree.rb +7 -7
  208. data/lib/sequel/plugins/serialization.rb +15 -33
  209. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  210. data/lib/sequel/plugins/sharding.rb +2 -8
  211. data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
  212. data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
  213. data/lib/sequel/plugins/static_cache.rb +8 -9
  214. data/lib/sequel/plugins/string_stripper.rb +3 -3
  215. data/lib/sequel/plugins/subclasses.rb +1 -1
  216. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  217. data/lib/sequel/plugins/table_select.rb +2 -2
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  219. data/lib/sequel/plugins/timestamps.rb +6 -7
  220. data/lib/sequel/plugins/touch.rb +4 -8
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +2 -2
  223. data/lib/sequel/plugins/unlimited_update.rb +1 -7
  224. data/lib/sequel/plugins/update_or_create.rb +3 -3
  225. data/lib/sequel/plugins/update_refresh.rb +3 -3
  226. data/lib/sequel/plugins/uuid.rb +7 -11
  227. data/lib/sequel/plugins/validation_class_methods.rb +10 -9
  228. data/lib/sequel/plugins/validation_contexts.rb +4 -4
  229. data/lib/sequel/plugins/validation_helpers.rb +26 -25
  230. data/lib/sequel/plugins/whitelist_security.rb +13 -9
  231. data/lib/sequel/plugins/xml_serializer.rb +24 -25
  232. data/lib/sequel/sql.rb +145 -276
  233. data/lib/sequel/timezones.rb +8 -23
  234. data/lib/sequel/version.rb +2 -2
  235. data/lib/sequel.rb +1 -1
  236. data/spec/adapter_spec.rb +1 -1
  237. data/spec/adapters/db2_spec.rb +2 -103
  238. data/spec/adapters/mssql_spec.rb +89 -68
  239. data/spec/adapters/mysql_spec.rb +111 -478
  240. data/spec/adapters/oracle_spec.rb +1 -9
  241. data/spec/adapters/postgres_spec.rb +459 -664
  242. data/spec/adapters/spec_helper.rb +12 -31
  243. data/spec/adapters/sqlanywhere_spec.rb +2 -77
  244. data/spec/adapters/sqlite_spec.rb +8 -146
  245. data/spec/bin_spec.rb +11 -16
  246. data/spec/core/connection_pool_spec.rb +173 -74
  247. data/spec/core/database_spec.rb +96 -244
  248. data/spec/core/dataset_spec.rb +99 -414
  249. data/spec/core/deprecated_spec.rb +3 -3
  250. data/spec/core/expression_filters_spec.rb +37 -144
  251. data/spec/core/mock_adapter_spec.rb +241 -4
  252. data/spec/core/object_graph_spec.rb +11 -60
  253. data/spec/core/placeholder_literalizer_spec.rb +1 -14
  254. data/spec/core/schema_generator_spec.rb +51 -40
  255. data/spec/core/schema_spec.rb +88 -77
  256. data/spec/core/spec_helper.rb +6 -24
  257. data/spec/core/version_spec.rb +1 -1
  258. data/spec/core_extensions_spec.rb +7 -83
  259. data/spec/core_model_spec.rb +2 -2
  260. data/spec/deprecation_helper.rb +2 -14
  261. data/spec/extensions/accessed_columns_spec.rb +1 -1
  262. data/spec/extensions/active_model_spec.rb +3 -3
  263. data/spec/extensions/after_initialize_spec.rb +1 -1
  264. data/spec/extensions/arbitrary_servers_spec.rb +2 -2
  265. data/spec/extensions/association_dependencies_spec.rb +1 -1
  266. data/spec/extensions/association_pks_spec.rb +30 -92
  267. data/spec/extensions/association_proxies_spec.rb +1 -1
  268. data/spec/extensions/auto_literal_strings_spec.rb +1 -12
  269. data/spec/extensions/auto_validations_spec.rb +1 -1
  270. data/spec/extensions/blacklist_security_spec.rb +1 -1
  271. data/spec/extensions/blank_spec.rb +1 -1
  272. data/spec/extensions/boolean_readers_spec.rb +1 -1
  273. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  274. data/spec/extensions/caching_spec.rb +1 -1
  275. data/spec/extensions/class_table_inheritance_spec.rb +53 -1118
  276. data/spec/extensions/column_conflicts_spec.rb +1 -1
  277. data/spec/extensions/column_select_spec.rb +4 -4
  278. data/spec/extensions/columns_introspection_spec.rb +1 -1
  279. data/spec/extensions/columns_updated_spec.rb +1 -1
  280. data/spec/extensions/composition_spec.rb +8 -30
  281. data/spec/extensions/connection_expiration_spec.rb +3 -3
  282. data/spec/extensions/connection_validator_spec.rb +3 -3
  283. data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
  284. data/spec/extensions/constraint_validations_spec.rb +1 -1
  285. data/spec/extensions/core_refinements_spec.rb +1 -3
  286. data/spec/extensions/csv_serializer_spec.rb +4 -9
  287. data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
  288. data/spec/extensions/dataset_associations_spec.rb +2 -1
  289. data/spec/extensions/dataset_source_alias_spec.rb +1 -1
  290. data/spec/extensions/date_arithmetic_spec.rb +3 -3
  291. data/spec/extensions/def_dataset_method_spec.rb +1 -1
  292. data/spec/extensions/defaults_setter_spec.rb +2 -2
  293. data/spec/extensions/delay_add_association_spec.rb +8 -9
  294. data/spec/extensions/dirty_spec.rb +1 -1
  295. data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
  296. data/spec/extensions/eager_each_spec.rb +2 -2
  297. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  298. data/spec/extensions/error_splitter_spec.rb +1 -1
  299. data/spec/extensions/error_sql_spec.rb +1 -1
  300. data/spec/extensions/eval_inspect_spec.rb +1 -1
  301. data/spec/extensions/finder_spec.rb +1 -1
  302. data/spec/extensions/force_encoding_spec.rb +2 -5
  303. data/spec/extensions/freeze_datasets_spec.rb +1 -1
  304. data/spec/extensions/graph_each_spec.rb +5 -5
  305. data/spec/extensions/hook_class_methods_spec.rb +1 -194
  306. data/spec/extensions/identifier_mangling_spec.rb +17 -170
  307. data/spec/extensions/implicit_subquery_spec.rb +1 -5
  308. data/spec/extensions/inflector_spec.rb +1 -1
  309. data/spec/extensions/input_transformer_spec.rb +7 -2
  310. data/spec/extensions/insert_returning_select_spec.rb +1 -1
  311. data/spec/extensions/instance_filters_spec.rb +1 -1
  312. data/spec/extensions/instance_hooks_spec.rb +1 -95
  313. data/spec/extensions/inverted_subsets_spec.rb +1 -1
  314. data/spec/extensions/json_serializer_spec.rb +1 -1
  315. data/spec/extensions/lazy_attributes_spec.rb +1 -7
  316. data/spec/extensions/list_spec.rb +5 -6
  317. data/spec/extensions/looser_typecasting_spec.rb +1 -1
  318. data/spec/extensions/many_through_many_spec.rb +25 -33
  319. data/spec/extensions/migration_spec.rb +12 -2
  320. data/spec/extensions/modification_detection_spec.rb +1 -1
  321. data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
  322. data/spec/extensions/named_timezones_spec.rb +3 -3
  323. data/spec/extensions/nested_attributes_spec.rb +1 -29
  324. data/spec/extensions/null_dataset_spec.rb +1 -11
  325. data/spec/extensions/optimistic_locking_spec.rb +2 -2
  326. data/spec/extensions/pagination_spec.rb +1 -1
  327. data/spec/extensions/pg_array_associations_spec.rb +22 -26
  328. data/spec/extensions/pg_array_ops_spec.rb +1 -1
  329. data/spec/extensions/pg_array_spec.rb +3 -48
  330. data/spec/extensions/pg_enum_spec.rb +1 -1
  331. data/spec/extensions/pg_extended_date_support_spec.rb +122 -0
  332. data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
  333. data/spec/extensions/pg_hstore_spec.rb +22 -31
  334. data/spec/extensions/pg_inet_ops_spec.rb +1 -1
  335. data/spec/extensions/pg_inet_spec.rb +1 -14
  336. data/spec/extensions/pg_interval_spec.rb +3 -13
  337. data/spec/extensions/pg_json_ops_spec.rb +1 -1
  338. data/spec/extensions/pg_json_spec.rb +1 -13
  339. data/spec/extensions/pg_loose_count_spec.rb +1 -1
  340. data/spec/extensions/pg_range_ops_spec.rb +1 -1
  341. data/spec/extensions/pg_range_spec.rb +3 -88
  342. data/spec/extensions/pg_row_ops_spec.rb +1 -1
  343. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  344. data/spec/extensions/pg_row_spec.rb +1 -44
  345. data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
  346. data/spec/extensions/prepared_statements_safe_spec.rb +7 -7
  347. data/spec/extensions/prepared_statements_spec.rb +13 -48
  348. data/spec/extensions/pretty_table_spec.rb +40 -9
  349. data/spec/extensions/query_spec.rb +1 -12
  350. data/spec/extensions/rcte_tree_spec.rb +23 -34
  351. data/spec/extensions/round_timestamps_spec.rb +1 -5
  352. data/spec/extensions/s_spec.rb +1 -1
  353. data/spec/extensions/schema_caching_spec.rb +1 -1
  354. data/spec/extensions/schema_dumper_spec.rb +43 -32
  355. data/spec/extensions/select_remove_spec.rb +1 -1
  356. data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
  357. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  358. data/spec/extensions/serialization_spec.rb +5 -17
  359. data/spec/extensions/server_block_spec.rb +1 -1
  360. data/spec/extensions/server_logging_spec.rb +2 -2
  361. data/spec/extensions/sharding_spec.rb +1 -1
  362. data/spec/extensions/shared_caching_spec.rb +1 -28
  363. data/spec/extensions/single_table_inheritance_spec.rb +2 -5
  364. data/spec/extensions/singular_table_names_spec.rb +1 -1
  365. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  366. data/spec/extensions/spec_helper.rb +5 -27
  367. data/spec/extensions/split_array_nil_spec.rb +1 -1
  368. data/spec/extensions/split_values_spec.rb +1 -1
  369. data/spec/extensions/sql_comments_spec.rb +1 -1
  370. data/spec/extensions/sql_expr_spec.rb +1 -1
  371. data/spec/extensions/static_cache_spec.rb +1 -1
  372. data/spec/extensions/string_agg_spec.rb +2 -2
  373. data/spec/extensions/string_date_time_spec.rb +1 -1
  374. data/spec/extensions/string_stripper_spec.rb +1 -1
  375. data/spec/extensions/subclasses_spec.rb +1 -1
  376. data/spec/extensions/subset_conditions_spec.rb +1 -1
  377. data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
  378. data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
  379. data/spec/extensions/synchronize_sql_spec.rb +124 -0
  380. data/spec/extensions/table_select_spec.rb +4 -4
  381. data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
  382. data/spec/extensions/thread_local_timezones_spec.rb +1 -1
  383. data/spec/extensions/timestamps_spec.rb +5 -7
  384. data/spec/extensions/to_dot_spec.rb +1 -1
  385. data/spec/extensions/touch_spec.rb +1 -1
  386. data/spec/extensions/tree_spec.rb +1 -1
  387. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  388. data/spec/extensions/unlimited_update_spec.rb +1 -1
  389. data/spec/extensions/update_or_create_spec.rb +12 -16
  390. data/spec/extensions/update_primary_key_spec.rb +4 -3
  391. data/spec/extensions/update_refresh_spec.rb +1 -1
  392. data/spec/extensions/uuid_spec.rb +10 -13
  393. data/spec/extensions/validate_associated_spec.rb +1 -1
  394. data/spec/extensions/validation_class_methods_spec.rb +3 -3
  395. data/spec/extensions/validation_contexts_spec.rb +1 -1
  396. data/spec/extensions/validation_helpers_spec.rb +10 -44
  397. data/spec/extensions/whitelist_security_spec.rb +5 -5
  398. data/spec/extensions/xml_serializer_spec.rb +8 -13
  399. data/spec/guards_helper.rb +2 -1
  400. data/spec/integration/associations_test.rb +1 -23
  401. data/spec/integration/database_test.rb +7 -7
  402. data/spec/integration/dataset_test.rb +12 -47
  403. data/spec/integration/eager_loader_test.rb +1 -1
  404. data/spec/integration/migrator_test.rb +1 -1
  405. data/spec/integration/model_test.rb +4 -82
  406. data/spec/integration/plugin_test.rb +7 -23
  407. data/spec/integration/prepared_statement_test.rb +8 -88
  408. data/spec/integration/schema_test.rb +10 -10
  409. data/spec/integration/spec_helper.rb +17 -21
  410. data/spec/integration/timezone_test.rb +5 -5
  411. data/spec/integration/transaction_test.rb +3 -55
  412. data/spec/integration/type_test.rb +9 -9
  413. data/spec/model/association_reflection_spec.rb +24 -9
  414. data/spec/model/associations_spec.rb +124 -303
  415. data/spec/model/base_spec.rb +43 -137
  416. data/spec/model/class_dataset_methods_spec.rb +2 -20
  417. data/spec/model/dataset_methods_spec.rb +1 -20
  418. data/spec/model/eager_loading_spec.rb +48 -17
  419. data/spec/model/hooks_spec.rb +5 -300
  420. data/spec/model/inflector_spec.rb +1 -1
  421. data/spec/model/model_spec.rb +29 -339
  422. data/spec/model/plugins_spec.rb +2 -16
  423. data/spec/model/record_spec.rb +33 -129
  424. data/spec/model/spec_helper.rb +5 -15
  425. data/spec/model/validations_spec.rb +1 -1
  426. data/spec/sequel_warning.rb +1 -12
  427. metadata +19 -65
  428. data/doc/active_record.rdoc +0 -927
  429. data/lib/sequel/adapters/cubrid.rb +0 -160
  430. data/lib/sequel/adapters/do/mysql.rb +0 -69
  431. data/lib/sequel/adapters/do/postgres.rb +0 -46
  432. data/lib/sequel/adapters/do/sqlite3.rb +0 -41
  433. data/lib/sequel/adapters/do.rb +0 -166
  434. data/lib/sequel/adapters/jdbc/as400.rb +0 -92
  435. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
  436. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
  437. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
  438. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
  439. data/lib/sequel/adapters/odbc/progress.rb +0 -12
  440. data/lib/sequel/adapters/shared/cubrid.rb +0 -245
  441. data/lib/sequel/adapters/shared/firebird.rb +0 -261
  442. data/lib/sequel/adapters/shared/informix.rb +0 -63
  443. data/lib/sequel/adapters/shared/progress.rb +0 -40
  444. data/lib/sequel/adapters/swift/mysql.rb +0 -50
  445. data/lib/sequel/adapters/swift/postgres.rb +0 -49
  446. data/lib/sequel/adapters/swift/sqlite.rb +0 -48
  447. data/lib/sequel/adapters/swift.rb +0 -169
  448. data/lib/sequel/adapters/utils/pg_types.rb +0 -4
  449. data/lib/sequel/dataset/mutation.rb +0 -98
  450. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
  451. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
  452. data/lib/sequel/extensions/filter_having.rb +0 -65
  453. data/lib/sequel/extensions/hash_aliases.rb +0 -51
  454. data/lib/sequel/extensions/meta_def.rb +0 -37
  455. data/lib/sequel/extensions/query_literals.rb +0 -86
  456. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
  457. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
  458. data/lib/sequel/extensions/set_overrides.rb +0 -82
  459. data/lib/sequel/no_core_ext.rb +0 -4
  460. data/lib/sequel/plugins/association_autoreloading.rb +0 -11
  461. data/lib/sequel/plugins/identifier_columns.rb +0 -49
  462. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
  463. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
  464. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
  465. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
  466. data/lib/sequel/plugins/schema.rb +0 -84
  467. data/lib/sequel/plugins/scissors.rb +0 -37
  468. data/spec/core/dataset_mutation_spec.rb +0 -253
  469. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
  470. data/spec/extensions/before_after_save_spec.rb +0 -40
  471. data/spec/extensions/filter_having_spec.rb +0 -42
  472. data/spec/extensions/from_block_spec.rb +0 -21
  473. data/spec/extensions/hash_aliases_spec.rb +0 -26
  474. data/spec/extensions/identifier_columns_spec.rb +0 -19
  475. data/spec/extensions/meta_def_spec.rb +0 -35
  476. data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
  477. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
  478. data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
  479. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
  480. data/spec/extensions/query_literals_spec.rb +0 -185
  481. data/spec/extensions/schema_spec.rb +0 -123
  482. data/spec/extensions/scissors_spec.rb +0 -27
  483. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
  484. data/spec/extensions/set_overrides_spec.rb +0 -75
data/doc/migration.rdoc CHANGED
@@ -23,7 +23,7 @@ you generally need to run Sequel's migrator with <tt>bin/sequel -m</tt>:
23
23
 
24
24
  sequel -m path/to/migrations postgres://host/database
25
25
 
26
- Migrations in Sequel use a very simple DSL via the <tt>Sequel.migration</tt>
26
+ Migrations in Sequel use a DSL via the <tt>Sequel.migration</tt>
27
27
  method, and inside the DSL, use the <tt>Sequel::Database</tt> schema
28
28
  modification methods such as +create_table+ and +alter_table+.
29
29
  See the {schema modification guide}[rdoc-ref:doc/schema_modification.rdoc]
@@ -37,7 +37,7 @@ Here is a fairly basic Sequel migration:
37
37
  up do
38
38
  create_table(:artists) do
39
39
  primary_key :id
40
- String :name, :null=>false
40
+ String :name, null: false
41
41
  end
42
42
  end
43
43
 
@@ -49,9 +49,8 @@ Here is a fairly basic Sequel migration:
49
49
  This migration has an +up+ block which adds an artist table with an integer primary key named id,
50
50
  and a varchar or text column (depending on the database) named +name+ that doesn't accept +NULL+ values.
51
51
  Migrations should include both up and +down+ blocks, with the +down+ block reversing
52
- the change made by up. However, if you never need to be able to migrate down
53
- (i.e. you are one of the people that doesn't make mistakes), you can leave out
54
- the +down+ block. In this case, the +down+ block just reverses the changes made by up,
52
+ the change made by up. However, if you never need to be able to migrate down,
53
+ you can leave out the +down+ block. In this case, the +down+ block just reverses the changes made by up,
55
54
  dropping the table.
56
55
 
57
56
  You can simplify the migration given above by using a reversible migration with a +change+
@@ -61,7 +60,7 @@ block:
61
60
  change do
62
61
  create_table(:artists) do
63
62
  primary_key :id
64
- String :name, :null=>false
63
+ String :name, null: false
65
64
  end
66
65
  end
67
66
  end
@@ -102,7 +101,7 @@ from Sacramento, CA, USA, but now you want to branch out and include artists in
102
101
  Sequel.migration do
103
102
  up do
104
103
  add_column :artists, :location, String
105
- from(:artists).update(:location=>'Sacramento')
104
+ from(:artists).update(location: 'Sacramento')
106
105
  end
107
106
 
108
107
  down do
@@ -117,18 +116,13 @@ just drops the +location+ column from the +artists+ table, reversing the actions
117
116
  block.
118
117
 
119
118
  Note that when updating the +artists+ table in the update, a plain dataset is used, <tt>from(:artists)</tt>.
120
- This looks a little weird, but you need to be aware that inside an up or +down+ block in a migration,
119
+ This may look a little strange, but you need to be aware that inside an up or +down+ block in a migration,
121
120
  self always refers to the <tt>Sequel::Database</tt> object that the migration is being applied to.
122
121
  Since <tt>Database#from</tt> creates datasets, using <tt>from(:artists)</tt> inside the +up+ block creates
123
122
  a dataset on the database representing all columns in the +artists+ table, and updates it to set the
124
123
  +location+ column to <tt>'Sacramento'</tt>. You should avoid referencing the <tt>Sequel::Database</tt>
125
124
  object directly in your migration, and always use self to reference it, otherwise you may run into problems.
126
125
 
127
- It is possible to use model classes inside migrations, as long as they are loaded into the ruby interpreter,
128
- but it's a bad habit as changes to your model classes can then break old migrations, and this breakage is
129
- often not caught until much later, such as when a new developer joins the team and wants to run all migrations
130
- to create their development database.
131
-
132
126
  == The +migration+ extension
133
127
 
134
128
  The migration code is not technically part of the core of Sequel. It's not loaded by default as it
@@ -244,15 +238,13 @@ the +TimestampMigrator+. They both have plusses and minuses:
244
238
  * Doesn't allow duplicate migrations
245
239
  * Doesn't allow missing migrations by default
246
240
  * Just stores the version of the last migration run
247
- * Good for single developer or small teams with close
248
- communication
241
+ * Good for single developer or small teams with close communication
249
242
  * Lower risk of undetected conflicting migrations
250
243
  * Requires manual merging of simultaneous migrations
251
244
 
252
245
  === +TimeStampMigrator+
253
246
 
254
- * More complex, use migration versions where the version should
255
- represent a timestamp
247
+ * More complex, uses migration versions where the version should represent a timestamp
256
248
  * Allows duplicate migrations (since you could have multiple in a given second)
257
249
  * Allows missing migrations (since you obviously don't have one every second)
258
250
  * Stores the file names of all applied migrations
@@ -360,7 +352,7 @@ you should give it some thought before using it.
360
352
 
361
353
  == Ignoring missing migrations
362
354
 
363
- In some cases, you may want to allow a migration in the database that does not exist in the filesystem (deploying to an older version of code without running a down migration when deploy auto-migrates, for example). If required, you can pass <tt>:allow_missing_migration_files => true</tt> as an option. This will stop errors from being raised if there are migrations in the database that do not exist in the filesystem.
355
+ In some cases, you may want to allow a migration in the database that does not exist in the filesystem (deploying to an older version of code without running a down migration when deploy auto-migrates, for example). If required, you can pass <tt>allow_missing_migration_files: true</tt> as an option. This will stop errors from being raised if there are migrations in the database that do not exist in the filesystem.
364
356
 
365
357
  == Modifying existing migrations
366
358
 
@@ -369,7 +361,7 @@ Just don't do it.
369
361
  In general, you should not modify any migration that has been run on the database and been committed to
370
362
  the source control repository, unless the migration contains an error that causes data loss. As long
371
363
  as it is possible to undo the migration without losing data, you should just add another migration
372
- that undoes the actions of the previous bad migration, and maybe does the correct action afterward.
364
+ that undoes the actions of the previous bad migration, and does the correct action afterward.
373
365
 
374
366
  The main problem with modifying existing migrations is that you will have to manually modify any
375
367
  databases that ran the migration before it was modified. If you are a single developer, that may be
@@ -409,17 +401,13 @@ artist per album to multiple artists per album:
409
401
  Sequel.migration do
410
402
  up do
411
403
  # Create albums_artists table
412
- create_table(:albums_artists) do
413
- foreign_key :album_id, :albums
414
- foreign_key :artist_id, :artists
415
- index [:album_id, :artist_id], :unique=>true
416
- end
404
+ create_join_table(album_id: :albums, artist_id: :artists)
417
405
 
418
406
  # Insert one row in the albums_artists table
419
407
  # for each row in the albums table where there
420
408
  # is an associated artist
421
- self[:albums_artists].insert([:album_id, :artist_id],
422
- self[:albums].select(:id, :artist_id).exclude(:artist_id=>nil))
409
+ from(:albums_artists).insert([:album_id, :artist_id],
410
+ from(:albums).select(:id, :artist_id).exclude(artist_id: nil))
423
411
 
424
412
  # Drop the now unnecesssary column from the albums table
425
413
  drop_column :albums, :artist_id
@@ -431,18 +419,13 @@ artist per album to multiple artists per album:
431
419
  # If possible, associate each album with one of the artists
432
420
  # it was associated with. This loses information, but
433
421
  # there's no way around that.
434
- self[:albums_artists].
435
- group(:album_id).
436
- select{[album_id, max(artist_id).as(artist_id)]}.
437
- having{artist_id > 0}.
438
- all do |r|
439
- self[:artists].
440
- where(:id=>r[:album_id]).
441
- update(:artist_id=>r[:artist_id])
442
- end
422
+ from(:albums).update(artist_id: from(:albums_artists).
423
+ select{max(artist_id)}.
424
+ where(album_id: Sequel[:albums][:id])
425
+ )
443
426
 
444
427
  # Drop the albums_artists table
445
- drop_table(:albums_artists)
428
+ drop_join_table(album_id: :albums, artist_id: :artists)
446
429
  end
447
430
  end
448
431
 
@@ -9,7 +9,7 @@ call the dataset methods directly:
9
9
 
10
10
  Album.
11
11
  select(:id, :name, :copies_sold).
12
- where(:release_year=>params[:year].to_i).
12
+ where(release_year: params[:year].to_i).
13
13
  order(Sequel.desc(:copies_sold)).
14
14
  all
15
15
 
@@ -19,7 +19,7 @@ One issue with this design is that it ties you to your current database schema,
19
19
  dataset_module do
20
20
  def all_albums_released_in_year(year)
21
21
  select(:id, :name, :copies_sold).
22
- where(:release_year=>year).
22
+ where(release_year: year).
23
23
  order(Sequel.desc(:copies_sold)).
24
24
  all
25
25
  end
@@ -30,7 +30,7 @@ Then your application code just needs to call your dataset method:
30
30
 
31
31
  Album.all_albums_released_in_year(params[:year].to_i)
32
32
 
33
- The advantage of this approach is that you can change your schema at any point in the future, and you should only need to change your model code, you should never need to change your application code.
33
+ The advantage of this approach is that you can change your schema at any point in the future, and you should only need to change your model code, you should never need to change other application code.
34
34
 
35
35
  == Performance
36
36
 
@@ -42,16 +42,14 @@ Second, assuming the performance issue is at the Sequel level, you need to under
42
42
 
43
43
  def all_albums_released_in_year(year)
44
44
  select(:id, :name, :copies_sold). # new dataset allocated
45
- where(:release_year=>year). # new dataset allocated
45
+ where(release_year: year). # new dataset allocated
46
46
  order(Sequel.desc(:copies_sold)). # new dataset allocated
47
47
  all
48
48
  end
49
49
 
50
- Third, you need to understand that Sequel has optimizations specifically designed to reduce the number of objects allocated, by caching intermediate data structures. However, these optimizations apply only to frozen datasets, and can only provide a benefit if related methods are called multiple times on the same dataset. One easy way to do this is to use frozen model datasets is to use the +freeze_datasets+ Database extension before creating your model class:
50
+ Third, you need to understand that Sequel has optimizations specifically designed to reduce the number of objects allocated, by caching intermediate datasets. Unfortunately, those optimizations do not apply in this case. The reason for this is that +select+, +where+, and +order+ can potentially receive arbitrary arguments, and enabling caching for them could easily lead to unbounded cache size (denial of service due to memory exhaustion).
51
51
 
52
- DB.extension :freeze_datasets
53
-
54
- Note that freezing datasets is not enough to enable caching in this case. The reason for this is that +select+, +where+, and +order+ can potentially receive arbitrary arguments, and enabling caching for them could easily lead to unbounded cache size (denial of service due to memory exhaustion). You need to signal to Sequel that particular arguments to these methods should be cached, and you can do that by calling methods inside +dataset_module+ blocks such as +select+ and +order+. These methods will add dataset methods to the model that can use caching to optimize performance. Here is an example using these methods:
52
+ To allow intermediate dataset caching to work, you need to signal to Sequel that particular arguments to these methods should be cached, and you can do that by calling methods inside +dataset_module+ blocks such as +select+ and +order+. These methods will add dataset methods to the model that can cache the returned dataset to optimize performance. Here is an example using these methods:
55
53
 
56
54
  class Album < Sequel::Model
57
55
  dataset_module do
@@ -61,7 +59,7 @@ Note that freezing datasets is not enough to enable caching in this case. The r
61
59
  def all_albums_released_in_year(year)
62
60
  with_name_and_units.
63
61
  by_units_sold.
64
- where(:release_year=>year).
62
+ where(release_year: year).
65
63
  all
66
64
  end
67
65
  end
@@ -74,14 +72,14 @@ By calling +select+ and +order+ here, Sequel expects that the created dataset me
74
72
  def all_albums_released_in_year(year)
75
73
  with_name_and_units. # cached dataset returned
76
74
  by_units_sold. # cached dataset returned
77
- where(:release_year=>year). # new dataset allocated
75
+ where(release_year: year). # new dataset allocated
78
76
  all
79
77
  end
80
78
 
81
79
  Note that the order of methods here is important. If you instead change the method chain to filter the dataset first, then no caching happens:
82
80
 
83
81
  def all_albums_released_in_year(year)
84
- where(:release_year=>year). # new dataset allocated
82
+ where(release_year: year). # new dataset allocated
85
83
  with_name_and_units. # new dataset allocated
86
84
  by_units_sold. # new dataset allocated
87
85
  all
@@ -89,7 +87,7 @@ Note that the order of methods here is important. If you instead change the met
89
87
 
90
88
  This is because any time a new, uncached dataset is returned by a dataset method, all subsequent methods in the method chain cannot benefit from caching.
91
89
 
92
- Usually, when you are designing methods to process data based on user input, the user input affects the rows selected, and not the columns selected or the order in which the rows are returned. Sequel is aware of this and has model dataset methods that specifically take user input (arguments), interpret them as a filter condition and either:
90
+ Usually, when you are designing methods to process data based on user input, the user input affects the rows selected, and not the columns selected or the order in which the rows are returned. Sequel is aware of this and has dataset methods that specifically take user input (arguments), interpret them as a filter condition and either:
93
91
 
94
92
  * Return all matching rows in an array (+where_all+)
95
93
  * Iterate over all matching rows (+where_each+)
@@ -101,14 +99,13 @@ After calling these methods on a cached dataset a number of times (currently 3),
101
99
  def all_albums_released_in_year(year)
102
100
  with_name_and_units. # cached dataset returned
103
101
  by_units_sold. # cached dataset returned
104
- where_all(:release_year=>year) # cached loader used
102
+ where_all(release_year: year) # cached loader used
105
103
  end
106
104
 
107
105
  This can significantly improve performance, up to 3x for complex method chains that only return a few rows.
108
106
 
109
- So the general advice on designing datasets for performance is:
107
+ So the general advice on designing dataset methods for performance is:
110
108
 
111
- * Use frozen datasets
112
109
  * Use +dataset_module+ methods to create named dataset methods that return cached datasets
113
110
  * If any filtering is to be done, have it done last using +where_all+, +where_each+, +first+, or +where_single_value+.
114
111
 
@@ -120,12 +117,12 @@ The best way to further increase performance at the Sequel level is to switch to
120
117
 
121
118
  class Album < Sequel::Model
122
119
  ALBUMS_RELEASED_IN_YEAR = select(:id, :name, :copies_sold).
123
- where(:release_year=>:$year).
120
+ where(release_year: :$year).
124
121
  order(Sequel.desc(:copies_sold)).
125
122
  prepare(:all, :all_albums_released_in_year)
126
123
 
127
124
  def self.all_albums_released_in_year(year)
128
- ALBUMS_RELEASED_IN_YEAR.call(:year=>year)
125
+ ALBUMS_RELEASED_IN_YEAR.call(year: year)
129
126
  end
130
127
  end
131
128
 
data/doc/model_hooks.rdoc CHANGED
@@ -4,7 +4,7 @@ This guide is based on http://guides.rubyonrails.org/activerecord_validations_ca
4
4
 
5
5
  == Overview
6
6
 
7
- Model hooks, also known as model callbacks, are used to specify actions that occur at a given point in a model instance's lifecycle, such as before or after the model object is saved, created, updated, destroyed, or validated. There are also around hooks for all types, which wrap the before hooks, the behavior, and the after hooks.
7
+ Model hooks are used to specify actions that occur at a given point in a model instance's lifecycle, such as before or after the model object is saved, created, updated, destroyed, or validated. There are also around hooks for all types, which wrap the before hooks, the behavior, and the after hooks.
8
8
 
9
9
  == Basic Usage
10
10
 
@@ -51,7 +51,7 @@ Sequel calls hooks in the following order when saving an existing object:
51
51
 
52
52
  Note that all of the hook calls are the same, except that +around_create+, +before_create+ and +after_create+ are used for a new object, and +around_update+, +before_update+ and +after_update+ are used for an existing object. Note that +around_save+, +before_save+, and +after_save+ are called in both cases.
53
53
 
54
- Also note that the validation hooks are not called if the <tt>:validate => false</tt> option is passed to save. However, the validation hooks are called if you call <tt>Model#valid?</tt> manually:
54
+ Note that the validation hooks are still called if <tt>validate: false</tt> option is passed to save. If you call <tt>Model#valid?</tt> manually, then only the validation hooks are called:
55
55
 
56
56
  * +around_validation+
57
57
  * +before_validation+
@@ -67,26 +67,19 @@ Sequel calls hooks in the following order when destroying an existing object:
67
67
 
68
68
  Note that these hooks are only called when using <tt>Model#destroy</tt>, they are not called if you use <tt>Model#delete</tt>.
69
69
 
70
- == Special Hook-Related Instance Variables
71
-
72
- For after_save hooks, a @was_new instance variable is present that indicates whether the record was a new record that was just inserted, or an existing record that was updated. Sequel marks a record as existing as soon as it inserts the record, so in an after_save or after_create hook, the instance is no longer considered new. You have to check @was_new to see if the record was inserted. This exists so that you don't have to have separate after_create and after_update hooks that are mostly the same and only differ slightly depending on whether the record was a new record.
73
-
74
- For after_update hooks, a @columns_updated instance variable is present that is a hash of the values used to update the row (keys are column symbols, values are column values). This should be used by any code that wants to check what columns and values were used during the update. You can't just check the current values of the instance, since Sequel offers ways to manually specify which columns to use during the save.
75
-
76
70
  == Transaction-related Hooks
77
71
 
78
- There are four other model hooks that <tt>Sequel::Model</tt> supports, all related to transactions. These are +after_commit+, +after_rollback+, +after_destroy_commit+, and +after_destroy_rollback+. +after_commit+ is called after the transaction in which you saved the object commits, only if it commits. +after_rollback+ is called after the transaction in which you saved the object rolls back, if it rolls back. +after_destroy_commit+ is called after the transaction in which you destroyed the object commits, if it commits. +after_destroy_rollback+ is called after the transaction in which you destroyed the object rolls back, if it rolls back.
79
-
80
- If you aren't using transactions when saving or destroying model objects, and there isn't a currently open transaction, +after_commit+ and +after_destroy_commit+ will be called after +after_save+ and +after_destroy+, respectively, and +after_rollback+ and +after_destroy_rollback+ won't be called at all.
81
-
82
- The purpose of these hooks is dealing with external systems that are interacting with the same database. For example, let's say you have a model that stores a picture, and you have a background job library that makes thumbnails of all of the pictures. So when a model object is created, you want to add a background job that will create the thumbnail for the picture. If you used after_save for this and transactions are being used, you are subject to a race condition where the background job library will check the database table for the record before the transaction that saved the record commits, and it won't be able to see the record's data. Using after_commit, you are guaranteed that the background job library will not get notified of the record until after the transaction commits and the data is viewable.
83
-
84
- Note that when using the after_commit or after_rollback hooks, you don't know whether the saved object was newly created or updated. If you only want to run an action after commit of a newly created record, you need to use the Database's after_commit inside the model's after_create hook:
72
+ Sequel::Model no longer offers transaction hooks for model instances. However, you can use the database transaction hooks inside model +before_save+ and +after_save+ hooks:
85
73
 
86
74
  class Album < Sequel::Model
87
- def after_create
75
+ def before_save
76
+ db.after_rollback{rollback_action}
77
+ super
78
+ end
79
+
80
+ def after_save
88
81
  super
89
- db.after_commit{update_external_cache}
82
+ db.after_commit{commit_action}
90
83
  end
91
84
  end
92
85
 
@@ -96,13 +89,13 @@ Sequel does not provide a simple way to turn off the running of save/create/upda
96
89
 
97
90
  However, you should note that there are plenty of ways to modify the database without saving a model object. One example is by using plain datasets, or one of the model's dataset methods:
98
91
 
99
- Album.where(:name=>'RF').update(:copies_sold=>Sequel.+(:copies_sold, 1))
92
+ Album.where(name: 'RF').update(copies_sold: Sequel.+(:copies_sold, 1))
100
93
  # UPDATE albums SET copies_sold = copies_sold + 1 WHERE name = 'RF'
101
94
 
102
95
  In this case, the +update+ method is called on the dataset returned by <tt>Album.where</tt>. Even if there is only a single object with the name RF, this will not call any hooks. If you want model hooks to be called, you need to make sure to operate on a model object:
103
96
 
104
- album = Album.first(:name=>'RF')
105
- album.update(:copies_sold=>album.copies_sold + 1)
97
+ album = Album.first(name: 'RF')
98
+ album.update(copies_sold: album.copies_sold + 1)
106
99
  # UPDATE albums SET copies_sold = 2 WHERE id = 1
107
100
 
108
101
  For the destroy hooks, you need to make sure you call +destroy+ on the object:
@@ -121,11 +114,11 @@ However, skipping hooks is a bad idea in general and should be avoided. As ment
121
114
 
122
115
  The +this+ dataset works just like any other dataset, so you can call +update+ on it to modify it:
123
116
 
124
- album.this.update(:copies_sold=>album.copies_sold + 1)
117
+ album.this.update(copies_sold: album.copies_sold + 1)
125
118
 
126
119
  If you want to insert a row into the model's table without running the creation hooks, you can use <tt>Model.insert</tt> instead of <tt>Model.create</tt>:
127
120
 
128
- Album.insert(:name=>'RF') # does not run hooks
121
+ Album.insert(name: 'RF') # does not run hooks
129
122
 
130
123
  == Canceling Actions in Hooks
131
124
 
@@ -138,8 +131,6 @@ Sometimes want to cancel an action in a before hook, so the action is not perfor
138
131
  end
139
132
  end
140
133
 
141
- For backwards compatibility, Sequel also treats the <tt>before_*</tt> hook methods returning +false+ as an indication that the action should be canceled. This usage is discouraged in new code, but you should be aware of this behavior so that you do not inadvertently return false.
142
-
143
134
  For around hooks, neglecting to call +super+ halts hook processing in the same way as calling +cancel_action+ in a before hook. It's probably a bad idea to use +cancel_action+ hook processing in after hooks, or after yielding in around hooks, since by then the main processing has already taken place.
144
135
 
145
136
  By default, Sequel runs hooks other than validation hooks inside a transaction, so if you cancel the action by calling +cancel_action+ in any hook, Sequel will rollback the transaction. However, note that the implicit use of transactions when saving and destroying model objects is conditional (it depends on the model instance's +use_transactions+ setting and the <tt>:transaction</tt> option passed to save).
@@ -216,7 +207,6 @@ This allows the following general principles to be true:
216
207
 
217
208
  * before hooks are run in reverse order of inclusion
218
209
  * after hooks are run in order of inclusion
219
- * returning false in any before hook will pass the false value down the hook method chain, halting the hook processing.
220
210
 
221
211
  So if you define the same before hook in both a model and a plugin that the model uses, the hooks will be called in this order:
222
212
 
@@ -33,7 +33,7 @@ Doing this, only Node and future subclasses of Node will have the tree plugin lo
33
33
  Some plugins require arguments and/or support options. For example, the single_table_inheritance plugin requires an argument containing the column that specifies the class to use, and options:
34
34
 
35
35
  class Employee < Sequel::Model
36
- plugin :single_table_inheritance, :type_id, :model_map=>{1=>:Staff, 2=>:Manager}
36
+ plugin :single_table_inheritance, :type_id, model_map: {1=>:Staff, 2=>:Manager}
37
37
  end
38
38
 
39
39
  You should read the documentation for the plugin to determine if it requires arguments and what if any options are supported.
@@ -120,7 +120,7 @@ This allows a plugin user to do:
120
120
 
121
121
  == Calling super to get Previous Behavior
122
122
 
123
- No matter if you are dealing with class, instance, or dataset methods, you can call super inside the method to get the previous behavior. This makes it easy to hook into the method, add your own behavior, but still (optionally?) get the previous behavior:
123
+ No matter if you are dealing with class, instance, or dataset methods, you can call super inside the method to get the previous behavior. This makes it easy to hook into the method, add your own behavior, but still get the previous behavior:
124
124
 
125
125
  module Sequel::Plugins::Foo
126
126
  module InstanceMethods
@@ -135,14 +135,14 @@ No matter if you are dealing with class, instance, or dataset methods, you can c
135
135
  private
136
136
 
137
137
  def allow_saving?
138
- `pom` =~ /Waxing/
138
+ moon =~ /Waxing/
139
139
  end
140
140
  end
141
141
  end
142
142
 
143
143
  == Running Code When the Plugin is Loaded
144
144
 
145
- Some plugins require more than just adding methods. Any plugin that requires state is going to have to initialize that state and store it somewhere. If you want to run code when a plugin is loaded (usually to initialize state, but possibly for other reasons), there are two methods you can define to do so. The first method is apply, and it is called only the first time the plugin is loaded into the class, before it is loaded into the class. This is generally only used if a plugin depends on another plugin or for initializing state. You define this method as a singleton method of the plugin module:
145
+ Some plugins require more than just adding methods. Any plugin that requires state is going to have to initialize that state and store it somewhere (generally in the model class itself). If you want to run code when a plugin is loaded (usually to initialize state, but possibly for other reasons), there are two methods you can define to do so. The first method is apply, and it is called only the first time the plugin is loaded into the class, before it is loaded into the class. This is generally only used if a plugin depends on another plugin or for initializing state. You define this method as a singleton method of the plugin module:
146
146
 
147
147
  module Sequel::Plugins::Foo
148
148
  def self.apply(model)
@@ -158,7 +158,7 @@ The other method is called configure, and it is called everytime the plugin is l
158
158
  module Sequel::Plugins::Foo
159
159
  def self.configure(model)
160
160
  model.instance_eval do
161
- @foo_state[:initial] = :baz
161
+ @foo_states[:initial] ||= :baz
162
162
  end
163
163
  end
164
164
  end
@@ -177,7 +177,7 @@ If you want your plugin to take arguments and/or support options, you handle tha
177
177
 
178
178
  def self.configure(model, opts={})
179
179
  model.instance_eval do
180
- @foo_state[:initial] = opts[:initial_state] || :baz
180
+ @foo_states[:initial] = opts[:initial_state] || @foo_states[:initial] || :baz
181
181
  end
182
182
  end
183
183
  end
@@ -185,7 +185,7 @@ If you want your plugin to take arguments and/or support options, you handle tha
185
185
  This allows a user of the plugin to do either of the following
186
186
 
187
187
  Bar.plugin :foo
188
- Bar.plugin :foo, :initial_state=>:quux
188
+ Bar.plugin :foo, initial_state: :quux
189
189
 
190
190
  If you want to require the initial state to be provided as an argument:
191
191
 
@@ -199,7 +199,7 @@ If you want to require the initial state to be provided as an argument:
199
199
 
200
200
  def self.configure(model, initial_state)
201
201
  model.instance_eval do
202
- @foo_state[:initial] = initial_state
202
+ @foo_states[:initial] = initial_state
203
203
  end
204
204
  end
205
205
  end
@@ -216,7 +216,7 @@ Sequel::Model uses a copy-on-subclassing approach to model state. So instead of
216
216
 
217
217
  module Sequel::Plugins::Foo
218
218
  module ClassMethods
219
- Sequel::Plugins.inherited_instance_variables(self, :@foo_state=>:dup)
219
+ Sequel::Plugins.inherited_instance_variables(self, :@foo_states => :dup)
220
220
  end
221
221
  end
222
222
 
@@ -238,7 +238,7 @@ In many plugins, if the model class changes the dataset, you need to change the
238
238
  private
239
239
 
240
240
  def set_foo_table
241
- @foo_state[:table] = table_name
241
+ @foo_states[:table] = table_name
242
242
  end
243
243
  end
244
244
  end
@@ -17,7 +17,7 @@ The following stored procedure is used as an example:
17
17
 
18
18
  Execute it as follows:
19
19
 
20
- DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', :output]})
20
+ DB.call_mssql_sproc(:SequelTest, {args: ['Input String', :output]})
21
21
 
22
22
  Use the +:output+ symbol to denote an output variable. The result will contain a
23
23
  hash of the output variables, as well as the result code and number of affected rows:
@@ -27,7 +27,7 @@ hash of the output variables, as well as the result code and number of affected
27
27
  Output variables will be strings by default. To specify their type, include the
28
28
  SQL type:
29
29
 
30
- DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', [:output, 'int']]})
30
+ DB.call_mssql_sproc(:SequelTest, {args: ['Input String', [:output, 'int']]})
31
31
 
32
32
  Result:
33
33
 
@@ -36,7 +36,7 @@ Result:
36
36
  Output variables will be named +var#{n}+ where n is their zero indexed position
37
37
  in the parameter list. To name the output variable, include their name:
38
38
 
39
- DB.call_mssql_sproc(:SequelTest, {:args => ['Input String', [:output, nil, 'Output']]})
39
+ DB.call_mssql_sproc(:SequelTest, {args: ['Input String', [:output, nil, 'Output']]})
40
40
 
41
41
  Result:
42
42