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
@@ -1,42 +1,35 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- if RUBY_VERSION < "1.9"
4
- # :nocov:
5
- require 'fastercsv'
6
- # :nocov:
7
- else
8
- require 'csv'
9
- end
3
+ require 'csv'
10
4
 
11
5
  module Sequel
12
6
  module Plugins
13
7
  # csv_serializer handles serializing entire Sequel::Model objects to CSV,
14
8
  # as well as support for deserializing CSV directly into Sequel::Model
15
- # objects. It requires either the csv standard library when usnig ruby 1.9+,
16
- # or the fastercsv gem when using ruby 1.8.
9
+ # objects. It requires the csv standard library.
17
10
  #
18
11
  # Basic Example:
19
12
  #
20
13
  # album = Album[1]
21
- # album.to_csv(:write_headers=>true)
14
+ # album.to_csv(write_headers: true)
22
15
  # # => "id,name,artist_id\n1,RF,2\n"
23
16
  #
24
17
  # You can provide options to control the CSV output:
25
18
  #
26
- # album.to_csv(:only=>:name)
27
- # album.to_csv(:except=>[:id, :artist_id])
19
+ # album.to_csv(only: :name)
20
+ # album.to_csv(except: [:id, :artist_id])
28
21
  # # => "RF\n"
29
22
  #
30
23
  # +to_csv+ also exists as a class and dataset method, both of which return
31
24
  # all objects in the dataset:
32
25
  #
33
26
  # Album.to_csv
34
- # Album.filter(:artist_id=>1).to_csv
27
+ # Album.where(artist_id: 1).to_csv
35
28
  #
36
- # If you have an existing array of model instance you want to convert to
29
+ # If you have an existing array of model instances you want to convert to
37
30
  # CSV, you can call the class to_csv method with the :array option:
38
31
  #
39
- # Album.to_csv(:array=>[Album[1], Album[2]])
32
+ # Album.to_csv(array: [Album[1], Album[2]])
40
33
  #
41
34
  # In addition to creating CSV, this plugin also enables Sequel::Model
42
35
  # classes to create instances directly from CSV using the from_csv class
@@ -48,7 +41,7 @@ module Sequel
48
41
  # The array_from_csv class method exists to parse arrays of model instances
49
42
  # from CSV:
50
43
  #
51
- # csv = Album.filter(:artist_id=>1).to_csv
44
+ # csv = Album.where(artist_id: 1).to_csv
52
45
  # albums = Album.array_from_csv(csv)
53
46
  #
54
47
  # These do not necessarily round trip, since doing so would let users
@@ -56,7 +49,7 @@ module Sequel
56
49
  # call set with the values in the hash. If you want to specify the allowed
57
50
  # fields, you can use the :headers option.
58
51
  #
59
- # Album.from_csv(album.to_csv, :headers=>%w'id name')
52
+ # Album.from_csv(album.to_csv, headers: %w'id name')
60
53
  #
61
54
  # If you want to update an existing instance, you can use the from_csv
62
55
  # instance method:
@@ -72,14 +65,30 @@ module Sequel
72
65
  # # Add CSV output capability to Album class instances
73
66
  # Album.plugin :csv_serializer
74
67
  module CsvSerializer
75
- CSV = Object.const_defined?(:CSV) ? ::CSV : ::FasterCSV
76
-
77
68
  # Set up the column readers to do deserialization and the column writers
78
69
  # to save the value in deserialized_values
79
- def self.configure(model, opts = {})
80
- model.instance_eval do
81
- @csv_serializer_opts = (@csv_serializer_opts || {}).merge(opts)
70
+ def self.configure(model, opts = OPTS)
71
+ model.instance_exec do
72
+ @csv_serializer_opts = (@csv_serializer_opts || OPTS).merge(opts)
73
+ end
74
+ end
75
+
76
+ # Avoid keyword argument separation warnings on Ruby 2.7, while still
77
+ # being compatible with 1.9.
78
+ if RUBY_VERSION >= "2.0"
79
+ instance_eval(<<-END, __FILE__, __LINE__+1)
80
+ def self.csv_call(*args, opts, &block)
81
+ CSV.send(*args, **opts, &block)
82
+ end
83
+ END
84
+ else
85
+ # :nocov:
86
+ # :nodoc:
87
+ def self.csv_call(*args, opts, &block)
88
+ CSV.send(*args, opts, &block)
82
89
  end
