sequel 4.36.0 → 5.61.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 (760) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +548 -5749
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +265 -159
  5. data/bin/sequel +34 -12
  6. data/doc/advanced_associations.rdoc +228 -187
  7. data/doc/association_basics.rdoc +281 -291
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +86 -51
  10. data/doc/code_order.rdoc +25 -19
  11. data/doc/core_extensions.rdoc +104 -63
  12. data/doc/dataset_basics.rdoc +12 -21
  13. data/doc/dataset_filtering.rdoc +99 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/fork_safety.rdoc +84 -0
  16. data/doc/mass_assignment.rdoc +74 -31
  17. data/doc/migration.rdoc +59 -51
  18. data/doc/model_dataset_method_design.rdoc +129 -0
  19. data/doc/model_hooks.rdoc +15 -25
  20. data/doc/model_plugins.rdoc +12 -12
  21. data/doc/mssql_stored_procedures.rdoc +3 -3
  22. data/doc/object_model.rdoc +58 -68
  23. data/doc/opening_databases.rdoc +85 -95
  24. data/doc/postgresql.rdoc +263 -38
  25. data/doc/prepared_statements.rdoc +29 -24
  26. data/doc/querying.rdoc +189 -167
  27. data/doc/reflection.rdoc +5 -6
  28. data/doc/release_notes/5.0.0.txt +159 -0
  29. data/doc/release_notes/5.1.0.txt +31 -0
  30. data/doc/release_notes/5.10.0.txt +84 -0
  31. data/doc/release_notes/5.11.0.txt +83 -0
  32. data/doc/release_notes/5.12.0.txt +141 -0
  33. data/doc/release_notes/5.13.0.txt +27 -0
  34. data/doc/release_notes/5.14.0.txt +63 -0
  35. data/doc/release_notes/5.15.0.txt +39 -0
  36. data/doc/release_notes/5.16.0.txt +110 -0
  37. data/doc/release_notes/5.17.0.txt +31 -0
  38. data/doc/release_notes/5.18.0.txt +69 -0
  39. data/doc/release_notes/5.19.0.txt +28 -0
  40. data/doc/release_notes/5.2.0.txt +33 -0
  41. data/doc/release_notes/5.20.0.txt +89 -0
  42. data/doc/release_notes/5.21.0.txt +87 -0
  43. data/doc/release_notes/5.22.0.txt +48 -0
  44. data/doc/release_notes/5.23.0.txt +56 -0
  45. data/doc/release_notes/5.24.0.txt +56 -0
  46. data/doc/release_notes/5.25.0.txt +32 -0
  47. data/doc/release_notes/5.26.0.txt +35 -0
  48. data/doc/release_notes/5.27.0.txt +21 -0
  49. data/doc/release_notes/5.28.0.txt +16 -0
  50. data/doc/release_notes/5.29.0.txt +22 -0
  51. data/doc/release_notes/5.3.0.txt +121 -0
  52. data/doc/release_notes/5.30.0.txt +20 -0
  53. data/doc/release_notes/5.31.0.txt +148 -0
  54. data/doc/release_notes/5.32.0.txt +46 -0
  55. data/doc/release_notes/5.33.0.txt +24 -0
  56. data/doc/release_notes/5.34.0.txt +40 -0
  57. data/doc/release_notes/5.35.0.txt +56 -0
  58. data/doc/release_notes/5.36.0.txt +60 -0
  59. data/doc/release_notes/5.37.0.txt +30 -0
  60. data/doc/release_notes/5.38.0.txt +28 -0
  61. data/doc/release_notes/5.39.0.txt +19 -0
  62. data/doc/release_notes/5.4.0.txt +80 -0
  63. data/doc/release_notes/5.40.0.txt +40 -0
  64. data/doc/release_notes/5.41.0.txt +25 -0
  65. data/doc/release_notes/5.42.0.txt +136 -0
  66. data/doc/release_notes/5.43.0.txt +98 -0
  67. data/doc/release_notes/5.44.0.txt +32 -0
  68. data/doc/release_notes/5.45.0.txt +34 -0
  69. data/doc/release_notes/5.46.0.txt +87 -0
  70. data/doc/release_notes/5.47.0.txt +59 -0
  71. data/doc/release_notes/5.48.0.txt +14 -0
  72. data/doc/release_notes/5.49.0.txt +59 -0
  73. data/doc/release_notes/5.5.0.txt +61 -0
  74. data/doc/release_notes/5.50.0.txt +78 -0
  75. data/doc/release_notes/5.51.0.txt +47 -0
  76. data/doc/release_notes/5.52.0.txt +87 -0
  77. data/doc/release_notes/5.53.0.txt +23 -0
  78. data/doc/release_notes/5.54.0.txt +27 -0
  79. data/doc/release_notes/5.55.0.txt +21 -0
  80. data/doc/release_notes/5.56.0.txt +51 -0
  81. data/doc/release_notes/5.57.0.txt +23 -0
  82. data/doc/release_notes/5.58.0.txt +31 -0
  83. data/doc/release_notes/5.59.0.txt +73 -0
  84. data/doc/release_notes/5.6.0.txt +31 -0
  85. data/doc/release_notes/5.60.0.txt +22 -0
  86. data/doc/release_notes/5.61.0.txt +43 -0
  87. data/doc/release_notes/5.7.0.txt +108 -0
  88. data/doc/release_notes/5.8.0.txt +170 -0
  89. data/doc/release_notes/5.9.0.txt +99 -0
  90. data/doc/schema_modification.rdoc +95 -75
  91. data/doc/security.rdoc +109 -80
  92. data/doc/sharding.rdoc +74 -47
  93. data/doc/sql.rdoc +147 -122
  94. data/doc/testing.rdoc +43 -20
  95. data/doc/thread_safety.rdoc +2 -4
  96. data/doc/transactions.rdoc +97 -18
  97. data/doc/validations.rdoc +52 -50
  98. data/doc/virtual_rows.rdoc +90 -109
  99. data/lib/sequel/adapters/ado/access.rb +15 -17
  100. data/lib/sequel/adapters/ado/mssql.rb +6 -15
  101. data/lib/sequel/adapters/ado.rb +150 -20
  102. data/lib/sequel/adapters/amalgalite.rb +11 -23
  103. data/lib/sequel/adapters/ibmdb.rb +47 -55
  104. data/lib/sequel/adapters/jdbc/db2.rb +29 -39
  105. data/lib/sequel/adapters/jdbc/derby.rb +58 -54
  106. data/lib/sequel/adapters/jdbc/h2.rb +93 -35
  107. data/lib/sequel/adapters/jdbc/hsqldb.rb +24 -31
  108. data/lib/sequel/adapters/jdbc/jtds.rb +2 -10
  109. data/lib/sequel/adapters/jdbc/mssql.rb +3 -11
  110. data/lib/sequel/adapters/jdbc/mysql.rb +17 -20
  111. data/lib/sequel/adapters/jdbc/oracle.rb +22 -18
  112. data/lib/sequel/adapters/jdbc/postgresql.rb +69 -71
  113. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +11 -23
  114. data/lib/sequel/adapters/jdbc/sqlite.rb +47 -11
  115. data/lib/sequel/adapters/jdbc/sqlserver.rb +34 -9
  116. data/lib/sequel/adapters/jdbc/transactions.rb +22 -38
  117. data/lib/sequel/adapters/jdbc.rb +145 -130
  118. data/lib/sequel/adapters/mock.rb +100 -111
  119. data/lib/sequel/adapters/mysql.rb +114 -122
  120. data/lib/sequel/adapters/mysql2.rb +147 -63
  121. data/lib/sequel/adapters/odbc/db2.rb +1 -1
  122. data/lib/sequel/adapters/odbc/mssql.rb +8 -14
  123. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  124. data/lib/sequel/adapters/odbc.rb +20 -25
  125. data/lib/sequel/adapters/oracle.rb +50 -56
  126. data/lib/sequel/adapters/postgres.rb +305 -327
  127. data/lib/sequel/adapters/postgresql.rb +1 -1
  128. data/lib/sequel/adapters/shared/access.rb +74 -78
  129. data/lib/sequel/adapters/shared/db2.rb +118 -71
  130. data/lib/sequel/adapters/shared/mssql.rb +301 -220
  131. data/lib/sequel/adapters/shared/mysql.rb +299 -217
  132. data/lib/sequel/adapters/shared/oracle.rb +226 -65
  133. data/lib/sequel/adapters/shared/postgres.rb +935 -395
  134. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -126
  135. data/lib/sequel/adapters/shared/sqlite.rb +447 -173
  136. data/lib/sequel/adapters/sqlanywhere.rb +48 -35
  137. data/lib/sequel/adapters/sqlite.rb +156 -111
  138. data/lib/sequel/adapters/tinytds.rb +30 -38
  139. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  140. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +3 -6
  141. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +2 -2
  142. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  143. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  144. data/lib/sequel/adapters/utils/replace.rb +1 -4
  145. data/lib/sequel/adapters/utils/stored_procedures.rb +7 -22
  146. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  147. data/lib/sequel/ast_transformer.rb +17 -89
  148. data/lib/sequel/connection_pool/sharded_single.rb +18 -15
  149. data/lib/sequel/connection_pool/sharded_threaded.rb +130 -111
  150. data/lib/sequel/connection_pool/single.rb +18 -13
  151. data/lib/sequel/connection_pool/threaded.rb +121 -120
  152. data/lib/sequel/connection_pool.rb +48 -29
  153. data/lib/sequel/core.rb +351 -301
  154. data/lib/sequel/database/connecting.rb +69 -57
  155. data/lib/sequel/database/dataset.rb +13 -5
  156. data/lib/sequel/database/dataset_defaults.rb +18 -102
  157. data/lib/sequel/database/features.rb +18 -4
  158. data/lib/sequel/database/logging.rb +12 -11
  159. data/lib/sequel/database/misc.rb +180 -122
  160. data/lib/sequel/database/query.rb +47 -27
  161. data/lib/sequel/database/schema_generator.rb +178 -84
  162. data/lib/sequel/database/schema_methods.rb +172 -97
  163. data/lib/sequel/database/transactions.rb +205 -44
  164. data/lib/sequel/database.rb +17 -2
  165. data/lib/sequel/dataset/actions.rb +339 -155
  166. data/lib/sequel/dataset/dataset_module.rb +46 -0
  167. data/lib/sequel/dataset/features.rb +90 -35
  168. data/lib/sequel/dataset/graph.rb +80 -58
  169. data/lib/sequel/dataset/misc.rb +137 -47
  170. data/lib/sequel/dataset/placeholder_literalizer.rb +63 -25
  171. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  172. data/lib/sequel/dataset/query.rb +530 -222
  173. data/lib/sequel/dataset/sql.rb +590 -368
  174. data/lib/sequel/dataset.rb +26 -16
  175. data/lib/sequel/deprecated.rb +12 -2
  176. data/lib/sequel/exceptions.rb +46 -16
  177. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  178. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  179. data/lib/sequel/extensions/_pretty_table.rb +2 -5
  180. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  181. data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
  182. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  183. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  184. data/lib/sequel/extensions/blank.rb +8 -0
  185. data/lib/sequel/extensions/caller_logging.rb +79 -0
  186. data/lib/sequel/extensions/columns_introspection.rb +4 -3
  187. data/lib/sequel/extensions/connection_expiration.rb +20 -10
  188. data/lib/sequel/extensions/connection_validator.rb +11 -10
  189. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  190. data/lib/sequel/extensions/constraint_validations.rb +62 -39
  191. data/lib/sequel/extensions/core_extensions.rb +42 -48
  192. data/lib/sequel/extensions/core_refinements.rb +80 -59
  193. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -4
  194. data/lib/sequel/extensions/date_arithmetic.rb +98 -39
  195. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  196. data/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
  197. data/lib/sequel/extensions/duplicate_columns_handler.rb +21 -14
  198. data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
  199. data/lib/sequel/extensions/escaped_like.rb +100 -0
  200. data/lib/sequel/extensions/eval_inspect.rb +12 -15
  201. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  202. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  203. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  204. data/lib/sequel/extensions/from_block.rb +1 -34
  205. data/lib/sequel/extensions/graph_each.rb +4 -4
  206. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  207. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  208. data/lib/sequel/extensions/index_caching.rb +109 -0
  209. data/lib/sequel/extensions/inflector.rb +13 -5
  210. data/lib/sequel/extensions/integer64.rb +32 -0
  211. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  212. data/lib/sequel/extensions/looser_typecasting.rb +17 -8
  213. data/lib/sequel/extensions/migration.rb +119 -78
  214. data/lib/sequel/extensions/named_timezones.rb +88 -23
  215. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -82
  216. data/lib/sequel/extensions/null_dataset.rb +8 -8
  217. data/lib/sequel/extensions/pagination.rb +32 -29
  218. data/lib/sequel/extensions/pg_array.rb +221 -287
  219. data/lib/sequel/extensions/pg_array_ops.rb +17 -9
  220. data/lib/sequel/extensions/pg_enum.rb +63 -23
  221. data/lib/sequel/extensions/pg_extended_date_support.rb +241 -0
  222. data/lib/sequel/extensions/pg_hstore.rb +45 -54
  223. data/lib/sequel/extensions/pg_hstore_ops.rb +58 -6
  224. data/lib/sequel/extensions/pg_inet.rb +31 -12
  225. data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
  226. data/lib/sequel/extensions/pg_interval.rb +56 -29
  227. data/lib/sequel/extensions/pg_json.rb +417 -140
  228. data/lib/sequel/extensions/pg_json_ops.rb +270 -18
  229. data/lib/sequel/extensions/pg_loose_count.rb +4 -2
  230. data/lib/sequel/extensions/pg_multirange.rb +372 -0
  231. data/lib/sequel/extensions/pg_range.rb +131 -191
  232. data/lib/sequel/extensions/pg_range_ops.rb +42 -13
  233. data/lib/sequel/extensions/pg_row.rb +48 -81
  234. data/lib/sequel/extensions/pg_row_ops.rb +33 -14
  235. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  236. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  237. data/lib/sequel/extensions/query.rb +9 -7
  238. data/lib/sequel/extensions/round_timestamps.rb +0 -6
  239. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  240. data/lib/sequel/extensions/s.rb +60 -0
  241. data/lib/sequel/extensions/schema_caching.rb +10 -1
  242. data/lib/sequel/extensions/schema_dumper.rb +71 -48
  243. data/lib/sequel/extensions/select_remove.rb +4 -4
  244. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  245. data/lib/sequel/extensions/server_block.rb +51 -27
  246. data/lib/sequel/extensions/split_array_nil.rb +4 -4
  247. data/lib/sequel/extensions/sql_comments.rb +119 -7
  248. data/lib/sequel/extensions/sql_expr.rb +2 -1
  249. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  250. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  251. data/lib/sequel/extensions/string_agg.rb +11 -8
  252. data/lib/sequel/extensions/string_date_time.rb +19 -23
  253. data/lib/sequel/extensions/symbol_aref.rb +55 -0
  254. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  255. data/lib/sequel/extensions/symbol_as.rb +23 -0
  256. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  257. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  258. data/lib/sequel/extensions/to_dot.rb +10 -4
  259. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  260. data/lib/sequel/model/associations.rb +1006 -284
  261. data/lib/sequel/model/base.rb +560 -805
  262. data/lib/sequel/model/dataset_module.rb +11 -10
  263. data/lib/sequel/model/default_inflections.rb +1 -1
  264. data/lib/sequel/model/errors.rb +10 -3
  265. data/lib/sequel/model/exceptions.rb +8 -10
  266. data/lib/sequel/model/inflections.rb +7 -20
  267. data/lib/sequel/model/plugins.rb +114 -0
  268. data/lib/sequel/model.rb +32 -82
  269. data/lib/sequel/plugins/active_model.rb +30 -14
  270. data/lib/sequel/plugins/after_initialize.rb +1 -1
  271. data/lib/sequel/plugins/association_dependencies.rb +25 -18
  272. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  273. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  274. data/lib/sequel/plugins/association_pks.rb +147 -70
  275. data/lib/sequel/plugins/association_proxies.rb +33 -9
  276. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  277. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  278. data/lib/sequel/plugins/auto_validations.rb +95 -28
  279. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  280. data/lib/sequel/plugins/before_after_save.rb +0 -42
  281. data/lib/sequel/plugins/blacklist_security.rb +21 -12
  282. data/lib/sequel/plugins/boolean_readers.rb +5 -5
  283. data/lib/sequel/plugins/boolean_subsets.rb +13 -8
  284. data/lib/sequel/plugins/caching.rb +25 -16
  285. data/lib/sequel/plugins/class_table_inheritance.rb +179 -100
  286. data/lib/sequel/plugins/column_conflicts.rb +16 -3
  287. data/lib/sequel/plugins/column_encryption.rb +728 -0
  288. data/lib/sequel/plugins/column_select.rb +7 -5
  289. data/lib/sequel/plugins/columns_updated.rb +42 -0
  290. data/lib/sequel/plugins/composition.rb +42 -26
  291. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  292. data/lib/sequel/plugins/constraint_validations.rb +20 -14
  293. data/lib/sequel/plugins/csv_serializer.rb +56 -35
  294. data/lib/sequel/plugins/dataset_associations.rb +40 -17
  295. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  296. data/lib/sequel/plugins/defaults_setter.rb +65 -10
  297. data/lib/sequel/plugins/delay_add_association.rb +1 -1
  298. data/lib/sequel/plugins/dirty.rb +62 -24
  299. data/lib/sequel/plugins/eager_each.rb +3 -3
  300. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  301. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  302. data/lib/sequel/plugins/enum.rb +124 -0
  303. data/lib/sequel/plugins/error_splitter.rb +17 -12
  304. data/lib/sequel/plugins/finder.rb +246 -0
  305. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  306. data/lib/sequel/plugins/force_encoding.rb +7 -12
  307. data/lib/sequel/plugins/hook_class_methods.rb +37 -54
  308. data/lib/sequel/plugins/input_transformer.rb +18 -10
  309. data/lib/sequel/plugins/insert_conflict.rb +76 -0
  310. data/lib/sequel/plugins/insert_returning_select.rb +2 -2
  311. data/lib/sequel/plugins/instance_filters.rb +10 -8
  312. data/lib/sequel/plugins/instance_hooks.rb +34 -17
  313. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  314. data/lib/sequel/plugins/inverted_subsets.rb +22 -13
  315. data/lib/sequel/plugins/json_serializer.rb +124 -64
  316. data/lib/sequel/plugins/lazy_attributes.rb +21 -14
  317. data/lib/sequel/plugins/list.rb +35 -21
  318. data/lib/sequel/plugins/many_through_many.rb +134 -21
  319. data/lib/sequel/plugins/modification_detection.rb +15 -5
  320. data/lib/sequel/plugins/mssql_optimistic_locking.rb +6 -5
  321. data/lib/sequel/plugins/nested_attributes.rb +61 -31
  322. data/lib/sequel/plugins/optimistic_locking.rb +3 -3
  323. data/lib/sequel/plugins/pg_array_associations.rb +103 -53
  324. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +350 -0
  325. data/lib/sequel/plugins/pg_row.rb +5 -51
  326. data/lib/sequel/plugins/prepared_statements.rb +60 -72
  327. data/lib/sequel/plugins/prepared_statements_safe.rb +9 -4
  328. data/lib/sequel/plugins/rcte_tree.rb +68 -82
  329. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  330. data/lib/sequel/plugins/serialization.rb +43 -46
  331. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -2
  332. data/lib/sequel/plugins/sharding.rb +15 -10
  333. data/lib/sequel/plugins/single_table_inheritance.rb +67 -28
  334. data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
  335. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  336. data/lib/sequel/plugins/split_values.rb +11 -6
  337. data/lib/sequel/plugins/sql_comments.rb +189 -0
  338. data/lib/sequel/plugins/static_cache.rb +77 -53
  339. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  340. data/lib/sequel/plugins/string_stripper.rb +3 -3
  341. data/lib/sequel/plugins/subclasses.rb +43 -10
  342. data/lib/sequel/plugins/subset_conditions.rb +15 -5
  343. data/lib/sequel/plugins/table_select.rb +2 -2
  344. data/lib/sequel/plugins/tactical_eager_loading.rb +96 -12
  345. data/lib/sequel/plugins/throw_failures.rb +110 -0
  346. data/lib/sequel/plugins/timestamps.rb +20 -8
  347. data/lib/sequel/plugins/touch.rb +19 -8
  348. data/lib/sequel/plugins/tree.rb +62 -32
  349. data/lib/sequel/plugins/typecast_on_load.rb +12 -4
  350. data/lib/sequel/plugins/unlimited_update.rb +1 -7
  351. data/lib/sequel/plugins/unused_associations.rb +521 -0
  352. data/lib/sequel/plugins/update_or_create.rb +4 -4
  353. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  354. data/lib/sequel/plugins/update_refresh.rb +26 -15
  355. data/lib/sequel/plugins/uuid.rb +7 -11
  356. data/lib/sequel/plugins/validate_associated.rb +18 -0
  357. data/lib/sequel/plugins/validation_class_methods.rb +38 -19
  358. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  359. data/lib/sequel/plugins/validation_helpers.rb +57 -41
  360. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  361. data/lib/sequel/plugins/xml_serializer.rb +30 -31
  362. data/lib/sequel/sql.rb +471 -331
  363. data/lib/sequel/timezones.rb +78 -47
  364. data/lib/sequel/version.rb +7 -2
  365. data/lib/sequel.rb +1 -1
  366. metadata +217 -521
  367. data/Rakefile +0 -164
  368. data/doc/active_record.rdoc +0 -928
  369. data/doc/release_notes/1.0.txt +0 -38
  370. data/doc/release_notes/1.1.txt +0 -143
  371. data/doc/release_notes/1.3.txt +0 -101
  372. data/doc/release_notes/1.4.0.txt +0 -53
  373. data/doc/release_notes/1.5.0.txt +0 -155
  374. data/doc/release_notes/2.0.0.txt +0 -298
  375. data/doc/release_notes/2.1.0.txt +0 -271
  376. data/doc/release_notes/2.10.0.txt +0 -328
  377. data/doc/release_notes/2.11.0.txt +0 -215
  378. data/doc/release_notes/2.12.0.txt +0 -534
  379. data/doc/release_notes/2.2.0.txt +0 -253
  380. data/doc/release_notes/2.3.0.txt +0 -88
  381. data/doc/release_notes/2.4.0.txt +0 -106
  382. data/doc/release_notes/2.5.0.txt +0 -137
  383. data/doc/release_notes/2.6.0.txt +0 -157
  384. data/doc/release_notes/2.7.0.txt +0 -166
  385. data/doc/release_notes/2.8.0.txt +0 -171
  386. data/doc/release_notes/2.9.0.txt +0 -97
  387. data/doc/release_notes/3.0.0.txt +0 -221
  388. data/doc/release_notes/3.1.0.txt +0 -406
  389. data/doc/release_notes/3.10.0.txt +0 -286
  390. data/doc/release_notes/3.11.0.txt +0 -254
  391. data/doc/release_notes/3.12.0.txt +0 -304
  392. data/doc/release_notes/3.13.0.txt +0 -210
  393. data/doc/release_notes/3.14.0.txt +0 -118
  394. data/doc/release_notes/3.15.0.txt +0 -78
  395. data/doc/release_notes/3.16.0.txt +0 -45
  396. data/doc/release_notes/3.17.0.txt +0 -58
  397. data/doc/release_notes/3.18.0.txt +0 -120
  398. data/doc/release_notes/3.19.0.txt +0 -67
  399. data/doc/release_notes/3.2.0.txt +0 -268
  400. data/doc/release_notes/3.20.0.txt +0 -41
  401. data/doc/release_notes/3.21.0.txt +0 -87
  402. data/doc/release_notes/3.22.0.txt +0 -39
  403. data/doc/release_notes/3.23.0.txt +0 -172
  404. data/doc/release_notes/3.24.0.txt +0 -420
  405. data/doc/release_notes/3.25.0.txt +0 -88
  406. data/doc/release_notes/3.26.0.txt +0 -88
  407. data/doc/release_notes/3.27.0.txt +0 -82
  408. data/doc/release_notes/3.28.0.txt +0 -304
  409. data/doc/release_notes/3.29.0.txt +0 -459
  410. data/doc/release_notes/3.3.0.txt +0 -192
  411. data/doc/release_notes/3.30.0.txt +0 -135
  412. data/doc/release_notes/3.31.0.txt +0 -146
  413. data/doc/release_notes/3.32.0.txt +0 -202
  414. data/doc/release_notes/3.33.0.txt +0 -157
  415. data/doc/release_notes/3.34.0.txt +0 -671
  416. data/doc/release_notes/3.35.0.txt +0 -144
  417. data/doc/release_notes/3.36.0.txt +0 -245
  418. data/doc/release_notes/3.37.0.txt +0 -338
  419. data/doc/release_notes/3.38.0.txt +0 -234
  420. data/doc/release_notes/3.39.0.txt +0 -237
  421. data/doc/release_notes/3.4.0.txt +0 -325
  422. data/doc/release_notes/3.40.0.txt +0 -73
  423. data/doc/release_notes/3.41.0.txt +0 -155
  424. data/doc/release_notes/3.42.0.txt +0 -74
  425. data/doc/release_notes/3.43.0.txt +0 -105
  426. data/doc/release_notes/3.44.0.txt +0 -152
  427. data/doc/release_notes/3.45.0.txt +0 -179
  428. data/doc/release_notes/3.46.0.txt +0 -122
  429. data/doc/release_notes/3.47.0.txt +0 -270
  430. data/doc/release_notes/3.48.0.txt +0 -477
  431. data/doc/release_notes/3.5.0.txt +0 -510
  432. data/doc/release_notes/3.6.0.txt +0 -366
  433. data/doc/release_notes/3.7.0.txt +0 -179
  434. data/doc/release_notes/3.8.0.txt +0 -151
  435. data/doc/release_notes/3.9.0.txt +0 -233
  436. data/doc/release_notes/4.0.0.txt +0 -262
  437. data/doc/release_notes/4.1.0.txt +0 -85
  438. data/doc/release_notes/4.10.0.txt +0 -226
  439. data/doc/release_notes/4.11.0.txt +0 -147
  440. data/doc/release_notes/4.12.0.txt +0 -105
  441. data/doc/release_notes/4.13.0.txt +0 -169
  442. data/doc/release_notes/4.14.0.txt +0 -68
  443. data/doc/release_notes/4.15.0.txt +0 -56
  444. data/doc/release_notes/4.16.0.txt +0 -36
  445. data/doc/release_notes/4.17.0.txt +0 -38
  446. data/doc/release_notes/4.18.0.txt +0 -36
  447. data/doc/release_notes/4.19.0.txt +0 -45
  448. data/doc/release_notes/4.2.0.txt +0 -129
  449. data/doc/release_notes/4.20.0.txt +0 -79
  450. data/doc/release_notes/4.21.0.txt +0 -94
  451. data/doc/release_notes/4.22.0.txt +0 -72
  452. data/doc/release_notes/4.23.0.txt +0 -65
  453. data/doc/release_notes/4.24.0.txt +0 -99
  454. data/doc/release_notes/4.25.0.txt +0 -181
  455. data/doc/release_notes/4.26.0.txt +0 -44
  456. data/doc/release_notes/4.27.0.txt +0 -78
  457. data/doc/release_notes/4.28.0.txt +0 -57
  458. data/doc/release_notes/4.29.0.txt +0 -41
  459. data/doc/release_notes/4.3.0.txt +0 -40
  460. data/doc/release_notes/4.30.0.txt +0 -37
  461. data/doc/release_notes/4.31.0.txt +0 -57
  462. data/doc/release_notes/4.32.0.txt +0 -132
  463. data/doc/release_notes/4.33.0.txt +0 -88
  464. data/doc/release_notes/4.34.0.txt +0 -86
  465. data/doc/release_notes/4.35.0.txt +0 -130
  466. data/doc/release_notes/4.36.0.txt +0 -116
  467. data/doc/release_notes/4.4.0.txt +0 -92
  468. data/doc/release_notes/4.5.0.txt +0 -34
  469. data/doc/release_notes/4.6.0.txt +0 -30
  470. data/doc/release_notes/4.7.0.txt +0 -103
  471. data/doc/release_notes/4.8.0.txt +0 -175
  472. data/doc/release_notes/4.9.0.txt +0 -190
  473. data/lib/sequel/adapters/cubrid.rb +0 -144
  474. data/lib/sequel/adapters/do/mysql.rb +0 -66
  475. data/lib/sequel/adapters/do/postgres.rb +0 -44
  476. data/lib/sequel/adapters/do/sqlite3.rb +0 -42
  477. data/lib/sequel/adapters/do.rb +0 -158
  478. data/lib/sequel/adapters/jdbc/as400.rb +0 -84
  479. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -64
  480. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -36
  481. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -33
  482. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -33
  483. data/lib/sequel/adapters/odbc/progress.rb +0 -10
  484. data/lib/sequel/adapters/shared/cubrid.rb +0 -245
  485. data/lib/sequel/adapters/shared/firebird.rb +0 -247
  486. data/lib/sequel/adapters/shared/informix.rb +0 -54
  487. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -152
  488. data/lib/sequel/adapters/shared/progress.rb +0 -40
  489. data/lib/sequel/adapters/swift/mysql.rb +0 -49
  490. data/lib/sequel/adapters/swift/postgres.rb +0 -47
  491. data/lib/sequel/adapters/swift/sqlite.rb +0 -49
  492. data/lib/sequel/adapters/swift.rb +0 -160
  493. data/lib/sequel/adapters/utils/pg_types.rb +0 -70
  494. data/lib/sequel/dataset/mutation.rb +0 -111
  495. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -5
  496. data/lib/sequel/extensions/filter_having.rb +0 -63
  497. data/lib/sequel/extensions/hash_aliases.rb +0 -49
  498. data/lib/sequel/extensions/meta_def.rb +0 -35
  499. data/lib/sequel/extensions/query_literals.rb +0 -84
  500. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -24
  501. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -122
  502. data/lib/sequel/extensions/set_overrides.rb +0 -76
  503. data/lib/sequel/no_core_ext.rb +0 -3
  504. data/lib/sequel/plugins/association_autoreloading.rb +0 -9
  505. data/lib/sequel/plugins/identifier_columns.rb +0 -47
  506. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -9
  507. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -81
  508. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -119
  509. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -61
  510. data/lib/sequel/plugins/schema.rb +0 -82
  511. data/lib/sequel/plugins/scissors.rb +0 -35
  512. data/spec/adapter_spec.rb +0 -4
  513. data/spec/adapters/db2_spec.rb +0 -160
  514. data/spec/adapters/firebird_spec.rb +0 -411
  515. data/spec/adapters/informix_spec.rb +0 -100
  516. data/spec/adapters/mssql_spec.rb +0 -733
  517. data/spec/adapters/mysql_spec.rb +0 -1319
  518. data/spec/adapters/oracle_spec.rb +0 -313
  519. data/spec/adapters/postgres_spec.rb +0 -3790
  520. data/spec/adapters/spec_helper.rb +0 -49
  521. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  522. data/spec/adapters/sqlite_spec.rb +0 -688
  523. data/spec/bin_spec.rb +0 -258
  524. data/spec/core/connection_pool_spec.rb +0 -1045
  525. data/spec/core/database_spec.rb +0 -2636
  526. data/spec/core/dataset_spec.rb +0 -5175
  527. data/spec/core/deprecated_spec.rb +0 -70
  528. data/spec/core/expression_filters_spec.rb +0 -1247
  529. data/spec/core/mock_adapter_spec.rb +0 -464
  530. data/spec/core/object_graph_spec.rb +0 -303
  531. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  532. data/spec/core/schema_generator_spec.rb +0 -203
  533. data/spec/core/schema_spec.rb +0 -1676
  534. data/spec/core/spec_helper.rb +0 -34
  535. data/spec/core/version_spec.rb +0 -7
  536. data/spec/core_extensions_spec.rb +0 -699
  537. data/spec/core_model_spec.rb +0 -2
  538. data/spec/core_spec.rb +0 -1
  539. data/spec/extensions/accessed_columns_spec.rb +0 -51
  540. data/spec/extensions/active_model_spec.rb +0 -85
  541. data/spec/extensions/after_initialize_spec.rb +0 -24
  542. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  543. data/spec/extensions/association_dependencies_spec.rb +0 -117
  544. data/spec/extensions/association_pks_spec.rb +0 -405
  545. data/spec/extensions/association_proxies_spec.rb +0 -86
  546. data/spec/extensions/auto_validations_spec.rb +0 -192
  547. data/spec/extensions/before_after_save_spec.rb +0 -40
  548. data/spec/extensions/blacklist_security_spec.rb +0 -88
  549. data/spec/extensions/blank_spec.rb +0 -69
  550. data/spec/extensions/boolean_readers_spec.rb +0 -93
  551. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  552. data/spec/extensions/caching_spec.rb +0 -270
  553. data/spec/extensions/class_table_inheritance_spec.rb +0 -444
  554. data/spec/extensions/column_conflicts_spec.rb +0 -60
  555. data/spec/extensions/column_select_spec.rb +0 -108
  556. data/spec/extensions/columns_introspection_spec.rb +0 -91
  557. data/spec/extensions/composition_spec.rb +0 -242
  558. data/spec/extensions/connection_expiration_spec.rb +0 -121
  559. data/spec/extensions/connection_validator_spec.rb +0 -127
  560. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -288
  561. data/spec/extensions/constraint_validations_spec.rb +0 -389
  562. data/spec/extensions/core_refinements_spec.rb +0 -519
  563. data/spec/extensions/csv_serializer_spec.rb +0 -180
  564. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  565. data/spec/extensions/dataset_associations_spec.rb +0 -343
  566. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  567. data/spec/extensions/date_arithmetic_spec.rb +0 -167
  568. data/spec/extensions/defaults_setter_spec.rb +0 -102
  569. data/spec/extensions/delay_add_association_spec.rb +0 -74
  570. data/spec/extensions/dirty_spec.rb +0 -180
  571. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -110
  572. data/spec/extensions/eager_each_spec.rb +0 -66
  573. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  574. data/spec/extensions/error_splitter_spec.rb +0 -18
  575. data/spec/extensions/error_sql_spec.rb +0 -20
  576. data/spec/extensions/eval_inspect_spec.rb +0 -73
  577. data/spec/extensions/filter_having_spec.rb +0 -40
  578. data/spec/extensions/force_encoding_spec.rb +0 -114
  579. data/spec/extensions/from_block_spec.rb +0 -21
  580. data/spec/extensions/graph_each_spec.rb +0 -119
  581. data/spec/extensions/hash_aliases_spec.rb +0 -24
  582. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  583. data/spec/extensions/identifier_columns_spec.rb +0 -17
  584. data/spec/extensions/inflector_spec.rb +0 -183
  585. data/spec/extensions/input_transformer_spec.rb +0 -54
  586. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  587. data/spec/extensions/instance_filters_spec.rb +0 -79
  588. data/spec/extensions/instance_hooks_spec.rb +0 -276
  589. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  590. data/spec/extensions/json_serializer_spec.rb +0 -304
  591. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  592. data/spec/extensions/list_spec.rb +0 -278
  593. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  594. data/spec/extensions/many_through_many_spec.rb +0 -2172
  595. data/spec/extensions/meta_def_spec.rb +0 -21
  596. data/spec/extensions/migration_spec.rb +0 -728
  597. data/spec/extensions/modification_detection_spec.rb +0 -80
  598. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  599. data/spec/extensions/named_timezones_spec.rb +0 -108
  600. data/spec/extensions/nested_attributes_spec.rb +0 -697
  601. data/spec/extensions/no_auto_literal_strings_spec.rb +0 -65
  602. data/spec/extensions/null_dataset_spec.rb +0 -85
  603. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  604. data/spec/extensions/pagination_spec.rb +0 -118
  605. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  606. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  607. data/spec/extensions/pg_array_spec.rb +0 -390
  608. data/spec/extensions/pg_enum_spec.rb +0 -92
  609. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  610. data/spec/extensions/pg_hstore_spec.rb +0 -206
  611. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  612. data/spec/extensions/pg_inet_spec.rb +0 -52
  613. data/spec/extensions/pg_interval_spec.rb +0 -76
  614. data/spec/extensions/pg_json_ops_spec.rb +0 -275
  615. data/spec/extensions/pg_json_spec.rb +0 -218
  616. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  617. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  618. data/spec/extensions/pg_range_spec.rb +0 -473
  619. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  620. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  621. data/spec/extensions/pg_row_spec.rb +0 -360
  622. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  623. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  624. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  625. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  626. data/spec/extensions/prepared_statements_spec.rb +0 -103
  627. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  628. data/spec/extensions/pretty_table_spec.rb +0 -92
  629. data/spec/extensions/query_literals_spec.rb +0 -183
  630. data/spec/extensions/query_spec.rb +0 -102
  631. data/spec/extensions/rcte_tree_spec.rb +0 -392
  632. data/spec/extensions/round_timestamps_spec.rb +0 -43
  633. data/spec/extensions/schema_caching_spec.rb +0 -41
  634. data/spec/extensions/schema_dumper_spec.rb +0 -814
  635. data/spec/extensions/schema_spec.rb +0 -117
  636. data/spec/extensions/scissors_spec.rb +0 -26
  637. data/spec/extensions/select_remove_spec.rb +0 -38
  638. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  639. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  640. data/spec/extensions/serialization_spec.rb +0 -362
  641. data/spec/extensions/server_block_spec.rb +0 -90
  642. data/spec/extensions/server_logging_spec.rb +0 -45
  643. data/spec/extensions/set_overrides_spec.rb +0 -61
  644. data/spec/extensions/sharding_spec.rb +0 -198
  645. data/spec/extensions/shared_caching_spec.rb +0 -175
  646. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  647. data/spec/extensions/singular_table_names_spec.rb +0 -22
  648. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  649. data/spec/extensions/spec_helper.rb +0 -71
  650. data/spec/extensions/split_array_nil_spec.rb +0 -24
  651. data/spec/extensions/split_values_spec.rb +0 -22
  652. data/spec/extensions/sql_comments_spec.rb +0 -27
  653. data/spec/extensions/sql_expr_spec.rb +0 -60
  654. data/spec/extensions/static_cache_spec.rb +0 -361
  655. data/spec/extensions/string_agg_spec.rb +0 -85
  656. data/spec/extensions/string_date_time_spec.rb +0 -95
  657. data/spec/extensions/string_stripper_spec.rb +0 -68
  658. data/spec/extensions/subclasses_spec.rb +0 -66
  659. data/spec/extensions/subset_conditions_spec.rb +0 -38
  660. data/spec/extensions/table_select_spec.rb +0 -71
  661. data/spec/extensions/tactical_eager_loading_spec.rb +0 -136
  662. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  663. data/spec/extensions/timestamps_spec.rb +0 -175
  664. data/spec/extensions/to_dot_spec.rb +0 -154
  665. data/spec/extensions/touch_spec.rb +0 -203
  666. data/spec/extensions/tree_spec.rb +0 -274
  667. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  668. data/spec/extensions/unlimited_update_spec.rb +0 -20
  669. data/spec/extensions/update_or_create_spec.rb +0 -87
  670. data/spec/extensions/update_primary_key_spec.rb +0 -100
  671. data/spec/extensions/update_refresh_spec.rb +0 -53
  672. data/spec/extensions/uuid_spec.rb +0 -106
  673. data/spec/extensions/validate_associated_spec.rb +0 -52
  674. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  675. data/spec/extensions/validation_helpers_spec.rb +0 -554
  676. data/spec/extensions/xml_serializer_spec.rb +0 -207
  677. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  678. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  679. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  680. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  681. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  682. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  683. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  684. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  685. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  686. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  687. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  688. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  689. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  690. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  691. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  692. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  693. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  694. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  695. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  696. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  697. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  698. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  699. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  700. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  701. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  702. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  703. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  704. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  705. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  706. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  707. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  708. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  709. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  710. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  711. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  712. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  713. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  714. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  715. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  716. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  717. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  718. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  719. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  720. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  721. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  722. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  723. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  724. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  725. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  726. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  727. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  728. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  729. data/spec/guards_helper.rb +0 -55
  730. data/spec/integration/associations_test.rb +0 -2506
  731. data/spec/integration/database_test.rb +0 -113
  732. data/spec/integration/dataset_test.rb +0 -1858
  733. data/spec/integration/eager_loader_test.rb +0 -687
  734. data/spec/integration/migrator_test.rb +0 -262
  735. data/spec/integration/model_test.rb +0 -230
  736. data/spec/integration/plugin_test.rb +0 -2297
  737. data/spec/integration/prepared_statement_test.rb +0 -467
  738. data/spec/integration/schema_test.rb +0 -815
  739. data/spec/integration/spec_helper.rb +0 -56
  740. data/spec/integration/timezone_test.rb +0 -86
  741. data/spec/integration/transaction_test.rb +0 -406
  742. data/spec/integration/type_test.rb +0 -133
  743. data/spec/model/association_reflection_spec.rb +0 -565
  744. data/spec/model/associations_spec.rb +0 -4589
  745. data/spec/model/base_spec.rb +0 -759
  746. data/spec/model/class_dataset_methods_spec.rb +0 -150
  747. data/spec/model/dataset_methods_spec.rb +0 -149
  748. data/spec/model/eager_loading_spec.rb +0 -2197
  749. data/spec/model/hooks_spec.rb +0 -604
  750. data/spec/model/inflector_spec.rb +0 -26
  751. data/spec/model/model_spec.rb +0 -1097
  752. data/spec/model/plugins_spec.rb +0 -299
  753. data/spec/model/record_spec.rb +0 -2162
  754. data/spec/model/spec_helper.rb +0 -46
  755. data/spec/model/validations_spec.rb +0 -193
  756. data/spec/model_no_assoc_spec.rb +0 -1
  757. data/spec/model_spec.rb +0 -1
  758. data/spec/plugin_spec.rb +0 -1
  759. data/spec/sequel_coverage.rb +0 -15
  760. data/spec/spec_config.rb +0 -10
