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,34 +1,28 @@
1
+ # frozen-string-literal: true
2
+
1
3
  # A connection pool allowing multi-threaded access to a pool of connections.
2
4
  # This is the default connection pool used by Sequel.
3
5
  class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
4
- # Whether or not a ConditionVariable should be used to wait for connections.
5
- # True except on ruby 1.8, where ConditionVariable#wait does not support a
6
- # timeout.
7
- unless defined?(USE_WAITER)
8
- USE_WAITER = RUBY_VERSION >= '1.9'
9
- end
6
+ USE_WAITER = true
7
+ Sequel::Deprecation.deprecate_constant(self, :USE_WAITER)
10
8
 
11
9
  # The maximum number of connections this pool will create (per shard/server
12
10
  # if sharding).
13
11
  attr_reader :max_size
14
12
 
15
13
  # An array of connections that are available for use by the pool.
14
+ # The calling code should already have the mutex before calling this.
16
15
  attr_reader :available_connections
17
16
 
18
- # A hash with thread keys and connection values for currently allocated
19
- # connections.
17
+ # A hash with thread keys and connection values for currently allocated connections.
18
+ # The calling code should already have the mutex before calling this.
20
19
  attr_reader :allocated
21
20
 
22
21
  # The following additional options are respected:
23
- # * :connection_handling - Set how to handle available connections. By default,
24
- # uses a a queue for fairness. Can be set to :stack to use a stack, which may
25
- # offer better performance.
26
- # * :max_connections - The maximum number of connections the connection pool
27
- # will open (default 4)
28
- # * :pool_sleep_time - The amount of time to sleep before attempting to acquire
29
- # a connection again, only used on ruby 1.8. (default 0.001)
30
- # * :pool_timeout - The amount of seconds to wait to acquire a connection
31
- # before raising a PoolTimeoutError (default 5)
22
+ # :max_connections :: The maximum number of connections the connection pool
23
+ # will open (default 4)
24
+ # :pool_timeout :: The amount of seconds to wait to acquire a connection
25
+ # before raising a PoolTimeoutError (default 5)
32
26
  def initialize(db, opts = OPTS)
33
27
  super
34
28
  @max_size = Integer(opts[:max_connections] || 4)
@@ -38,14 +32,7 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
38
32
  @available_connections = []
39
33
  @allocated = {}
40
34
  @timeout = Float(opts[:pool_timeout] || 5)
41
-
42
- if USE_WAITER
43
- @waiter = ConditionVariable.new
44
- else
45
- # :nocov:
46
- @sleep_time = Float(opts[:pool_sleep_time] || 0.001)
47
- # :nocov:
48
- end
35
+ @waiter = ConditionVariable.new
49
36
  end
50
37
 
51
38
  # Yield all of the available connections, and the one currently allocated to
@@ -68,15 +55,18 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
68
55
  # being used. If you want to be able to disconnect connections that are
69
56
  # currently in use, use the ShardedThreadedConnectionPool, which can do that.
70
57
  # This connection pool does not, for performance reasons. To use the sharded pool,
71
- # pass the <tt>:servers=>{}</tt> option when connecting to the database.
58
+ # pass the <tt>servers: {}</tt> option when connecting to the database.
72
59
  #
73
60
  # Once a connection is requested using #hold, the connection pool
74
61
  # creates new connections to the database.
75
62
  def disconnect(opts=OPTS)
63
+ conns = nil
76
64
  sync do
77
- @available_connections.each{|conn| db.disconnect_connection(conn)}
65
+ conns = @available_connections.dup
78
66
  @available_connections.clear
67
+ @waiter.signal
79
68
  end
69
+ conns.each{|conn| disconnect_connection(conn)}
80
70
  end
81
71
 
82
72
  # Chooses the first available connection, or if none are
@@ -91,24 +81,33 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
91
81
  # If no connection is immediately available and the pool is already using the maximum
92
82
  # number of connections, Pool#hold will block until a connection
93
83
  # is available or the timeout expires. If the timeout expires before a
94
- # connection can be acquired, a Sequel::PoolTimeout is
95
- # raised.
84
+ # connection can be acquired, a Sequel::PoolTimeout is raised.
96
85
  def hold(server=nil)
97
- t = Thread.current
86
+ t = Sequel.current
98
87
  if conn = owned_connection(t)
99
88
  return yield(conn)
100
89
  end
101
90
  begin
102
91
  conn = acquire(t)
103
92
  yield conn
104
- rescue Sequel::DatabaseDisconnectError
105
- oconn = conn
106
- conn = nil
107
- db.disconnect_connection(oconn) if oconn
108
- @allocated.delete(t)
93
+ rescue Sequel::DatabaseDisconnectError, *@error_classes => e
94
+ if disconnect_error?(e)
95
+ oconn = conn
96
+ conn = nil
97
+ disconnect_connection(oconn) if oconn
98
+ sync do
99
+ @allocated.delete(t)
100
+ @waiter.signal
101
+ end
102
+ end
109
103
  raise
110
104
  ensure
111
- sync{release(t)} if conn
105
+ if conn
106
+ sync{release(t)}
107
+ if @connection_handling == :disconnect
108
+ disconnect_connection(conn)
109
+ end
110
+ end
112
111
  end
113
112
  end
114
113
 
@@ -117,111 +116,115 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
117
116
  end
118
117
 
119
118
  # The total number of connections opened, either available or allocated.
120
- # This may not be completely accurate as it isn't protected by the mutex.
119
+ # The calling code should not have the mutex before calling this.
121
120
  def size
122
- @allocated.length + @available_connections.length
121
+ @mutex.synchronize{_size}
123
122
  end
124
123
 
125
124
  private
126
125
 
126
+ # The total number of connections opened, either available or allocated.
127
+ # The calling code should already have the mutex before calling this.
128
+ def _size
129
+ @allocated.length + @available_connections.length
130
+ end
131
+
127
132
  # Assigns a connection to the supplied thread, if one