90
+ # :nodoc:
91
+ # :nocov:
83
92
  end
84
93
 
85
94
  module ClassMethods
@@ -87,26 +96,36 @@ module Sequel
87
96
  attr_reader :csv_serializer_opts
88
97
 
89
98
  # Attempt to parse an array of instances from the given CSV string
90
- def array_from_csv(csv, opts = {})
91
- CSV.parse(csv, process_csv_serializer_opts(opts)).map do |row|
99
+ def array_from_csv(csv, opts = OPTS)
100
+ CsvSerializer.csv_call(:parse, csv, process_csv_serializer_opts(opts)).map do |row|
92
101
  row = row.to_hash
93
102
  row.delete(nil)
94
103
  new(row)
95
104
  end
96
105
  end
97
106
 
107
+ # Freeze csv serializier opts when freezing model class
108
+ def freeze
109
+ @csv_serializer_opts.freeze.each_value do |v|
110
+ v.freeze if v.is_a?(Array) || v.is_a?(Hash)
111
+ end
112
+
113
+ super
114
+ end
115
+
98
116
  # Attempt to parse a single instance from the given CSV string
99
- def from_csv(csv, opts = {})
117
+ def from_csv(csv, opts = OPTS)
100
118
  new.from_csv(csv, opts)
101
119
  end
102
120
 
103
121
  # Convert the options hash to one that can be passed to CSV.
104
122
  def process_csv_serializer_opts(opts)
105
- opts = (csv_serializer_opts || {}).merge(opts)
123
+ opts = (csv_serializer_opts || OPTS).merge(opts)
106
124
  opts_cols = opts.delete(:columns)
107
125
  opts_include = opts.delete(:include)
108
126
  opts_except = opts.delete(:except)
109
- opts[:headers] ||= Array(opts.delete(:only) || opts_cols || columns) + Array(opts_include) - Array(opts_except)
127
+ only = opts.delete(:only)
128
+ opts[:headers] ||= Array(only || opts_cols || columns) + Array(opts_include) - Array(opts_except)
110
129
  opts
111
130
  end
112
131
 
@@ -127,8 +146,8 @@ module Sequel
127
146
  #
128
147
  # :headers :: The headers to use for the CSV line. Use nil for a header
129
148
  # to specify the column should be ignored.
130
- def from_csv(csv, opts = {})
131
- row = CSV.parse_line(csv, model.process_csv_serializer_opts(opts)).to_hash
149
+ def from_csv(csv, opts = OPTS)
150
+ row = CsvSerializer.csv_call(:parse_line, csv, model.process_csv_serializer_opts(opts)).to_hash
132
151
  row.delete(nil)
133
152
  set(row)
134
153
  end
@@ -142,11 +161,12 @@ module Sequel
142
161
  # output, ignoring all other columns
143
162
  # :include :: Symbol or Array of Symbols specifying non-column
144
163
  # attributes to include in the CSV output.
145
- def to_csv(opts = {})
164
+ def to_csv(opts = OPTS)
146
165
  opts = model.process_csv_serializer_opts(opts)
166
+ headers = opts[:headers]
147
167
 
148
- CSV.generate(opts) do |csv|
149
- csv << opts[:headers].map{|k| send(k)}
168
+ CsvSerializer.csv_call(:generate, model.process_csv_serializer_opts(opts)) do |csv|
169
+ csv << headers.map{|k| public_send(k)}
150
170
  end
151
171
  end
152
172
  end
@@ -159,13 +179,14 @@ module Sequel
159
179
  #
160
180
  # :array :: An array of instances. If this is not provided, calls #all
161
181
  # on the receiver to get the array.
162
- def to_csv(opts = {})
182
+ def to_csv(opts = OPTS)
163
183
  opts = model.process_csv_serializer_opts({:columns=>columns}.merge!(opts))