@@ -16,6 +16,24 @@ module Sequel
16
16
  #
17
17
  # # Make the Album class support validating associated objects
18
18
  # Album.plugin :validate_associated
19
+ #
20
+ # class Album
21
+ # many_to_one :artist
22
+ # many_to_many :tags
23
+ #
24
+ # # Always validate associated artist when saving the album
25
+ # def validate
26
+ # super
27
+ # if artist
28
+ # validate_associated_object(model.association_reflection(:artist), artist)
29
+ # end
30
+ # end
31
+ #
32
+ # # When saving after calling this method, validate the given tag as well.
33
+ # def check_tag!(tag)
34
+ # delay_validate_associated_object(model.association_reflection(:tags), tag)
35
+ # end
36
+ # end
19
37
  module ValidateAssociated
20
38
  # Depend on the instance_hooks plugin.
21
39
  def self.apply(mod)
@@ -1,8 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  module Sequel
4
- extension :blank
5
-
6
4
  module Plugins
7
5
  # Sequel's built-in validation_class_methods plugin adds backwards compatibility
8
6
  # for the legacy class-level validation methods (e.g. validates_presence_of :column).
@@ -11,7 +9,7 @@ module Sequel
11
9
  # as it is less complex and more flexible. However, this plugin provides reflection
12
10
  # support, since it is class-level, while the instance-level validation_helpers
