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/querying.rdoc CHANGED
@@ -4,15 +4,15 @@ This guide is based on http://guides.rubyonrails.org/active_record_querying.html
4
4
 
5
5
  == Purpose of this Guide
6
6
 
7
- Sequel is a simple to use, very flexible, and powerful database library
7
+ Sequel is a flexible and powerful database library
8
8
  that supports a wide variety of different querying methods. This guide
9
- aims to be a gentle introduction to Sequel's querying support.
9
+ aims to be a introduction to Sequel's querying support.
10
10
 
11
- While you can easily use raw SQL with Sequel, a large part of the
11
+ While you can use raw SQL with Sequel, a large part of the
12
12
  advantage you get from using Sequel is Sequel's ability to abstract
13
- SQL from you and give you a much nicer interface. Sequel also ships with
13
+ SQL from you and give you a pure-ruby interface. Sequel also ships with
14
14
  a {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc],
15
- which better integrates Sequel's DSL into the ruby language.
15
+ which adds methods to core ruby types to work with Sequel.
16
16
 
17
17
  == Retrieving Objects
18
18
 
@@ -39,7 +39,7 @@ by its primary key value:
39
39
 
40
40
  # Find artist with primary key (id) 1
41
41
  artist = Artist[1]
42
- # SELECT * FROM artists WHERE id = 1
42
+ # SELECT * FROM artists WHERE (id = 1)
43
43
  # => #<Artist @values={:name=>"YJM", :id=>1}>
44
44
 
45
45
  If there is no record with the given primary key, nil will be returned. If you want
@@ -49,7 +49,7 @@ to raise an exception if no record is found, you can use <tt>Sequel::Model.with_
49
49
 
50
50
  ==== Using +first+
51
51
 
52
- If you just want the first record in the dataset,
52
+ If you want the first record in the dataset,
53
53
  <tt>Sequel::Dataset#first</tt> is probably the most obvious method to use:
54
54
 
55
55
  artist = Artist.first
@@ -58,7 +58,7 @@ If you just want the first record in the dataset,
58
58
 
59
59
  Any options you pass to +first+ will be used as a filter:
60
60
 
61
- artist = Artist.first(:name => 'YJM')
61
+ artist = Artist.first(name: 'YJM')
62
62
  # SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
63
63
  # => #<Artist @values={:name=>"YJM", :id=>1}>
64
64
 
@@ -72,7 +72,7 @@ raise an exception instead, use <tt>first!</tt>.
72
72
  <tt>Sequel::Dataset#[]</tt> is basically an alias for +first+, except it
73
73
  requires an argument:
74
74
 
75
- DB[:artists][:name => 'YJM']
75
+ DB[:artists][{name: 'YJM'}]
76
76
  # SELECT * FROM artists WHERE (name = 'YJM') LIMIT 1
77
77
  # => {:name=>"YJM", :id=>1}
78
78
 
@@ -82,22 +82,19 @@ Dataset#[] does not (unless it is a model dataset).
82
82
  ==== Using +last+
83
83
 
84
84
  If you want the last record in the dataset,
85
- <tt>Sequel::Dataset#last</tt> is an obvious method to use. Note
86
- that last requires that the dataset be ordered, unless the
87
- dataset is a model dataset. For a model dataset, +last+ will do a
88
- reverse order by the primary key field:
85
+ <tt>Sequel::Dataset#last</tt> is an obvious method to use. +last+ requires the
86
+ dataset be ordered, unless the dataset is a model dataset in which case +last+
87
+ will do a reverse order by the primary key field:
89
88
 
90
89
  artist = Artist.last
91
90
  # SELECT * FROM artists ORDER BY id DESC LIMIT 1
92
91
  # => #<Artist @values={:name=>"YJM", :id=>1}>
93
92
 
94
- Note that what +last+ does is reverse the order of the dataset and then
95
- call +first+. This is why +last+ raises a Sequel::Error if there is no
96
- order on a plain dataset, because otherwise it would provide the same record
97
- as +first+, and most users would find that confusing.
93
+ Note:
98
94
 
99
- Note that +last+ is not necessarily going to give you the last record
100
- in the dataset unless you give the dataset an unambiguous order.
95
+ 1. +last+ is equivalent to running a +reverse.first+ query, in other words it reverses the order of the dataset and then calls +first+. This is why +last+ raises a Sequel::Error when there is no order on a plain dataset - because it will provide the same record as +first+, and most users will find that confusing.
96
+ 2. +last+ is not necessarily going to give you the last record in the dataset unless you give the dataset an unambiguous order.
97
+ 3. +last+ will ignore +limit+ if chained together in a query because it sets a limit of 1 if no arguments are given.
101
98
 
102
99
  ==== Retrieving a Single Column Value
103
100
 
@@ -109,6 +106,15 @@ you want:
109
106
  # SELECT name FROM artists LIMIT 1
110
107
  # => "YJM"
111
108
 
109
+ ==== Retrieving a Multiple Column Values
110
+
111
+ If you want the value for multiple columns, you can pass an array to
112
+ <tt>Sequel::Dataset#get</tt>:
113
+
114
+ artist_id, artist_name = Artist.get([:id, :name])
115
+ # SELECT id, name FROM artists LIMIT 1
116
+ # => [1, "YJM"]
117
+
112
118
  === Retrieving Multiple Objects
113
119
 
114
120
  ==== As an Array of Hashes or Model Objects
@@ -181,21 +187,21 @@ an array of arrays of values will be returned:
181
187
  ==== As a Hash