164
184
  items = opts.delete(:array) || self
185
+ headers = opts[:headers]
165
186
 
166
- CSV.generate(opts) do |csv|
187
+ CsvSerializer.csv_call(:generate, opts) do |csv|
167
188
  items.each do |object|
168
- csv << opts[:headers].map{|header| object.send(header) }
189
+ csv << headers.map{|header| object.public_send(header)}
169
190
  end
170
191
  end
171
192
  end
@@ -12,7 +12,7 @@ module Sequel
12
12
  # plugin :dataset_associations
13
13
  # one_to_many :albums
14
14
  # end
15
- # Artist.filter(id=>1..100).albums
15
+ # Artist.where(id: 1..100).albums
16
16
  # # SELECT * FROM albums
17
17
  # # WHERE (albums.artist_id IN (
18
18
  # # SELECT id FROM artists
@@ -27,7 +27,7 @@ module Sequel
27
27
  # As the dataset methods return datasets, you can easily chain the
28
28
  # methods to get associated datasets of associated datasets:
29
29
  #
30
- # Artist.filter(id=>1..100).albums.filter{name < 'M'}.tags
30
+ # Artist.where(id: 1..100).albums.where{name < 'M'}.tags
31
31
  # # SELECT tags.* FROM tags
32
32
  # # WHERE (tags.id IN (
33
33
  # # SELECT albums_tags.tag_id FROM albums
@@ -62,7 +62,10 @@ module Sequel
62
62
  ret = super
63
63
  r = association_reflection(name)
64
64
  meth = r.returns_array? ? name : pluralize(name).to_sym
65
- def_dataset_method(meth){associated(name)}
65
+ dataset_module do
66
+ define_method(meth){associated(name)}
67
+ alias_method(meth, meth)
68
+ end
66
69
  ret
67
70
  end
68
71
 
@@ -83,29 +86,49 @@ module Sequel
83
86
  sds = opts[:limit] ? self : unordered
84
87
  ds = case r[:type]
85
88
  when :many_to_one
86
- ds.filter(r.qualified_primary_key=>sds.select(*Array(r[:qualified_key])))
89
+ ds.where(r.qualified_primary_key=>sds.select(*Array(r[:qualified_key])))
87
90
  when :one_to_one, :one_to_many
88
- r.send(:apply_filter_by_associations_limit_strategy, ds.filter(r.qualified_key=>sds.select(*Array(r.qualified_primary_key))))
91
+ r.send(:apply_filter_by_associations_limit_strategy, ds.where(r.qualified_key=>sds.select(*Array(r.qualified_primary_key))))
89
92
  when :many_to_many, :one_through_one
90
93
  mds = r.associated_class.dataset.
91
94
  join(r[:join_table], r[:right_keys].zip(r.right_primary_keys)).
92
95
  select(*Array(r.qualified_right_key)).