128
- # is available. The calling code should already have the mutex when
133
+ # is available. The calling code should NOT already have the mutex when
129
134
  # calling this.
130
- def _acquire(thread)
131
- if conn = available
132
- @allocated[thread] = conn
135
+ #
136
+ # This should return a connection is one is available within the timeout,
137
+ # or nil if a connection could not be acquired within the timeout.
138
+ def acquire(thread)
139
+ if conn = assign_connection(thread)
140
+ return conn
133
141
  end
134
- end
135
-
136
- if USE_WAITER
137
- # Assigns a connection to the supplied thread, if one
138
- # is available. The calling code should NOT already have the mutex when
139
- # calling this.
140
- #
141
- # This should return a connection is one is available within the timeout,
142
- # or nil if a connection could not be acquired within the timeout.
143
- def acquire(thread)
142
+
143
+ timeout = @timeout
144
+ timer = Sequel.start_timer
145
+
146
+ sync do
147
+ @waiter.wait(@mutex, timeout)
148
+ if conn = next_available
149
+ return(@allocated[thread] = conn)
150
+ end
151
+ end
152
+
153
+ until conn = assign_connection(thread)
154
+ elapsed = Sequel.elapsed_seconds_since(timer)
155
+ # :nocov:
156
+ raise_pool_timeout(elapsed) if elapsed > timeout
157
+
158
+ # It's difficult to get to this point, it can only happen if there is a race condition
159
+ # where a connection cannot be acquired even after the thread is signalled by the condition variable
144
160
  sync do
145
- if conn = _acquire(thread)
146
- return conn
161
+ @waiter.wait(@mutex, timeout - elapsed)
162
+ if conn = next_available
163
+ return(@allocated[thread] = conn)
147
164
  end
165
+ end
166
+ # :nocov:
167
+ end
168
+
169
+ conn
170
+ end
148
171
 
149
- time = Time.now
150
- @waiter.wait(@mutex, @timeout)
172
+ # Assign a connection to the thread, or return nil if one cannot be assigned.
173
+ # The caller should NOT have the mutex before calling this.
174
+ def assign_connection(thread)
175
+ # Thread safe as instance variable is only assigned to local variable
176
+ # and not operated on outside mutex.
177
+ allocated = @allocated
178
+ do_make_new = false
179
+ to_disconnect = nil
151
180
 
152
- # Not sure why this is helpful, but calling Thread.pass after conditional
153
- # variable access dramatically increases reliability when under heavy
154
- # resource contention (almost eliminating timeouts), at a small cost to
155
- # runtime performance.
156
- Thread.pass
181
+ sync do
182
+ if conn = next_available
183
+ return(allocated[thread] = conn)
184
+ end
157
185
 
158
- until conn = _acquire(thread)
159
- deadline ||= time + @timeout
160
- current_time = Time.now
161
- raise(::Sequel::PoolTimeout, "timeout: #{@timeout}, elapsed: #{current_time - time}") if current_time > deadline
162
- # :nocov:
163
- # It's difficult to get to this point, it can only happen if there is a race condition
164
- # where a connection cannot be acquired even after the thread is signalled by the condition
165
- @waiter.wait(@mutex, deadline - current_time)
166
- Thread.pass
167
- # :nocov:
186
+ if (n = _size) >= (max = @max_size)
187
+ allocated.keys.each do |t|
188
+ unless t.alive?
189
+ (to_disconnect ||= []) << allocated.delete(t)
190
+ end
168
191
  end
192
+ n = nil
193
+ end
169
194
 
170
- conn
195
+ if (n || _size) < max
196
+ do_make_new = allocated[thread] = true
171
197
  end
172
198
  end
173
- else
174
- # :nocov:
175
- def acquire(thread)
176
- unless conn = sync{_acquire(thread)}
177
- time = Time.now
178
- timeout = time + @timeout
179
- sleep_time = @sleep_time
180
- sleep sleep_time
181
- until conn = sync{_acquire(thread)}
182
- raise(::Sequel::PoolTimeout, "timeout: #{@timeout}, elapsed: #{Time.now - time}") if Time.now > timeout
183
- sleep sleep_time
199
+
200
+ if to_disconnect
201
+ to_disconnect.each{|dconn| disconnect_connection(dconn)}
202
+ end
203
+
204
+ # Connect to the database outside of the connection pool mutex,
205
+ # as that can take a long time and the connection pool mutex
206
+ # shouldn't be locked while the connection takes place.
207
+ if do_make_new
208
+ begin
209
+ conn = make_new(:default)
210
+ sync{allocated[thread] = conn}
211
+ ensure
212
+ unless conn
213
+ sync{allocated.delete(thread)}
184
214
  end
185
215
  end
186
- conn
187
216
  end
188
- # :nocov:
189
- end
190
217
 
191
- # Returns an available connection. If no connection is
192
- # available, tries to create a new connection. The calling code should already
193
- # have the mutex before calling this.
194
- def available
195
- next_available || make_new(DEFAULT_SERVER)
218
+ conn
196
219
  end
197
220
 
198
221
  # Return a connection to the pool of available connections, returns the connection.
199
222
  # The calling code should already have the mutex before calling this.
200
223
  def checkin_connection(conn)
201
224
  @available_connections << conn
202
- if USE_WAITER
203
- @waiter.signal
204
- Thread.pass
205
- end
206
225
  conn
207
226
  end
208
227
 
209
- unless method_defined?(:default_make_new)
210
- # Alias the default make_new method, so subclasses can call it directly.
211
- alias default_make_new make_new
212
- end
213
-
214
- # Creates a new connection to the given server if the size of the pool for
215
- # the server is less than the maximum size of the pool. The calling code
216
- # should already have the mutex before calling this.
217
- def make_new(server)
218
- if (n = size) >= @max_size
219
- @allocated.keys.each{|t| release(t) unless t.alive?}
220
- n = nil
221
- end
222
- super if (n || size) < @max_size
223
- end
224
-
225
228
  # Return the next available connection in the pool, or nil if there