13
11
  # plugin does not.
14
- #
12
+ #
15
13
  # Usage:
16
14
  #
17
15
  # # Add the validation class methods to all model subclasses (called before loading subclasses)
@@ -39,13 +37,26 @@ module Sequel
39
37
  # options.
40
38
  attr_reader :validation_reflections
41
39
 
40
+ # Freeze validation metadata when freezing model class.
41
+ def freeze
42
+ @validations.freeze.each_value(&:freeze)
43
+ @validation_reflections.freeze.each_value do |vs|
44
+ vs.freeze.each do |v|
45
+ v.freeze
46
+ v.last.freeze
47
+ end
48
+ end
49
+
50
+ super
51
+ end
52
+
42
53
  # The Generator class is used to generate validation definitions using
43
54
  # the validates {} idiom.
44
55
  class Generator
45
56
  # Initializes a new generator.
46
57
  def initialize(receiver ,&block)
47
58
  @receiver = receiver
48
- instance_eval(&block)
59
+ instance_exec(&block)
49
60
  end
50
61
 
51
62
  # Delegates method calls to the receiver by calling receiver.validates_xxx.
@@ -86,15 +97,16 @@ module Sequel
86
97
  #
87
98
  # class MyClass < Sequel::Model
88
99
  # validates do
89
- # length_of :name, :minimum => 6
90
- # length_of :password, :minimum => 8
100
+ # length_of :name, minimum: 6
101
+ # length_of :password, minimum: 8
91
102
  # end