182
188
 
183
189
  Sequel makes it easy to take an SQL query and return it as a ruby hash,
184
- using the +to_hash+ method:
190
+ using the +as_hash+ method:
185
191
 
186
- artist_names = Artist.to_hash(:id, :name)
192
+ artist_names = Artist.as_hash(:id, :name)
187
193
  # SELECT * FROM artists
188
194
  # => {1=>"YJM", 2=>"AS"}
189
195
 
190
- As you can see, the +to_hash+ method uses the first symbol as the key
196
+ As you can see, the +as_hash+ method uses the first symbol as the key
191
197
  and the second symbol as the value. So if you swap the two arguments the hash
192
198
  will have its keys and values transposed:
193
199
 
194
- artist_names = Artist.to_hash(:name, :id)
200
+ artist_names = Artist.as_hash(:name, :id)
195
201
  # SELECT * FROM artists
196
202
  # => {"YJM"=>1, "AS"=>2}
197
203
 
198
- Now what if you have multiple values for the same key? By default, +to_hash+
204
+ Now what if you have multiple values for the same key? By default, +as_hash+
199
205
  will just have the last matching value. If you care about all matching values,
200
206
  use +to_hash_groups+, which makes the values of the array an array of matching
201
207
  values, in the order they were received:
@@ -204,10 +210,10 @@ values, in the order they were received:
204
210
  # SELECT * FROM artists
205
211
  # => {"YJM"=>[1, 10, ...], "AS"=>[2, 20, ...]}
206
212
 
207
- If you only provide one argument to +to_hash+, it uses the entire hash
213
+ If you only provide one argument to +as_hash+, it uses the entire hash
208
214
  or model object as the value:
209
215
 
210
- artist_names = DB[:artists].to_hash(:name)
216
+ artist_names = DB[:artists].as_hash(:name)
211
217
  # SELECT * FROM artists
212
218
  # => {"YJM"=>{:id=>1, :name=>"YJM"}, "AS"=>{:id=>2, :name=>"AS"}}
213
219
 
@@ -217,12 +223,12 @@ and +to_hash_groups+ works similarly:
217
223
  # SELECT * FROM artists
218
224
  # => {"YJM"=>[{:id=>1, :name=>"YJM"}, {:id=>10, :name=>"YJM"}], ...}
219
225
 
220
- Model datasets have a +to_hash+ method that can be called without any
226
+ Model datasets have a +as_hash+ method that can be called without any
221
227
  arguments, in which case it will use the primary key as the key and
222
228
  the model object as the value. This can be used to easily create an
223
229
  identity map:
224
230
 
225
- artist_names = Artist.to_hash
231
+ artist_names = Artist.as_hash
226
232
  # SELECT * FROM artists
227
233
  # => {1=>#<Artist @values={:id=>1, :name=>"YGM"}>,
228
234
  # 2=>#<Artist @values={:id=>2, :name=>"AS"}>}
@@ -230,7 +236,7 @@ identity map:
230
236
  There is no equivalent handling to +to_hash_groups+, since there would
231
237
  only be one matching record, as the primary key must be unique.
232
238
 
233
- Note that +to_hash+ never modifies the columns selected. However, just
239
+ Note that +as_hash+ never modifies the columns selected. However, just
234
240
  like Sequel has a +select_map+ method to modify the columns selected and
235
241
  return an array, Sequel also has a +select_hash+ method to modify the
236
242
  columns selected and return a hash:
@@ -260,8 +266,8 @@ be using:
260
266
  1. Methods that return row(s), discussed above
261
267
  2. Methods that return modified datasets, discussed below
262
268
 
263
- Sequel uses a method chaining, functional style API to
264
- modify datasets. Let's start with a simple example.
269
+ Sequel datasets are frozen and use a method chaining, functional style API
270
+ that returns modified datasets. Let's start with a simple example.
265
271
 
266
272
  This is a basic dataset that includes all records in the
267
273
  table +artists+:
@@ -273,7 +279,7 @@ Let's say we are only interested in the artists whose names
273
279
  start with "A":
274
280
 
275
281
  ds2 = ds1.where(Sequel.like(:name, 'A%'))
276
- # SELECT * FROM artists WHERE name LIKE 'A%' ESCAPE '\'
282
+ # SELECT * FROM artists WHERE (name LIKE 'A%' ESCAPE '\')
277
283
 
278
284
  Here we see that +where+ returns a dataset that adds a +WHERE+
279
285
  clause to the query. It's important to note that +where+ does
@@ -282,10 +288,9 @@ not modify the receiver:
282
288
  ds1
283
289
  # SELECT * FROM artists
284
290
  ds2
285
- # SELECT * FROM artists WHERE name LIKE 'A%' ESCAPE '\'
291
+ # SELECT * FROM artists WHERE (name LIKE 'A%' ESCAPE '\')
286
292
 
287
- In Sequel, most dataset methods that you will be using will
288
- not modify the dataset itself, so you can freely use the dataset in multiple
293
+ In Sequel, dataset methods do not modify the dataset itself, so you can freely use the dataset in multiple
289
294
  places without worrying that its usage in one place will affect its usage
290
295
  in another place. This is what is meant by a functional style API.
291
296
 
@@ -293,7 +298,7 @@ Let's say we only want to select the id and name columns, and that
293
298
  we want to order by name:
294
299
 
295
300
  ds3 = ds2.order(:name).select(:id, :name)