93
96
  where(r.qualify(r.join_table_alias, r[:left_keys])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
94
- ds.filter(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
97
+ ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
95
98
  when :many_through_many, :one_through_many
96
- fre = r.reverse_edges.first
97
- fe, *edges = r.edges
98
- edges << r.final_edge
99
- mds = model.
100
- select(*Array(r.qualify(fre[:table], fre[:left]))).
101
- join(fe[:table], Array(fe[:right]).zip(Array(fe[:left])), :implicit_qualifier=>model.table_name).
102
- where(r.qualify(fe[:table], fe[:right])=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
103
- edges.each{|e| mds = mds.join(e[:table], Array(e[:right]).zip(Array(e[:left])))}
104
- ds.filter(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
99
+ if r.reverse_edges.empty?
100
+ mds = r.associated_dataset
101
+ fe = r.edges.first
102
+ selection = Array(r.qualify(fe[:table], r.final_edge[:left]))
103
+ predicate_key = r.qualify(fe[:table], fe[:right])
104
+ else
105
+ mds = model.dataset
106
+ iq = model.table_name
107
+ edges = r.edges.map(&:dup)
108
+ edges << r.final_edge.dup
109
+ edges.each do |e|
110
+ alias_expr = e[:table]
111
+ aliaz = mds.unused_table_alias(e[:table])
112
+ unless aliaz == alias_expr
113
+ alias_expr = Sequel.as(e[:table], aliaz)
114
+ end
115
+ e[:alias] = aliaz
116
+ mds = mds.join(alias_expr, Array(e[:right]).zip(Array(e[:left])), :implicit_qualifier=>iq)
117
+ iq = nil
118
+ end
119
+ fe, f1e, f2e = edges.values_at(0, -1, -2)
120
+ selection = Array(r.qualify(f2e[:alias], f1e[:left]))
121
+ predicate_key = r.qualify(fe[:alias], fe[:right])
122
+ end
123
+
124
+ mds = mds.
125
+ select(*selection).
126
+ where(predicate_key=>sds.select(*r.qualify(model.table_name, r[:left_primary_key_columns])))
127
+ ds.where(r.qualified_right_primary_key=>r.send(:apply_filter_by_associations_limit_strategy, mds))
105
128
  when :pg_array_to_many
106
- ds.filter(Sequel.expr(r.primary_key=>sds.select{Sequel.pg_array_op(r.qualify(r[:model].table_name, r[:key])).unnest}))
129
+ ds.where(Sequel[r.primary_key=>sds.select{Sequel.pg_array_op(r.qualify(r[:model].table_name, r[:key])).unnest}])
107
130
  when :many_to_pg_array
108
- ds.filter(Sequel.function(:coalesce, Sequel.pg_array_op(r[:key]).overlaps(sds.select{array_agg(r.qualify(r[:model].table_name, r.primary_key))}), false))
131
+ ds.where(Sequel.function(:coalesce, Sequel.pg_array_op(r[:key]).overlaps(sds.select{array_agg(r.qualify(r[:model].table_name, r.primary_key))}), false))
109
132
  else
110
133
  raise Error, "unrecognized association type for association #{name.inspect}: #{r[:type].inspect}"
111
134
  end
@@ -0,0 +1,90 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The def_dataset_method plugin adds Model.def_dataset_method
6
+ # for defining dataset methods:
7
+ #
8
+ # Album.def_dataset_method(:by_name) do |name|
9
+ # where(name: name)
10
+ # end
11
+ #
12
+ # Additionally, this adds support for Model.subset, which can also
13
+ # be used to define dataset methods that add specific filters:
14
+ #
15
+ # Album.subset(:gold){copies_sold >= 500000}
16
+ #
17
+ # This exists for backwards compatibility with previous Sequel versions.
18
+ #
19
+ # Usage:
20
+ #
21
+ # # Make all model subclasses support Model.def_dataset_method
22
+ # # (called before loading subclasses)
23
+ # Sequel::Model.plugin :def_dataset_method
24
+ #
25
+ # # Make the Album class support Model.def_dataset_method
26
+ # Album.plugin :def_dataset_method
27
+ module DefDatasetMethod
28
+ module ClassMethods
29
+ # If a block is given, define a method on the dataset (if the model currently has an dataset) with the given argument name using
30
+ # the given block. Also define a class method on the model that calls the
31
+ # dataset method. Stores the method name and block so that it can be reapplied if the model's
32
+ # dataset changes.
33
+ #
34
+ # If a block is not given, just define a class method on the model for each argument
35
+ # that calls the dataset method of the same argument name.
36
+ #
37
+ # Using dataset_module is recommended over using this method. In addition to allowing
38
+ # more natural ruby syntax for defining methods manually, it also offers numerous
39
+ # helper methods that make defining common dataset methods more easily, as well as
40
+ # supporting dataset caching (assuming the arguments allow it).
41
+ #
42
+ # # Add new dataset method and class method that calls it
43
+ # Artist.def_dataset_method(:by_name){order(:name)}
44
+ # Artist.where(Sequel[:name].like('A%')).by_name
45
+ # Artist.by_name.where(Sequel[:name].like('A%'))
46
+ #
47
+ # # Just add a class method that calls an existing dataset method
48
+ # Artist.def_dataset_method(:paginate)
49
+ # Artist.paginate(2, 10)
50
+ def def_dataset_method(*args, &block)
51
+ raise(Error, "No arguments given") if args.empty?
52
+
53
+ if block
54
+ raise(Error, "Defining a dataset method using a block requires only one argument") if args.length > 1
55
+ dataset_module{define_method(args.first, &block)}
56
+ else
57
+ args.each{|arg| def_model_dataset_method(arg)}
58
+ end
59
+ end
60
+
61
+ # Sets up a dataset method that returns a filtered dataset.
62
+ # Sometimes thought of as a scope, and like most dataset methods,
63
+ # they can be chained.
64
+ # For example:
65
+ #
66
+ # Topic.subset(:joes, Sequel[:username].like('%joe%'))
67
+ # Topic.subset(:popular){num_posts > 100}
68
+ # Topic.subset(:recent){created_on > Date.today - 7}
69
+ #
70
+ # Allows you to do:
71
+ #
72
+ # Topic.joes.recent.popular
73
+ #
74
+ # to get topics with a username that includes joe that
75
+ # have more than 100 posts and were created less than
76
+ # 7 days ago.
77
+ #
78
+ # Both the args given and the block are passed to <tt>Dataset#where</tt>.
79
+ #
80
+ # This method creates dataset methods that do not accept arguments. To create
81
+ # dataset methods that accept arguments, you should use define a
82
+ # method directly inside a #dataset_module block.
83
+ def subset(*args, &block)
84
+ dataset_module{subset(*args, &block)}
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
@@ -10,9 +10,37 @@ module Sequel
10
10
  # album = Album.new
11
11
  # album.a # => nil
12
12
  # album.b # => 2
13
- # album = Album.new(:a=>1, :b=>3)
13
+ # album = Album.new(a: 1, b: 3)
14
14
  # album.a # => 1
15
15
  # album.b # => 3
16
+ #
17
+ # You can manually set default values as well:
18
+ #
19
+ # Album.default_values[:a] = 4
20
+ # Album.new.a # => 4
21
+ #
22
+ # You can also provide procs to set default values:
23
+ #
24
+ # Album.default_values[:a] = lambda{Date.today}
25
+ # Album.new.a # => Date.today
26
+ #
27
+ # By default, default values returned are not cached:
28
+ #
29
+ # Album.new.a.equal?(Album.new.a) # => false
30
+ #
31
+ # However, you can turn on caching of default values:
32
+ #
33
+ # Album.plugin :defaults_setter, cache: true
34
+ # Album.new.a.equal?(Album.new.a) # => false
35
+ #
36
+ # Note that if the cache is turned on, the cached values are stored in
37
+ # the values hash:
38
+ #
39
+ # Album.plugin :defaults_setter, cache: true
40
+ # album = Album.new
41
+ # album.values # => {}
42
+ # album.a
43
+ # album.values # => {:a => Date.today}
16
44
  #
17
45
  # Usage:
18
46
  #
@@ -22,27 +50,52 @@ module Sequel
22
50
  # # Make the Album class set defaults
23
51
  # Album.plugin :defaults_setter
24
52
  module DefaultsSetter
25
- # Set the default values based on the model schema
26
- def self.configure(model)
27
- model.send(:set_default_values)
53
+ # Set the default values based on the model schema. Options:
54
+ # :cache :: Cache default values returned in the model's values hash.
55
+ def self.configure(model, opts=OPTS)
56
+ model.instance_exec do
57
+ set_default_values
58
+ @cache_default_values = opts[:cache] if opts.has_key?(:cache)
59
+ end
28
60
  end
29
61
 
30
62
  module ClassMethods
31
- # The default values to set in initialize for this model. A hash with column symbol
63
+ # The default values to use for this model. A hash with column symbol
32
64
  # keys and default values. If the default values respond to +call+, it will be called
33
65
  # to get the value, otherwise the value will be used directly. You can manually modify
34
66
  # this hash to set specific default values, by default the ones will be parsed from the database.
35
67
  attr_reader :default_values
36
-
68
+
37
69
  Plugins.after_set_dataset(self, :set_default_values)
38
70
 
71
+ Plugins.inherited_instance_variables(self, :@default_values=>:dup, :@cache_default_values=>nil)
72
+
73
+ # Whether default values should be cached in the values hash after being retrieved.
74
+ def cache_default_values?
75
+ @cache_default_values
76
+ end
77
+
78
+ # Freeze default values when freezing model class
79
+ def freeze
80
+ @default_values.freeze
81
+ super
82
+ end
83
+
39
84
  private
40
85
 
41
86
  # Parse the cached database schema for this model and set the default values appropriately.
42
87
  def set_default_values
43
88
  h = {}
44
- @db_schema.each{|k, v| h[k] = convert_default_value(v[:ruby_default]) unless v[:ruby_default].nil?} if @db_schema
45
- @default_values = h
89
+ if @db_schema
90
+ @db_schema.each do |k, v|
91
+ if v[:callable_default]
92
+ h[k] = v[:callable_default]
93
+ elsif !v[:ruby_default].nil?
94
+ h[k] = convert_default_value(v[:ruby_default])
95
+ end
96
+ end
97
+ end
98
+ @default_values = h.merge!(@default_values || OPTS)
46
99
  end
47
100
 
48
101
  # Handle the CURRENT_DATE and CURRENT_TIMESTAMP values specially by returning an appropriate Date or
@@ -63,8 +116,10 @@ module Sequel
63
116
  # Use default value for a new record if values doesn't already contain an entry for it.
64
117
  def [](k)
65
118
  if new? && !values.has_key?(k)
66
- v = model.default_values[k]
67
- v.respond_to?(:call) ? v.call : v
119
+ v = model.default_values.fetch(k){return}
120
+ v = v.call if v.respond_to?(:call)
121
+ values[k] = v if model.cache_default_values?
122
+ v
68
123
  else
69
124
  super
70
125
  end
@@ -40,7 +40,7 @@ module Sequel
40
40
  if opts.dataset_need_primary_key? && new?
41
41
  o = make_add_associated_object(opts, o)
42
42
  delay_validate_associated_object(opts, o)
43
- send(opts[:name]) << o
43
+ public_send(opts[:name]) << o
44
44
  after_create_hook{super(opts, o, *args)}
45
45
  o
46
46
  else
@@ -41,6 +41,15 @@ module Sequel
41
41
  # artist.column_changes # => {}
42
42
  # artist.previous_changes # => {:name=>['Foo', 'Bar']}
43
43
  #
44
+ # artist.column_previously_was(:name)
45
+ # # => 'Foo'
46
+ # artist.column_previously_changed?(:name)
47
+ # # => true
48
+ # artist.column_previously_changed?(:name, from: 'Foo', to: 'Bar')
49
+ # # => true
50
+ # artist.column_previously_changed?(:name, from: 'Foo', to: 'Baz')
51
+ # # => false
52
+ #
44
53
  # There is one caveat; when used with a column that also uses the
45
54
  # serialization plugin, setting the column back to its original value
46
55
  # after changing it is not correctly detected and will leave an entry
@@ -61,6 +70,19 @@ module Sequel
61
70
  # that were used in the update statement.
62
71
  attr_reader :previous_changes
63
72
 
73
+ # Reset the initial values after saving.
74
+ def after_save
75
+ super
76
+ reset_initial_values
77
+ end
78
+
79
+ # Save the current changes so they are available after updating. This happens
80
+ # before after_save resets them.
81
+ def after_update
82
+ super
83
+ @previous_changes = column_changes
84
+ end
85
+
64
86
  # An array with the initial value and the current value
65
87
  # of the column, if the column has been changed. If the
66
88
  # column has not been changed, returns nil.
@@ -92,6 +114,41 @@ module Sequel
92
114
  initial_values.has_key?(column)
93
115
  end
94
116
 
117
+ # Whether the column was previously changed.
118
+ # Options:
119
+ # :from :: If given, the previous initial value of the column must match this
120
+ # :to :: If given, the previous changed value of the column must match this
121
+ #
122
+ # update(name: 'Current')
123
+ # previous_changes # => {:name=>['Initial', 'Current']}
124
+ # column_previously_changed?(:name) # => true
125
+ # column_previously_changed?(:id) # => false
126
+ # column_previously_changed?(:name, from: 'Initial', to: 'Current') # => true
127
+ # column_previously_changed?(:name, from: 'Foo', to: 'Current') # => false
128
+ def column_previously_changed?(column, opts=OPTS)
129
+ return false unless (pc = @previous_changes) && (val = pc[column])
130
+
131
+ if opts.has_key?(:from)
132
+ return false unless val[0] == opts[:from]
133
+ end
134
+
135
+ if opts.has_key?(:to)
136
+ return false unless val[1] == opts[:to]
137
+ end
138
+
139
+ true
140
+ end
141
+
142
+ # The previous value of the column, which is the initial value of
143
+ # the column before the object was previously saved.
144
+ #
145
+ # initial_value(:name) # => 'Initial'
146
+ # update(name: 'Current')
147
+ # column_previously_was(:name) # => 'Initial'
148
+ def column_previously_was(column)
149
+ (pc = @previous_changes) && (val = pc[column]) && val[0]
150
+ end
151
+
95
152
  # Freeze internal data structures
96
153
  def freeze
97
154
  initial_values.freeze
@@ -137,7 +194,7 @@ module Sequel
137
194
  # name.gsub(/i/i, 'o')
138
195
  # column_change(:name) # => ['Initial', 'onotoal']
139
196
  def will_change_column(column)
140
- changed_columns << column unless changed_columns.include?(column)
197
+ _add_changed_column(column)
141
198
  check_missing_initial_value(column)
142
199
 
143
200
  value = if initial_values.has_key?(column)
@@ -159,23 +216,10 @@ module Sequel
159
216
 
160
217
  private
161
218
 
162
- # Reset the initial values when setting values.
163
- def _refresh_set_values(hash)
164
- reset_initial_values
165
- super
166
- end
167
-
168
- # Reset the initial values after saving.
169
- def after_save
170
- super
171
- reset_initial_values
172
- end
173
-
174
- # Save the current changes so they are available after updating. This happens
175
- # before after_save resets them.
176
- def after_update
219
+ # Reset initial values when clearing changed columns
220
+ def _clear_changed_columns(reason)
221
+ reset_initial_values if reason == :initialize || reason == :refresh
177
222
  super
178
- @previous_changes = column_changes
179
223
  end
180
224
 
181
225
  # When changing the column value, save the initial column value. If the column
@@ -186,7 +230,7 @@ module Sequel
186
230
  initial = iv[column]
187
231
  super
188
232
  if value == initial
189
- changed_columns.delete(column) unless missing_initial_values.include?(column)
233
+ _changed_columns.delete(column) unless missing_initial_values.include?(column)
190
234
  iv.delete(column)
191
235
  end
192
236
  else
@@ -214,12 +258,6 @@ module Sequel
214
258
  self
215
259
  end
216
260
 
217
- # Reset the initial values when initializing.
218
- def initialize_set(h)
219
- super
220
- reset_initial_values
221
- end
222
-
223
261
  # Array holding column symbols that were not present initially. This is necessary
224
262
  # to differentiate between values that were not present and values that were
225
263
  # present but equal to nil.
@@ -30,16 +30,16 @@ module Sequel
30
30
  module EagerEach
31
31
  module DatasetMethods
32
32
  # Don't call #all when attempting to load the columns.
33
- def columns
33
+ def columns!
34
34
  if use_eager_all?
35
- clone(:all_called=>true).columns
35
+ clone(:all_called=>true).columns!
36
36
  else
37
37
  super
38
38
  end
39
39
  end
40
40
 
41
41
  # Call #all instead of #each if eager loading,
42
- # uless #each is being called by #all.
42
+ # unless #each is being called by #all.
43
43
  def each(&block)
44
44
  if use_eager_all?
45
45
  all(&block)