92
103
  # end
93
104
  #
94
105
  # is equivalent to:
106
+ #
95
107
  # class MyClass < Sequel::Model
96
- # validates_length_of :name, :minimum => 6
97
- # validates_length_of :password, :minimum => 8
108
+ # validates_length_of :name, minimum: 6
109
+ # validates_length_of :password, minimum: 8
98
110
  # end
99
111
  def validates(&block)
100
112
  Generator.new(self, &block)
@@ -105,7 +117,7 @@ module Sequel
105
117
  validations.each do |att, procs|
106
118
  v = case att
107
119
  when Array
108
- att.collect{|a| o.get_column_value(a)}
120
+ att.map{|a| o.get_column_value(a)}
109
121
  else
110
122
  o.get_column_value(att)
111
123
  end
@@ -176,16 +188,25 @@ module Sequel
176
188
  # Sequel will attempt to insert a NULL value into the database, instead of using the
177
189
  # database's default.
178
190
  # :allow_nil :: Whether to skip the validation if the value is nil.
179
- # :if :: A symbol (indicating an instance_method) or proc (which is instance_evaled)
191
+ # :if :: A symbol (indicating an instance_method) or proc (which is used to define an instance method)
180
192
  # skipping this validation if it returns nil or false.
181
193
  # :tag :: The tag to use for this validation.