296
- # SELECT id, name FROM artists WHERE name LIKE 'A%' ESCAPE '\' ORDER BY name
301
+ # SELECT id, name FROM artists WHERE (name LIKE 'A%' ESCAPE '\') ORDER BY name
297
302
 
298
303
  Note how you don't need to assign the returned value of order to a variable,
299
304
  and then call select on that. Because order just returns a dataset, you can
@@ -315,54 +320,59 @@ below.
315
320
  === Hashes
316
321
 
317
322
  The most common format for providing filters is via a hash. In general, Sequel
318
- treats conditions specified with a hash as equality or inclusion. What type
323
+ treats conditions specified with a hash as equality, inclusion, or identity. What type
319
324
  of condition is used depends on the values in the hash.
320
325
 
321
326
  Unless Sequel has special support for the value's class, it uses a simple
322
327
  equality statement:
323
328
 
324
- Artist.where(:id=>1)
325
- # SELECT * FROM artists WHERE id = 1
329
+ Artist.where(id: 1)
330
+ # SELECT * FROM artists WHERE (id = 1)
326
331
 
327
- Artist.where(:name=>'YJM')
328
- # SELECT * FROM artists WHERE name = 'YJM'
332
+ Artist.where(name: 'YJM')
333
+ # SELECT * FROM artists WHERE (name = 'YJM')
329
334
 
330
- For arrays, Sequel uses the IN operator.
335
+ For arrays, Sequel uses the IN operator with a value list:
331
336
 
332
- Artist.where(:id=>[1, 2])
333
- # SELECT * FROM artists WHERE id IN (1, 2)
337
+ Artist.where(id: [1, 2])
338
+ # SELECT * FROM artists WHERE (id IN (1, 2))
334
339
 
335
340
  For datasets, Sequel uses the IN operator with a subselect:
336
341
 
337
- Artist.where(:id=>Album.select(:artist_id))
338
- # SELECT * FROM artists WHERE id IN (
339
- # SELECT artist_id FROM albums)
342
+ Artist.where(id: Album.select(:artist_id))
343
+ # SELECT * FROM artists WHERE (id IN (
344
+ # SELECT artist_id FROM albums))
340
345
 
341
346
  For boolean values such as nil, true, and false, Sequel uses the IS operator:
342
347
 
343
- Artist.where(:id=>nil)
344
- # SELECT * FROM artists WHERE id IS NULL
348
+ Artist.where(id: nil)
349
+ # SELECT * FROM artists WHERE (id IS NULL)
345
350
 
346
351
  For ranges, Sequel uses a pair of inequality statements:
347
352
 
348
- Artist.where(:id=>1..5)
349
- # SELECT * FROM artists WHERE id >= 1 AND id <= 5
353
+ Artist.where(id: 1..5)
354
+ # SELECT * FROM artists WHERE ((id >= 1) AND (id <= 5))
355
+
356
+ Artist.where(id: 1...5)
357
+ # SELECT * FROM artists WHERE ((id >= 1) AND (id < 5))
350
358
 
351
359
  Finally, for regexps, Sequel uses an SQL regular expression. Note that this
352
- is probably only supported on PostgreSQL and MySQL.
360
+ is only supported by default on PostgreSQL and MySQL. It can also be supported
361
+ on SQLite when using the sqlite adapter with the :setup_regexp_function
362
+ Database option.
353
363
 
354
- Artist.where(:name=>/JM$/)
355
- # SELECT * FROM artists WHERE name ~ 'JM$'
364
+ Artist.where(name: /JM$/)
365
+ # SELECT * FROM artists WHERE (name ~ 'JM$')
356
366
 
357
367
  If there are multiple arguments in the hash, the filters are ANDed together:
358
368
 
359
- Artist.where(:id=>1, :name=>/JM$/)
360
- # SELECT * FROM artists WHERE id = 1 AND name ~ 'JM$'
369
+ Artist.where(id: 1, name: /JM$/)
370
+ # SELECT * FROM artists WHERE ((id = 1) AND (name ~ 'JM$'))
361
371
 
362
372
  This works the same as if you used two separate +where+ calls:
363
373
 
364
- Artist.where(:id=>1).where(:name=>/JM$/)
365
- # SELECT * FROM artists WHERE id = 1 AND name ~ 'JM$'
374
+ Artist.where(id: 1).where(name: /JM$/)
375
+ # SELECT * FROM artists WHERE ((id = 1) AND (name ~ 'JM$'))
366
376
 
367
377
  === Array of Two Element Arrays
368
378
 
@@ -371,28 +381,28 @@ advantage to using an array of two element arrays is that it allows you to
371
381
  duplicate keys, so you can do:
372
382
 
373
383
  Artist.where([[:name, /JM$/], [:name, /^YJ/]])
374
- # SELECT * FROM artists WHERE name ~ 'JM$' AND name ~ '^YJ'
384
+ # SELECT * FROM artists WHERE ((name ~ 'JM$')) AND ((name ~ '^YJ'))
375
385
 
376
386
  === Virtual Row Blocks
377
387
 
378
388
  If a block is passed to a filter, it is treated as a virtual row block:
379
389
 
380
390
  Artist.where{id > 5}
381
- # SELECT * FROM artists WHERE id > 5
391
+ # SELECT * FROM artists WHERE (id > 5)
382
392
 
383
393
  You can learn more about virtual row blocks in the {"Virtual Rows" guide}[rdoc-ref:doc/virtual_rows.rdoc].
384
394
 
385
395
  You can provide both regular arguments and a block, in which case the results
