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
data/README.rdoc CHANGED
@@ -8,24 +8,24 @@ toolkit for Ruby.
8
8
  * Sequel includes a comprehensive ORM layer for mapping
9
9
  records to Ruby objects and handling associated records.
10
10
  * Sequel supports advanced database features such as prepared
11
- statements, bound variables, stored procedures, savepoints,
12
- two-phase commit, transaction isolation, master/slave
13
- configurations, and database sharding.
14
- * Sequel currently has adapters for ADO, Amalgalite, CUBRID,
15
- DataObjects, IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
16
- PostgreSQL, SQLAnywhere, SQLite3, Swift, and TinyTDS.
11
+ statements, bound variables, savepoints, two-phase commit,
12
+ transaction isolation, primary/replica configurations, and
13
+ database sharding.
14
+ * Sequel currently has adapters for ADO, Amalgalite,
15
+ IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
16
+ PostgreSQL, SQLAnywhere, SQLite3, and TinyTDS.
17
17
 
18
18
  == Resources
19
19
 
20
- Website :: http://sequel.jeremyevans.net
21
- RDoc Documentation :: http://sequel.jeremyevans.net/rdoc
20
+ Website :: https://sequel.jeremyevans.net
21
+ RDoc Documentation :: https://sequel.jeremyevans.net/rdoc
22
22
  Source Code :: https://github.com/jeremyevans/sequel