182
194
  def validates_each(*atts, &block)
183
195
  opts = extract_options!(atts)
184
- blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank])
196
+ blank_meth = db.method(:blank_object?).to_proc
197
+ i = opts[:if]
198
+ am = opts[:allow_missing]
199
+ an = opts[:allow_nil]
200
+ ab = opts[:allow_blank]
201
+ blk = if i || am || an || ab
202
+ if i.is_a?(Proc)
203
+ i = Plugins.def_sequel_method(self, "validation_class_methods_if", 0, &i)
204
+ end
205
+
185
206
  proc do |o,a,v|
186
207
  next if i && !validation_if_proc(o, i)
187
208
  next if an && Array(v).all?(&:nil?)
188
- next if ab && Array(v).all?(&:blank?)
209
+ next if ab && Array(v).all?(&blank_meth)
189
210
  next if am && Array(a).all?{|x| !o.values.has_key?(x)}
190
211
  block.call(o,a,v)
191
212
  end
@@ -261,7 +282,7 @@ module Sequel
261
282
  o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && v.size == i
262
283
  end
263
284
  if w = opts[:within]
264
- o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.send(w.respond_to?(:cover?) ? :cover? : :include?, v.size)
285
+ o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.public_send(w.respond_to?(:cover?) ? :cover? : :include?, v.size)
265
286
  end