386
396
  will be ANDed together:
387
397
 
388
- Artist.where(:name=>'A'...'M'){id > 5}
389
- # SELECT * FROM artists WHERE name >= 'A' AND name < 'M' AND id > 5
398
+ Artist.where(name: 'A'...'M'){id > 5}
399
+ # SELECT * FROM artists WHERE ((name >= 'A') AND (name < 'M') AND (id > 5))
390
400
 
391
401
  Using virtual row blocks, what you can do with single entry hash or an array with
392
402
  a single two element array can also be done using the =~ method:
393
403
 
394
404
  Artist.where{id =~ 5}
395
- # SELECT * FROM artists WHERE id = 5
405
+ # SELECT * FROM artists WHERE (id = 5)
396
406
 
397
407
  === Symbols
398
408
 
@@ -416,47 +426,48 @@ which is used directly in the filter.
416
426
 
417
427
  You can use the DSL to create arbitrarily complex expressions. SQL::Expression
418
428
  objects can be created via singleton methods on the Sequel module. The most common
419
- method is Sequel.expr, which takes any object and wraps it in a SQL::Expression
429
+ method is Sequel.[], which takes any object and wraps it in a SQL::Expression
420
430
  object. In most cases, the SQL::Expression returned supports the & operator for
421
431
  +AND+, the | operator for +OR+, and the ~ operator for inversion:
422
432
 
423
- Artist.where(Sequel.like(:name, 'Y%') & (Sequel.expr(:b=>1) | Sequel.~(:c=>3)))
424
- # SELECT * FROM artists WHERE name LIKE 'Y%' ESCAPE '\' AND (b = 1 OR c != 3)
433
+ Artist.where(Sequel.like(:name, 'Y%') & (Sequel[{b: 1}] | Sequel.~(c: 3)))
434
+ # SELECT * FROM artists WHERE ((name LIKE 'Y%' ESCAPE '\') AND ((b = 1) OR (c != 3)))
425
435
 
426
436
  You can combine these expression operators with the virtual row support:
427
437
 
428
438
  Artist.where{(a > 1) & ~((b(c) < 1) | d)}
429
- # SELECT * FROM artists WHERE a > 1 AND b(c) >= 1 AND NOT d
439
+ # SELECT * FROM artists WHERE ((a > 1) AND (b(c) >= 1) AND NOT d)
430
440
 
431
441
  Note the use of parentheses when using the & and | operators, as they have lower
432
442
  precedence than other operators. The following will not work:
433
443
 
434
444
  Artist.where{a > 1 & ~(b(c) < 1 | d)}
435
- # Raises a TypeError, as it calls Integer#| with a Sequel::SQL::Identifier
445
+ # Raises a TypeError
436
446
 
437
447
  === Strings with Placeholders
438
448
 
439
- Assuming you want to get your hands dirty and write some SQL, Sequel allows you
440
- to use strings using placeholders for the values:
449
+ Assuming you want to get your hands dirty and use SQL fragments in filters, Sequel allows you
450
+ to do so if you explicitly mark the strings as literal strings using +Sequel.lit+. You can
451
+ use placeholders in the string and pass arguments for the placeholders:
441
452
 
442
- Artist.where("name LIKE ?", 'Y%')
443
- # SELECT * FROM artists WHERE name LIKE 'Y%'
453
+ Artist.where(Sequel.lit("name LIKE ?", 'Y%'))
454
+ # SELECT * FROM artists WHERE (name LIKE 'Y%')
444
455
 
445
456
  This is the most common type of placeholder, where each question mark is substituted
446
457
  with the next argument:
447
458
 
448
- Artist.where("name LIKE ? AND id = ?", 'Y%', 5)
449
- # SELECT * FROM artists WHERE name LIKE 'Y%' AND id = 5
459
+ Artist.where(Sequel.lit("name LIKE ? AND id = ?", 'Y%', 5))
460
+ # SELECT * FROM artists WHERE (name LIKE 'Y%' AND id = 5)
450
461
 
451
462
  You can also use named placeholders with a hash, where the named placeholders use
452
463
  colons before the placeholder names:
453
464
 
454
- Artist.where("name LIKE :name AND id = :id", :name=>'Y%', :id=>5)
455
- # SELECT * FROM artists WHERE name LIKE 'Y%' AND id = 5
465
+ Artist.where(Sequel.lit("name LIKE :name AND id = :id", name: 'Y%', id: 5))
466
+ # SELECT * FROM artists WHERE (name LIKE 'Y%' AND id = 5)
456
467
 
457
468
  You don't have to provide any placeholders if you don't want to:
458
469
 
459
- Artist.where("id = 2")
470
+ Artist.where(Sequel.lit("id = 2"))
460
471
  # SELECT * FROM artists WHERE id = 2
461
472
 
462
473
  However, if you are using any untrusted input, you should definitely be using placeholders.
@@ -464,9 +475,9 @@ In general, unless you are hardcoding values in the strings, you should use plac
464
475
  You should never pass a string that has been built using interpolation, unless you are
465
476
  sure of what you are doing.
466
477
 
467
- Artist.where("id = #{params[:id]}") # Don't do this!
468
- Artist.where("id = ?", params[:id]) # Do this instead
469
- Artist.where(:id=>params[:id].to_i) # Even better
478
+ Artist.where(Sequel.lit("id = #{params[:id]}")) # Don't do this!
479
+ Artist.where(Sequel.lit("id = ?", params[:id])) # Do this instead
480
+ Artist.where(id: params[:id].to_i) # Even better
470
481
 