226
229
  # is not currently an available connection. The calling code should already
227
230
  # have the mutex before calling this.
@@ -240,9 +243,25 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
240
243
  sync{@allocated[thread]}
241
244
  end
242
245
 
243
- # Create the maximum number of connections immediately.
244
- def preconnect
245
- (max_size - size).times{checkin_connection(make_new(nil))}
246
+ # Create the maximum number of connections immediately. The calling code should
247
+ # NOT have the mutex before calling this.
248
+ def preconnect(concurrent = false)
249
+ enum = (max_size - _size).times
250
+
251
+ conns = if concurrent
252
+ enum.map{Thread.new{make_new(:default)}}.map(&:value)
253
+ else
254
+ enum.map{make_new(:default)}
255
+ end
256
+
257
+ sync{conns.each{|conn| checkin_connection(conn)}}
258
+ end
259
+
260
+ # Raise a PoolTimeout error showing the current timeout, the elapsed time, and the
261
+ # database's name (if any).
262
+ def raise_pool_timeout(elapsed)
263
+ name = db.opts[:name]
264
+ raise ::Sequel::PoolTimeout, "timeout: #{@timeout}, elapsed: #{elapsed}#{", database name: #{name}" if name}"
246
265
  end
247
266
 
248
267
  # Releases the connection assigned to the supplied thread back to the pool.
@@ -250,11 +269,12 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
250
269
  def release(thread)
251
270
  conn = @allocated.delete(thread)
252
271
 
253
- if @connection_handling == :disconnect
254
- db.disconnect_connection(conn)
255
- else
272
+ unless @connection_handling == :disconnect
256
273
  checkin_connection(conn)
257
274
  end
275
+
276
+ @waiter.signal
277
+ nil
258
278
  end
259
279
 
260
280
  # Yield to the block while inside the mutex. The calling code should NOT
@@ -262,6 +282,4 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
262
282
  def sync
263
283
  @mutex.synchronize{yield}
264
284
  end
265
-
266
- CONNECTION_POOL_MAP[[false, false]] = self
267
285
  end
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  %w'bigdecimal date thread time uri'.each{|f| require f}
2
4
 
3
5
  # Top level module for Sequel
@@ -7,13 +9,16 @@
7
9
  #
8
10
  # DB = Sequel.sqlite # Memory database
9
11
  # DB = Sequel.sqlite('blog.db')
10
- # DB = Sequel.postgres('database_name', :user=>'user',
11
- # :password=>'password', :host=>'host', :port=>5432,
12
- # :max_connections=>10)
12
+ # DB = Sequel.postgres('database_name',
13
+ # user:'user',
14
+ # password: 'password',
15
+ # host: 'host'
16
+ # port: 5432,
17
+ # max_connections: 10)
13
18
  #
14
19
  # If a block is given to these methods, it is passed the opened Database
15
20
  # object, which is closed (disconnected) when the block exits, just
16
- # like a block passed to connect. For example:
21
+ # like a block passed to Sequel.connect. For example:
17
22
  #
18
23
  # Sequel.sqlite('blog.db'){|db| puts db[:users].count}
19
24
  #
@@ -22,11 +27,18 @@
22
27
  module Sequel
23
28
  @convert_two_digit_years = true
24
29
  @datetime_class = Time
25
-
26
- # Whether Sequel is being run in single threaded mode
30
+ @split_symbols = false
27
31
  @single_threaded = false
28
32
 
29
- class << self
33
+ # Mutex used to protect mutable data structures
34
+ @data_mutex = Mutex.new
35
+
36
+ # Frozen hash used as the default options hash for most options.
37
+ OPTS = {}.freeze
38
+
39
+ SPLIT_SYMBOL_CACHE = {}
40
+
41
+ module SequelMethods
30
42
  # Sequel converts two digit years in <tt>Date</tt>s and <tt>DateTime</tt>s by default,
31
43
  # so 01/02/03 is interpreted at January 2nd, 2003, and 12/13/99 is interpreted
32
44
  # as December 13, 1999. You can override this to treat those dates as
@@ -40,365 +52,385 @@ module Sequel
40
52
  #
41
53
  # Sequel.datetime_class = DateTime
42
54
  #
43
- # For ruby versions less than 1.9.2, +Time+ has a limited range (1901 to
44
- # 2038), so if you use datetimes out of that range, you need to switch
45
- # to +DateTime+. Also, before 1.9.2, +Time+ can only handle local and UTC
46
- # times, not other timezones. Note that +Time+ and +DateTime+ objects
47
- # have a different API, and in cases where they implement the same methods,
48
- # they often implement them differently (e.g. + using seconds on +Time+ and
49
- # days on +DateTime+).
55
+ # Note that +Time+ and +DateTime+ objects have a different API, and in
56
+ # cases where they implement the same methods, they often implement them
57
+ # differently (e.g. + using seconds on +Time+ and days on +DateTime+).
50
58
  attr_accessor :datetime_class
51
- end
52
-
53
- # Returns true if the passed object could be a specifier of conditions, false otherwise.
54
- # Currently, Sequel considers hashes and arrays of two element arrays as
55
- # condition specifiers.
56
- #
57
- # Sequel.condition_specifier?({}) # => true
58
- # Sequel.condition_specifier?([[1, 2]]) # => true
59
- # Sequel.condition_specifier?([]) # => false
60
- # Sequel.condition_specifier?([1]) # => false
61
- # Sequel.condition_specifier?(1) # => false
62
- def self.condition_specifier?(obj)
63
- case obj
64
- when Hash
65
- true
66
- when Array
67
- !obj.empty? && !obj.is_a?(SQL::ValueList) && obj.all?{|i| i.is_a?(Array) && (i.length == 2)}
68
- else
69
- false
70
- end
71
- end
72
59
 