266
287
  end
267
288
  end
@@ -304,7 +325,7 @@ module Sequel
304
325
  reflect_validation(:presence, opts, atts)
305
326
  atts << opts
306
327
  validates_each(*atts) do |o, a, v|
307
- o.errors.add(a, opts[:message]) if v.blank? && v != false
328
+ o.errors.add(a, opts[:message]) if db.send(:blank_object?, v) && v != false
308
329
  end
309
330
  end
310
331
 
@@ -323,7 +344,7 @@ module Sequel
323
344
  reflect_validation(:inclusion, opts, atts)
324
345
  atts << opts
325
346
  validates_each(*atts) do |o, a, v|
326
- o.errors.add(a, opts[:message]) unless n.send(n.respond_to?(:cover?) ? :cover? : :include?, v)
347
+ o.errors.add(a, opts[:message]) unless n.public_send(n.respond_to?(:cover?) ? :cover? : :include?, v)
327
348
  end
328
349
  end
329
350
 
@@ -378,7 +399,7 @@ module Sequel
378
399
  a = Array(a)
379
400
  v = Array(v)
380
401
  next if v.empty? || !v.all?
381
- ds = o.class.filter(a.zip(v))
402
+ ds = o.class.where(a.zip(v))
382
403
  num_dups = ds.count
383
404
  allow = if num_dups == 0
384
405
  # No unique value in the database
@@ -406,7 +427,7 @@ module Sequel
406
427
  # an empty hash is returned This method is useful when writing methods that
407
428
  # take an options hash as the last parameter.
408
429
  def extract_options!(array)
409
- array.last.is_a?(Hash) ? array.pop : {}
430
+ array.last.is_a?(Hash) ? array.pop : OPTS
410
431
  end
411
432
 
412
433
  # Add the validation reflection to the class's validations.
@@ -421,8 +442,6 @@ module Sequel
421
442
  case i
422
443
  when Symbol
423
444
  o.get_column_value(i)
424
- when Proc
425
- o.instance_eval(&i)
426
445
  else
427
446
  raise(::Sequel::Error, "invalid value for :if validation option")
428
447
  end
@@ -0,0 +1,49 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The validation_contexts plugin adds support for a validation_context method inside a validate
6
+ # method. You pass in the validation context to use via the :validation_context option to
7
+ # Sequel::Model#save && Sequel::Model#valid?:
8
+ #
9
+ # class Album < Sequel::Model
10
+ # plugin :validation_contexts
11
+ # def validate
12
+ # super
13
+ # errors.add(:status_id, 'not 1') if status_id != 1 && validation_context == :initial
14
+ # errors.add(:status_id, 'not 2') if status_id != 2 && validation_context == :approve
15
+ # end
16
+ # end
17
+ #
18
+ # Album.new(status_id: 1).valid?(validation_context: :initial) # => true
19
+ # Album.new(status_id: 2).valid?(validation_context: :initial) # => false
20
+ #
21
+ # Album.new(status_id: 1).valid?(validation_context: :approve) # => false
22
+ # Album.new(status_id: 2).valid?(validation_context: :approve) # => true
23
+ #
24
+ # There is no validation context used by default, so validation_context will be
25
+ # +nil+ if one is not specified. If you want to differentiate between creating new
26
+ # objects and updating existing objects, just use +new?+.
27
+ #
28
+ # Once this plugin is loaded into a model, after you freeze an instance
29
+ # of that model, you can no longer specify a validation context when
30
+ # validating the instance.
31
+ module ValidationContexts
32
+ module InstanceMethods
33
+ # The validation context to use for the current validation.
34
+ # Set via the :validation_context option passed to save/valid?.
35
+ attr_reader :validation_context
36
+
37
+ private
38
+
39
+ # Set validation context before running validations
40
+ def _valid?(opts)
41
+ @validation_context = opts[:validation_context] if opts[:validation_context]
42
+ super
43
+ ensure
44
+ @validation_context = nil if @validation_context
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Sequel
4
4
  module Plugins