23
- Bug tracking (GitHub Issues) :: http://github.com/jeremyevans/sequel/issues
24
- Discussion Forum (sequel-talk Google Group) :: http://groups.google.com/group/sequel-talk
25
- IRC Channel (#sequel) :: irc://irc.freenode.net/sequel
23
+ Bug tracking (GitHub Issues) :: https://github.com/jeremyevans/sequel/issues
24
+ Discussion Forum (GitHub Discussions) :: https://github.com/jeremyevans/sequel/discussions
25
+ Alternate Discussion Forum (sequel-talk Google Group) :: http://groups.google.com/group/sequel-talk
26
26
 
27
27
  If you have questions about how to use Sequel, please ask on the
28
- sequel-talk Google Group or IRC. Only use the the bug tracker to report
28
+ sequel-talk Google Group. Only use the the bug tracker to report
29
29
  bugs in Sequel, not to ask for help on using Sequel.
30
30
 
31
31
  To check out the source code:
@@ -71,7 +71,7 @@ Sequel includes an IRB console for quick access to databases (usually referred t
71
71
 
72
72
  sequel sqlite://test.db # test.db in current directory
73
73
 
74
- You get an IRB session with the database object stored in DB.
74
+ You get an IRB session with the Sequel::Database object stored in DB.
75
75
 
76
76
  In addition to providing an IRB shell (the default behavior), bin/sequel also has support for migrating databases, dumping schema migrations, and copying databases. See the {bin/sequel guide}[rdoc-ref:doc/bin_sequel.rdoc] for more details.
77
77
 
@@ -83,24 +83,25 @@ Sequel uses the concept of datasets to retrieve data. A Dataset object encapsula
83
83
 
84
84
  For example, the following one-liner returns the average GDP for countries in the middle east region:
85
85
 
86
- DB[:countries].filter(:region => 'Middle East').avg(:GDP)
86
+ DB[:countries].where(:region => 'Middle East').avg(:GDP)
87
87
 
88
88
  Which is equivalent to:
89
89
 
90
90
  SELECT avg(GDP) FROM countries WHERE region = 'Middle East'
91
91
 
92
- Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes (or custom model objects), and are accessed using an +Enumerable+ interface:
92
+ Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes, and are accessed using an +Enumerable+ interface:
93
93
 
94
- middle_east = DB[:countries].filter(:region => 'Middle East')
94
+ middle_east = DB[:countries].where(:region => 'Middle East')
95
95
  middle_east.order(:name).each{|r| puts r[:name]}
96
96
 
97
97
  Sequel also offers convenience methods for extracting data from Datasets, such as an extended +map+ method:
98
98
 
99
- middle_east.map(:name) #=> ['Egypt', 'Turkey', 'Israel', ...]
99
+ middle_east.map(:name) # => ['Egypt', 'Turkey', 'Israel', ...]
100
+ middle_east.map([:id, :name]) # => [[1, 'Egypt'], [3, 'Turkey'], [2, 'Israel'], ...]
100
101
 
101
- Or getting results as a hash via +to_hash+, with one column as key and another as value:
102
+ Or getting results as a hash via +as_hash+, with one column as key and another as value:
102
103
 
103
- middle_east.to_hash(:name, :area) #=> {'Israel' => 20000, 'Turkey' => 120000, ...}
104
+ middle_east.as_hash(:name, :area) # => {'Israel' => 20000, 'Turkey' => 120000, ...}
104
105
 
105
106
  == Getting Started
106
107
 
@@ -118,7 +119,12 @@ The connection URL can also include such stuff as the user name, password, and p
118
119
  You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
119
120
 
120
121
  DB = Sequel.connect("postgres://user:password@host:port/database_name",
121
- :max_connections => 10, :logger => Logger.new('log/db.log'))
122
+ max_connections: 10, logger: Logger.new('log/db.log'))
123
+
124
+ It is also possible to use a hash instead of a connection URL, but make sure to include the :adapter option in this case:
125
+
126
+ DB = Sequel.connect(adapter: :postgres, user: 'user', password: 'password', host: 'host', port: port,
127
+ database: 'database_name', max_connections: 10, logger: Logger.new('log/db.log'))
122
128
 
123
129
  You can specify a block to connect, which will disconnect from the database after it completes:
124
130
 
@@ -166,7 +172,7 @@ Datasets are the primary way records are retrieved and manipulated. They are ge
166
172
  posts = DB.from(:posts)
167
173
  posts = DB[:posts] # same
168
174
 
169
- Datasets will only fetch records when you tell them to. They can be manipulated to filter records, change ordering, join tables, etc..
175
+ Datasets will only fetch records when you tell them to. They can be manipulated to filter records, change ordering, join tables, etc. Datasets are always frozen, and they are safe to use by multiple threads concurrently.
170
176
 
171
177
  === Retrieving Records
172
178
 
@@ -175,7 +181,7 @@ You can retrieve all records by using the +all+ method:
175
181
  posts.all
176
182
  # SELECT * FROM posts
177
183
 
178
- The all method returns an array of hashes, where each hash corresponds to a record.
184
+ The +all+ method returns an array of hashes, where each hash corresponds to a record.
179
185
 
180
186
  You can also iterate through records one at a time using +each+:
181
187
 
@@ -188,68 +194,92 @@ Or perform more advanced stuff:
188
194
 
189
195
  You can also retrieve the first record in a dataset:
190
196
 
191
- posts.first
192
- # SELECT * FROM posts LIMIT 1
197
+ posts.order(:id).first
198
+ # SELECT * FROM posts ORDER BY id LIMIT 1
193
199
 
194
- Or retrieve a single record with a specific value:
200
+ Note that you can get the first record in a dataset even if it isn't ordered:
195
201
 
196
- posts[:id => 1]
197
- # SELECT * FROM posts WHERE id = 1 LIMIT 1
202
+ posts.first
203
+ # SELECT * FROM posts LIMIT 1
198
204
 
199
205
  If the dataset is ordered, you can also ask for the last record:
200
206
 
201
207
  posts.order(:stamp).last
202
208
  # SELECT * FROM posts ORDER BY stamp DESC LIMIT 1
203
209
 
210
+ You can also provide a filter when asking for a single record:
211
+
212
+ posts.first(:id => 1)
213
+ # SELECT * FROM posts WHERE id = 1 LIMIT 1
214
+
215
+ Or retrieve a single value for a specific record:
216
+
217
+ posts.where(:id => 1).get(:name)
218
+ # SELECT name FROM posts WHERE id = 1 LIMIT 1
219
+
204
220
  === Filtering Records
205
221
 
206
- An easy way to filter records is to provide a hash of values to match to +where+:
222
+ The most common way to filter records is to provide a hash of values to match to +where+:
207
223
 
208
- my_posts = posts.where(:category => 'ruby', :author => 'david')
209
- # WHERE category = 'ruby' AND author = 'david'
224
+ my_posts = posts.where(category: 'ruby', author: 'david')
225
+ # WHERE ((category = 'ruby') AND (author = 'david'))
210
226
 
211
227
  You can also specify ranges:
212
228
 
213
- my_posts = posts.where(:stamp => (Date.today - 14)..(Date.today - 7))
214
- # WHERE stamp >= '2010-06-30' AND stamp <= '2010-07-07'
229
+ my_posts = posts.where(stamp: (Date.today - 14)..(Date.today - 7))
230
+ # WHERE ((stamp >= '2010-06-30') AND (stamp <= '2010-07-07'))
215
231
 
216
232
  Or arrays of values:
217
233
 
218
- my_posts = posts.where(:category => ['ruby', 'postgres', 'linux'])
219
- # WHERE category IN ('ruby', 'postgres', 'linux')
234
+ my_posts = posts.where(category: ['ruby', 'postgres', 'linux'])
235
+ # WHERE (category IN ('ruby', 'postgres', 'linux'))
220
236
 
221
- Sequel also accepts expressions:
237
+ By passing a block to where, you can use expressions (this is fairly "magical"):
222
238
 
223
239
  my_posts = posts.where{stamp > Date.today << 1}
224
- # WHERE stamp > '2010-06-14'
240
+ # WHERE (stamp > '2010-06-14')
225
241
  my_posts = posts.where{stamp =~ Date.today}
226
- # WHERE stamp = '2010-07-14'
242
+ # WHERE (stamp = '2010-07-14')
243
+
244
+ If you want to wrap the objects yourself, you can use expressions without the "magic":
227
245
 
228
- Some adapters will also let you specify Regexps:
246
+ my_posts = posts.where(Sequel[:stamp] > Date.today << 1)
247
+ # WHERE (stamp > '2010-06-14')
248
+ my_posts = posts.where(Sequel[:stamp] =~ Date.today)
249
+ # WHERE (stamp = '2010-07-14')
250
+
251
+ Some databases such as PostgreSQL and MySQL also support filtering via Regexps:
229
252
 
230
- my_posts = posts.where(:category => /ruby/i)
231
- # WHERE category ~* 'ruby'
253
+ my_posts = posts.where(category: /ruby/i)
254
+ # WHERE (category ~* 'ruby')
232
255
 
233
256
  You can also use an inverse filter via +exclude+:
234
257
 
235
- my_posts = posts.exclude(:category => ['ruby', 'postgres', 'linux'])
236
- # WHERE category NOT IN ('ruby', 'postgres', 'linux')
258
+ my_posts = posts.exclude(category: ['ruby', 'postgres', 'linux'])
259
+ # WHERE (category NOT IN ('ruby', 'postgres', 'linux'))
260
+
261
+ But note that this does a full inversion of the filter:
262
+
263
+ my_posts = posts.exclude(category: ['ruby', 'postgres', 'linux'], id: 1)
264
+ # WHERE ((category NOT IN ('ruby', 'postgres', 'linux')) OR (id != 1))
237
265
 
238
- You can also specify a custom WHERE clause using a string:
266
+ If at any point you want to use a custom SQL fragment for part of a query,
267
+ you can do so via +Sequel.lit+:
239
268
 
240
- posts.where('stamp IS NOT NULL')
241
- # WHERE stamp IS NOT NULL
269
+ posts.where(Sequel.lit('stamp IS NOT NULL'))
270
+ # WHERE (stamp IS NOT NULL)
242
271
 
243
- You can use parameters in your string, as well:
272
+ You can safely interpolate parameters into the custom SQL fragment by
273
+ providing them as additional arguments:
244
274
 
245
275
  author_name = 'JKR'
246
- posts.where('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
247
- # WHERE (stamp < '2010-07-11') AND (author != 'JKR')
276
+ posts.where(Sequel.lit('(stamp < ?) AND (author != ?)', Date.today - 3, author_name))
277
+ # WHERE ((stamp < '2010-07-11') AND (author != 'JKR'))
248
278
 
249
279
  Datasets can also be used as subqueries:
250
280
 
251
- DB[:items].where('price > ?', DB[:items].select{avg(price) + 100})
252
- # WHERE price > (SELECT avg(price) + 100 FROM items)
281
+ DB[:items].where(Sequel[:price] > DB[:items].select{avg(price) + 100})
282
+ # WHERE (price > (SELECT avg(price) + 100 FROM items))
253
283
 
254
284
  After filtering, you can retrieve the matching records by using any of the retrieval methods:
255
285
 
@@ -268,7 +298,7 @@ issues that you should be aware of when using Sequel.
268
298
  Counting records is easy using +count+:
269
299
 
270
300
  posts.where(Sequel.like(:category, '%ruby%')).count
271
- # SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
301
+ # SELECT COUNT(*) FROM posts WHERE (category LIKE '%ruby%' ESCAPE '\')
272
302
 
273
303
  And you can also query maximum/minimum values via +max+ and +min+:
274
304
 
@@ -294,18 +324,15 @@ Ordering datasets is simple using +order+:
294
324
  posts.order(:stamp, :name)
295
325
  # ORDER BY stamp, name
296
326
 
297
- Chaining +order+ doesn't work the same as +where+:
327
+ +order+ always overrides the existing order:
298
328
 
299
329
  posts.order(:stamp).order(:name)
300
330
  # ORDER BY name
301
331
 
302
- The +order_append+ method chains this way, though:
332
+ If you would like to add to the existing order, use +order_append+ or +order_prepend+:
303
333
 
304
334
  posts.order(:stamp).order_append(:name)
305
335
  # ORDER BY stamp, name
306
-
307
- The +order_prepend+ method can be used as well:
308
-
309
336
  posts.order(:stamp).order_prepend(:name)
310
337
  # ORDER BY name, stamp
311
338
 
@@ -318,7 +345,7 @@ You can also specify descending order:
318
345
 
319
346
  === Core Extensions
320
347
 
321
- Note the use of <tt>Sequel.desc(:stamp)</tt> in the above example. Much of Sequel's DSL uses this style, calling methods on the Sequel module that return SQL expression objects. Sequel also ships with a {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc]) that integrates Sequel's DSL better into the ruby language, allowing you to write:
348
+ Note the use of <tt>Sequel.desc(:stamp)</tt> in the above example. Much of Sequel's DSL uses this style, calling methods on the Sequel module that return SQL expression objects. Sequel also ships with a {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc] that integrates Sequel's DSL better into the Ruby language, allowing you to write:
322
349
 
323
350
  :stamp.desc
324
351
 
@@ -335,7 +362,7 @@ Selecting specific columns to be returned is also simple using +select+:
335
362
  posts.select(:stamp, :name)
336
363
  # SELECT stamp, name FROM posts
337
364
 
338
- Chaining +select+ works like +order+, not +where+:
365
+ Like +order+, +select+ overrides an existing selection:
339
366
 
340
367
  posts.select(:stamp).select(:name)
341
368
  # SELECT name FROM posts
@@ -349,52 +376,81 @@ As you might expect, there is an +order_append+ equivalent for +select+ called +
349
376
 
350
377
  Deleting records from the table is done with +delete+:
351
378
 
352
- posts.where('stamp < ?', Date.today - 3).delete
353
- # DELETE FROM posts WHERE stamp < '2010-07-11'
379
+ posts.where(Sequel[:stamp] < Date.today - 3).delete
380
+ # DELETE FROM posts WHERE (stamp < '2010-07-11')
354
381
 
355
382
  Be very careful when deleting, as +delete+ affects all rows in the dataset.
356
383
  Call +where+ first and +delete+ second:
357
384
 
358
385
  # DO THIS:
359
- posts.where('stamp < ?', Date.today - 7).delete
386
+ posts.where(Sequel[:stamp] < Date.today - 7).delete
360
387
  # NOT THIS:
361
- posts.delete.where('stamp < ?', Date.today - 7)
388
+ posts.delete.where(Sequel[:stamp] < Date.today - 7)
362
389
 
363
390
  === Inserting Records
364
391
 
365
392
  Inserting records into the table is done with +insert+:
366
393
 
367
- posts.insert(:category => 'ruby', :author => 'david')
394
+ posts.insert(category: 'ruby', author: 'david')
368
395
  # INSERT INTO posts (category, author) VALUES ('ruby', 'david')
369
396
 
370
397
  === Updating Records
371
398
 
372
399
  Updating records in the table is done with +update+:
373
400
 
374
- posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
375
- # UPDATE posts SET state = 'archived' WHERE stamp < '2010-07-07'
401
+ posts.where(Sequel[:stamp] < Date.today - 7).update(state: 'archived')
402
+ # UPDATE posts SET state = 'archived' WHERE (stamp < '2010-07-07')
376
403
 
377
- You can reference table columns when choosing what values to set:
404
+ You can provide arbitrary expressions when choosing what values to set:
378
405
 
379
- posts.where{|o| o.stamp < Date.today - 7}.update(:backup_number => Sequel.+(:backup_number, 1))
380
- # UPDATE posts SET backup_number = backup_number + 1 WHERE stamp < '2010-07-07'
406
+ posts.where(Sequel[:stamp] < Date.today - 7).update(backup_number: Sequel[:backup_number] + 1)
407
+ # UPDATE posts SET backup_number = (backup_number + 1) WHERE (stamp < '2010-07-07'))))
381
408
 
382
409
  As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
383
410
  +update+ second:
384
411
 
385
412
  # DO THIS:
386
- posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
413
+ posts.where(Sequel[:stamp] < Date.today - 7).update(:state => 'archived')
387
414
  # NOT THIS:
388
- posts.update(:state => 'archived').where('stamp < ?', Date.today - 7)
415
+ posts.update(:state => 'archived').where(Sequel[:stamp] < Date.today - 7)
416
+
417
+ === Merging records
418
+
419
+ Merging records using the SQL MERGE statement is done using <tt>merge*</tt> methods.
420
+ You use +merge_using+ to specify the merge source and join conditions.
421
+ You can use +merge_insert+, +merge_delete+, and/or +merge_update+ to set the
422
+ INSERT, DELETE, and UPDATE clauses for the merge. +merge_insert+ takes the same
423
+ arguments as +insert+, and +merge_update+ takes the same arguments as +update+.
424
+ +merge_insert+, +merge_delete+, and +merge_update+ can all be called with blocks,
425
+ to set the conditions for the related INSERT, DELETE, or UPDATE.
426
+
427
+ Finally, after calling all of the other <tt>merge_*</tt> methods, you call +merge+
428
+ to run the MERGE statement on the database.
429
+
430
+ ds = DB[:m1]
431
+ merge_using(:m2, i1: :i2).
432
+ merge_insert(i1: :i2, a: Sequel[:b]+11).
433
+ merge_delete{a > 30}.
434
+ merge_update(i1: Sequel[:i1]+:i2+10, a: Sequel[:a]+:b+20)
435
+
436
+ ds.merge
437
+ # MERGE INTO m1 USING m2 ON (i1 = i2)
438
+ # WHEN NOT MATCHED THEN INSERT (i1, a) VALUES (i2, (b + 11))
439
+ # WHEN MATCHED AND (a > 30) THEN DELETE
440
+ # WHEN MATCHED THEN UPDATE SET i1 = (i1 + i2 + 10), a = (a + b + 20)
389
441
 
390
442
  === Transactions
391
443
 
392
- You can wrap some code in a database transaction using the <tt>Database#transaction</tt> method:
444
+ You can wrap a block of code in a database transaction using the <tt>Database#transaction</tt> method:
393
445
 
394
446
  DB.transaction do
395
- posts.insert(:category => 'ruby', :author => 'david')
396
- posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
447
+ # BEGIN
448
+ posts.insert(category: 'ruby', author: 'david')
449
+ # INSERT
450
+ posts.where(Sequel[:stamp] < Date.today - 7).update(:state => 'archived')
451
+ # UPDATE
397
452
  end
453
+ # COMMIT
398
454
 
399
455
  If the block does not raise an exception, the transaction will be committed.
400
456
  If the block does raise an exception, the transaction will be rolled back,
@@ -403,21 +459,24 @@ and not raise an exception outside the block, you can raise the
403
459
  <tt>Sequel::Rollback</tt> exception inside the block:
404
460
 
405
461
  DB.transaction do
462
+ # BEGIN
406
463
  posts.insert(:category => 'ruby', :author => 'david')
407
- if posts.filter('stamp < ?', Date.today - 7).update(:state => 'archived') == 0
464
+ # INSERT
465
+ if posts.where('stamp < ?', Date.today - 7).update(:state => 'archived') == 0
466
+ # UPDATE
408
467
  raise Sequel::Rollback
409
468
  end
410
469
  end
470
+ # ROLLBACK
411
471
 
412
472
  === Joining Tables
413
473
 
414
474
  Sequel makes it easy to join tables:
415
475
 
416
- order_items = DB[:items].join(:order_items, :item_id => :id).
417
- where(:order_id => 1234)
418
- # SELECT * FROM items INNER JOIN order_items
419
- # ON order_items.item_id = items.id
420
- # WHERE order_id = 1234
476
+ order_items = DB[:items].join(:order_items, item_id: :id).where(order_id: 1234)
477
+ # SELECT * FROM items
478
+ # INNER JOIN order_items ON (order_items.item_id = items.id)
479
+ # WHERE (order_id = 1234)
421
480
 
422
481
  The important thing to note here is that item_id is automatically qualified with
423
482
  the table being joined, and id is automatically qualified with the last table
@@ -426,9 +485,9 @@ joined.
426
485
  You can then do anything you like with the dataset:
427
486
 
428
487
  order_total = order_items.sum(:price)
429
- # SELECT sum(price) FROM items INNER JOIN order_items
430
- # ON order_items.item_id = items.id
431
- # WHERE order_items.order_id = 1234
488
+ # SELECT sum(price) FROM items
489
+ # INNER JOIN order_items ON (order_items.item_id = items.id)
490
+ # WHERE (order_id = 1234)
432
491
 
433
492
  Note that the default selection in Sequel is <tt>*</tt>, which includes all columns
434
493
  in all joined tables. Because Sequel returns results as a hash keyed by column name
@@ -440,54 +499,53 @@ selection using +select+, +select_all+, and/or +select_append+.
440
499
 
441
500
  Sequel expects column names to be specified using symbols. In addition, returned hashes always use symbols as their keys. This allows you to freely mix literal values and column references in many cases. For example, the two following lines produce equivalent SQL:
442
501
 
443
- items.where(:x => 1)
502
+ items.where(x: 1)
444
503
  # SELECT * FROM items WHERE (x = 1)
445
504
  items.where(1 => :x)
446
505
  # SELECT * FROM items WHERE (1 = x)"
447
506
 
448
507
  Ruby strings are generally treated as SQL strings:
449
508
 
450
- items.where(:x => 'x')
509
+ items.where(x: 'x')
451
510
  # SELECT * FROM items WHERE (x = 'x')
452
511
 
453
512
  === Qualifying identifiers (column/table names)
454
513
 
455
514
  An identifier in SQL is a name that represents a column, table, or schema.
456
- Identifiers can be qualified by using the double underscore special notation <tt>:table__column</tt>:
515
+ The recommended way to qualify columns is to use <tt>Sequel[][]</tt> or +Sequel.qualify+
457
516
 
458
- items.literal(:items__price)
459
- # items.price
517
+ Sequel[:table][:column]
518
+ Sequel.qualify(:table, :column)
519
+ # table.column
460
520
 
461
- Another way to qualify columns is to use the <tt>Sequel.qualify</tt> method:
521
+ You can also qualify tables with schemas:
462
522
 
463
- items.literal(Sequel.qualify(:items, :price))
464
- # items.price
523
+ Sequel[:schema][:table]
524
+ # schema.table
465
525
 
466
- While it is more common to qualify column identifiers with table identifiers, you can also qualify table identifiers with schema identifiers
467
- to select from a qualified table:
526
+ or use multi-level qualification:
468
527
 
469
- posts = DB[:some_schema__posts]
470
- # SELECT * FROM some_schema.posts
528
+ Sequel[:schema][:table][:column]
529
+ # schema.table.column
471
530
 
472
- === Identifier aliases
531
+ === Expression aliases
473
532
 
474
- You can also alias identifiers by using the triple underscore special notation <tt>:column___alias</tt> or <tt>:table__column___alias</tt>:
533
+ You can alias identifiers using <tt>Sequel[].as</tt> or +Sequel.as+:
475
534
 
476
- items.literal(:price___p)
477
- # price AS p
478
- items.literal(:items__price___p)
479
- # items.price AS p
480
-
481
- Another way to alias columns is to use the <tt>Sequel.as</tt> method:
482
-
483
- items.literal(Sequel.as(:price, :p))
484
- # price AS p
535
+ Sequel[:column].as(:alias)
536
+ Sequel.as(:column, :alias)
537
+ # column AS alias
485
538
 
486
539
  You can use the <tt>Sequel.as</tt> method to alias arbitrary expressions, not just identifiers:
487
540
 
488
- items.literal(Sequel.as(DB[:posts].select{max(id)}, :p))
541
+ Sequel.as(DB[:posts].select{max(id)}, :p)
489
542
  # (SELECT max(id) FROM posts) AS p
490
543
 
544
+ And most Sequel expression objects support an +as+ method for aliasing:
545
+
546
+ (Sequel[:column] + 2).as(:c_plus_2)
547
+ # (column + 2) AS c_plus_2
548
+
491
549
  == Sequel Models
492
550
 
493
551
  A model class wraps a dataset, and an instance of that class wraps a single record in the dataset.
@@ -504,38 +562,37 @@ implements the active record pattern).
504
562
 
505
563
  Sequel model classes assume that the table name is an underscored plural of the class name:
506
564
 
507
- Post.table_name #=> :posts
565
+ Post.table_name # => :posts
508
566
 
509
567
  You can explicitly set the table name or even the dataset used:
510
568
 
511
- class Post < Sequel::Model(:my_posts)
512
- end
569
+ class Post < Sequel::Model(:my_posts); end
513
570
  # or:
514
- Post.set_dataset :my_posts
571
+ class Post < Sequel::Model(DB[:my_posts]); end
515
572
 
516
- If you call +set_dataset+ with a symbol, it assumes you are referring to the table with the same name. You can also call it with a dataset, which will set the defaults for all retrievals for that model:
573
+ If you pass a symbol to the <tt>Sequel::Model</tt> method, it assumes you are referring to the table with the same name. You can also call it with a dataset, which will set the defaults for all retrievals for that model:
517
574
 
518
- Post.set_dataset DB[:my_posts].where(:category => 'ruby')
519
- Post.set_dataset DB[:my_posts].select(:id, :name).order(:date)
575
+ class Post < Sequel::Model(DB[:my_posts].where(category: 'ruby')); end
576
+ class Post < Sequel::Model(DB[:my_posts].select(:id, :name).order(:date)); end
520
577
 
521
578
  === Model instances
522
579
 
523
- Model instances are identified by a primary key. In most cases, Sequel can query the database to determine the primary key, but if not, it defaults to using <tt>:id</tt>. The <tt>Model.[]</tt> method can be used to fetch records by their primary key:
580
+ Model instances are identified by a primary key. Sequel queries the database to determine the primary key for each model. The <tt>Model.[]</tt> method can be used to fetch records by their primary key:
524
581
 
525
582
  post = Post[123]
526
583
 
527
584
  The +pk+ method is used to retrieve the record's primary key value:
528
585
 
529
- post.pk #=> 123
586
+ post.pk # => 123
530
587
 
531
- Sequel models allow you to use any column as a primary key, and even composite keys made from multiple columns:
588
+ If you want to override which column(s) to use as the primary key, you can use +set_primary_key+:
532
589
 
533
590
  class Post < Sequel::Model
534
591
  set_primary_key [:category, :title]
535
592
  end
536
593
 
537
594
  post = Post['ruby', 'hello world']
538
- post.pk #=> ['ruby', 'hello world']
595
+ post.pk # => ['ruby', 'hello world']
539
596
 
540
597
  You can also define a model class that does not have a primary key via +no_primary_key+, but then you lose the ability to easily update and delete records:
541
598
 
@@ -543,39 +600,43 @@ You can also define a model class that does not have a primary key via +no_prima
543
600
 
544
601
  A single model instance can also be fetched by specifying a condition:
545
602
 
546
- post = Post[:title => 'hello world']
603
+ post = Post.first(title: 'hello world')
547
604
  post = Post.first{num_comments < 10}
548
605
 
606
+ The dataset for a model class returns rows of model instances instead of plain hashes:
607
+
608
+ DB[:posts].first.class # => Hash
609
+ Post.first.class # => Post
610
+
549
611
  === Acts like a dataset
550
612
 
551
613
  A model class forwards many methods to the underlying dataset. This means that you can use most of the +Dataset+ API to create customized queries that return model instances, e.g.:
552
614
 
553
- Post.where(:category => 'ruby').each{|post| p post}
615
+ Post.where(category: 'ruby').each{|post| p post}
554
616
 
555
617
  You can also manipulate the records in the dataset:
556
618
 
557
619
  Post.where{num_comments < 7}.delete
558
- Post.where(Sequel.like(:title, /ruby/)).update(:category => 'ruby')
620
+ Post.where(Sequel.like(:title, /ruby/)).update(category: 'ruby')
559
621
 
560
622
  === Accessing record values
561
623
 
562
624
  A model instance stores its values as a hash with column symbol keys, which you can access directly via the +values+ method:
563
625
 
564
- post.values #=> {:id => 123, :category => 'ruby', :title => 'hello world'}
626
+ post.values # => {:id => 123, :category => 'ruby', :title => 'hello world'}
565
627
 
566
628
  You can read the record values as object attributes, assuming the attribute names are valid columns in the model's dataset:
567
629
 
568
- post.id #=> 123
569
- post.title #=> 'hello world'
630
+ post.id # => 123
631
+ post.title # => 'hello world'
570
632
 
571
633
  If the record's attributes names are not valid columns in the model's dataset (maybe because you used +select_append+ to add a computed value column), you can use <tt>Model#[]</tt> to access the values:
572
634
 
573
- post[:id] #=> 123
574
- post[:title] #=> 'hello world'
635
+ post[:id] # => 123
636
+ post[:title] # => 'hello world'
575
637
 
576
638
  You can also modify record values using attribute setters or the <tt>[]=</tt> method.
577
639
 
578
-
579
640
  post.title = 'hey there'
580
641
  post[:title] = 'hey there'
581
642
 
@@ -587,24 +648,26 @@ That will just change the value for the object, it will not update the row in th
587
648
 
588
649
  You can also set the values for multiple columns in a single method call, using one of the mass-assignment methods. See the {mass assignment guide}[rdoc-ref:doc/mass_assignment.rdoc] for details. For example +set+ updates the model's column values without saving:
589
650
 
590
- post.set(:title=>'hey there', :updated_by=>'foo')
651
+ post.set(title: 'hey there', updated_by: 'foo')
591
652
 
592
653
  and +update+ updates the model's column values and then saves the changes to the database:
593
654
 
594
- post.update(:title => 'hey there', :updated_by=>'foo')
655
+ post.update(title: 'hey there', updated_by: 'foo')
595
656
 
596
657
  === Creating new records
597
658
 
598
- New records can be created by calling <tt>Model.create</tt>:
659
+ New model instances can be created by calling <tt>Model.new</tt>, which returns a new model instance without updating the database:
599
660
 
600
- post = Post.create(:title => 'hello world')
661
+ post = Post.new(title: 'hello world')
601
662
 
602
- Another way is to construct a new instance and save it later:
663
+ You can save the record to the database later by calling +save+ on the model instance:
603
664
 
604
- post = Post.new
605
- post.title = 'hello world'
606
665
  post.save
607
666
 
667
+ If you want to create a new record and save it to the database at the same time, you can use <tt>Model.create</tt>:
668
+
669
+ post = Post.create(title: 'hello world')
670
+
608
671
  You can also supply a block to <tt>Model.new</tt> and <tt>Model.create</tt>:
609
672
 
610
673
  post = Post.new do |p|
@@ -631,7 +694,7 @@ You can execute custom code when creating, updating, or deleting records by defi
631
694
 
632
695
  Note the use of +super+ if you define your own hook methods. Almost all <tt>Sequel::Model</tt> class and instance methods (not just hook methods) can be overridden safely, but you have to make sure to call +super+ when doing so, otherwise you risk breaking things.
633
696
 
634
- For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances, and even then they are often subject to race conditions. It's best to use database triggers and constraints to enforce data integrity.
697
+ For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances, and even then they are often subject to race conditions. It's best to use database triggers and database constraints to enforce data integrity.
635
698
 
636
699
  === Deleting records
637
700
 
@@ -663,21 +726,21 @@ Associations are used in order to specify relationships between model classes th
663
726
 
664
727
  +many_to_one+ and +one_to_one+ create a getter and setter for each model object:
665
728
 
666
- post = Post.create(:name => 'hi!')
667
- post.author = Author[:name => 'Sharon']
729
+ post = Post.create(name: 'hi!')
730
+ post.author = Author.first(name: 'Sharon')
668
731
  post.author
669
732
 
670
733
  +one_to_many+ and +many_to_many+ create a getter method, a method for adding an object to the association, a method for removing an object from the association, and a method for removing all associated objects from the association:
671
734
 
672
- post = Post.create(:name => 'hi!')
735
+ post = Post.create(name: 'hi!')
673
736
  post.comments
674
737
 
675
- comment = Comment.create(:text=>'hi')
738
+ comment = Comment.create(text: 'hi')
676
739
  post.add_comment(comment)
677
740
  post.remove_comment(comment)
678
741
  post.remove_all_comments
679
742
 
680
- tag = Tag.create(:tag=>'interesting')
743
+ tag = Tag.create(tag: 'interesting')
681
744
  post.add_tag(tag)
682
745
  post.remove_tag(tag)
683
746
  post.remove_all_tags
@@ -690,7 +753,7 @@ All associations add a dataset method that can be used to further filter or reor
690
753
  post.comments_dataset.destroy
691
754
 
692
755
  # Return all tags related to this post with no subscribers, ordered by the tag's name
693
- post.tags_dataset.where(:subscribers=>0).order(:name).all
756
+ post.tags_dataset.where(subscribers: 0).order(:name).all
694
757
 
695
758
  === Eager Loading
696
759
 
@@ -732,36 +795,36 @@ Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> associati
732
795
  Post.eager(:person).eager(:tags).all
733
796
 
734
797
  # Cascading via .eager
735
- Tag.eager(:posts=>:replies).all
798
+ Tag.eager(posts: :replies).all
736
799
 
737
800
  # Will also grab all associated posts' tags (because of :eager)
738
- Reply.eager(:person=>:posts).all
801
+ Reply.eager(person: :posts).all
739
802
 
740
803
  # No depth limit (other than memory/stack), and will also grab posts' tags
741
804
  # Loads all people, their posts, their posts' tags, replies to those posts,
742
805
  # the person for each reply, the tag for each reply, and all posts and
743
806
  # replies that have that tag. Uses a total of 8 queries.
744
- Person.eager(:posts=>{:replies=>[:person, {:tags=>[:posts, :replies]}]}).all
807
+ Person.eager(posts: {replies: [:person, {tags: [:posts, :replies]}]}).all
745
808
 
746
- In addition to using +eager+, you can also use +eager_graph+, which will use a single query to get the object and all associated objects. This may be necessary if you want to filter or order the result set based on columns in associated tables. It works with cascading as well, the API is very similar. Note that using +eager_graph+ to eagerly load multiple <tt>*_to_many</tt> associations will cause the result set to be a cartesian product, so you should be very careful with your filters when using it in that case.
809
+ In addition to using +eager+, you can also use +eager_graph+, which will use a single query to get the object and all associated objects. This may be necessary if you want to filter or order the result set based on columns in associated tables. It works with cascading as well, the API is similar. Note that using +eager_graph+ to eagerly load multiple <tt>*_to_many</tt> associations will cause the result set to be a cartesian product, so you should be very careful with your filters when using it in that case.
747
810
 
748
- You can dynamically customize the eagerly loaded dataset by using using a proc. This proc is passed the dataset used for eager loading, and should return a modified copy of that dataset:
811
+ You can dynamically customize the eagerly loaded dataset by using a proc. This proc is passed the dataset used for eager loading, and should return a modified copy of that dataset:
749
812
 
750
813
  # Eagerly load only replies containing 'foo'
751
- Post.eager(:replies=>proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
814
+ Post.eager(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
752
815
 
753
816
  This also works when using +eager_graph+, in which case the proc is called with dataset to graph into the current dataset:
754
817
 
755
- Post.eager_graph(:replies=>proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
818
+ Post.eager_graph(replies: proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
756
819
 
757
820
  You can dynamically customize eager loads for both +eager+ and +eager_graph+ while also cascading, by making the value a single entry hash with the proc as a key, and the cascaded associations as the value:
758
821
 
759
822
  # Eagerly load only replies containing 'foo', and the person and tags for those replies
760
- Post.eager(:replies=>{proc{|ds| ds.where(Sequel.like(text, '%foo%'))}=>[:person, :tags]}).all
823
+ Post.eager(replies: {proc{|ds| ds.where(Sequel.like(text, '%foo%'))} => [:person, :tags]}).all
761
824
 
762
825
  === Joining with Associations
763
826
 
764
- You can use the association_join method to add a join to the model's dataset based on the assocation:
827
+ You can use the +association_join+ method to add a join to the model's dataset based on the assocation:
765
828
 
766
829
  Post.association_join(:author)
767
830
  # SELECT * FROM posts
@@ -775,7 +838,7 @@ This comes with variants for different join types:
775
838
 
776
839
  Similar to the eager loading methods, you can use multiple associations and nested associations:
777
840
 
778
- Post.association_join(:author, :replies=>:person).all
841
+ Post.association_join(:author, replies: :person).all
779
842
  # SELECT * FROM posts
780
843
  # INNER JOIN authors AS author ON (author.id = posts.author_id)
781
844
  # INNER JOIN replies ON (replies.post_id = posts.id)
@@ -787,27 +850,44 @@ The recommended way to implement table-wide logic by defining methods on the dat
787
850
 
788
851
  class Post < Sequel::Model
789
852
  dataset_module do
790
- def posts_with_few_comments
853
+ def with_few_comments
791
854
  where{num_comments < 30}
792
855
  end
793
856
 
794
- def clean_posts_with_few_comments
795
- posts_with_few_comments.delete
857
+ def clean_boring
858
+ with_few_comments.delete
796
859
  end
797
860
  end
798
861
  end
799
862
 
800
863
  This allows you to have access to your model API from filtered datasets as well:
801
864
 
802
- Post.where(:category => 'ruby').clean_posts_with_few_comments
865
+ Post.where(category: 'ruby').clean_boring
866
+ # DELETE FROM posts WHERE ((category = 'ruby') AND (num_comments < 30))
803
867
 
804
- Sequel models also provide a +subset+ class method that creates a dataset method with a simple filter:
868
+ Inside +dataset_module+ blocks, there are numerous methods that support easy creation of dataset methods.
869
+ Most of these methods are named after the dataset methods themselves, such as +select+, +order+, and
870
+ +group+:
805
871
 
806
872
  class Post < Sequel::Model
807
- subset(:posts_with_few_comments){num_comments < 30}
808
- subset :invisible, Sequel.~(:visible)
873
+ dataset_module do
874
+ where(:with_few_comments, Sequel[:num_comments] < 30)
875
+ select :with_title_and_date, :id, :title, :post_date
876
+ order :by_post_date, :post_date
877
+ limit :top10, 10
878
+ end
809
879
  end
810
880
 
881
+ Post.with_few_comments.with_title_and_date.by_post_date.top10
882
+ # SELECT id, title, post_date
883
+ # FROM posts
884
+ # ORDER BY post_date
885
+ # LIMIT 10
886
+
887
+ One advantage of using these methods inside dataset_module blocks, instead of
888
+ defining methods manually, is that the created methods will generally cache
889
+ the resulting values and result in better performance.
890
+
811
891
  === Model Validations
812
892
 
813
893
  You can define a +validate+ method for your model, which +save+
@@ -815,8 +895,7 @@ will check before attempting to save the model in the database.
815
895
  If an attribute of the model isn't valid, you should add an error
816
896
  message for that attribute to the model object's +errors+. If an
817
897
  object has any errors added by the validate method, +save+ will
818
- raise an error or return false depending on how it is configured
819
- (the +raise_on_save_failure+ flag).
898
+ raise an error by default:
820
899
 
821
900
  class Post < Sequel::Model
822
901
  def validate
@@ -825,3 +904,30 @@ raise an error or return false depending on how it is configured
825
904
  errors.add(:written_on, "should be in the past") if written_on >= Time.now
826
905
  end
827
906
  end
907
+
908
+ == Testing Sequel
909
+
910
+ Please see the {testing guide}[rdoc-ref:doc/testing.rdoc] for recommendations on testing
911
+ applications that use Sequel, as well as the how to run the tests for Sequel itself.
912
+
913
+ == Sequel Release Policy
914
+
915
+ New major versions of Sequel do not have a defined release policy, but historically have
916
+ occurred once every few years.
917
+
918
+ New minor versions of Sequel are released around once a month near the start of the month.
919
+
920
+ New tiny versions of Sequel are only released to address security issues or regressions
921
+ in the most current release.
922
+
923
+ == Ruby Support Policy
924
+
925
+ Sequel fully supports the currently supported versions of Ruby (MRI) and JRuby. It may
926
+ support unsupported versions of Ruby or JRuby, but such support may be dropped in any
927
+ minor version if keeping it becomes a support issue. The minimum Ruby version
928
+ required to run the current version of Sequel is 1.9.2, and the minimum JRuby version is
929
+ 9.0.0.0.
930
+
931
+ == Maintainer
932
+
933
+ Jeremy Evans <code@jeremyevans.net>