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/doc/security.rdoc CHANGED
@@ -16,13 +16,11 @@ as it never calls eval on a string that is derived from user input.
16
16
  However, some Sequel methods used for creating methods via metaprogramming
17
17
  could conceivably be abused to do so:
18
18
 
19
- * Sequel::Schema::CreateTableGenerator.add_type_method
20
- * Sequel::Dataset.def_mutation_method
21
19
  * Sequel::Dataset.def_sql_method
22
- * Sequel::Model::Plugins.def_dataset_methods
23
- * Sequel.def_adapter_method (private)
20
+ * Sequel::JDBC.load_driver
21
+ * Sequel::Plugins.def_dataset_methods
22
+ * Sequel::Dataset.prepared_statements_module (private)
24
23
  * Sequel::SQL::Expression.to_s_method (private)
25
- * Sequel::Plugins::HookClassMethods::ClassMethods#add_hook_type
26
24
 
27
25
  As long as you don't call those with user input, you should not be
28
26
  vulnerable to code execution.
@@ -47,6 +45,9 @@ There are basically two kinds of possible SQL injections in Sequel:
47
45
  Some Sequel methods are designed to execute raw SQL strings, including:
48
46
 
49
47
  * Sequel::Database#execute
48
+ * Sequel::Database#execute_ddl
49
+ * Sequel::Database#execute_dui
50
+ * Sequel::Database#execute_insert
50
51
  * Sequel::Database#run
51
52
  * Sequel::Database#<<
52
53
  * Sequel::Dataset#fetch_rows
@@ -60,9 +61,12 @@ Some Sequel methods are designed to execute raw SQL strings, including:
60
61
 
61
62
  Here are some examples of use:
62
63
 
64
+ DB.execute 'SQL'
65
+ DB.execute_ddl 'SQL'
66
+ DB.execute_dui 'SQL'
67
+ DB.execute_insert 'SQL'
63
68
  DB.run 'SQL'
64
69
  DB << 'SQL'
65
- DB.execute 'SQL'
66
70
  DB.fetch_rows('SQL'){|row| }
67
71
  DB.dataset.with_sql_all('SQL')
68
72
  DB.dataset.with_sql_delete('SQL')
@@ -101,19 +105,16 @@ With these methods you should use placeholders, in which case Sequel automatical
101
105
 
102
106
  Sequel generally treats ruby strings as SQL strings (escaping them correctly), and
103
107
  not as raw SQL. However, you can convert a ruby string to a literal string, and
104
- Sequel will then treat it as raw SQL. This is typically done through String#lit
105
- if the {core_extensions}[rdoc-ref:doc/core_extensions.rdoc] are in use,
106
- or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] if they are not in use.
108
+ Sequel will then treat it as raw SQL. This is typically done through
109
+ Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit].
107
110
 
108
- 'a'.lit
109
111
  Sequel.lit('a')
110
112
 
111
- Using String#lit or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
113
+ Using Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
112
114
  in SQL injection if the string is derived from user input. With both of these
113
115
  methods, the strings can contain placeholders, which you can use to safely include
114
116
  user input inside a literal string:
115
117
 
116
- 'a = ?'.lit(params[:user_id].to_s)
117
118
  Sequel.lit('a = ?', params[:user_id].to_s)
118
119
 
119
120
  Even though they have similar names, note that Sequel::Database#literal operates very differently from
@@ -131,83 +132,117 @@ a ruby string as raw SQL. For example:
131
132
 
132
133
  ==== SQL Filter Fragments
133
134
 
134
- The most common way to use raw SQL with Sequel is in filters:
135
+ Starting in Sequel 5, Sequel does not automatically convert plain strings to
136
+ literal strings in typical code. Instead, you can use Sequel.lit to
137
+ create literal strings:
135
138
 
136
- DB[:table].where("name > 'M'")
139
+ Sequel.lit("name > 'A'")
137
140
 
138
- If a filter method is passed a string as the first argument, it treats the rest of
139
- the arguments (if any) as placeholders to the string. So you should never do:
141
+ To safely include user input as part of an SQL filter fragment, use Sequel.lit
142
+ with placeholders:
140
143
 