471
482
  === Inverting
472
483
 
@@ -474,53 +485,53 @@ You may be wondering how to specify a not equals condition in Sequel, or the NOT
474
485
  operator. Sequel has generic support for inverting conditions, so to write a not
475
486
  equals condition, you write an equals condition, and invert it:
476
487
 
477
- Artist.where(:id=>5).invert
478
- # SELECT * FROM artists WHERE id != 5
488
+ Artist.where(id: 5).invert
489
+ # SELECT * FROM artists WHERE (id != 5)
479
490
 
480
491
  Note that +invert+ inverts the entire filter:
481
492
 
482
- Artist.where(:id=>5).where{name > 'A'}.invert
483
- # SELECT * FROM artists WHERE id != 5 OR name <= 'A'
493
+ Artist.where(id: 5).where{name > 'A'}.invert
494
+ # SELECT * FROM artists WHERE ((id != 5) OR (name <= 'A'))
484
495
 
485
496
  In general, +invert+ is used rarely, since +exclude+ allows you to invert only specific
486
497
  filters:
487
498
 
488
- Artist.exclude(:id=>5)
489
- # SELECT * FROM artists WHERE id != 5
499
+ Artist.exclude(id: 5)
500
+ # SELECT * FROM artists WHERE (id != 5)
490
501
 
491
- Artist.where(:id=>5).exclude{name > 'A'}
492
- # SELECT * FROM artists WHERE id = 5 OR name <= 'A'
502
+ Artist.where(id: 5).exclude{name > 'A'}
503
+ # SELECT * FROM artists WHERE ((id = 5) AND (name <= 'A')
493
504
 
494
505
  So to do a NOT IN with an array:
495
506
 
496
- Artist.exclude(:id=>[1, 2])
497
- # SELECT * FROM artists WHERE id NOT IN (1, 2)
507
+ Artist.exclude(id: [1, 2])
508
+ # SELECT * FROM artists WHERE (id NOT IN (1, 2))
498
509
 
499
510
  Or to use the NOT LIKE operator:
500
511
 
501
512
  Artist.exclude(Sequel.like(:name, '%J%'))
502
- # SELECT * FROM artists WHERE name NOT LIKE '%J%' ESCAPE '\'
513
+ # SELECT * FROM artists WHERE (name NOT LIKE '%J%' ESCAPE '\')
503
514
 
504
515
  You can use Sequel.~ to negate expressions:
505
516
 
506
- Artist.where(Sequel.~(:id=>5))
517
+ Artist.where(Sequel.~(id: 5))
507
518
  # SELECT * FROM artists WHERE id != 5
508
519
 
509
520
  On Sequel expression objects, you can use ~ to negate them:
510
521
 
511
522
  Artist.where(~Sequel.like(:name, '%J%'))
512
- # SELECT * FROM artists WHERE name NOT LIKE '%J%' ESCAPE '\'
523
+ # SELECT * FROM artists WHERE (name NOT LIKE '%J%' ESCAPE '\')
513
524
 
514
- On Ruby 1.9+, you can use !~ on Sequel expressions to create negated expressions:
525
+ You can use !~ on Sequel expressions to create negated expressions:
515
526
 
516
- Artist.where{ id !~ 5}
517
- # SELECT * FROM artists WHERE id != 5
527
+ Artist.where{id !~ 5}
528
+ # SELECT * FROM artists WHERE (id != 5)
518
529
 
519
530
  === Removing
520
531
 
521
532
  To remove all existing filters, use +unfiltered+:
522
533
 
523
- Artist.where(:id=>1).unfiltered
534
+ Artist.where(id: 1).unfiltered
524
535
  # SELECT * FROM artists
525
536
 
526
537
  == Ordering
@@ -555,14 +566,17 @@ If you want to add a column to the beginning of the existing order:
555
566
  === Reversing
556
567
 
557
568
  Just like you can invert an existing filter, you can reverse an existing
558
- order, using +reverse+:
569
+ order, using +reverse+ without an order:
559
570
 
560
571
  Artist.order(:id).reverse
561
572
  # SELECT FROM artists ORDER BY id DESC
562
573
 
563
- As you might expect, +reverse+ is not used all that much. In general,
564
- <tt>Sequel.desc</tt> is used more commonly to specify a descending order
565
- for columns:
574
+ Alternatively, you can provide reverse with the order:
575
+
576
+ Artist.reverse(:id)
577
+ # SELECT FROM artists ORDER BY id DESC
578
+
579
+ To specify a single entry be reversed, <tt>Sequel.desc</tt> can be used:
566
580
 
567
581
  Artist.order(Sequel.desc(:id))
568
582
  # SELECT FROM artists ORDER BY id DESC
@@ -658,7 +672,7 @@ You can also call the +offset+ method separately:
658
672
  Either of these would return the 11th through 15th records in the original
659
673
  dataset.
660
674
 
661
- To remove a limit from a dataset, use +unlimited+:
675
+ To remove a limit and offset from a dataset, use +unlimited+:
662
676
 
663
677
  Artist.limit(5, 10).unlimited
664
678
  # SELECT * FROM artists
@@ -709,50 +723,46 @@ filters the results after the grouping has been applied, instead of
709
723
  before. One possible use is if you only wanted to return artists
710
724
  who had at least 10 albums:
711
725
 
712
- Album.group_and_count(:artist_id).having{count(:*){} >= 10}
726
+ Album.group_and_count(:artist_id).having{count.function.* >= 10}
713
727
  # SELECT artist_id, count(*) AS count FROM albums