5
- # The validation_helpers plugin contains instance method equivalents for most of the legacy
6
- # class-level validations. The names and APIs are different, though. Example:
5
+ # The validation_helpers plugin contains validate_* methods designed to be called inside Model#validate
6
+ # to perform validations:
7
7
  #
8
8
  # Sequel::Model.plugin :validation_helpers
9
9
  # class Album < Sequel::Model
@@ -19,9 +19,7 @@ module Sequel
19
19
  # atts :: Single attribute symbol or an array of attribute symbols specifying the
20
20
  # attribute(s) to validate.
21
21
  # Options:
22
- # :allow_blank :: Whether to skip the validation if the value is blank. You should
23
- # make sure all objects respond to blank if you use this option, which you can do by:
24
- # Sequel.extension :blank
22
+ # :allow_blank :: Whether to skip the validation if the value is blank.
25
23
  # :allow_missing :: Whether to skip the validation if the attribute isn't a key in the
26
24
  # values hash. This is different from allow_nil, because Sequel only sends the attributes
27
25
  # in the values when doing an insert or update. If the attribute is not present, Sequel
@@ -38,19 +36,27 @@ module Sequel
38
36
  # :message :: The message to use. Can be a string which is used directly, or a
39
37
  # proc which is called. If the validation method takes a argument before the array of attributes,
40
38
  # that argument is passed as an argument to the proc.
39
+ # :skip_invalid :: Do not try to validate columns that are already invalid.
41
40
  #
42
41
  # The default validation options for all models can be modified by
43
- # changing the values of the Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS hash. You
44
- # change change the default options on a per model basis
45
- # by overriding a private instance method default_validation_helpers_options.
46
- #
42
+ # overridding the Model#default_validation_helpers_options private method.
47
43
  # By changing the default options, you can setup internationalization of the
48
44
  # error messages. For example, you would modify the default options:
49
45
  #
50
- # Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS.merge!(
51
- # :exact_length=>{:message=>lambda{|exact| I18n.t("errors.exact_length", :exact => exact)}},
52
- # :integer=>{:message=>lambda{I18n.t("errors.integer")}}
53
- # )
46
+ # class Sequel::Model
47
+ # private
48
+ #
49
+ # def default_validation_helpers_options(type)
50
+ # case type
51
+ # when :exact_length
52
+ # {message: lambda{|exact| I18n.t("errors.exact_length", exact: exact)}}
53
+ # when :integer
54
+ # {message: lambda{I18n.t("errors.integer")}}
55
+ # else
56
+ # super
57
+ # end
58
+ # end
59
+ # end
54
60
  #
55
61
  # and then use something like this in your yaml translation file:
56
62
  #
@@ -60,23 +66,16 @@ module Sequel
60
66
  # integer: "is not a number"
61
67
  #
62
68
  # Note that if you want to support internationalization of Errors#full_messages,
63
- # you need to override the method. Here's an example:
69
+ # it is easiest to override Errors#full_message (note singular form and not plural form).
70
+ # Here's an example:
64
71
  #
65
72
  # class Sequel::Model::Errors
66
- # ATTRIBUTE_JOINER = I18n.t('errors.joiner').freeze
67
- # def full_messages
68
- # inject([]) do |m, kv|
69
- # att, errors = *kv
70
- # att.is_a?(Array) ? Array(att).map!{|v| I18n.t("attributes.#{v}")} : att = I18n.t("attributes.#{att}")
71
- # errors.each {|e| m << (e.is_a?(LiteralString) ? e : "#{Array(att).join(ATTRIBUTE_JOINER)} #{e}")}
72
- # m
73
- # end
73
+ # private
74
+ # def full_message(attribute, error_msg)
75
+ # "#{Array(attribute).join(I18n.t('errors.joiner'))} #{error_msg}"
74
76
  # end
75
77
  # end
76
78
  module ValidationHelpers
77
- # Default validation options used by Sequel. Can be modified to change the error
78
- # messages for all models (e.g. for internationalization), or to set certain
79
- # default options for validations (e.g. :allow_nil=>true for all validates_format).
80
79
  DEFAULT_OPTIONS = {
81
80
  :exact_length=>{:message=>lambda{|exact| "is not #{exact} characters"}},
82
81
  :format=>{:message=>lambda{|with| 'is invalid'}},
@@ -86,12 +85,14 @@ module Sequel
86
85
  :max_length=>{:message=>lambda{|max| "is longer than #{max} characters"}, :nil_message=>lambda{"is not present"}},
87
86
  :min_length=>{:message=>lambda{|min| "is shorter than #{min} characters"}},
88
87
  :not_null=>{:message=>lambda{"is not present"}},
88
+ :no_null_byte=>{:message=>lambda{"contains a null byte"}},
89
89
  :numeric=>{:message=>lambda{"is not a number"}},
90
90
  :operator=>{:message=>lambda{|operator, rhs| "is not #{operator} #{rhs}"}},
91
91
  :type=>{:message=>lambda{|klass| klass.is_a?(Array) ? "is not a valid #{klass.join(" or ").downcase}" : "is not a valid #{klass.to_s.downcase}"}},
92
92
  :presence=>{:message=>lambda{"is not present"}},
93
93
  :unique=>{:message=>lambda{'is already taken'}}
94
- }
94
+ }.freeze
95
+ DEFAULT_OPTIONS.each_value(&:freeze)
95
96
 
96
97
  module InstanceMethods
97
98
  # Check that the attribute values are the given exact length.
@@ -106,7 +107,7 @@ module Sequel
106
107
 
107
108
  # Check attribute value(s) is included in the given set.
108
109
  def validates_includes(set, atts, opts=OPTS)
109
- validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
110
+ validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
110
111
  end
111
112
 
112
113
  # Check attribute value(s) string representation is a valid integer.
@@ -123,7 +124,7 @@ module Sequel
123
124
 
124
125
  # Check that the attribute values length is in the specified range.
125
126
  def validates_length_range(range, atts, opts=OPTS)
126
- validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.send(range.respond_to?(:cover?) ? :cover? : :include?, v.length)}
127
+ validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.cover?(v.length)}
127
128
  end
128
129
 
129
130
  # Check that the attribute values are not longer than the given max length.
@@ -131,7 +132,13 @@ module Sequel
131
132
  # Accepts a :nil_message option that is the error message to use when the
132
133
  # value is nil instead of being too long.
133
134
  def validates_max_length(max, atts, opts=OPTS)
134
- validatable_attributes_for_type(:max_length, atts, opts){|a,v,m| v ? validation_error_message(m, max) : validation_error_message(opts[:nil_message] || DEFAULT_OPTIONS[:max_length][:nil_message]) if v.nil? || v.length > max}
135
+ validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m|
136
+ if v.nil?
137
+ validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message])
138
+ elsif v.length > max
139
+ validation_error_message(m, max)
140
+ end
141
+ end
135
142
  end
136
143
 
137
144
  # Check that the attribute values are not shorter than the given min length.
@@ -143,6 +150,11 @@ module Sequel
143
150
  def validates_not_null(atts, opts=OPTS)
144
151
  validatable_attributes_for_type(:not_null, atts, opts){|a,v,m| validation_error_message(m) if v.nil?}
145
152
  end
153
+
154
+ # Check attribute value(s) does not contain a null ("\0", ASCII NUL) byte.
155
+ def validates_no_null_byte(atts, opts=OPTS)
156
+ validatable_attributes_for_type(:no_null_byte, atts, opts){|a,v,m| validation_error_message(m) if String === v && v.include?("\0")}
157
+ end
146
158
 
147
159
  # Check attribute value(s) string representation is a valid float.
148
160
  def validates_numeric(atts, opts=OPTS)
@@ -159,7 +171,7 @@ module Sequel
159
171
  # Check attribute value(s) against a specified value and operation, e.g.
160
172
  # validates_operator(:>, 3, :value) validates that value > 3.
161
173
  def validates_operator(operator, rhs, atts, opts=OPTS)
162
- validatable_attributes_for_type(:operator, atts, opts){|a,v,m| validation_error_message(m, operator, rhs) if v.nil? || !v.send(operator, rhs)}
174
+ validatable_attributes_for_type(:operator, atts, opts){|a,v,m| validation_error_message(m, operator, rhs) if v.nil? || !v.public_send(operator, rhs)}
163
175
  end
164
176
 
165
177
  # Validates for all of the model columns (or just the given columns)
@@ -204,7 +216,7 @@ module Sequel
204
216
  # must be unique. So if you are doing a soft delete of records, in which
205
217
  # the name must be unique, but only for active records:
206
218
  #
207
- # validates_unique(:name){|ds| ds.filter(:active)}
219
+ # validates_unique(:name){|ds| ds.where(:active)}
208
220
  #
209
221
  # You should also add a unique index in the
210
222
  # database, as this suffers from a fairly obvious race condition.