141
- DB[:table].where("name > #{params[:id].to_s}") # SQL Injection!
144
+ DB[:table].where(Sequel.lit("name > ?", params[:id].to_s)) # Safe
142
145
 
143
- Instead, you should use a placeholder:
146
+ Be careful to never call Sequel.lit where the first argument is derived from
147
+ user input.
144
148
 
145
- DB[:table].where("name > ?", params[:id].to_s) # Safe
146
-
147
- Note that for that type of query, Sequel generally encourages the following form:
149
+ There are a few uncommon cases where Sequel will still convert
150
+ plain strings to literal strings.
151
+
152
+ ==== SQL Fragment passed to Dataset#lock_style and Model#lock!
153
+
154
+ The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
155
+ an input string as SQL code. These methods should not be called with user input.
156
+
157
+ DB[:table].lock_style(params[:id]) # SQL injection!
158
+ Album.first.lock!(params[:id]) # SQL injection!
159
+
160
+ ==== SQL Type Names
161
+
162
+ In general, most places where Sequel needs to use an SQL type that should
163
+ be specified by the user, it allows you to use a ruby string, and that
164
+ string is used verbatim as the SQL type. You should not use user input
165
+ for type strings.
166
+
167
+ DB[:table].select(Sequel.cast(:a, params[:id])) # SQL injection!
168
+
169
+ ==== SQL Function Names
170
+
171
+ In most cases, Sequel does not quote SQL function names. You should not use
172
+ user input for function names.
173
+
174
+ DB[:table].select(Sequel.function(params[:id])) # SQL injection!
175
+
176
+ ==== SQL Window Frames
177
+
178
+ For backwards compatibility, Sequel supports regular strings in the
179
+ window function :frame option, which will be treated as a literal string:
180
+
181
+ DB[:table].select{fun(arg).over(:frame=>'SQL Here')}
182
+
183
+ You should make sure the frame argument is not derived from user input,
184
+ or switch to using a hash as the :frame option value.
185
+
186
+ ==== auto_literal_strings extension
148
187
 
149
- DB[:table].where{|o| o.name > params[:id].to_s} # Safe
188
+ If the auto_literal_strings extension is used for backwards compatibility,
189
+ then Sequel will treat plain strings as literal strings if they are used
190
+ as the first argument to a filtering method. This can lead to SQL
191
+ injection:
150
192
 
151
- Sequel's DSL supports a wide variety of SQL concepts, so it's possible to
152
- code most applications without ever using raw SQL.
193
+ DB[:table].where("name > #{params[:id].to_s}")
194
+ # SQL injection when using auto_literal_strings extension
153
195
 
154
- A large number of dataset methods ultimately pass down their arguments to a filter
155
- method, even some you may not expect, so you should be careful. At least the
156
- following methods pass their arguments to a filter method:
196
+ If you are using the auto_literal_strings extension, you need to be very careful,
197
+ as the following methods will treat a plain string given as the first argument
198
+ as a literal string:
157
199
 
158
200
  * Sequel::Dataset#where
159
201
  * Sequel::Dataset#having
160
202
  * Sequel::Dataset#filter
161
203
  * Sequel::Dataset#exclude
162
- * Sequel::Dataset#exclude_where
163
204
  * Sequel::Dataset#exclude_having
164
- * Sequel::Dataset#and
165
205
  * Sequel::Dataset#or
166
206
  * Sequel::Dataset#first
167
207
  * Sequel::Dataset#last
168
208
  * Sequel::Dataset#[]
169
209
 
170
- The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
171
- class methods also call down to the filter methods.
210
+ Even stuff that looks like it may be safe isn't:
172
211
 
173
- The no_auto_string_literals extension can be used to remove the default support
174
- for plain strings as literal strings in filter methods.
212
+ DB[:table].first(params[:num_rows])
213
+ # SQL injection when using auto_literal_strings extension
175
214
 
176
- ==== SQL Fragment passed to Dataset#update
215
+ The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and
216
+ Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
217
+ class methods will also treat string arguments as literal strings if the
218
+ auto_literal_strings extension is used:
177
219
 