73
- # Frozen hash used as the default options hash for most options.
74
- OPTS = {}.freeze
60
+ # Set whether Sequel is being used in single threaded mode. By default,
61
+ # Sequel uses a thread-safe connection pool, which isn't as fast as the
62
+ # single threaded connection pool, and also has some additional thread
63
+ # safety checks. If your program will only have one thread,
64
+ # and speed is a priority, you should set this to true:
65
+ #
66
+ # Sequel.single_threaded = true
67
+ attr_accessor :single_threaded
75
68
 
76
- # Creates a new database object based on the supplied connection string
77
- # and optional arguments. The specified scheme determines the database
78
- # class used, and the rest of the string specifies the connection options.
79
- # For example:
80
- #
81
- # DB = Sequel.connect('sqlite:/') # Memory database
82
- # DB = Sequel.connect('sqlite://blog.db') # ./blog.db
83
- # DB = Sequel.connect('sqlite:///blog.db') # /blog.db
84
- # DB = Sequel.connect('postgres://user:password@host:port/database_name')
85
- # DB = Sequel.connect('sqlite:///blog.db', :max_connections=>10)
86
- #
87
- # You can also pass a single options hash:
88
- #
89
- # DB = Sequel.connect(:adapter=>'sqlite', :database=>'./blog.db')
90
- #
91
- # If a block is given, it is passed the opened +Database+ object, which is
92
- # closed when the block exits. For example:
93
- #
94
- # Sequel.connect('sqlite://blog.db'){|db| puts db[:users].count}
95
- #
96
- # If a block is not given, a reference to this database will be held in
97
- # <tt>Sequel::DATABASES</tt> until it is removed manually. This is by
98
- # design, and used by <tt>Sequel::Model</tt> to pick the default
99
- # database. It is recommended to pass a block if you do not want the
100
- # resulting Database object to remain in memory until the process
101
- # terminates.
102
- #
103
- # For details, see the {"Connecting to a Database" guide}[rdoc-ref:doc/opening_databases.rdoc].
104
- # To set up a master/slave or sharded database connection, see the {"Master/Slave Databases and Sharding" guide}[rdoc-ref:doc/sharding.rdoc].
105
- def self.connect(*args, &block)
106
- Database.connect(*args, &block)
107
- end
69
+ # Alias of original require method, as Sequel.require does a relative
70
+ # require for backwards compatibility.
71
+ alias orig_require require
72
+ private :orig_require
108
73
 
109
- # Assume the core extensions are not loaded by default, if the core_extensions
110
- # extension is loaded, this will be overridden.
111
- def self.core_extensions?
112
- false
113
- end
74
+ # Returns true if the passed object could be a specifier of conditions, false otherwise.
75
+ # Currently, Sequel considers hashes and arrays of two element arrays as
76
+ # condition specifiers.
77
+ #
78
+ # Sequel.condition_specifier?({}) # => true
79
+ # Sequel.condition_specifier?([[1, 2]]) # => true
80
+ # Sequel.condition_specifier?([]) # => false
81
+ # Sequel.condition_specifier?([1]) # => false
82
+ # Sequel.condition_specifier?(1) # => false
83
+ def condition_specifier?(obj)
84
+ case obj
85
+ when Hash
86
+ true
87
+ when Array
88
+ !obj.empty? && !obj.is_a?(SQL::ValueList) && obj.all?{|i| i.is_a?(Array) && (i.length == 2)}
89
+ else
90
+ false
91
+ end
92
+ end
114
93
 
115
- # Convert the +exception+ to the given class. The given class should be
116
- # <tt>Sequel::Error</tt> or a subclass. Returns an instance of +klass+ with
117
- # the message and backtrace of +exception+.
118
- def self.convert_exception_class(exception, klass)
119
- return exception if exception.is_a?(klass)
120
- e = klass.new("#{exception.class}: #{exception.message}")
121
- e.wrapped_exception = exception
122
- e.set_backtrace(exception.backtrace)
123
- e
124
- end
94
+ # Creates a new database object based on the supplied connection string
95
+ # and optional arguments. The specified scheme determines the database
96
+ # class used, and the rest of the string specifies the connection options.
97
+ # For example:
98
+ #
99
+ # DB = Sequel.connect('sqlite:/') # Memory database
100
+ # DB = Sequel.connect('sqlite://blog.db') # ./blog.db
101
+ # DB = Sequel.connect('sqlite:///blog.db') # /blog.db
102
+ # DB = Sequel.connect('postgres://user:password@host:port/database_name')
103
+ # DB = Sequel.connect('sqlite:///blog.db', max_connections: 10)
104
+ #
105
+ # You can also pass a single options hash:
106
+ #
107
+ # DB = Sequel.connect(adapter: 'sqlite', database: './blog.db')
108
+ #
109
+ # If a block is given, it is passed the opened +Database+ object, which is
110
+ # closed when the block exits. For example:
111
+ #
112
+ # Sequel.connect('sqlite://blog.db'){|db| puts db[:users].count}
113
+ #
114
+ # If a block is not given, a reference to this database will be held in
115
+ # <tt>Sequel::DATABASES</tt> until it is removed manually. This is by
116
+ # design, and used by <tt>Sequel::Model</tt> to pick the default
117
+ # database. It is recommended to pass a block if you do not want the
118
+ # resulting Database object to remain in memory until the process
119
+ # terminates, or use the <tt>keep_reference: false</tt> Database option.
120
+ #
121
+ # For details, see the {"Connecting to a Database" guide}[rdoc-ref:doc/opening_databases.rdoc].
122
+ # To set up a primary/replica or sharded database connection, see the {"Primary/Replica Database Configurations and Sharding" guide}[rdoc-ref:doc/sharding.rdoc].
123
+ def connect(*args, &block)
124
+ Database.connect(*args, &block)
125
+ end
125
126
 