714
- # GROUP BY artist_id HAVING count(*) >= 10
728
+ # GROUP BY artist_id HAVING (count(*) >= 10)
715
729
 
716
730
  Both the WHERE clause and the HAVING clause are removed by +unfiltered+:
717
731
 
718
- Album.group_and_count(:artist_id).having{count(:*){} >= 10}.
732
+ Album.group_and_count(:artist_id).having{count.function.* >= 10}.
719
733
  where(:name.like('A%')).unfiltered
720
734
  # SELECT artist_id, count(*) AS count FROM albums GROUP BY artist_id
721
735
 
722
736
  == Joins
723
737
 
724
- Sequel makes it very easy to join a dataset to another table or dataset.
738
+ Sequel has support for many different SQL join types.
725
739
  The underlying method used is +join_table+:
726
740
 
727
- Album.join_table(:inner, :artists, :id=>:artist_id)
741
+ Album.join_table(:inner, :artists, id: :artist_id)
728
742
  # SELECT * FROM albums
729
- # INNER JOIN artists ON artists.id = albums.artist_id
743
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
730
744
 
731
745
  In most cases, you won't call +join_table+ directly, as Sequel provides
732
746
  shortcuts for all common (and most uncommon) join types. For example
733
747
  +join+ does an inner join:
734
748
 
735
- Album.join(:artists, :id=>:artist_id)
749
+ Album.join(:artists, id: :artist_id)
736
750
  # SELECT * FROM albums
737
- # INNER JOIN artists ON artists.id = albums.artist_id
751
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
738
752
 
739
753
  And +left_join+ does a LEFT JOIN:
740
754
 
741
- Album.left_join(:artists, :id=>:artist_id)
755
+ Album.left_join(:artists, id: :artist_id)
742
756
  # SELECT * FROM albums
743
- # LEFT JOIN artists ON artists.id = albums.artist_id
757
+ # LEFT JOIN artists ON (artists.id = albums.artist_id)
744
758
 
745
759
  === Table/Dataset to Join
746
760
 
747
761
  For all of these specialized join methods, the first argument is
748
762
  generally the name of the table to which you are joining. However, you
749
- can also provide a model class:
763
+ can also provide a dataset, in which case a subselect is used:
750
764
 
751
- Album.join(Artist, :id=>:artist_id)
752
-
753
- Or a dataset, in which case a subselect is used:
754
-
755
- Album.join(Artist.where{name < 'A'}, :id=>:artist_id)
765
+ Album.join(Artist.where{name < 'A'}, id: :artist_id)
756
766
  # SELECT * FROM albums
757
767
  # INNER JOIN (SELECT * FROM artists WHERE (name < 'A')) AS t1
758
768
  # ON (t1.id = albums.artist_id)
@@ -768,80 +778,78 @@ a few minor exceptions.
768
778
  A hash used as the join conditions operates similarly to a filter,
769
779
  except that unqualified symbol keys are automatically qualified
770
780
  with the table from the first argument, and unqualified symbol values
771
- are automatically qualified with the first table or the last table
772
- joined. This implicit qualification is one of the reasons that joins
773
- in Sequel are easy to specify:
781
+ are automatically qualified with the last table joined (or the first
782
+ table in the dataset if there hasn't been a previous join):
774
783
 
775
- Album.join(:artists, :id=>:artist_id)
784
+ Album.join(:artists, id: :artist_id)
776
785
  # SELECT * FROM albums
777
- # INNER JOIN artists ON artists.id = albums.artist_id
786
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
778
787
 
779
- Note how the <tt>:id</tt> symbol is automatically qualified with +artists+,
788
+ Note how the +id+ symbol is automatically qualified with +artists+,
780
789
  while the +artist_id+ symbol is automatically qualified with +albums+.
781
790
 
782
791
  Because Sequel uses the last joined table for implicit qualifications
783
792
  of values, you can do things like:
784
793
 
785
- Album.join(:artists, :id=>:artist_id).
786
- join(:members, :artist_id=>:id)
794
+ Album.join(:artists, id: :artist_id).
795
+ join(:members, artist_id: :id)
787
796
  # SELECT * FROM albums
788
- # INNER JOIN artists ON artists.id = albums.artist_id
789
- # INNER JOIN members ON members.artist_id = artists.id
797
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
798
+ # INNER JOIN members ON (members.artist_id = artists.id)
790
799
 
791
800
  Note that when joining to the +members+ table, +artist_id+ is qualified
792
801
  with +members+ and +id+ is qualified with +artists+.
793
802
 
794
803
  While a good default, implicit qualification is not always correct:
795
804
 
796
- Album.join(:artists, :id=>:artist_id).
797
- join(:tracks, :album_id=>:id)
805
+ Album.join(:artists, id: :artist_id).
806
+ join(:tracks, album_id: :id)
798
807
  # SELECT * FROM albums
799
- # INNER JOIN artists ON artists.id = albums.artist_id
800
- # INNER JOIN tracks ON tracks.album_id = artists.id
808
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
809
+ # INNER JOIN tracks ON (tracks.album_id = artists.id)
801
810
 
802
811
  Note here how +id+ is qualified with +artists+ instead of +albums+. This
803
812
  is wrong as the foreign key <tt>tracks.album_id</tt> refers to <tt>albums.id</tt>, not
804
813
  <tt>artists.id</tt>. To fix this, you need to explicitly qualify when joining:
805
814
 
806
- Album.join(:artists, :id=>:artist_id).
807
- join(:tracks, :album_id=>:albums__id)
815
+ Album.join(:artists, id: :artist_id).
816
+ join(:tracks, album_id: Sequel[:albums][:id])
808
817
  # SELECT * FROM albums
809
- # INNER JOIN artists ON artists.id = albums.artist_id
810
- # INNER JOIN tracks ON tracks.album_id = albums.id
818
+ # INNER JOIN artists ON (artists.id = albums.artist_id)
819
+ # INNER JOIN tracks ON (tracks.album_id = albums.id)
811
820
 
812
821
  Just like in filters, an array of two element arrays is treated the same
813
822
  as a hash, but allows for duplicate keys:
814
823
 
815
824
  Album.join(:artists, [[:id, :artist_id], [:id, 1..5]])
816
825
  # SELECT * FROM albums INNER JOIN artists
817
- # ON artists.id = albums.artist_id
818
- # AND artists.id >= 1 AND artists.id <= 5
826
+ # ON ((artists.id = albums.artist_id)
827
+ # AND (artists.id >= 1) AND (artists.id <= 5))
819
828
 
820
829
  And just like in the hash case, unqualified symbol elements in the
821
830
  array are implicitly qualified.
822
831
 
823
832
  By default, Sequel only qualifies unqualified symbols in the conditions. However,
824
- You can provide an options hash with a <tt>:qualify=>:deep</tt> option to do a deep
833
+ You can provide an options hash with a <tt>qualify: :deep</tt> option to do a deep
825
834
  qualification, which can qualify subexpressions. For example, let's say you are doing
826
835
  a JOIN using case insensitive string comparison:
827
836
 
828
837
  Album.join(:artists, {Sequel.function(:lower, :name) =>
829
838
  Sequel.function(:lower, :artist_name)},
830
- :qualify => :deep)
839
+ qualify: :deep)
831
840
  # SELECT * FROM albums INNER JOIN artists