@@ -217,7 +229,7 @@ module Sequel
217
229
  # model's dataset.
218
230
  # :message :: The message to use (default: 'is already taken')
219
231
  # :only_if_modified :: Only check the uniqueness if the object is new or
220
- # one of the columns has been modified.
232
+ # one of the columns has been modified, true by default.
221
233
  # :where :: A callable object where call takes three arguments, a dataset,
222
234
  # the current object, and an array of columns, and should return
223
235
  # a modified dataset that is filtered to include only rows with
@@ -226,9 +238,9 @@ module Sequel
226
238
  # If you want to do a case insensitive uniqueness validation on a database that
227
239
  # is case sensitive by default, you can use:
228
240
  #
229
- # validates_unique :column, :where=>(proc do |ds, obj, cols|
241
+ # validates_unique :column, where:(lambda do |ds, obj, cols|
230
242
  # ds.where(cols.map do |c|
231
- # v = obj.send(c)
243
+ # v = obj.public_send(c)
232
244
  # v = v.downcase if v
233
245
  # [Sequel.function(:lower, c), v]
234
246
  # end)
@@ -236,7 +248,7 @@ module Sequel
236
248
  def validates_unique(*atts)
237
249
  opts = default_validation_helpers_options(:unique)
238
250
  if atts.last.is_a?(Hash)
239
- opts = Hash[opts].merge!(atts.pop)
251
+ opts = opts.merge(atts.pop)
240
252
  end
241
253
  message = validation_error_message(opts[:message])
242
254
  from_values = opts[:from] == :values
@@ -244,7 +256,8 @@ module Sequel
244
256
  atts.each do |a|
245
257
  arr = Array(a)
246
258
  next if arr.any?{|x| errors.on(x)}
247
- next if opts[:only_if_modified] && !new? && !arr.any?{|x| changed_columns.include?(x)}
259
+ cc = changed_columns
260
+ next if opts.fetch(:only_if_modified, true) && !new? && !arr.any?{|x| cc.include?(x)}
248
261
  ds = opts[:dataset] || model.dataset
249
262
  ds = if where
250
263
  where.call(ds, self, arr)
@@ -253,7 +266,7 @@ module Sequel
253
266
  next if vals.any?(&:nil?)
254
267
  ds.where(arr.zip(vals))
255
268
  end
256
- ds = yield(ds) if block_given?
269
+ ds = yield(ds) if defined?(yield)
257
270
  unless new?
258
271
  h = ds.joined_dataset? ? qualified_pk_hash : pk_hash
259
272
  ds = ds.exclude(h)
@@ -272,18 +285,21 @@ module Sequel
272
285
  DEFAULT_OPTIONS[type]
273
286
  end
274
287
 
275
- # Skip validating any attribute that matches one of the allow_* options.
288
+ # Skip validating any attribute that matches one of the allow_* options,
289
+ # or already has an error if the skip_invalid option is given.
290
+ #
276
291
  # Otherwise, yield the attribute, value, and passed option :message to
277
292
  # the block. If the block returns anything except nil or false, add it as
278
293
  # an error message for that attributes.
279
294
  def validatable_attributes(atts, opts)
280
- am, an, ab, m = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message)
295
+ am, an, ab, m, si = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message, :skip_invalid)
281
296
  from_values = opts[:from] == :values
282
297
  Array(atts).each do |a|
298
+ next if si && errors.on(a)
283
299
  next if am && !values.has_key?(a)
284
300
  v = from_values ? values[a] : get_column_value(a)
285
301
  next if an && v.nil?
286
- next if ab && v.respond_to?(:blank?) && v.blank?
302
+ next if ab && model.db.send(:blank_object?, v)
287
303
  if message = yield(a, v, m)
288
304
  errors.add(a, message)
289
305
  end
@@ -293,7 +309,7 @@ module Sequel
293
309
  # Merge the given options with the default options for the given type
294
310
  # and call validatable_attributes with the merged options.
295
311
  def validatable_attributes_for_type(type, atts, opts, &block)
296
- validatable_attributes(atts, Hash[default_validation_helpers_options(type)].merge!(opts), &block)
312
+ validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block)
297
313
  end
298
314
 
299
315
  # The validation error message to use, as a string. If message
@@ -0,0 +1,122 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The whitelist_security plugin contains whitelist-based support for
6
+ # mass assignment, explicitly specifying which columns to allow mass assignment for,
7
+ # disallowing mass assignment for columns not listed. This exists mostly for backwards
8
+ # compatibility, it's best to use Sequel::Model#set_fields and Sequel::Model#update_fields
9
+ # to decide which fields to allow on a per-call basis.
10
+ #
11
+ # Usage:
12
+ #
13
+ # # Make all model subclasses support allowed_columns
14
+ # Sequel::Model.plugin :whitelist_security
15
+ #
16
+ # # Make the Album class support allowed_columns
17
+ # Album.plugin :whitelist_security
18
+ module WhitelistSecurity
19
+ module ClassMethods
20
+ # Which columns should be the only columns allowed in a call to a mass assignment method (e.g. set)
21
+ # (default: not set, so all columns not otherwise restricted are allowed).
22
+ attr_reader :allowed_columns
23
+
24
+ Plugins.inherited_instance_variables(self, :@allowed_columns=>:dup)
25
+
26
+ # Freeze allowed columns when freezing model class.
27
+ def freeze
28
+ @allowed_columns.freeze
29
+ super
30
+ end
31
+
32
+ # Set the columns to allow when using mass assignment (e.g. +set+). Using this means that
33
+ # any columns not listed here will not be modified. If you have any virtual
34
+ # setter methods (methods that end in =) that you want to be used during
35
+ # mass assignment, they need to be listed here as well (without the =).
36
+ #
37
+ # It may be better to use +set_fields+ which lets you specify
38
+ # the allowed fields per call.
39
+ #
40
+ # Artist.set_allowed_columns(:name, :hometown)
41
+ # Artist.set(name: 'Bob', hometown: 'Sactown') # No Error
42
+ # Artist.set(name: 'Bob', records_sold: 30000) # Error
43
+ def set_allowed_columns(*cols)
44
+ clear_setter_methods_cache
45
+ @allowed_columns = cols
46
+ end
47
+
48
+ private
49
+
50
+ # If allowed_columns is set, only allow those columns.
51
+ def get_setter_methods
52
+ if allowed_columns
53
+ allowed_columns.map{|x| "#{x}="}
54
+ else
55
+ super
56
+ end
57
+ end
58
+ end
59
+
60
+ module InstanceMethods
61
+ # Set all values using the entries in the hash, ignoring any setting of
62
+ # allowed_columns in the model.
63
+ #
64
+ # Artist.set_allowed_columns(:num_albums)
65
+ # artist.set_all(name: 'Jim')
66
+ # artist.name # => 'Jim'
67
+ def set_all(hash)
68
+ set_restricted(hash, :all)
69
+ end
70
+
71
+ # Set the values using the entries in the hash, only if the key
72
+ # is included in only. It may be a better idea to use +set_fields+
73
+ # instead of this method.
74
+ #
75
+ # artist.set_only({name: 'Jim'}, :name)
76
+ # artist.name # => 'Jim'
77
+ #
78
+ # artist.set_only({hometown: 'LA'}, :name) # Raise Error
79
+ def set_only(hash, *only)
80
+ set_restricted(hash, only.flatten)
81
+ end
82
+
83
+ # Update all values using the entries in the hash, ignoring any setting of
84
+ # +allowed_columns+ in the model.
85
+ #
86
+ # Artist.set_allowed_columns(:num_albums)
87
+ # artist.update_all(name: 'Jim') # UPDATE artists SET name = 'Jim' WHERE (id = 1)
88
+ def update_all(hash)
89
+ update_restricted(hash, :all)
90
+ end
91
+
92
+ # Update the values using the entries in the hash, only if the key
93
+ # is included in only. It may be a better idea to use +update_fields+
94
+ # instead of this method.
95
+ #
96
+ # artist.update_only({name: 'Jim'}, :name)
97
+ # # UPDATE artists SET name = 'Jim' WHERE (id = 1)
98
+ #
99
+ # artist.update_only({hometown: 'LA'}, :name) # Raise Error
100
+ def update_only(hash, *only)
101
+ update_restricted(hash, only.flatten)
102
+ end
103
+
104
+ private
105
+
106
+ # If allowed_columns is set and set/update is called, only allow those columns.
107
+ def setter_methods(type)
108
+ if type == :default && model.allowed_columns
109
+ model.setter_methods
110
+ elsif type.is_a?(Array)
111
+ type.map{|x| "#{x}="}
112
+ elsif type == :all && primary_key && model.restrict_primary_key?
113
+ super + Array(primary_key).map{|x| "#{x}="}
114
+ else
115
+ super
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+