178
- Similar to the filter methods, Sequel::Dataset#update also treats a
179
- string argument as raw SQL:
220
+ Album.find(params[:id])
221
+ # SQL injection when using auto_literal_strings extension
222
+
223
+ Similar to the filter methods, the auto_literal_strings extension
224
+ also makes Sequel::Dataset#update treats a string argument as raw SQL:
180
225
 
181
226
  DB[:table].update("column = 1")
182
227
 
183
228
  So you should not do:
184
229
 
185
- DB[:table].update("column = #{params[:value].to_s}") # SQL Injection!
186
-
187
- Instead, you should do:
230
+ DB[:table].update(params[:changes])
231
+ # SQL injection when using auto_literal_strings extension
188
232
 
189
- DB[:table].update(:column => params[:value].to_s) # Safe
190
-
191
- The no_auto_string_literals extension can also be used to remove the default support
192
- for plain strings as literal strings in update methods.
193
-
194
- ==== SQL Fragment passed to Dataset#lock_style and Model#lock!
233
+ or:
195
234
 
196
- The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
197
- an input string as SQL code. This method should not be called with user input.
198
-
199
- ==== SQL Type Names
200
-
201
- In general, most places where Sequel needs to use an SQL type that should
202
- be specified by the user, it allows you to use a ruby string, and that
203
- string is used verbatim as the SQL type. You should not use user input
204
- for type strings.
235
+ DB[:table].update("column = #{params[:value].to_s}")
236
+ # SQL injection when using auto_literal_strings extension
205
237
 
206
- ==== SQL Function Names
238
+ Instead, you should do:
207
239
 
208
- In most cases, Sequel does not quote SQL function names. You should not use
209
- user input for function names.
240
+ DB[:table].update(:column => params[:value].to_s) # Safe
210
241
 
242
+ Because using the auto_literal_strings extension makes SQL injection
243
+ so much eaiser, it is recommended to not use it, and instead
244
+ use Sequel.lit with placeholders.
245
+
211
246
  === SQL Identifier Injections
212
247
 
213
248
  Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
@@ -227,7 +262,7 @@ the Sequel::Dataset#insert and Sequel::Dataset#update methods:
227
262
  DB[:t].insert('b'=>1) # INSERT INTO "t" ("b") VALUES (1)
228
263
 
229
264
  Note how the identifier is still quoted in these cases. Sequel quotes identifiers by default
230
- on most databases. However, it does not quote identifiers by default on DB2 and Informix.
265
+ on most databases. However, it does not quote identifiers by default on DB2.
231
266
  On those databases using an identifier derived from user input can lead to SQL injection.
232
267
  Similarly, if you turn off identifier quoting manually on other databases, you open yourself
233
268
  up to SQL injection if you use identifiers derived from user input.
@@ -242,7 +277,8 @@ derived from user input unless absolutely necessary.
242
277
 
243
278
  Sequel also allows you to create identifiers using