832
841
  # ON (lower(artists.name) = lower(albums.artist_name))
833
842
 
834
- Note how the arguments to lower were qualified correctly in both cases. Starting in Sequel 4,
835
- the <tt>:qualify=>:deep</tt> option is going to become the default.
843
+ Note how the arguments to lower were qualified correctly in both cases.
836
844
 
837
845
  ==== USING Joins
838
846
 
839
847
  The most common type of join conditions is a JOIN ON, as displayed
840
848
  above. However, the SQL standard allows for join conditions to be
841
- specified with JOIN USING, which Sequel makes easy to use.
849
+ specified with JOIN USING, assuming the column name is the same in
850
+ both tables.
842
851
 
843
- JOIN USING is useful when the columns you are using have the same
844
- names in both tables. For example, if instead of having a primary
852
+ For example, if instead of having a primary
845
853
  column named +id+ in all of your tables, you use +artist_id+ in your
846
854
  +artists+ table and +album_id+ in your +albums+ table, you could do:
847
855
 
@@ -852,7 +860,7 @@ See here how you specify the USING columns as an array of symbols.
852
860
 
853
861
  ==== NATURAL Joins
854
862
 
855
- NATURAL Joins take it one step further than USING joins, by assuming
863
+ NATURAL joins take it one step further than USING joins, by assuming
856
864
  that all columns with the same names in both tables should be
857
865
  used for joining:
858
866
 
@@ -864,23 +872,23 @@ In this case, you don't even need to specify any conditions.
864
872
  ==== Join Blocks
865
873
 
866
874
  You can provide a block to any of the join methods that accept
867
- conditions. This block should accept 3 arguments, the table alias
875
+ conditions. This block should accept 3 arguments: the table alias
868
876
  for the table currently being joined, the table alias for the last
869
877
  table joined (or first table), and an array of previous
870
878
  <tt>Sequel::SQL::JoinClause</tt>s.
871
879
 
872
880
  This allows you to qualify columns similar to how the implicit
873
881
  qualification works, without worrying about the specific aliases
874
- being used. For example, lets say you wanted to join the albums
882
+ being used. For example, let's say you wanted to join the albums
875
883
  and artists tables, but only want albums where the artist's name
876
884
  comes before the album's name.
877
885
 
878
- Album.join(:artists, :id=>:artist_id) do |j, lj, js|
879
- Sequel.qualify(j, :name) < Sequel.qualify(lj, :name)
886
+ Album.join(:artists, id: :artist_id) do |j, lj, js|
887
+ Sequel[j][:name] < Sequel[lj][:name]
880
888
  end
881
889
  # SELECT * FROM albums INNER JOIN artists
882
- # ON artists.id = albums.artist_id
883
- # AND artists.name < albums.name
890
+ # ON ((artists.id = albums.artist_id)
891
+ # AND (artists.name < albums.name))
884
892
 
885
893
  Because greater than can't be expressed with a hash in Sequel, you
886
894
  need to use a block and qualify the tables manually.
@@ -904,8 +912,8 @@ number of old albums.
904
912
  Using multiple FROM tables and setting conditions in the WHERE clause is
905
913
  an old-school way of joining tables:
906
914
 
907
- DB.from(:albums, :artists).where(:artists__id=>:albums__artist_id)
908
- # SELECT * FROM albums, artists WHERE artists.id = albums.artist_id
915
+ DB.from(:albums, :artists).where{{artists[:id]=>albums[:artist_id]}}
916
+ # SELECT * FROM albums, artists WHERE (artists.id = albums.artist_id)
909
917
 