126
- # Load all Sequel extensions given. Extensions are just files that exist under
127
- # <tt>sequel/extensions</tt> in the load path, and are just required. Generally,
128
- # extensions modify the behavior of +Database+ and/or +Dataset+, but Sequel ships
129
- # with some extensions that modify other classes that exist for backwards compatibility.
130
- # In some cases, requiring an extension modifies classes directly, and in others,
131
- # it just loads a module that you can extend other classes with. Consult the documentation
132
- # for each extension you plan on using for usage.
133
- #
134
- # Sequel.extension(:schema_dumper)
135
- # Sequel.extension(:pagination, :query)
136
- def self.extension(*extensions)
137
- extensions.each{|e| Kernel.require "sequel/extensions/#{e}"}
138
- end
139
-
140
- # Set the method to call on identifiers going into the database. This affects
141
- # the literalization of identifiers by calling this method on them before they are input.
142
- # Sequel upcases identifiers in all SQL strings for most databases, so to turn that off:
143
- #
144
- # Sequel.identifier_input_method = nil
145
- #
146
- # to downcase instead:
147
- #
148
- # Sequel.identifier_input_method = :downcase
149
- #
150
- # Other String instance methods work as well.
151
- def self.identifier_input_method=(value)
152
- Database.identifier_input_method = value
153
- end
127
+ # Assume the core extensions are not loaded by default, if the core_extensions
128
+ # extension is loaded, this will be overridden.
129
+ def core_extensions?
130
+ false
131
+ end
154
132
 
155
- # Set the method to call on identifiers coming out of the database. This affects
156
- # the literalization of identifiers by calling this method on them when they are
157
- # retrieved from the database. Sequel downcases identifiers retrieved for most
158
- # databases, so to turn that off:
159
- #
160
- # Sequel.identifier_output_method = nil
161
- #
162
- # to upcase instead:
163
- #
164
- # Sequel.identifier_output_method = :upcase
165
- #
166
- # Other String instance methods work as well.
167
- def self.identifier_output_method=(value)
168
- Database.identifier_output_method = value
169
- end
133
+ # Convert the +exception+ to the given class. The given class should be
134
+ # <tt>Sequel::Error</tt> or a subclass. Returns an instance of +klass+ with
135
+ # the message and backtrace of +exception+.
136
+ def convert_exception_class(exception, klass)
137
+ return exception if exception.is_a?(klass)
138
+ e = klass.new("#{exception.class}: #{exception.message}")
139
+ e.wrapped_exception = exception
140
+ e.set_backtrace(exception.backtrace)
141
+ e
142
+ end
170
143
 
171
- # The exception classed raised if there is an error parsing JSON.
172
- # This can be overridden to use an alternative json implementation.
173
- def self.json_parser_error_class
174
- JSON::ParserError
175
- end
144
+ # The current concurrency primitive, Thread.current by default.
145
+ def current
146
+ Thread.current
147
+ end
176
148
 
177
- # Convert given object to json and return the result.
178
- # This can be overridden to use an alternative json implementation.
179
- def self.object_to_json(obj, *args)
180
- obj.to_json(*args)
181
- end
149
+ # Load all Sequel extensions given. Extensions are just files that exist under
150
+ # <tt>sequel/extensions</tt> in the load path, and are just required.
151
+ # In some cases, requiring an extension modifies classes directly, and in others,
152
+ # it just loads a module that you can extend other classes with. Consult the documentation
153
+ # for each extension you plan on using for usage.
154
+ #
155
+ # Sequel.extension(:blank)
156
+ # Sequel.extension(:core_extensions, :named_timezones)
157
+ def extension(*extensions)
158
+ extensions.each{|e| orig_require("sequel/extensions/#{e}")}
159
+ end
160
+
161
+ # The exception classed raised if there is an error parsing JSON.
162
+ # This can be overridden to use an alternative json implementation.
163
+ def json_parser_error_class
164
+ JSON::ParserError
165
+ end
182
166
 
183
- # Parse the string as JSON and return the result.
184
- # This can be overridden to use an alternative json implementation.
185
- def self.parse_json(json)
186
- JSON.parse(json, :create_additions=>false)
187
- end
167
+ # Convert given object to json and return the result.
168
+ # This can be overridden to use an alternative json implementation.
169
+ def object_to_json(obj, *args, &block)
170
+ obj.to_json(*args, &block)
171
+ end
188
172
 
189
- # Set whether to quote identifiers for all databases by default. By default,
190
- # Sequel quotes identifiers in all SQL strings, so to turn that off:
191
- #
192
- # Sequel.quote_identifiers = false
193
- def self.quote_identifiers=(value)
194
- Database.quote_identifiers = value
195
- end
173
+ # Parse the string as JSON and return the result.
174
+ # This can be overridden to use an alternative json implementation.
175
+ def parse_json(json)
176
+ JSON.parse(json, :create_additions=>false)
177
+ end
196
178
 
197
- # Convert each item in the array to the correct type, handling multi-dimensional
198
- # arrays. For each element in the array or subarrays, call the converter,
199
- # unless the value is nil.
200
- def self.recursive_map(array, converter)
201
- array.map do |i|
202
- if i.is_a?(Array)
203
- recursive_map(i, converter)
204
- elsif i
205
- converter.call(i)
179
+ # Convert each item in the array to the correct type, handling multi-dimensional
180
+ # arrays. For each element in the array or subarrays, call the converter,
181
+ # unless the value is nil.
182
+ def recursive_map(array, converter)
183
+ array.map do |i|
184
+ if i.is_a?(Array)
185
+ recursive_map(i, converter)
186
+ elsif !i.nil?
187
+ converter.call(i)
188
+ end
206
189
  end
207
190
  end