244
279
  Sequel.identifier[rdoc-ref:Sequel::SQL::Builders#identifier] for plain identifiers,
245
- Sequel.qualify[rdoc-ref:Sequel::SQL::Builders#qualify] for qualified identifiers, and
280
+ Sequel.qualify[rdoc-ref:Sequel::SQL::Builders#qualify] and
281
+ Sequel::SQL::Indentifier#[][rdoc-ref:Sequel::SQL::QualifyingMethods#[]] for qualified identifiers, and
246
282
  Sequel.as[rdoc-ref:Sequel::SQL::Builders#as] for aliased expressions. So if you
247
283
  pass any of those values derived from user input, you are dealing with the same scenario.
248
284
 
@@ -252,6 +288,10 @@ uses symbols as identifiers. However, if you are creating symbols from user inp
252
288
  you at least have a denial of service vulnerability in ruby <2.2, and possibly a
253
289
  more serious vulnerability.
254
290
 
291
+ Note that many Database schema modification methods (e.g. create_table, add_column)
292
+ also allow for SQL identifier injections, and possibly also SQL code injections.
293
+ These methods should never be called with user input.
294
+
255
295
  == Denial of Service
256
296
 
257
297
  Sequel converts some strings to symbols. Because symbols in ruby <2.2 are not
@@ -283,7 +323,7 @@ if you allow the user to control the alias name:
283
323
 
284
324
  DB[:table].select(:column.as(params[:alias]))
285
325
 
286
- Then you have a denial of service vulnerability. In general, such a vulnerability
326
+ Then you can have a denial of service vulnerability. In general, such a vulnerability
287
327
  is unlikely, because you are probably indexing into the returned hash(es) by name,
288
328
  and if an alias was used and you didn't expect it, your application wouldn't work.
289
329
 
@@ -343,28 +383,17 @@ These two methods iterate over the second argument (+:name+ and +:copies_sold+ i
343
383
  this example) instead of iterating over the entries in the first argument
344
384
  (<tt>params[:album]</tt> in this example).
345
385
 
346
- In addition to these two methods, you can also use
347
- Model#set_only[rdoc-ref:Sequel::Model::InstanceMethods#set_only] or
348
- Model#update_only[rdoc-ref:Sequel::Model::InstanceMethods#update_only],
349
- which are similar but iterate over the entries in the first argument, checking
350
- the second argument to see if setting the entries is allowed.
351
-
352
- album.set_only(params[:album], [:name, :copies_sold])
353
- album.update_only(params[:album], [:name, :copies_sold])
354
-
355
- If you expect all entries in the second argument to be present in the first
356
- argument, use +set_fields+ or +update_fields+. If you are not sure if all
357
- arguments in the second argument will be present in the first argument, but
358
- do not want to allow setting any column other than the ones listed in the
359
- second argument, use +set_only+ or +update_only+.
360
-
361
- You can override the columns to allow by default during mass assignment via
362
- the Model.set_allowed_columns[rdoc-ref:Sequel::Model::ClassMethods#set_allowed_columns] class method. This is a good
363
- practice, though being explicit on a per-call basis is still recommended:
386
+ If you want to override the columns that Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set]
387
+ allows by default during mass assignment, you can use the whitelist_security plugin, then call
388
+ the set_allowed_columns class method.
364
389
 
390
+ Album.plugin :whitelist_security
365
391
  Album.set_allowed_columns(:name, :copies_sold)
366
392
  Album.create(params[:album]) # Only name and copies_sold set
367
393
 
394
+ Being explicit on a per-call basis using the set_fields and update_fields methods is recommended
395
+ instead of using the whitelist_security plugin and setting a global whitelist.
396
+
368
397
  For more details on the mass assignment methods, see the {Mass Assignment Guide}[rdoc-ref:doc/mass_assignment.rdoc].
369
398
 
370
399
  == General Parameter Handling
@@ -376,7 +405,7 @@ their type. For example:
376
405
  Album.where(:id=>params[:id])
377
406
 
378
407
  is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
379
- be a string, an array, a hash, or nil.
408
+ be a string, an array, a hash, nil, or potentially something else.
380
409
 
381
410
  Assuming that +id+ is an integer field, you probably want to do:
382
411
 
@@ -390,7 +419,7 @@ a string:
390
419
  If you are trying to use an IN clause with a list of id values based on input provided
391
420
  on a web form:
392
421
 
393
- Album.where(:id=>params[:ids].to_a.map{|i| i.to_i})
422
+ Album.where(:id=>params[:ids].to_a.map(&:to_i))
394
423
 
395
424
  Basically, be as explicit as possible. While there aren't any known security issues
396
425
  in Sequel when you do:
data/doc/sharding.rdoc CHANGED
@@ -1,7 +1,7 @@
1
- = Read-Only Slaves/Writable Master and Database Sharding
1
+ = Primary/Replica Configurations and Database Sharding
2
2
 
3
- Sequel has support for read only slave databases
4
- with a writable master database, as well as database sharding (where you can
3
+ Sequel has support for primary/replica configurations (writable primary
4
+ database with read only replicas databases), as well as database sharding (where you can
5
5
  pick a server to use for a given dataset). Support for both
6
6
  features is database independent, and should work for all database adapters
7
7
  that ship with Sequel.
@@ -13,7 +13,7 @@ option. Using the :servers database option makes Sequel use a connection pool
13
13
  class that supports sharding, and the minimum required to enable sharding
14
14
  support is to use the empty hash:
15
15
 
16
- DB=Sequel.connect('postgres://master_server/database', :servers=>{})
16
+ DB=Sequel.connect('postgres://primary_server/database', servers: {})
17
17
 
18
18
  In most cases, you are probably not going to want to use an empty hash. Keys in the server hash are
19
19
  not restricted to type, but the general recommendation is to use a symbol
@@ -28,69 +28,69 @@ a :host entry in each shard's hash.
28
28
  Note that all servers should have the same schema for all
29
29
  tables you are accessing, unless you really know what you are doing.
30
30
 
31
- == Master and Slave Database Configurations
31
+ == Primary and Replica Database Configurations
32
32
 
33
- === Single Read-Only Slave, Single Master
33
+ === Single Primary, Single Replica
34
34
 
35
- To use a single, read-only slave that handles SELECT queries, the following
35
+ To use a single, read-only replica that handles SELECT queries, the following
36
36
  is the simplest configuration:
37
37
 
38
- DB=Sequel.connect('postgres://master_server/database', \
39
- :servers=>{:read_only=>{:host=>'slave_server'}})
38
+ DB=Sequel.connect('postgres://primary_server/database',
39
+ servers: {read_only: {host: 'replica_server'}})
40
40
 
41
- This will use the slave_server for SELECT queries and master_server for
41
+ This will use the replica_server for SELECT queries and primary_server for
42
42
  other queries.
43
43
 
44
44
  If you want to ensure your queries are going to a specific database, you
45
45
  can force this for a given query by using the .server method and passing
46
46
  the symbol name defined in the connect options. For example:
47
47
 
48
- # Force the SELECT to run on the master
48
+ # Force the SELECT to run on the primary server
49
49
  DB[:users].server(:default).all
50
50
 
51
- # Force the SELECT to run on the read-only slave
52
- DB[:users].server(:read_only).all
51
+ # Force the DELETE to run on the read-only replica
52
+ DB[:users].server(:read_only).delete
53
53
 
54
- === Multiple Read-Only Slaves, Single Master
54
+ === Single Primary, Multiple Replicas
55
55
 
56
- Let's say you have 4 slave database servers with names slave_server0,
57
- slave_server1, slave_server2, and slave_server3.
56
+ Let's say you have 4 replica servers with names replica_server0,
57
+ replica_server1, replica_server2, and replica_server3.
58
58
 
59
59
  num_read_only = 4
60
60
  read_only_host = rand(num_read_only)
61
61
  read_only_proc = proc do |db|
62
- {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
62
+ {host: "replica_server#{(read_only_host+=1) % num_read_only}"}
63
63
  end
64
- DB=Sequel.connect('postgres://master_server/database', \
65
- :servers=>{:read_only=>read_only_proc})
64
+ DB=Sequel.connect('postgres://primary_server/database',
65
+ servers: {read_only: read_only_proc})
66
66
 
67
- This will use one of the slave servers for SELECT queries and use the
68
- master_server for other queries. It's also possible to pick a random host
67
+ This will use one of the replica servers for SELECT queries and use the
68
+ primary server for other queries. It's also possible to pick a random host
69
69
  instead of using the round robin approach presented above, but that can result
70
70
  in less optimal resource usage.
71
71
 
72
- === Multiple Read-Only Slaves, Multiple Masters
72
+ === Multiple Primary, Multiple Replicas
73
73
 
74
- This involves the same basic idea as the multiple slaves, single master, but
75
- it shows that the master database is named :default. So for 4 masters and
76
- 4 slaves:
74
+ This involves the same basic idea as the multiple replicas, single primary, but
75
+ it shows that the primary database is named :default. So for 4 primary servers and
76
+ 4 replica servers:
77
77
 
78
78
  num_read_only = 4
79
79
  read_only_host = rand(num_read_only)
80
80
  read_only_proc = proc do |db|
81
- {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
81
+ {host: "replica_server#{(read_only_host+=1) % num_read_only}"}
82
82
  end
83
83
  num_default = 4
84
84
  default_host = rand(num_default)
85
85
  default_proc = proc do |db|
86
- {:host=>"master_server#{(default_host+=1) % num_default}"}
86
+ {host: "primary_server#{(default_host+=1) % num_default}"}
87
87
  end
88
- DB=Sequel.connect('postgres://master_server/database', \
89
- :servers=>{:default=>default_proc, :read_only=>read_only_proc})
88
+ DB=Sequel.connect('postgres://primary_server/database',
89
+ servers: {default: default_proc, read_only: read_only_proc})
90
90
 
91
91
  == Sharding
92
92
 
93
- There is specific support in Sequel for handling master/slave database
93
+ There is specific support in Sequel for handling primary/replica database
94
94
  combinations, with the only necessary setup being the database configuration.
95
95
  However, since sharding is always going to be implementation dependent, Sequel
96
96
  supplies the basic infrastructure, but you have to tell it which server to use
@@ -100,16 +100,16 @@ of 16 shards). First, you need to configure the database:
100
100
 
101
101
  servers = {}
102
102
  (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
103
- servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
103
+ servers[hex.to_sym] = {host: "hash_host_#{hex}"}
104
104
  end
105
- DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers)
105
+ DB=Sequel.connect('postgres://hash_host/hashes', servers: servers)
106
106
 
107
107
  This configures 17 servers, the 16 shard servers (/hash_host_[0-9a-f]/), and 1
108
108
  default server which will be used if no shard is specified ("hash_host"). If
109
109
  you want the default server to be one of the shard servers (e.g. hash_host_a),
110
110
  it's easiest to do:
111
111
 
112
- DB=Sequel.connect('postgres://hash_host_a/hashes', :servers=>servers)
112
+ DB=Sequel.connect('postgres://hash_host_a/hashes', servers: servers)
113
113
 
114
114
  That will still set up a second pool of connections for the default server,
115
115
  since it considers the default server and shard servers independent. Note that
@@ -120,7 +120,7 @@ schemas, so you should always have a default server that works.
120
120
 
121
121
  To set the shard for a given query, you use the Dataset#server method:
122
122
 
123
- DB[:hashes].server(:a).where(:hash=>/31337/)
123
+ DB[:hashes].server(:a).where(hash: /31337/)
124
124
 
125
125
  That will return all matching rows on the hash_host_a shard that have a hash
126
126
  column that contains 31337.
@@ -133,37 +133,39 @@ the shard to use. This is fairly easy using a Sequel::Model:
133
133
  dataset_module do
134
134
  def plaintext_for_hash(hash)
135
135
  raise(ArgumentError, 'Invalid SHA-1 Hash') unless /\A[0-9a-f]{40}\z/.match(hash)
136
- server(hash[0...1].to_sym).where(:hash=>hash).get(:plaintext)
136
+ server(hash[0...1].to_sym).where(hash: hash).get(:plaintext)
137
137
  end
138
138
  end
139
139
  end
140
140
 
141
141
  Rainbow.plaintext_for_hash("e580726d31f6e1ad216ffd87279e536d1f74e606")
142
142
 
143
+ === :servers_hash Option
144
+
143
145
  The connection pool can be further controlled to change how it handles attempts
144
146
  to access shards that haven't been configured. The default is
145
147
  to assume the :default shard. However, you can specify a
146
148
  different shard using the :servers_hash option when connecting
147
149
  to the database:
148
150
 
149
- DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new(:some_shard))
151
+ DB = Sequel.connect('postgres://...', servers_hash: Hash.new(:some_shard))
150
152
 
151
153
  You can also use this feature to raise an exception if an
152
154
  unconfigured shard is used:
153
155
 
154
- DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new{raise 'foo'})
156
+ DB = Sequel.connect('postgres://...', servers_hash: Hash.new{raise 'foo'})
155
157
 
156
158
  If you specify a :servers_hash option to raise an exception for non configured
157
159
  shards you should also explicitly specify a :read_only entry in your :servers option
158
160
  for the case where a shard is not specified. In most cases it is sufficient
159
161
  to make the :read_only entry the same as the :default shard:
160
162
 
161
- servers = {:read_only => {}}
163
+ servers = {read_only: {}}
162
164
  (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
163
- servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
165
+ servers[hex.to_sym] = {host: "hash_host_#{hex}"}
164
166
  end
165
- DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers,
166
- :servers_hash=>Hash.new{raise Exception.new("Invalid Server")})
167
+ DB=Sequel.connect('postgres://hash_host/hashes', servers: servers,
168
+ servers_hash: Hash.new{raise "Invalid Server"})
167
169
 
168
170
  === Sharding Plugin
169
171
 
@@ -176,7 +178,7 @@ work well with shards. You just need to remember to set to model to use the plu
176
178
  plugin :sharding
177
179
  end
178
180
 
179
- Rainbow.server(:a).first(:id=>1).update(:plaintext=>'VGM')
181
+ Rainbow.server(:a).first(id: 1).update(plaintext: 'VGM')
180
182
 
181
183
  If all of your models are sharded, you can set all models to use the plugin via:
182
184
 
@@ -186,7 +188,7 @@ If all of your models are sharded, you can set all models to use the plugin via:
186
188
 
187
189
  By default, you must specify the server/shard you want to use for every dataset/action,
188
190
  or Sequel will use the default shard. If you have a group of queries that should use the
189
- same shard, it can get a bit redundent to specify the same shard for all of them.
191
+ same shard, it can get a bit redundant to specify the same shard for all of them.
190
192
 
191
193
  The server_block extension adds a Database#with_server method that scopes all database
192
194
  access inside the block to the given shard by default:
@@ -194,7 +196,7 @@ access inside the block to the given shard by default:
194
196
  DB.extension :server_block
195
197
  DB.with_server(:a) do
196
198
  # this SELECT query uses the "a" shard
197
- if r = Rainbow.first(:hash=>/31337/)
199
+ if r = Rainbow.first(hash: /31337/)
198
200
  r.count += 1
199
201
  # this UPDATE query also uses the "a" shard
200
202
  r.save
@@ -209,6 +211,19 @@ you retrieve the models inside the block and save them outside of the block. If
209
211
  need to do that, call the server method explicitly on the dataset used to retrieve the
210
212
  model objects.
211
213
 
214
+ The with_server method also supports a second argument for the default read_only server
215
+ to use, which can be useful if you are mixing sharding and primary/replica servers:
216
+
217
+ DB.extension :server_block
218
+ DB.with_server(:a, :a_read_only) do
219
+ # this SELECT query uses the "a_read_only" shard
220
+ if r = Rainbow.first(hash: /31337/)
221
+ r.count += 1
222
+ # this UPDATE query also uses the "a" shard
223
+ r.save
224
+ end
225
+ end
226
+
212
227
  === arbitrary_servers Extension
213
228
 
214
229
  By default, Sequel's sharding support is designed to work with predefined shards. It ships
@@ -220,13 +235,13 @@ The arbitrary_servers extension allows you to pass a server/shard options hash a
220
235
  server to use, and those options will be merged directly into the database's default options:
221
236
 
222
237
  DB.extension :arbitrary_servers
223
- DB[:rainbows].server(:host=>'hash_host_a').all
238
+ DB[:rainbows].server(host: 'hash_host_a').all
224
239
  # or
225
- DB[:rainbows].server(:host=>'hash_host_b', :database=>'backup').all
240
+ DB[:rainbows].server(host: 'hash_host_b', database: 'backup').all
226
241
 
227
242
  arbitrary_servers is designed to work well in conjunction with the server_block extension:
228
243
 
229
- DB.with_server(:host=>'hash_host_b', :database=>'backup') do
244
+ DB.with_server(host: 'hash_host_b', database: 'backup') do
230
245
  DB.synchronize do
231
246
  # All queries here default to the backup database on hash_host_b
232
247
  end
@@ -255,3 +270,15 @@ the Database, just remove that option. If you are setting:
255
270
  Sequel.single_threaded = true
256
271
 
257
272
  just remove or comment out that code.
273
+
274
+ == JDBC
275
+
276
+ If you are using the jdbc adapter, note that it does not handle separate
277
+ options such as +:host+, +:user+, and +:port+. If you would like to use
278
+ the +:servers+ option when connecting to a JDBC database, each hash value in
279
+ the +servers+ option should contain a +:uri+ key with a JDBC connection string
280
+ for that shard as the value. Example:
281
+
282
+ DB=Sequel.connect('jdbc:postgresql://primary_server/database',
283
+ servers: {read_only: {uri: 'jdbc:postgresql://replica_server/database'}})
284
+