910
918
  === Using the current dataset in a subselect
911
919
 
@@ -916,7 +924,7 @@ Here's an example using +from_self+:
916
924
  # SELECT * FROM (SELECT * FROM albums ORDER BY artist_id LIMIT 100)
917
925
  # AS t1 GROUP BY artist_id
918
926
 
919
- This is slightly different than without +from_self+:
927
+ This is different than without +from_self+:
920
928
 
921
929
  Album.order(:artist_id).limit(100).group(:artist_id)
922
930
  # SELECT * FROM albums GROUP BY artist_id ORDER BY name LIMIT 100
@@ -937,8 +945,8 @@ current transaction commits. You just use the +for_update+ dataset
937
945
  method when returning the rows:
938
946
 
939
947
  DB.transaction do
940
- album = Album.for_update.first(:id=>1)
941
- # SELECT * FROM albums WHERE id = 1 FOR UPDATE
948
+ album = Album.for_update.first(id: 1)
949
+ # SELECT * FROM albums WHERE (id = 1) FOR UPDATE
942
950
  album.num_tracks += 1
943
951
  album.save
944
952
  end
@@ -956,7 +964,7 @@ stateless nature.
956
964
 
957
965
  == Custom SQL
958
966
 
959
- Sequel makes it easy to use custom SQL by providing it to the <tt>Database#[]</tt>
967
+ Sequel makes it easy to use custom SQL for the query by providing it to the <tt>Database#[]</tt>
960
968
  method as a string:
961
969
 
962
970
  DB["SELECT * FROM artists"]
@@ -973,7 +981,7 @@ With either of these methods, you can use placeholders:
973
981
  DB["SELECT * FROM artists WHERE id = ?", 5]
974
982
  # SELECT * FROM artists WHERE id = 5
975
983
 
976
- DB[:albums].with_sql("SELECT * FROM artists WHERE id = :id", :id=>5)
984
+ DB[:albums].with_sql("SELECT * FROM artists WHERE id = :id", id: 5)
977
985
  # SELECT * FROM artists WHERE id = 5
978
986
 
979
987
  Note that if you specify the dataset using custom SQL, you can still call the dataset
@@ -982,6 +990,13 @@ modification methods, but in many cases they will appear to have no affect:
982
990
  DB["SELECT * FROM artists"].select(:name).order(:id)
983
991
  # SELECT * FROM artists
984
992
 
993
+ You can use the implicit_subquery extension to automatically wrap queries that use
994
+ custom SQL in subqueries if a method is called that would modify the SQL:
995
+
996
+ DB.extension :implicit_subquery
997
+ DB["SELECT * FROM artists"].select(:name).order(:id)
998
+ # SELECT name FROM (SELECT * FROM artists) AS t1 ORDER BY id"
999
+
985
1000
  If you must drop down to using custom SQL, it's recommended that you only do so for
986
1001
  specific parts of a query. For example, if the reason you are using custom SQL is
987
1002
  to use a custom operator in the database in the SELECT clause:
@@ -1003,12 +1018,12 @@ If you just want to know whether the current dataset would return any rows, use
1003
1018
  # SELECT 1 FROM albums LIMIT 1
1004
1019
  # => false
1005
1020
 
1006
- Album.where(:id=>0).empty?
1007
- # SELECT 1 FROM albums WHERE id = 0 LIMIT 1
1021
+ Album.where(id: 0).empty?
1022
+ # SELECT 1 FROM albums WHERE (id = 0) LIMIT 1
1008
1023
  # => true
1009
1024
 
1010
1025
  Album.where(Sequel.like(:name, 'R%')).empty?
1011
- # SELECT 1 FROM albums WHERE name LIKE 'R%' ESCAPE '\' LIMIT 1
1026
+ # SELECT 1 FROM albums WHERE (name LIKE 'R%' ESCAPE '\') LIMIT 1
1012
1027
  # => false
1013
1028
 
1014
1029
  == Aggregate Calculations
@@ -1022,22 +1037,29 @@ for each of these aggregate functions.
1022
1037
  Album.count
1023
1038
  # SELECT count(*) AS count FROM albums LIMIT 1
1024
1039
  # => 2
1025
-
1040
+
1041
+ If you pass an expression to count, it will return the number of records where
1042
+ that expression in not NULL:
1043
+
1044
+ Album.count(:artist_id)
1045
+ # SELECT count(artist_id) AS count FROM albums LIMIT 1
1046
+ # => 1
1047
+
1026
1048
  The other methods take a column argument and call the aggregate function with
1027
1049
  the argument:
1028
1050
 
1029
1051
  Album.sum(:id)
1030
- # SELECT sum(id) FROM albums LIMIT 1
1052
+ # SELECT sum(id) AS sum FROM albums LIMIT 1
1031
1053
  # => 3
1032
1054
 
1033
1055
  Album.avg(:id)
1034
- # SELECT avg(id) FROM albums LIMIT 1
1056
+ # SELECT avg(id) AS avg FROM albums LIMIT 1
1035
1057
  # => 1.5
1036
1058
 
1037
1059
  Album.min(:id)
1038
- # SELECT min(id) FROM albums LIMIT 1
1060
+ # SELECT min(id) AS min FROM albums LIMIT 1
1039
1061
  # => 1
1040
1062
 
1041
1063
  Album.max(:id)
1042
- # SELECT max(id) FROM albums LIMIT 1
1064
+ # SELECT max(id) AS max FROM albums LIMIT 1
1043
1065
  # => 2