208
- end
209
-
210
- # Require all given +files+ which should be in the same or a subdirectory of
211
- # this file. If a +subdir+ is given, assume all +files+ are in that subdir.
212
- # This is used to ensure that the files loaded are from the same version of
213
- # Sequel as this file.
214
- def self.require(files, subdir=nil)
215
- Array(files).each{|f| super("#{File.dirname(__FILE__).untaint}/#{"#{subdir}/" if subdir}#{f}")}
216
- end
217
191
 
218
- # Set whether Sequel is being used in single threaded mode. By default,
219
- # Sequel uses a thread-safe connection pool, which isn't as fast as the
220
- # single threaded connection pool, and also has some additional thread
221
- # safety checks. If your program will only have one thread,
222
- # and speed is a priority, you should set this to true:
223
- #
224
- # Sequel.single_threaded = true
225
- def self.single_threaded=(value)
226
- @single_threaded = value
227
- Database.single_threaded = value
228
- end
229
-
230
- COLUMN_REF_RE1 = /\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/.freeze
231
- COLUMN_REF_RE2 = /\A((?:(?!___).)+)___(.+)\z/.freeze
232
- COLUMN_REF_RE3 = /\A((?:(?!__).)+)__(.+)\z/.freeze
233
- SPLIT_SYMBOL_CACHE = {}
192
+ # For backwards compatibility only. require_relative should be used instead.
193
+ def require(files, subdir=nil)
194
+ # Use Kernel.require_relative to work around JRuby 9.0 bug
195
+ Array(files).each{|f| Kernel.require_relative "#{"#{subdir}/" if subdir}#{f}"}
196
+ end
234
197
 
235
- # Splits the symbol into three parts. Each part will
236
- # either be a string or nil.
237
- #
238
- # For columns, these parts are the table, column, and alias.
239
- # For tables, these parts are the schema, table, and alias.
240
- def self.split_symbol(sym)
241
- unless v = Sequel.synchronize{SPLIT_SYMBOL_CACHE[sym]}
242
- v = case s = sym.to_s
243
- when COLUMN_REF_RE1
244
- [$1.freeze, $2.freeze, $3.freeze].freeze
245
- when COLUMN_REF_RE2
246
- [nil, $1.freeze, $2.freeze].freeze
247
- when COLUMN_REF_RE3
248
- [$1.freeze, $2.freeze, nil].freeze
249
- else
250
- [nil, s.freeze, nil].freeze
198
+ # Splits the symbol into three parts, if symbol splitting is enabled (not the default).
199
+ # Each part will either be a string or nil. If symbol splitting
200
+ # is disabled, returns an array with the first and third parts
201
+ # being nil, and the second part beind a string version of the symbol.
202
+ #
203
+ # For columns, these parts are the table, column, and alias.
204
+ # For tables, these parts are the schema, table, and alias.
205
+ def split_symbol(sym)
206
+ unless v = Sequel.synchronize{SPLIT_SYMBOL_CACHE[sym]}
207
+ if split_symbols?
208
+ v = case s = sym.to_s
209
+ when /\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/
210
+ [$1.freeze, $2.freeze, $3.freeze].freeze
211
+ when /\A((?:(?!___).)+)___(.+)\z/
212
+ [nil, $1.freeze, $2.freeze].freeze
213
+ when /\A((?:(?!__).)+)__(.+)\z/
214
+ [$1.freeze, $2.freeze, nil].freeze
215
+ else
216
+ [nil, s.freeze, nil].freeze
217
+ end
218
+ else
219
+ v = [nil,sym.to_s.freeze,nil].freeze
220
+ end
221
+ Sequel.synchronize{SPLIT_SYMBOL_CACHE[sym] = v}
251
222
  end
252
- Sequel.synchronize{SPLIT_SYMBOL_CACHE[sym] = v}
223
+ v
224
+ end
225
+
226
+ # Setting this to true enables Sequel's historical behavior of splitting
227
+ # symbols on double or triple underscores:
228
+ #
229
+ # :table__column # table.column
230
+ # :column___alias # column AS alias
231
+ # :table__column___alias # table.column AS alias
232
+ #
233
+ # It is only recommended to turn this on for backwards compatibility until
234
+ # such symbols have been converted to use newer Sequel APIs such as:
235
+ #
236
+ # Sequel[:table][:column] # table.column
237
+ # Sequel[:column].as(:alias) # column AS alias
238
+ # Sequel[:table][:column].as(:alias) # table.column AS alias
239
+ #
240
+ # Sequel::Database instances do their own caching of literalized
241
+ # symbols, and changing this setting does not affect those caches. It is
242
+ # recommended that if you want to change this setting, you do so directly
243
+ # after requiring Sequel, before creating any Sequel::Database instances.
244
+ #
245
+ # Disabling symbol splitting will also disable the handling
246
+ # of double underscores in virtual row methods, causing such methods to
247
+ # yield regular identifers instead of qualified identifiers:
248
+ #
249
+ # # Sequel.split_symbols = true
250
+ # Sequel.expr{table__column} # table.column
251
+ # Sequel.expr{table[:column]} # table.column
252
+ #
253
+ # # Sequel.split_symbols = false
254
+ # Sequel.expr{table__column} # table__column
255
+ # Sequel.expr{table[:column]} # table.column
256
+ def split_symbols=(v)
257
+ Sequel.synchronize{SPLIT_SYMBOL_CACHE.clear}
258
+ @split_symbols = v
253
259
  end
254
- v
255
- end
256
260
 
257
- # Converts the given +string+ into a +Date+ object.
258
- #
259
- # Sequel.string_to_date('2010-09-10') # Date.civil(2010, 09, 10)
260
- def self.string_to_date(string)
261
- begin
262
- Date.parse(string, Sequel.convert_two_digit_years)
263
- rescue => e
264
- raise convert_exception_class(e, InvalidValue)
261
+ # Whether Sequel currently splits symbols into qualified/aliased identifiers.
262
+ def split_symbols?
263
+ @split_symbols
265
264
  end
266
- end
267
265
 
268
- # Converts the given +string+ into a +Time+ or +DateTime+ object, depending on the
269
- # value of <tt>Sequel.datetime_class</tt>.
270
- #
271
- # Sequel.string_to_datetime('2010-09-10 10:20:30') # Time.local(2010, 09, 10, 10, 20, 30)
272
- def self.string_to_datetime(string)
273
- begin
274
- if datetime_class == DateTime
275
- DateTime.parse(string, convert_two_digit_years)
276
- else
277
- datetime_class.parse(string)
266
+ # Converts the given +string+ into a +Date+ object.
267
+ #
268
+ # Sequel.string_to_date('2010-09-10') # Date.civil(2010, 09, 10)
269
+ def string_to_date(string)
270
+ begin
271
+ Date.parse(string, Sequel.convert_two_digit_years)
272
+ rescue => e
273
+ raise convert_exception_class(e, InvalidValue)
278
274
  end
279
- rescue => e
280
- raise convert_exception_class(e, InvalidValue)
281
275
  end
282
- end
283
276
 
284
- # Converts the given +string+ into a <tt>Sequel::SQLTime</tt> object.
285
- #
286
- # v = Sequel.string_to_time('10:20:30') # Sequel::SQLTime.parse('10:20:30')
287
- # DB.literal(v) # => '10:20:30'
288
- def self.string_to_time(string)
289
- begin
290
- SQLTime.parse(string)
291
- rescue => e
292
- raise convert_exception_class(e, InvalidValue)
277
+ # Converts the given +string+ into a +Time+ or +DateTime+ object, depending on the
278
+ # value of <tt>Sequel.datetime_class</tt>.
279
+ #
280
+ # Sequel.string_to_datetime('2010-09-10 10:20:30') # Time.local(2010, 09, 10, 10, 20, 30)
281
+ def string_to_datetime(string)
282
+ begin
283
+ if datetime_class == DateTime
284
+ DateTime.parse(string, convert_two_digit_years)
285
+ else
286
+ datetime_class.parse(string)
287
+ end
288
+ rescue => e
289
+ raise convert_exception_class(e, InvalidValue)
290
+ end
293
291
  end
294
- end
295
292
 
296
- if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'ruby'
297
- # :nocov:
298
- # Mutex used to protect mutable data structures
299
- @data_mutex = Mutex.new
293
+ # Converts the given +string+ into a <tt>Sequel::SQLTime</tt> object.
294
+ #
295
+ # v = Sequel.string_to_time('10:20:30') # Sequel::SQLTime.parse('10:20:30')
296
+ # DB.literal(v) # => '10:20:30'
297
+ def string_to_time(string)
298
+ begin
299
+ SQLTime.parse(string)
300
+ rescue => e
301
+ raise convert_exception_class(e, InvalidValue)
302
+ end
303
+ end
300
304
 
301
305
  # Unless in single threaded mode, protects access to any mutable
302
306
  # global data structure in Sequel.
303
307
  # Uses a non-reentrant mutex, so calling code should be careful.
304
- def self.synchronize(&block)
308
+ # In general, this should only be used around the minimal possible code
309
+ # such as Hash#[], Hash#[]=, Hash#delete, Array#<<, and Array#delete.
310
+ def synchronize(&block)
305
311
  @single_threaded ? yield : @data_mutex.synchronize(&block)
306
312
  end
307
- # :nocov:
308
- else
309
- # Yield directly to the block. You don't need to synchronize
310
- # access on MRI because the GVL makes certain methods atomic.
311
- def self.synchronize
312
- yield
313
+
314
+ if RUBY_VERSION >= '2.1'
315
+ # A timer object that can be passed to Sequel.elapsed_seconds_since
316
+ # to return the number of seconds elapsed.
317
+ def start_timer
318
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
319
+ end
320
+ else
321
+ # :nocov:
322
+ def start_timer # :nodoc:
323
+ Time.now
324
+ end
325
+ # :nocov:
313
326
  end
314
- end
315
327
 
316
- # Uses a transaction on all given databases with the given options. This:
317
- #
318
- # Sequel.transaction([DB1, DB2, DB3]){...}
319
- #
320
- # is equivalent to:
321
- #
322
- # DB1.transaction do
323
- # DB2.transaction do
324
- # DB3.transaction do
325
- # ...
326
- # end
327
- # end
328
- # end
329
- #
330
- # except that if Sequel::Rollback is raised by the block, the transaction is
331
- # rolled back on all databases instead of just the last one.
332
- #
333
- # Note that this method cannot guarantee that all databases will commit or
334
- # rollback. For example, if DB3 commits but attempting to commit on DB2
335
- # fails (maybe because foreign key checks are deferred), there is no way
336
- # to uncommit the changes on DB3. For that kind of support, you need to
337
- # have two-phase commit/prepared transactions (which Sequel supports on
338
- # some databases).
339
- def self.transaction(dbs, opts=OPTS, &block)
340
- unless opts[:rollback]
341
- rescue_rollback = true
342
- opts = Hash[opts].merge!(:rollback=>:reraise)
328
+ # The elapsed seconds since the given timer object was created. The
329
+ # timer object should have been created via Sequel.start_timer.
330
+ def elapsed_seconds_since(timer)
331
+ start_timer - timer
343
332
  end
344
- pr = dbs.reverse.inject(block){|bl, db| proc{db.transaction(opts, &bl)}}
345
- if rescue_rollback
346
- begin
333
+
334
+ # Uses a transaction on all given databases with the given options. This:
335
+ #
336
+ # Sequel.transaction([DB1, DB2, DB3]){}
337
+ #
338
+ # is equivalent to:
339
+ #
340
+ # DB1.transaction do
341
+ # DB2.transaction do
342
+ # DB3.transaction do
343
+ # end
344
+ # end
345
+ # end
346
+ #
347
+ # except that if Sequel::Rollback is raised by the block, the transaction is
348
+ # rolled back on all databases instead of just the last one.
349
+ #
350
+ # Note that this method cannot guarantee that all databases will commit or
351
+ # rollback. For example, if DB3 commits but attempting to commit on DB2
352
+ # fails (maybe because foreign key checks are deferred), there is no way
353
+ # to uncommit the changes on DB3. For that kind of support, you need to
354
+ # have two-phase commit/prepared transactions (which Sequel supports on
355
+ # some databases).
356
+ def transaction(dbs, opts=OPTS, &block)
357
+ unless opts[:rollback]
358
+ rescue_rollback = true
359
+ opts = Hash[opts].merge!(:rollback=>:reraise)
360
+ end
361
+ pr = dbs.reverse.inject(block){|bl, db| proc{db.transaction(opts, &bl)}}
362
+ if rescue_rollback
363
+ begin
364
+ pr.call
365
+ rescue Sequel::Rollback
366
+ nil
367
+ end
368
+ else
347
369
  pr.call
348
- rescue Sequel::Rollback
349
- nil
350
370
  end
351
- else
352
- pr.call
353
371
  end
354
- end
355
372
 
356
- # If the supplied block takes a single argument,
357
- # yield an <tt>SQL::VirtualRow</tt> instance to the block
358
- # argument. Otherwise, evaluate the block in the context of a
359
- # <tt>SQL::VirtualRow</tt> instance.
360
- #
361
- # Sequel.virtual_row{a} # Sequel::SQL::Identifier.new(:a)
362
- # Sequel.virtual_row{|o| o.a{}} # Sequel::SQL::Function.new(:a)
363
- def self.virtual_row(&block)
364
- vr = VIRTUAL_ROW
365
- case block.arity
366
- when -1, 0
367
- vr.instance_exec(&block)
368
- else
369
- block.call(vr)
370
- end
371
- end
373
+ # If the supplied block takes a single argument,
374
+ # yield an <tt>SQL::VirtualRow</tt> instance to the block
375
+ # argument. Otherwise, evaluate the block in the context of a
376
+ # <tt>SQL::VirtualRow</tt> instance.
377
+ #
378
+ # Sequel.virtual_row{a} # Sequel::SQL::Identifier.new(:a)
379
+ # Sequel.virtual_row{|o| o.a} # Sequel::SQL::Function.new(:a)
380
+ def virtual_row(&block)
381
+ vr = VIRTUAL_ROW
382
+ case block.arity
383
+ when -1, 0
384
+ vr.instance_exec(&block)
385
+ else
386
+ block.call(vr)
387
+ end
388
+ end
372
389
 
373
- ### Private Class Methods ###
390
+ private
374
391
 
375
- # Helper method that the database adapter class methods that are added to Sequel via
376
- # metaprogramming use to parse arguments.
377
- def self.adapter_method(adapter, *args, &block)
378
- options = args.last.is_a?(Hash) ? args.pop : {}
379
- opts = {:adapter => adapter.to_sym}
380
- opts[:database] = args.shift if args.first.is_a?(String)
381
- if args.any?
382
- raise ::Sequel::Error, "Wrong format of arguments, either use (), (String), (Hash), or (String, Hash)"
383
- end
392
+ # Helper method that the database adapter class methods that are added to Sequel via
393
+ # metaprogramming use to parse arguments.
394
+ def adapter_method(adapter, *args, &block)
395
+ options = args.last.is_a?(Hash) ? args.pop : OPTS
396
+ opts = {:adapter => adapter.to_sym}
397
+ opts[:database] = args.shift if args.first.is_a?(String)
398
+ if args.any?
399
+ raise ::Sequel::Error, "Wrong format of arguments, either use (), (String), (Hash), or (String, Hash)"
400
+ end
384
401
 
385
- connect(opts.merge(options), &block)
386
- end
402
+ connect(opts.merge(options), &block)
403
+ end
387
404
 
388
- # Method that adds a database adapter class method to Sequel that calls
389
- # Sequel.adapter_method.
390
- #
391
- # Do not call this method with untrusted input, as that can result in
392
- # arbitrary code execution.
393
- def self.def_adapter_method(*adapters) # :nodoc:
394
- adapters.each do |adapter|
395
- instance_eval("def #{adapter}(*args, &block); adapter_method('#{adapter}', *args, &block) end", __FILE__, __LINE__)
405
+ # Method that adds a database adapter class method to Sequel that calls
406
+ # Sequel.adapter_method.
407
+ def def_adapter_method(*adapters) # :nodoc:
408
+ adapters.each do |adapter|
409
+ define_singleton_method(adapter){|*args, &block| adapter_method(adapter, *args, &block)}
410
+ end
396
411
  end
397
412
  end
413
+ extend SequelMethods
414
+
415
+ require_relative "deprecated"
416
+ require_relative "sql"
417
+ require_relative "connection_pool"
418
+ require_relative "exceptions"
419
+ require_relative "dataset"
420
+ require_relative "database"
421
+ require_relative "timezones"
422
+ require_relative "ast_transformer"
423
+ require_relative "version"
398
424
 
399
- private_class_method :adapter_method, :def_adapter_method
400
-
401
- require(%w"deprecated sql connection_pool exceptions dataset database timezones ast_transformer version")
425
+ class << self
426
+ # Allow nicer syntax for creating Sequel expressions:
427
+ #
428
+ # Sequel[1] # => Sequel::SQL::NumericExpression: 1
429
+ # Sequel["a"] # => Sequel::SQL::StringExpression: 'a'
430
+ # Sequel[:a] # => Sequel::SQL::Identifier: "a"
431
+ # Sequel[a: 1] # => Sequel::SQL::BooleanExpression: ("a" = 1)
432
+ alias_method :[], :expr
433
+ end
402
434
 
403
435
  # Add the database adapter class methods to Sequel via metaprogramming
404
436
  def_adapter_method(*Database::ADAPTERS)