sequel 4.26.0 → 5.37.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 (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  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/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,30 +1,38 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
- # A dataset represents an SQL query, or more generally, an abstract
3
- # set of rows in the database. Datasets
4
- # can be used to create, retrieve, update and delete records.
4
+ # A dataset represents an SQL query. Datasets
5
+ # can be used to select, insert, update and delete records.
5
6
  #
6
7
  # Query results are always retrieved on demand, so a dataset can be kept
7
8
  # around and reused indefinitely (datasets never cache results):
8
9
  #
9
- # my_posts = DB[:posts].filter(:author => 'david') # no records are retrieved
10
+ # my_posts = DB[:posts].where(author: 'david') # no records are retrieved
10
11
  # my_posts.all # records are retrieved
11
12
  # my_posts.all # records are retrieved again
12
13
  #
13
- # Most dataset methods return modified copies of the dataset (functional style), so you can
14
- # reuse different datasets to access data:
14
+ # Datasets are frozen and use a functional style where modification methods
15
+ # return modified copies of the the dataset. This allows you to reuse
16
+ # datasets:
15
17
  #
16
18
  # posts = DB[:posts]
17
- # davids_posts = posts.filter(:author => 'david')
18
- # old_posts = posts.filter('stamp < ?', Date.today - 7)
19
- # davids_old_posts = davids_posts.filter('stamp < ?', Date.today - 7)
19
+ # davids_posts = posts.where(author: 'david')
20
+ # old_posts = posts.where{stamp < Date.today - 7}
21
+ # davids_old_posts = davids_posts.where{stamp < Date.today - 7}
20
22
  #
21
- # Datasets are Enumerable objects, so they can be manipulated using any
22
- # of the Enumerable methods, such as map, inject, etc.
23
+ # Datasets are Enumerable objects, so they can be manipulated using many
24
+ # of the Enumerable methods, such as +map+ and +inject+. Note that there are some methods
25
+ # that Dataset defines that override methods defined in Enumerable and result in different
26
+ # behavior, such as +select+ and +group_by+.
23
27
  #
24
28
  # For more information, see the {"Dataset Basics" guide}[rdoc-ref:doc/dataset_basics.rdoc].
25
29
  class Dataset
26
30
  OPTS = Sequel::OPTS
27
31
 
32
+ # Whether Dataset#freeze can actually freeze datasets. True only on ruby 2.4+,
33
+ # as it requires clone(freeze: false)
34
+ TRUE_FREEZE = RUBY_VERSION >= '2.4'
35
+
28
36
  include Enumerable
29
37
  include SQL::AliasMethods
30
38
  include SQL::BooleanMethods
@@ -36,5 +44,13 @@ module Sequel
36
44
  include SQL::StringMethods
37
45
  end
38
46
 
39
- require(%w"query actions features graph prepared_statements misc mutation sql placeholder_literalizer", 'dataset')
47
+ require_relative "dataset/query"
48
+ require_relative "dataset/actions"
49
+ require_relative "dataset/features"
50
+ require_relative "dataset/graph"
51
+ require_relative "dataset/prepared_statements"
52
+ require_relative "dataset/misc"
53
+ require_relative "dataset/sql"
54
+ require_relative "dataset/placeholder_literalizer"
55
+ require_relative "dataset/dataset_module"
40
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
4
  class Dataset
3
5
  # ---------------------
@@ -8,17 +10,21 @@ module Sequel
8
10
  # ---------------------
9
11
 
10
12
  # Action methods defined by Sequel that execute code on the database.
11
- ACTION_METHODS = (<<-METHS).split.map(&:to_sym)
12
- << [] all avg count columns columns! delete each
13
- empty? fetch_rows first first! get import insert interval last
14
- map max min multi_insert paged_each range select_hash select_hash_groups select_map select_order_map
15
- single_record single_value sum to_hash to_hash_groups truncate update
13
+ ACTION_METHODS = (<<-METHS).split.map(&:to_sym).freeze
14
+ << [] all as_hash avg count columns columns! delete each
15
+ empty? fetch_rows first first! get import insert last
16
+ map max min multi_insert paged_each select_hash select_hash_groups select_map select_order_map
17
+ single_record single_record! single_value single_value! sum to_hash to_hash_groups truncate update
18
+ where_all where_each where_single_value
16
19
  METHS
17
20
 
21
+ # The clone options to use when retrieving columns for a dataset.
22
+ COLUMNS_CLONE_OPTIONS = {:distinct => nil, :limit => 1, :offset=>nil, :where=>nil, :having=>nil, :order=>nil, :row_proc=>nil, :graph=>nil, :eager_graph=>nil}.freeze
23
+
18
24
  # Inserts the given argument into the database. Returns self so it
19
25
  # can be used safely when chaining:
20
26
  #
21
- # DB[:items] << {:id=>0, :name=>'Zero'} << DB[:old_items].select(:id, name)
27
+ # DB[:items] << {id: 0, name: 'Zero'} << DB[:old_items].select(:id, name)
22
28
  def <<(arg)
23
29
  insert(arg)
24
30
  self
@@ -26,10 +32,10 @@ module Sequel
26
32
 
27
33
  # Returns the first record matching the conditions. Examples:
28
34
  #
29
- # DB[:table][:id=>1] # SELECT * FROM table WHERE (id = 1) LIMIT 1
30
- # # => {:id=1}
35
+ # DB[:table][id: 1] # SELECT * FROM table WHERE (id = 1) LIMIT 1
36
+ # # => {:id=>1}
31
37
  def [](*conditions)
32
- raise(Error, ARRAY_ACCESS_ERROR_MSG) if (conditions.length == 1 and conditions.first.is_a?(Integer)) or conditions.length == 0
38
+ raise(Error, 'You cannot call Dataset#[] with an integer or with no arguments') if (conditions.length == 1 and conditions.first.is_a?(Integer)) or conditions.length == 0
33
39
  first(*conditions)
34
40
  end
35
41
 
@@ -52,8 +58,9 @@ module Sequel
52
58
  # # => 3
53
59
  # DB[:table].avg{function(column)} # SELECT avg(function(column)) FROM table LIMIT 1
54
60
  # # => 1
55
- def avg(column=Sequel.virtual_row(&Proc.new))
56
- aggregate_dataset.get{avg(column).as(:avg)}
61
+ def avg(arg=(no_arg = true), &block)
62
+ arg = Sequel.virtual_row(&block) if no_arg
63
+ _aggregate(:avg, arg)
57
64
  end
58
65
 
59
66
  # Returns the columns in the result set in order as an array of symbols.
@@ -66,11 +73,7 @@ module Sequel
66
73
  # DB[:table].columns
67
74
  # # => [:id, :name]
68
75
  def columns
69
- return @columns if @columns
70
- ds = unfiltered.unordered.naked.clone(:distinct => nil, :limit => 1, :offset=>nil)
71
- ds.each{break}
72
- @columns = ds.instance_variable_get(:@columns)
73
- @columns || []
76
+ _columns || columns!
74
77
  end
75
78
 
76
79
  # Ignore any cached column information and perform a query to retrieve
@@ -79,10 +82,18 @@ module Sequel
79
82
  # DB[:table].columns!
80
83
  # # => [:id, :name]
81
84
  def columns!
82
- @columns = nil
83
- columns
85
+ ds = clone(COLUMNS_CLONE_OPTIONS)
86
+ ds.each{break}
87
+
88
+ if cols = ds.cache[:_columns]
89
+ self.columns = cols
90
+ else
91
+ []
92
+ end
84
93
  end
85
94
 
95
+ COUNT_SELECT = Sequel.function(:count).*.as(:count)
96
+
86
97
  # Returns the number of records in the dataset. If an argument is provided,
87
98
  # it is used as the argument to count. If a block is provided, it is
88
99
  # treated as a virtual row, and the result is used as the argument to
@@ -95,22 +106,24 @@ module Sequel
95
106
  # DB[:table].count{foo(column)} # SELECT count(foo(column)) AS count FROM table LIMIT 1
96
107
  # # => 1
97
108
  def count(arg=(no_arg=true), &block)
98
- if no_arg
109
+ if no_arg && !block
110
+ cached_dataset(:_count_ds) do
111
+ aggregate_dataset.select(COUNT_SELECT).single_value_ds
112
+ end.single_value!.to_i
113
+ else
99
114
  if block
100
- arg = Sequel.virtual_row(&block)
101
- aggregate_dataset.get{count(arg).as(:count)}
102
- else
103
- aggregate_dataset.get{count{}.*.as(:count)}.to_i
115
+ if no_arg
116
+ arg = Sequel.virtual_row(&block)
117
+ else
118
+ raise Error, 'cannot provide both argument and block to Dataset#count'
119
+ end
104
120
  end
105
- elsif block
106
- raise Error, 'cannot provide both argument and block to Dataset#count'
107
- else
108
- aggregate_dataset.get{count(arg).as(:count)}
121
+
122
+ _aggregate(:count, arg)
109
123
  end
110
124
  end
111
-
112
- # Deletes the records in the dataset. The returned value should be
113
- # number of records deleted, but that is adapter dependent.
125
+
126
+ # Deletes the records in the dataset, returning the number of records deleted.
114
127
  #
115
128
  # DB[:table].delete # DELETE * FROM table
116
129
  # # => 3
@@ -133,27 +146,30 @@ module Sequel
133
146
  # running queries inside the block, you should use +all+ instead of +each+
134
147
  # for the outer queries, or use a separate thread or shard inside +each+.
135
148
  def each
136
- if row_proc = @row_proc
137
- fetch_rows(select_sql){|r| yield row_proc.call(r)}
149
+ if rp = row_proc
150
+ fetch_rows(select_sql){|r| yield rp.call(r)}
138
151
  else
139
152
  fetch_rows(select_sql){|r| yield r}
140
153
  end
141
154
  self
142
155
  end
143
156
 
157
+ EMPTY_SELECT = Sequel::SQL::AliasedExpression.new(1, :one)
158
+
144
159
  # Returns true if no records exist in the dataset, false otherwise
145
160
  #
146
161
  # DB[:table].empty? # SELECT 1 AS one FROM table LIMIT 1
147
162
  # # => false
148
163
  def empty?
149
- ds = @opts[:order] ? unordered : self
150
- ds.get(Sequel::SQL::AliasedExpression.new(1, :one)).nil?
164
+ cached_dataset(:_empty_ds) do
165
+ single_value_ds.unordered.select(EMPTY_SELECT)
166
+ end.single_value!.nil?
151
167
  end
152
168
 
169
+ # Returns the first matching record if no arguments are given.
153
170
  # If a integer argument is given, it is interpreted as a limit, and then returns all
154
- # matching records up to that limit. If no argument is passed,
155
- # it returns the first matching record. If any other type of
156
- # argument(s) is passed, it is given to filter and the
171
+ # matching records up to that limit. If any other type of
172
+ # argument(s) is passed, it is treated as a filter and the
157
173
  # first matching record is returned. If a block is given, it is used
158
174
  # to filter the dataset before returning anything.
159
175
  #
@@ -168,35 +184,65 @@ module Sequel
168
184
  # DB[:table].first(2) # SELECT * FROM table LIMIT 2
169
185
  # # => [{:id=>6}, {:id=>4}]
170
186
  #
171
- # DB[:table].first(:id=>2) # SELECT * FROM table WHERE (id = 2) LIMIT 1
187
+ # DB[:table].first(id: 2) # SELECT * FROM table WHERE (id = 2) LIMIT 1
172
188
  # # => {:id=>2}
173
189
  #
174
- # DB[:table].first("id = 3") # SELECT * FROM table WHERE (id = 3) LIMIT 1
190
+ # DB[:table].first(Sequel.lit("id = 3")) # SELECT * FROM table WHERE (id = 3) LIMIT 1
175
191
  # # => {:id=>3}
176
192
  #
177
- # DB[:table].first("id = ?", 4) # SELECT * FROM table WHERE (id = 4) LIMIT 1
193
+ # DB[:table].first(Sequel.lit("id = ?", 4)) # SELECT * FROM table WHERE (id = 4) LIMIT 1
178
194
  # # => {:id=>4}
179
195
  #
180
196
  # DB[:table].first{id > 2} # SELECT * FROM table WHERE (id > 2) LIMIT 1
181
197
  # # => {:id=>5}
182
198
  #
183
- # DB[:table].first("id > ?", 4){id < 6} # SELECT * FROM table WHERE ((id > 4) AND (id < 6)) LIMIT 1
199
+ # DB[:table].first(Sequel.lit("id > ?", 4)){id < 6} # SELECT * FROM table WHERE ((id > 4) AND (id < 6)) LIMIT 1
184
200
  # # => {:id=>5}
185
201
  #
186
202
  # DB[:table].first(2){id < 2} # SELECT * FROM table WHERE (id < 2) LIMIT 2
187
203
  # # => [{:id=>1}]
188
204
  def first(*args, &block)
189
- ds = block ? filter(&block) : self
205
+ case args.length
206
+ when 0
207
+ unless block
208
+ return single_record
209
+ end
210
+ when 1
211
+ arg = args[0]
212
+ if arg.is_a?(Integer)
213
+ res = if block
214
+ if loader = cached_placeholder_literalizer(:_first_integer_cond_loader) do |pl|
215
+ where(pl.arg).limit(pl.arg)
216
+ end
190
217
 
191
- if args.empty?
192
- ds.single_record
193
- else
194
- args = (args.size == 1) ? args.first : args
195
- if args.is_a?(Integer)
196
- ds.limit(args).all
197
- else
198
- ds.filter(args).single_record
218
+ loader.all(filter_expr(&block), arg)
219
+ else
220
+ where(&block).limit(arg).all
221
+ end
222
+ else
223
+ if loader = cached_placeholder_literalizer(:_first_integer_loader) do |pl|
224
+ limit(pl.arg)
225
+ end
226
+
227
+ loader.all(arg)
228
+ else
229
+ limit(arg).all
230
+ end
231
+ end
232
+
233
+ return res
234
+ end
235
+ where_args = args
236
+ args = arg
237
+ end
238
+
239
+ if loader = cached_where_placeholder_literalizer(where_args||args, block, :_first_cond_loader) do |pl|
240
+ _single_record_ds.where(pl.arg)
199
241
  end
242
+
243
+ loader.first(filter_expr(args, &block))
244
+ else
245
+ _single_record_ds.where(args, &block).single_record!
200
246
  end
201
247
  end
202
248
 
@@ -227,15 +273,32 @@ module Sequel
227
273
  def get(column=(no_arg=true; nil), &block)
228
274
  ds = naked
229
275
  if block
230
- raise(Error, ARG_BLOCK_ERROR_MSG) unless no_arg
276
+ raise(Error, 'Must call Dataset#get with an argument or a block, not both') unless no_arg
231
277
  ds = ds.select(&block)
232
278
  column = ds.opts[:select]
233
279
  column = nil if column.is_a?(Array) && column.length < 2
234
280
  else
235
- ds = if column.is_a?(Array)
236
- ds.select(*column)
281
+ case column
282
+ when Array
283
+ ds = ds.select(*column)
284
+ when LiteralString, Symbol, SQL::Identifier, SQL::QualifiedIdentifier, SQL::AliasedExpression
285
+ if loader = cached_placeholder_literalizer(:_get_loader) do |pl|
286
+ ds.single_value_ds.select(pl.arg)
287
+ end
288
+
289
+ return loader.get(column)
290
+ end
291
+
292
+ ds = ds.select(column)
237
293
  else
238
- ds.select(auto_alias_expression(column))
294
+ if loader = cached_placeholder_literalizer(:_get_alias_loader) do |pl|
295
+ ds.single_value_ds.select(Sequel.as(pl.arg, :v))
296
+ end
297
+
298
+ return loader.get(column)
299
+ end
300
+
301
+ ds = ds.select(Sequel.as(column, :v))
239
302
  end
240
303
  end
241
304
 
@@ -270,6 +333,7 @@ module Sequel
270
333
  # after every 50 records.
271
334
  # :return :: When this is set to :primary_key, returns an array of
272
335
  # autoincremented primary key values for the rows inserted.
336
+ # This does not have an effect if +values+ is a Dataset.
273
337
  # :server :: Set the server/shard to use for the transaction and insert
274
338
  # queries.
275
339
  # :slice :: Same as :commit_every, :commit_every takes precedence.
@@ -277,7 +341,7 @@ module Sequel
277
341
  return @db.transaction{insert(columns, values)} if values.is_a?(Dataset)
278
342
 
279
343
  return if values.empty?
280
- raise(Error, IMPORT_ERROR_MSG) if columns.empty?
344
+ raise(Error, 'Using Sequel::Dataset#import with an empty column array is not allowed') if columns.empty?
281
345
  ds = opts[:server] ? server(opts[:server]) : self
282
346
 
283
347
  if slice_size = opts.fetch(:commit_every, opts.fetch(:slice, default_import_slice))
@@ -294,11 +358,12 @@ module Sequel
294
358
  end
295
359
 
296
360
  # Inserts values into the associated table. The returned value is generally
297
- # the value of the primary key for the inserted row, but that is adapter dependent.
361
+ # the value of the autoincremented primary key for the inserted row, assuming that
362
+ # a single row is inserted and the table has an autoincrementing primary key.
298
363
  #
299
364
  # +insert+ handles a number of different argument formats:
300
365
  # no arguments or single empty hash :: Uses DEFAULT VALUES
301
- # single hash :: Most common format, treats keys as columns an values as values
366
+ # single hash :: Most common format, treats keys as columns and values as values
302
367
  # single array :: Treats entries as values, with no columns
303
368
  # two arrays :: Treats first array as columns, second array as values
304
369
  # single Dataset :: Treats as an insert based on a selection from the dataset given,
@@ -320,7 +385,7 @@ module Sequel
320
385
  # DB[:items].insert([:a, :b], [1,2])
321
386
  # # INSERT INTO items (a, b) VALUES (1, 2)
322
387
  #
323
- # DB[:items].insert(:a => 1, :b => 2)
388
+ # DB[:items].insert(a: 1, b: 2)
324
389
  # # INSERT INTO items (a, b) VALUES (1, 2)
325
390
  #
326
391
  # DB[:items].insert(DB[:old_items])
@@ -337,17 +402,6 @@ module Sequel
337
402
  end
338
403
  end
339
404
 
340
- # Returns the interval between minimum and maximum values for the given
341
- # column/expression. Uses a virtual row block if no argument is given.
342
- #
343
- # DB[:table].interval(:id) # SELECT (max(id) - min(id)) FROM table LIMIT 1
344
- # # => 6
345
- # DB[:table].interval{function(column)} # SELECT (max(function(column)) - min(function(column))) FROM table LIMIT 1
346
- # # => 7
347
- def interval(column=Sequel.virtual_row(&Proc.new))
348
- aggregate_dataset.get{(max(column) - min(column)).as(:interval)}
349
- end
350
-
351
405
  # Reverses the order and then runs #first with the given arguments and block. Note that this
352
406
  # will not necessarily give you the last record in the dataset,
353
407
  # unless you have an unambiguous order. If there is not
@@ -363,8 +417,8 @@ module Sequel
363
417
  reverse.first(*args, &block)
364
418
  end
365
419
 
366
- # Maps column values for each record in the dataset (if a column name is
367
- # given), or performs the stock mapping functionality of +Enumerable+ otherwise.
420
+ # Maps column values for each record in the dataset (if an argument is given)
421
+ # or performs the stock mapping functionality of +Enumerable+ otherwise.
368
422
  # Raises an +Error+ if both an argument and block are given.
369
423
  #
370
424
  # DB[:table].map(:id) # SELECT * FROM table
@@ -379,7 +433,7 @@ module Sequel
379
433
  # # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
380
434
  def map(column=nil, &block)
381
435
  if column
382
- raise(Error, ARG_BLOCK_ERROR_MSG) if block
436
+ raise(Error, 'Must call Dataset#map with either an argument or a block, not both') if block
383
437
  return naked.map(column) if row_proc
384
438
  if column.is_a?(Array)
385
439
  super(){|r| r.values_at(*column)}
@@ -398,8 +452,9 @@ module Sequel
398
452
  # # => 10
399
453
  # DB[:table].max{function(column)} # SELECT max(function(column)) FROM table LIMIT 1
400
454
  # # => 7
401
- def max(column=Sequel.virtual_row(&Proc.new))
402
- aggregate_dataset.get{max(column).as(:max)}
455
+ def max(arg=(no_arg = true), &block)
456
+ arg = Sequel.virtual_row(&block) if no_arg
457
+ _aggregate(:max, arg)
403
458
  end
404
459
 
405
460
  # Returns the minimum value for the given column/expression.
@@ -409,14 +464,15 @@ module Sequel
409
464
  # # => 1
410
465
  # DB[:table].min{function(column)} # SELECT min(function(column)) FROM table LIMIT 1
411
466
  # # => 0
412
- def min(column=Sequel.virtual_row(&Proc.new))
413
- aggregate_dataset.get{min(column).as(:min)}
467
+ def min(arg=(no_arg = true), &block)
468
+ arg = Sequel.virtual_row(&block) if no_arg
469
+ _aggregate(:min, arg)
414
470
  end
415
471
 
416
472
  # This is a front end for import that allows you to submit an array of
417
473
  # hashes instead of arrays of columns and values:
418
474
  #
419
- # DB[:table].multi_insert([{:x => 1}, {:x => 2}])
475
+ # DB[:table].multi_insert([{x: 1}, {x: 2}])
420
476
  # # INSERT INTO table (x) VALUES (1)
421
477
  # # INSERT INTO table (x) VALUES (2)
422
478
  #
@@ -431,7 +487,7 @@ module Sequel
431
487
  import(columns, hashes.map{|h| columns.map{|c| h[c]}}, opts)
432
488
  end
433
489
 
434
- # Yields each row in the dataset, but interally uses multiple queries as needed to
490
+ # Yields each row in the dataset, but internally uses multiple queries as needed to
435
491
  # process the entire result set without keeping all rows in the dataset in memory,
436
492
  # even if the underlying driver buffers all query results in memory.
437
493
  #
@@ -443,6 +499,10 @@ module Sequel
443
499
  # Sequel checks that the datasets using this method have an order, but it cannot
444
500
  # ensure that the order is unambiguous.
445
501
  #
502
+ # Note that this method is not safe to use on many adapters if you are
503
+ # running additional queries inside the provided block. If you are
504
+ # running queries inside the block, use a separate thread or shard inside +paged_each+.
505
+ #
446
506
  # Options:
447
507
  # :rows_per_fetch :: The number of rows to fetch per query. Defaults to 1000.
448
508
  # :strategy :: The strategy to use for paging of results. By default this is :offset,
@@ -452,8 +512,8 @@ module Sequel
452
512
  # selecting the columns you are ordering by, and none of the columns can contain
453
513
  # NULLs. Note that some Sequel adapters have optimized implementations that will
454
514
  # use cursors or streaming regardless of the :strategy option used.
455
- # :filter_values :: If the :strategy=>:filter option is used, this option should be a proc
456
- # that accepts the last retreived row for the previous page and an array of
515
+ # :filter_values :: If the strategy: :filter option is used, this option should be a proc
516
+ # that accepts the last retrieved row for the previous page and an array of
457
517
  # ORDER BY expressions, and returns an array of values relating to those
458
518
  # expressions for the last retrieved row. You will need to use this option
459
519
  # if your ORDER BY expressions are not simple columns, if they contain
@@ -472,13 +532,13 @@ module Sequel
472
532
  # # SELECT * FROM table ORDER BY id LIMIT 100 OFFSET 100
473
533
  # # ...
474
534
  #
475
- # DB[:table].order(:id).paged_each(:strategy=>:filter){|row| }
535
+ # DB[:table].order(:id).paged_each(strategy: :filter){|row| }
476
536
  # # SELECT * FROM table ORDER BY id LIMIT 1000
477
537
  # # SELECT * FROM table WHERE id > 1001 ORDER BY id LIMIT 1000
478
538
  # # ...
479
539
  #
480
- # DB[:table].order(:table__id).paged_each(:strategy=>:filter,
481
- # :filter_values=>proc{|row, exprs| [row[:id]]}){|row| }
540
+ # DB[:table].order(:id).paged_each(strategy: :filter,
541
+ # filter_values: lambda{|row, exprs| [row[:id]]}){|row| }
482
542
  # # SELECT * FROM table ORDER BY id LIMIT 1000
483
543
  # # SELECT * FROM table WHERE id > 1001 ORDER BY id LIMIT 1000
484
544
  # # ...
@@ -542,55 +602,47 @@ module Sequel
542
602
  self
543
603
  end
544
604
 
545
- # Returns a +Range+ instance made from the minimum and maximum values for the
546
- # given column/expression. Uses a virtual row block if no argument is given.
547
- #
548
- # DB[:table].range(:id) # SELECT max(id) AS v1, min(id) AS v2 FROM table LIMIT 1
549
- # # => 1..10
550
- # DB[:table].interval{function(column)} # SELECT max(function(column)) AS v1, min(function(column)) AS v2 FROM table LIMIT 1
551
- # # => 0..7
552
- def range(column=Sequel.virtual_row(&Proc.new))
553
- if r = aggregate_dataset.select{[min(column).as(v1), max(column).as(v2)]}.first
554
- (r[:v1]..r[:v2])
555
- end
556
- end
557
-
558
605
  # Returns a hash with key_column values as keys and value_column values as
559
- # values. Similar to to_hash, but only selects the columns given.
606
+ # values. Similar to as_hash, but only selects the columns given. Like
607
+ # as_hash, it accepts an optional :hash parameter, into which entries will
608
+ # be merged.
560
609
  #
561
- # DB[:table].select_hash(:id, :name) # SELECT id, name FROM table
610
+ # DB[:table].select_hash(:id, :name)
611
+ # # SELECT id, name FROM table
562
612
  # # => {1=>'a', 2=>'b', ...}
563
613
  #
564
614
  # You can also provide an array of column names for either the key_column,
565
615
  # the value column, or both:
566
616
  #
567
- # DB[:table].select_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
568
- # # {[1, 3]=>['a', 'c'], [2, 4]=>['b', 'd'], ...}
617
+ # DB[:table].select_hash([:id, :foo], [:name, :bar])
618
+ # # SELECT id, foo, name, bar FROM table
619
+ # # => {[1, 3]=>['a', 'c'], [2, 4]=>['b', 'd'], ...}
569
620
  #
570
621
  # When using this method, you must be sure that each expression has an alias
571
- # that Sequel can determine. Usually you can do this by calling the #as method
572
- # on the expression and providing an alias.
573
- def select_hash(key_column, value_column)
574
- _select_hash(:to_hash, key_column, value_column)
622
+ # that Sequel can determine.
623
+ def select_hash(key_column, value_column, opts = OPTS)
624
+ _select_hash(:as_hash, key_column, value_column, opts)
575
625
  end
576
626
 
577
627
  # Returns a hash with key_column values as keys and an array of value_column values.
578
- # Similar to to_hash_groups, but only selects the columns given.
628
+ # Similar to to_hash_groups, but only selects the columns given. Like to_hash_groups,
629
+ # it accepts an optional :hash parameter, into which entries will be merged.
579
630
  #
580
- # DB[:table].select_hash_groups(:name, :id) # SELECT id, name FROM table
631
+ # DB[:table].select_hash_groups(:name, :id)
632
+ # # SELECT id, name FROM table
581
633
  # # => {'a'=>[1, 4, ...], 'b'=>[2, ...], ...}
582
634
  #
583
635
  # You can also provide an array of column names for either the key_column,
584
636
  # the value column, or both:
585
637
  #
586
- # DB[:table].select_hash_groups([:first, :middle], [:last, :id]) # SELECT * FROM table
587
- # # {['a', 'b']=>[['c', 1], ['d', 2], ...], ...}
638
+ # DB[:table].select_hash_groups([:first, :middle], [:last, :id])
639
+ # # SELECT first, middle, last, id FROM table
640
+ # # => {['a', 'b']=>[['c', 1], ['d', 2], ...], ...}
588
641
  #
589
642
  # When using this method, you must be sure that each expression has an alias
590
- # that Sequel can determine. Usually you can do this by calling the #as method
591
- # on the expression and providing an alias.
592
- def select_hash_groups(key_column, value_column)
593
- _select_hash(:to_hash_groups, key_column, value_column)
643
+ # that Sequel can determine.
644
+ def select_hash_groups(key_column, value_column, opts = OPTS)
645
+ _select_hash(:to_hash_groups, key_column, value_column, opts)
594
646
  end
595
647
 
596
648
  # Selects the column given (either as an argument or as a block), and
@@ -611,8 +663,7 @@ module Sequel
611
663
  # # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
612
664
  #
613
665
  # If you provide an array of expressions, you must be sure that each entry
614
- # in the array has an alias that Sequel can determine. Usually you can do this
615
- # by calling the #as method on the expression and providing an alias.
666
+ # in the array has an alias that Sequel can determine.
616
667
  def select_map(column=nil, &block)
617
668
  _select_map(column, false, &block)
618
669
  end
@@ -631,27 +682,56 @@ module Sequel
631
682
  # # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
632
683
  #
633
684
  # If you provide an array of expressions, you must be sure that each entry
634
- # in the array has an alias that Sequel can determine. Usually you can do this
635
- # by calling the #as method on the expression and providing an alias.
685
+ # in the array has an alias that Sequel can determine.
636
686
  def select_order_map(column=nil, &block)
637
687
  _select_map(column, true, &block)
638
688
  end
639
689
 
640
- # Returns the first record in the dataset, or nil if the dataset
641
- # has no records. Users should probably use +first+ instead of
642
- # this method.
690
+ # Limits the dataset to one record, and returns the first record in the dataset,
691
+ # or nil if the dataset has no records. Users should probably use +first+ instead of
692
+ # this method. Example:
693
+ #
694
+ # DB[:test].single_record # SELECT * FROM test LIMIT 1
695
+ # # => {:column_name=>'value'}
643
696
  def single_record
644
- clone(:limit=>1).each{|r| return r}
645
- nil
697
+ _single_record_ds.single_record!
698
+ end
699
+
700
+ # Returns the first record in dataset, without limiting the dataset. Returns nil if
701
+ # the dataset has no records. Users should probably use +first+ instead of this method.
702
+ # This should only be used if you know the dataset is already limited to a single record.
703
+ # This method may be desirable to use for performance reasons, as it does not clone the
704
+ # receiver. Example:
705
+ #
706
+ # DB[:test].single_record! # SELECT * FROM test
707
+ # # => {:column_name=>'value'}
708
+ def single_record!
709
+ with_sql_first(select_sql)
646
710
  end
647
711
 
648
712
  # Returns the first value of the first record in the dataset.
649
713
  # Returns nil if dataset is empty. Users should generally use
650
- # +get+ instead of this method.
714
+ # +get+ instead of this method. Example:
715
+ #
716
+ # DB[:test].single_value # SELECT * FROM test LIMIT 1
717
+ # # => 'value'
651
718
  def single_value
652
- if r = ungraphed.naked.single_record
653
- r.values.first
719
+ single_value_ds.each do |r|
720
+ r.each{|_, v| return v}
654
721
  end
722
+ nil
723
+ end
724
+
725
+ # Returns the first value of the first record in the dataset, without limiting the dataset.
726
+ # Returns nil if the dataset is empty. Users should generally use +get+ instead of this
727
+ # method. Should not be used on graphed datasets or datasets that have row_procs that
728
+ # don't return hashes. This method may be desirable to use for performance reasons, as
729
+ # it does not clone the receiver.
730
+ #
731
+ # DB[:test].single_value! # SELECT * FROM test
732
+ # # => 'value'
733
+ def single_value!
734
+ with_sql_single_value(select_sql)
655
735
  end
656
736
 
657
737
  # Returns the sum for the given column/expression.
@@ -661,8 +741,9 @@ module Sequel
661
741
  # # => 55
662
742
  # DB[:table].sum{function(column)} # SELECT sum(function(column)) FROM table LIMIT 1
663
743
  # # => 10
664
- def sum(column=Sequel.virtual_row(&Proc.new))
665
- aggregate_dataset.get{sum(column).as(:sum)}
744
+ def sum(arg=(no_arg = true), &block)
745
+ arg = Sequel.virtual_row(&block) if no_arg
746
+ _aggregate(:sum, arg)
666
747
  end
667
748
 
668
749
  # Returns a hash with one column used as key and another used as value.
@@ -670,45 +751,57 @@ module Sequel
670
751
  # will overwrite the value of the previous row(s). If the value_column
671
752
  # is not given or nil, uses the entire hash as the value.
672
753
  #
673
- # DB[:table].to_hash(:id, :name) # SELECT * FROM table
754
+ # DB[:table].as_hash(:id, :name) # SELECT * FROM table
674
755
  # # {1=>'Jim', 2=>'Bob', ...}
675
756
  #
676
- # DB[:table].to_hash(:id) # SELECT * FROM table
757
+ # DB[:table].as_hash(:id) # SELECT * FROM table
677
758
  # # {1=>{:id=>1, :name=>'Jim'}, 2=>{:id=>2, :name=>'Bob'}, ...}
678
759
  #
679
760
  # You can also provide an array of column names for either the key_column,
680
761
  # the value column, or both:
681
762
  #
682
- # DB[:table].to_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
763
+ # DB[:table].as_hash([:id, :foo], [:name, :bar]) # SELECT * FROM table
683
764
  # # {[1, 3]=>['Jim', 'bo'], [2, 4]=>['Bob', 'be'], ...}
684
765
  #
685
- # DB[:table].to_hash([:id, :name]) # SELECT * FROM table
686
- # # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob'=>{:id=>2, :name=>'Bob'}, ...}
687
- def to_hash(key_column, value_column = nil)
688
- h = {}
766
+ # DB[:table].as_hash([:id, :name]) # SELECT * FROM table
767
+ # # {[1, 'Jim']=>{:id=>1, :name=>'Jim'}, [2, 'Bob']=>{:id=>2, :name=>'Bob'}, ...}
768
+ #
769
+ # Options:
770
+ # :all :: Use all instead of each to retrieve the objects
771
+ # :hash :: The object into which the values will be placed. If this is not
772
+ # given, an empty hash is used. This can be used to use a hash with
773
+ # a default value or default proc.
774
+ def as_hash(key_column, value_column = nil, opts = OPTS)
775
+ h = opts[:hash] || {}
776
+ meth = opts[:all] ? :all : :each
689
777
  if value_column
690
- return naked.to_hash(key_column, value_column) if row_proc
778
+ return naked.as_hash(key_column, value_column, opts) if row_proc
691
779
  if value_column.is_a?(Array)
692
780
  if key_column.is_a?(Array)
693
- each{|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
781
+ public_send(meth){|r| h[r.values_at(*key_column)] = r.values_at(*value_column)}
694
782
  else
695
- each{|r| h[r[key_column]] = r.values_at(*value_column)}
783
+ public_send(meth){|r| h[r[key_column]] = r.values_at(*value_column)}
696
784
  end
697
785
  else
698
786
  if key_column.is_a?(Array)
699
- each{|r| h[r.values_at(*key_column)] = r[value_column]}
787
+ public_send(meth){|r| h[r.values_at(*key_column)] = r[value_column]}
700
788
  else
701
- each{|r| h[r[key_column]] = r[value_column]}
789
+ public_send(meth){|r| h[r[key_column]] = r[value_column]}
702
790
  end
703
791
  end
704
792
  elsif key_column.is_a?(Array)
705
- each{|r| h[key_column.map{|k| r[k]}] = r}
793
+ public_send(meth){|r| h[key_column.map{|k| r[k]}] = r}
706
794
  else
707
- each{|r| h[r[key_column]] = r}
795
+ public_send(meth){|r| h[r[key_column]] = r}
708
796
  end
709
797
  h
710
798
  end
711
799
 
800
+ # Alias of as_hash for backwards compatibility.
801
+ def to_hash(*a)
802
+ as_hash(*a)
803
+ end
804
+
712
805
  # Returns a hash with one column used as key and the values being an
713
806
  # array of column values. If the value_column is not given or nil, uses
714
807
  # the entire hash as the value.
@@ -727,27 +820,34 @@ module Sequel
727
820
  #
728
821
  # DB[:table].to_hash_groups([:first, :middle]) # SELECT * FROM table
729
822
  # # {['Jim', 'Bob']=>[{:id=>1, :first=>'Jim', :middle=>'Bob', :last=>'Smith'}, ...], ...}
730
- def to_hash_groups(key_column, value_column = nil)
731
- h = {}
823
+ #
824
+ # Options:
825
+ # :all :: Use all instead of each to retrieve the objects
826
+ # :hash :: The object into which the values will be placed. If this is not
827
+ # given, an empty hash is used. This can be used to use a hash with
828
+ # a default value or default proc.
829
+ def to_hash_groups(key_column, value_column = nil, opts = OPTS)
830
+ h = opts[:hash] || {}
831
+ meth = opts[:all] ? :all : :each
732
832
  if value_column
733
- return naked.to_hash_groups(key_column, value_column) if row_proc
833
+ return naked.to_hash_groups(key_column, value_column, opts) if row_proc
734
834
  if value_column.is_a?(Array)
735
835
  if key_column.is_a?(Array)
736
- each{|r| (h[r.values_at(*key_column)] ||= []) << r.values_at(*value_column)}
836
+ public_send(meth){|r| (h[r.values_at(*key_column)] ||= []) << r.values_at(*value_column)}
737
837
  else
738
- each{|r| (h[r[key_column]] ||= []) << r.values_at(*value_column)}
838
+ public_send(meth){|r| (h[r[key_column]] ||= []) << r.values_at(*value_column)}
739
839
  end
740
840
  else
741
841
  if key_column.is_a?(Array)
742
- each{|r| (h[r.values_at(*key_column)] ||= []) << r[value_column]}
842
+ public_send(meth){|r| (h[r.values_at(*key_column)] ||= []) << r[value_column]}
743
843
  else
744
- each{|r| (h[r[key_column]] ||= []) << r[value_column]}
844
+ public_send(meth){|r| (h[r[key_column]] ||= []) << r[value_column]}
745
845
  end
746
846
  end
747
847
  elsif key_column.is_a?(Array)
748
- each{|r| (h[key_column.map{|k| r[k]}] ||= []) << r}
848
+ public_send(meth){|r| (h[key_column.map{|k| r[k]}] ||= []) << r}
749
849
  else
750
- each{|r| (h[r[key_column]] ||= []) << r}
850
+ public_send(meth){|r| (h[r[key_column]] ||= []) << r}
751
851
  end
752
852
  h
753
853
  end
@@ -760,15 +860,14 @@ module Sequel
760
860
  execute_ddl(truncate_sql)
761
861
  end
762
862
 
763
- # Updates values for the dataset. The returned value is generally the
764
- # number of rows updated, but that is adapter dependent. +values+ should
765
- # a hash where the keys are columns to set and values are the values to
863
+ # Updates values for the dataset. The returned value is the number of rows updated.
864
+ # +values+ should be a hash where the keys are columns to set and values are the values to
766
865
  # which to set the columns.
767
866
  #
768
- # DB[:table].update(:x=>nil) # UPDATE table SET x = NULL
867
+ # DB[:table].update(x: nil) # UPDATE table SET x = NULL
769
868
  # # => 10
770
869
  #
771
- # DB[:table].update(:x=>Sequel.expr(:x)+1, :y=>0) # UPDATE table SET x = (x + 1), y = 0
870
+ # DB[:table].update(x: Sequel[:x]+1, y: 0) # UPDATE table SET x = (x + 1), y = 0
772
871
  # # => 10
773
872
  def update(values=OPTS, &block)
774
873
  sql = update_sql(values)
@@ -779,6 +878,52 @@ module Sequel
779
878
  end
780
879
  end
781
880
 
881
+ # Return an array of all rows matching the given filter condition, also
882
+ # yielding each row to the given block. Basically the same as where(cond).all(&block),
883
+ # except it can be optimized to not create an intermediate dataset.
884
+ #
885
+ # DB[:table].where_all(id: [1,2,3])
886
+ # # SELECT * FROM table WHERE (id IN (1, 2, 3))
887
+ def where_all(cond, &block)
888
+ if loader = _where_loader([cond], nil)
889
+ loader.all(filter_expr(cond), &block)
890
+ else
891
+ where(cond).all(&block)
892
+ end
893
+ end
894
+
895
+ # Iterate over all rows matching the given filter condition,
896
+ # yielding each row to the given block. Basically the same as where(cond).each(&block),
897
+ # except it can be optimized to not create an intermediate dataset.
898
+ #
899
+ # DB[:table].where_each(id: [1,2,3]){|row| p row}
900
+ # # SELECT * FROM table WHERE (id IN (1, 2, 3))
901
+ def where_each(cond, &block)
902
+ if loader = _where_loader([cond], nil)
903
+ loader.each(filter_expr(cond), &block)
904
+ else
905
+ where(cond).each(&block)
906
+ end
907
+ end
908
+
909
+ # Filter the datasets using the given filter condition, then return a single value.
910
+ # This assumes that the dataset has already been setup to limit the selection to
911
+ # a single column. Basically the same as where(cond).single_value,
912
+ # except it can be optimized to not create an intermediate dataset.
913
+ #
914
+ # DB[:table].select(:name).where_single_value(id: 1)
915
+ # # SELECT name FROM table WHERE (id = 1) LIMIT 1
916
+ def where_single_value(cond)
917
+ if loader = cached_where_placeholder_literalizer([cond], nil, :_where_single_value_loader) do |pl|
918
+ single_value_ds.where(pl.arg)
919
+ end
920
+
921
+ loader.get(filter_expr(cond))
922
+ else
923
+ where(cond).single_value
924
+ end
925
+ end
926
+
782
927
  # Run the given SQL and return an array of all rows. If a block is given,
783
928
  # each row is yielded to the block after all rows are loaded. See with_sql_each.
784
929
  def with_sql_all(sql, &block)
@@ -794,14 +939,11 @@ module Sequel
794
939
  alias with_sql_update with_sql_delete
795
940
 
796
941
  # Run the given SQL and yield each returned row to the block.
797
- #
798
- # This method should not be called on a shared dataset if the columns selected
799
- # in the given SQL do not match the columns in the receiver.
800
942
  def with_sql_each(sql)
801
- if row_proc = @row_proc
802
- fetch_rows(sql){|r| yield row_proc.call(r)}
943
+ if rp = row_proc
944
+ _with_sql_dataset.fetch_rows(sql){|r| yield rp.call(r)}
803
945
  else
804
- fetch_rows(sql){|r| yield r}
946
+ _with_sql_dataset.fetch_rows(sql){|r| yield r}
805
947
  end
806
948
  self
807
949
  end
@@ -818,7 +960,7 @@ module Sequel
818
960
  # only a single value. See with_sql_each.
819
961
  def with_sql_single_value(sql)
820
962
  if r = with_sql_first(sql)
821
- r.values.first
963
+ r.each{|_, v| return v}
822
964
  end
823
965
  end
824
966
 
@@ -834,7 +976,8 @@ module Sequel
834
976
  # separate insert commands for each row. Otherwise, call #multi_insert_sql
835
977
  # and execute each statement it gives separately.
836
978
  def _import(columns, values, opts)
837
- trans_opts = Hash[opts].merge!(:server=>@opts[:server])
979
+ trans_opts = Hash[opts]
980
+ trans_opts[:server] = @opts[:server]
838
981
  if opts[:return] == :primary_key
839
982
  @db.transaction(trans_opts){values.map{|v| insert(columns, v)}}
840
983
  else
@@ -850,9 +993,15 @@ module Sequel
850
993
 
851
994
  # Returns an array of the first value in each row.
852
995
  def _select_map_single
853
- map{|r| r.values.first}
996
+ k = nil
997
+ map{|r| r[k||=r.keys.first]}
854
998
  end
855
999
 
1000
+ # A dataset for returning single values from the current dataset.
1001
+ def single_value_ds
1002
+ clone(:limit=>1).ungraphed.naked
1003
+ end
1004
+
856
1005
  private
857
1006
 
858
1007
  # Internals of all and with_sql_all
@@ -864,10 +1013,21 @@ module Sequel
864
1013
  a
865
1014
  end
866
1015
 
1016
+ # Cached placeholder literalizer for methods that return values using aggregate functions.
1017
+ def _aggregate(function, arg)
1018
+ if loader = cached_placeholder_literalizer(:"_#{function}_loader") do |pl|
1019
+ aggregate_dataset.limit(1).select(SQL::Function.new(function, pl.arg).as(function))
1020
+ end
1021
+ loader.get(arg)
1022
+ else
1023
+ aggregate_dataset.get(SQL::Function.new(function, arg).as(function))
1024
+ end
1025
+ end
1026
+
867
1027
  # Internals of +select_hash+ and +select_hash_groups+
868
- def _select_hash(meth, key_column, value_column)
1028
+ def _select_hash(meth, key_column, value_column, opts=OPTS)
869
1029
  select(*(key_column.is_a?(Array) ? key_column : [key_column]) + (value_column.is_a?(Array) ? value_column : [value_column])).
870
- send(meth, hash_key_symbols(key_column), hash_key_symbols(value_column))
1030
+ public_send(meth, hash_key_symbols(key_column), hash_key_symbols(value_column), opts)
871
1031
  end
872
1032
 
873
1033
  # Internals of +select_map+ and +select_order_map+
@@ -884,6 +1044,18 @@ module Sequel
884
1044
  end
885
1045
  end
886
1046
 
1047
+ # A cached dataset for a single record for this dataset.
1048
+ def _single_record_ds
1049
+ cached_dataset(:_single_record_ds){clone(:limit=>1)}
1050
+ end
1051
+
1052
+ # Loader used for where_all and where_each.
1053
+ def _where_loader(where_args, where_block)
1054
+ cached_where_placeholder_literalizer(where_args, where_block, :_where_loader) do |pl|
1055
+ where(pl.arg)
1056
+ end
1057
+ end
1058
+
887
1059
  # Automatically alias the given expression if it does not have an identifiable alias.
888
1060
  def auto_alias_expression(v)
889
1061
  case v
@@ -902,7 +1074,7 @@ module Sequel
902
1074
 
903
1075
  # Set the server to use to :default unless it is already set in the passed opts
904
1076
  def default_server_opts(opts)
905
- if @db.sharded?
1077
+ if @db.sharded? && !opts.has_key?(:server)
906
1078
  opts = Hash[opts]
907
1079
  opts[:server] = @opts[:server] || :default
908
1080
  end
@@ -913,7 +1085,7 @@ module Sequel
913
1085
  # :read_only server unless a specific server is set.
914
1086
  def execute(sql, opts=OPTS, &block)
915
1087
  db = @db
916
- if db.sharded?
1088
+ if db.sharded? && !opts.has_key?(:server)
917
1089
  opts = Hash[opts]
918
1090
  opts[:server] = @opts[:server] || (@opts[:lock] ? :default : :read_only)
919
1091
  opts
@@ -1003,11 +1175,10 @@ module Sequel
1003
1175
  Sequel.|(*cond)
1004
1176
  end
1005
1177
 
1006
- # Modify the identifier returned from the database based on the
1007
- # identifier_output_method.
1178
+ # Downcase identifiers by default when outputing them from the database.
1008
1179
  def output_identifier(v)
1009
1180
  v = 'untitled' if v == ''
1010
- (i = identifier_output_method) ? v.to_s.send(i).to_sym : v.to_sym
1181
+ v.to_s.downcase.to_sym
1011
1182
  end
1012
1183
 
1013
1184
  # This is run inside .all, after all of the records have been loaded
@@ -1056,5 +1227,18 @@ module Sequel
1056
1227
  c
1057
1228
  end
1058
1229
  end
1230
+
1231
+ # Cached dataset to use for with_sql_#{all,each,first,single_value}.
1232
+ # This is used so that the columns returned by the given SQL do not
1233
+ # affect the receiver of the with_sql_* method.
1234
+ def _with_sql_dataset
1235
+ if @opts[:_with_sql_ds]
1236
+ self
1237
+ else
1238
+ cached_dataset(:_with_sql_ds) do
1239
+ clone(:_with_sql_ds=>true)
1240
+ end
1241
+ end
1242
+ end
1059
1243
  end
1060
1244
  end