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,21 +1,26 @@
1
- Sequel.require 'adapters/utils/split_alter_table'
2
- Sequel.require 'adapters/utils/replace'
1
+ # frozen-string-literal: true
3
2
 
4
- module Sequel
5
- Dataset::NON_SQL_OPTIONS << :insert_ignore
6
- Dataset::NON_SQL_OPTIONS << :update_ignore
7
- Dataset::NON_SQL_OPTIONS << :on_duplicate_key_update
3
+ require_relative '../utils/replace'
4
+ require_relative '../utils/split_alter_table'
5
+ require_relative '../utils/unmodified_identifiers'
8
6
 
7
+ module Sequel
9
8
  module MySQL
10
- @convert_tinyint_to_bool = true
9
+ Sequel::Database.set_shared_adapter_scheme(:mysql, self)
11
10
 
12
- class << self
13
- # Sequel converts the column type tinyint(1) to a boolean by default when
14
- # using the native MySQL or Mysql2 adapter. You can turn off the conversion by setting
15
- # this to false. This setting is ignored when connecting to MySQL via the do or jdbc
16
- # adapters, both of which automatically do the conversion.
17
- attr_accessor :convert_tinyint_to_bool
11
+ def self.mock_adapter_setup(db)
12
+ db.instance_exec do
13
+ @server_version = 50617
14
+ end
15
+ end
16
+
17
+ module DatabaseMethods
18
+ include UnmodifiedIdentifiers::DatabaseMethods
19
+ include Sequel::Database::SplitAlterTable
18
20
 
21
+ CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}.freeze
22
+ COLUMN_DEFINITION_ORDER = [:generated, :collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze
23
+
19
24
  # Set the default charset used for CREATE TABLE. You can pass the
20
25
  # :charset option to create_table to override this setting.
21
26
  attr_accessor :default_charset
@@ -27,34 +32,17 @@ module Sequel
27
32
  # Set the default engine used for CREATE TABLE. You can pass the
28
33
  # :engine option to create_table to override this setting.
29
34
  attr_accessor :default_engine
30
- end
31
-
32
- # Methods shared by Database instances that connect to MySQL,
33
- # currently supported by the native and JDBC adapters.
34
- module DatabaseMethods
35
- extend Sequel::Database::ResetIdentifierMangling
36
35
 
37
- AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
38
- CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}
39
- COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references]
40
- PRIMARY = 'PRIMARY'.freeze
41
- MYSQL_TIMESTAMP_RE = /\ACURRENT_(?:DATE|TIMESTAMP)?\z/
42
-
43
- include Sequel::Database::SplitAlterTable
44
-
45
36
  # MySQL's cast rules are restrictive in that you can't just cast to any possible
46
37
  # database type.
47
38
  def cast_type_literal(type)
48
39
  CAST_TYPES[type] || super
49
40
  end
50
41
 
51
- # Commit an existing prepared transaction with the given transaction
52
- # identifier string.
53
42
  def commit_prepared_transaction(transaction_id, opts=OPTS)
54
43
  run("XA COMMIT #{literal(transaction_id)}", opts)
55
44
  end
56
45
 
57
- # MySQL uses the :mysql database type
58
46
  def database_type
59
47
  :mysql
60
48
  end
@@ -66,11 +54,12 @@ module Sequel
66
54
  m = output_identifier_meth
67
55
  im = input_identifier_meth
68
56
  ds = metadata_dataset.
69
- from(:INFORMATION_SCHEMA__KEY_COLUMN_USAGE).
57
+ from(Sequel[:INFORMATION_SCHEMA][:KEY_COLUMN_USAGE]).
70
58
  where(:TABLE_NAME=>im.call(table), :TABLE_SCHEMA=>Sequel.function(:DATABASE)).
71
59
  exclude(:CONSTRAINT_NAME=>'PRIMARY').
72
60
  exclude(:REFERENCED_TABLE_NAME=>nil).
73
- select(:CONSTRAINT_NAME___name, :COLUMN_NAME___column, :REFERENCED_TABLE_NAME___table, :REFERENCED_COLUMN_NAME___key)
61
+ order(:CONSTRAINT_NAME, :POSITION_IN_UNIQUE_CONSTRAINT).
62
+ select(Sequel[:CONSTRAINT_NAME].as(:name), Sequel[:COLUMN_NAME].as(:column), Sequel[:REFERENCED_TABLE_NAME].as(:table), Sequel[:REFERENCED_COLUMN_NAME].as(:key))
74
63
 
75
64
  h = {}
76
65
  ds.each do |row|
@@ -84,6 +73,13 @@ module Sequel
84
73
  h.values
85
74
  end
86
75
 
76
+ def freeze
77
+ server_version
78
+ mariadb?
79
+ supports_timestamp_usecs?
80
+ super
81
+ end
82
+
87
83
  # MySQL namespaces indexes per table.
88
84
  def global_index_namespace?
89
85
  false
@@ -98,10 +94,18 @@ module Sequel
98
94
  indexes = {}
99
95
  remove_indexes = []
100
96
  m = output_identifier_meth
101
- im = input_identifier_meth
102
- metadata_dataset.with_sql("SHOW INDEX FROM ?", SQL::Identifier.new(im.call(table))).each do |r|
97
+ schema, table = schema_and_table(table)
98
+
99
+ table = Sequel::SQL::Identifier.new(table)
100
+ sql = "SHOW INDEX FROM #{literal(table)}"
101
+ if schema
102
+ schema = Sequel::SQL::Identifier.new(schema)
103
+ sql += " FROM #{literal(schema)}"
104
+ end
105
+
106
+ metadata_dataset.with_sql(sql).each do |r|
103
107
  name = r[:Key_name]
104
- next if name == PRIMARY
108
+ next if name == 'PRIMARY'
105
109
  name = m.call(name)
106
110
  remove_indexes << name if r[:Sub_part] && ! opts[:partial]
107
111
  i = indexes[name] ||= {:columns=>[], :unique=>r[:Non_unique] != 1}
@@ -110,16 +114,20 @@ module Sequel
110
114
  indexes.reject{|k,v| remove_indexes.include?(k)}
111
115
  end
112
116
 
113
- # Rollback an existing prepared transaction with the given transaction
114
- # identifier string.
115
117
  def rollback_prepared_transaction(transaction_id, opts=OPTS)
116
118
  run("XA ROLLBACK #{literal(transaction_id)}", opts)
117
119
  end
118
120
 
121
+ # Whether the database is MariaDB and not MySQL
122
+ def mariadb?
123
+ return @is_mariadb if defined?(@is_mariadb)
124
+ @is_mariadb = !(fetch('SELECT version()').single_value! !~ /mariadb/i)
125
+ end
126
+
119
127
  # Get version of MySQL server, used for determined capabilities.
120
128
  def server_version
121
129
  @server_version ||= begin
122
- m = /(\d+)\.(\d+)\.(\d+)/.match(get(SQL::Function.new(:version)))
130
+ m = /(\d+)\.(\d+)\.(\d+)/.match(fetch('SELECT version()').single_value!)
123
131
  (m[1].to_i * 10000) + (m[2].to_i * 100) + m[3].to_i
124
132
  end
125
133
  end
@@ -129,6 +137,11 @@ module Sequel
129
137
  true
130
138
  end
131
139
 
140
+ # Generated columns are supported in MariaDB 5.2.0+ and MySQL 5.7.6+.
141
+ def supports_generated_columns?
142
+ server_version >= (mariadb? ? 50200 : 50706)
143
+ end
144
+
132
145
  # MySQL 5+ supports prepared transactions (two-phase commit) using XA
133
146
  def supports_prepared_transactions?
134
147
  server_version >= 50000
@@ -150,7 +163,8 @@ module Sequel
150
163
  # automatic initialization of datetime values wasn't supported to 5.6.5+,
151
164
  # and this is related to that.
152
165
  def supports_timestamp_usecs?
153
- @supports_timestamp_usecs ||= server_version >= 50605 && typecast_value_boolean(opts[:fractional_seconds])
166
+ return @supports_timestamp_usecs if defined?(@supports_timestamp_usecs)
167
+ @supports_timestamp_usecs = server_version >= 50605 && typecast_value_boolean(opts[:fractional_seconds])
154
168
  end
155
169
 
156
170
  # MySQL supports transaction isolation levels
@@ -166,15 +180,6 @@ module Sequel
166
180
  full_tables('BASE TABLE', opts)
167
181
  end
168
182
 
169
- # Changes the database in use by issuing a USE statement. I would be
170
- # very careful if I used this.
171
- def use(db_name)
172
- disconnect
173
- @opts[:database] = db_name if self << "USE #{db_name}"
174
- @schemas = {}
175
- self
176
- end
177
-
178
183
  # Return an array of symbols specifying view names in the current database.
179
184
  #
180
185
  # Options:
@@ -186,17 +191,22 @@ module Sequel
186
191
  private
187
192
 
188
193
  def alter_table_add_column_sql(table, op)
189
- if related = op.delete(:table)
190
- sql = super
194
+ pos = if after_col = op[:after]
195
+ " AFTER #{quote_identifier(after_col)}"
196
+ elsif op[:first]
197
+ " FIRST"
198
+ end
199
+
200
+ sql = if related = op.delete(:table)
201
+ sql = super + "#{pos}, ADD "
191
202
  op[:table] = related
192
203
  op[:key] ||= primary_key_from_schema(related)
193
- sql << ", ADD "
194
204
  if constraint_name = op.delete(:foreign_key_constraint_name)
195
205
  sql << "CONSTRAINT #{quote_identifier(constraint_name)} "
196
206
  end
197
207
  sql << "FOREIGN KEY (#{quote_identifier(op[:name])})#{column_references_sql(op)}"
198
208
  else
199
- super
209
+ "#{super}#{pos}"
200
210
  end
201
211
  end
202
212
 
@@ -222,7 +232,18 @@ module Sequel
222
232
  alias alter_table_rename_column_sql alter_table_change_column_sql
223
233
  alias alter_table_set_column_type_sql alter_table_change_column_sql
224
234
  alias alter_table_set_column_null_sql alter_table_change_column_sql
225
- alias alter_table_set_column_default_sql alter_table_change_column_sql
235
+
236
+ def alter_table_set_column_default_sql(table, op)
237
+ return super unless op[:default].nil?
238
+
239
+ opts = schema(table).find{|x| x[0] == op[:name]}
240
+
241
+ if opts && opts[1][:allow_null] == false
242
+ "ALTER COLUMN #{quote_identifier(op[:name])} DROP DEFAULT"
243
+ else
244
+ super
245
+ end
246
+ end
226
247
 
227
248
  def alter_table_add_constraint_sql(table, op)
228
249
  if op[:type] == :foreign_key
@@ -240,10 +261,13 @@ module Sequel
240
261
  "DROP FOREIGN KEY #{quote_identifier(name)}"
241
262
  when :unique
242
263
  "DROP INDEX #{quote_identifier(op[:name])}"
264
+ when :check, nil
265
+ if supports_check_constraints?
266
+ "DROP CONSTRAINT #{quote_identifier(op[:name])}"
267
+ end
243
268
  end
244
269
  end
245
270
 
246
- # MySQL server requires table names when dropping indexes.
247
271
  def alter_table_sql(table, op)
248
272
  case op[:op]
249
273
  when :drop_index
@@ -263,12 +287,17 @@ module Sequel
263
287
  # Handle MySQL specific default format.
264
288
  def column_schema_normalize_default(default, type)
265
289
  if column_schema_default_string_type?(type)
266
- return if [:date, :datetime, :time].include?(type) && MYSQL_TIMESTAMP_RE.match(default)
290
+ return if [:date, :datetime, :time].include?(type) && /\ACURRENT_(?:DATE|TIMESTAMP)?\z/.match(default)
267
291
  default = "'#{default.gsub("'", "''").gsub('\\', '\\\\')}'"
268
292
  end
269
293
  super(default, type)
270
294
  end
271
295
 
296
+ def column_schema_to_ruby_default(default, type)
297
+ return Sequel::CURRENT_DATE if mariadb? && server_version >= 100200 && default == 'curdate()'
298
+ super
299
+ end
300
+
272
301
  # Don't allow combining adding foreign key operations with other
273
302
  # operations, since in some cases adding a foreign key constraint in
274
303
  # the same query as other operations results in MySQL error 150.
@@ -298,9 +327,8 @@ module Sequel
298
327
  sqls
299
328
  end
300
329
 
301
- # Use MySQL specific AUTO_INCREMENT text.
302
330
  def auto_increment_sql
303
- AUTO_INCREMENT
331
+ 'AUTO_INCREMENT'
304
332
  end
305
333
 
306
334
  # MySQL needs to set transaction isolation before begining a transaction
@@ -319,7 +347,23 @@ module Sequel
319
347
  end
320
348
  end
321
349
 
322
- # The order of the column definition, as an array of symbols.
350
+ # Add generation clause SQL fragment to column creation SQL.
351
+ def column_definition_generated_sql(sql, column)
352
+ if (generated_expression = column[:generated_always_as])
353
+ sql << " GENERATED ALWAYS AS (#{literal(generated_expression)})"
354
+ case (type = column[:generated_type])
355
+ when nil
356
+ # none, database default
357
+ when :virtual
358
+ sql << " VIRTUAL"
359
+ when :stored
360
+ sql << (mariadb? ? " PERSISTENT" : " STORED")
361
+ else
362
+ raise Error, "unsupported :generated_type option: #{type.inspect}"
363
+ end
364
+ end
365
+ end
366
+
323
367
  def column_definition_order
324
368
  COLUMN_DEFINITION_ORDER
325
369
  end
@@ -344,9 +388,9 @@ module Sequel
344
388
 
345
389
  # Use MySQL specific syntax for engine type and character encoding
346
390
  def create_table_sql(name, generator, options = OPTS)
347
- engine = options.fetch(:engine, Sequel::MySQL.default_engine)
348
- charset = options.fetch(:charset, Sequel::MySQL.default_charset)
349
- collate = options.fetch(:collate, Sequel::MySQL.default_collate)
391
+ engine = options.fetch(:engine, default_engine)
392
+ charset = options.fetch(:charset, default_charset)
393
+ collate = options.fetch(:collate, default_collate)
350
394
  generator.constraints.sort_by{|c| (c[:type] == :primary_key) ? -1 : 1}
351
395
 
352
396
  # Proc for figuring out the primary key for a given table.
@@ -356,6 +400,8 @@ module Sequel
356
400
  [pk]
357
401
  elsif !(pkc = generator.constraints.select{|con| con[:type] == :primary_key}).empty?
358
402
  pkc.first[:columns]
403
+ elsif !(pkc = generator.columns.select{|con| con[:primary_key] == true}).empty?
404
+ pkc.map{|c| c[:name]}
359
405
  end
360
406
  else
361
407
  primary_key_from_schema(t)
@@ -394,6 +440,8 @@ module Sequel
394
440
  /foreign key constraint fails/ => ForeignKeyConstraintViolation,
395
441
  /cannot be null/ => NotNullConstraintViolation,
396
442
  /Deadlock found when trying to get lock; try restarting transaction/ => SerializationFailure,
443
+ /CONSTRAINT .+ failed for/ => CheckConstraintViolation,
444
+ /\A(Statement aborted because lock\(s\) could not be acquired immediately and NOWAIT is set\.|Lock wait timeout exceeded; try restarting transaction)/ => DatabaseLockTimeout,
397
445
  }.freeze
398
446
  def database_error_regexps
399
447
  DATABASE_ERROR_REGEXPS
@@ -405,17 +453,6 @@ module Sequel
405
453
  metadata_dataset.with_sql('SHOW FULL TABLES').server(opts[:server]).map{|r| m.call(r.values.first) if r.delete(:Table_type) == type}.compact
406
454
  end
407
455
 
408
- # MySQL folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on input.
409
- def identifier_input_method_default
410
- nil
411
- end
412
-
413
- # MySQL folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on output.
414
- def identifier_output_method_default
415
- nil
416
- end
417
-
418
- # Handle MySQL specific index SQL syntax
419
456
  def index_definition_sql(table_name, index)
420
457
  index_name = quote_identifier(index[:name] || default_index_name(table_name, index[:columns]))
421
458
  raise Error, "Partial indexes are not supported for this database" if index[:where] && !supports_partial_indexes?
@@ -447,7 +484,6 @@ module Sequel
447
484
  end
448
485
  end
449
486
 
450
- # Recognize MySQL set type.
451
487
  def schema_column_type(db_type)
452
488
  case db_type
453
489
  when /\Aset/io
@@ -470,7 +506,11 @@ module Sequel
470
506
  metadata_dataset.with_sql("DESCRIBE ?", table).map do |row|
471
507
  extra = row.delete(:Extra)
472
508
  if row[:primary_key] = row.delete(:Key) == 'PRI'
473
- row[:auto_increment] = !!(extra.to_s =~ /auto_increment/io)
509
+ row[:auto_increment] = !!(extra.to_s =~ /auto_increment/i)
510
+ end
511
+ if supports_generated_columns?
512
+ # Extra field contains VIRTUAL or PERSISTENT for generated columns
513
+ row[:generated] = !!(extra.to_s =~ /VIRTUAL|STORED|PERSISTENT/i)
474
514
  end
475
515
  row[:allow_null] = row.delete(:Null) == 'YES'
476
516
  row[:default] = row.delete(:Default)
@@ -486,6 +526,11 @@ module Sequel
486
526
  server_version >= 50600 && (op[:op] == :drop_index || (op[:op] == :drop_constraint && op[:type] == :unique))
487
527
  end
488
528
 
529
+ # Whether the database supports CHECK constraints
530
+ def supports_check_constraints?
531
+ mariadb? && server_version >= 100200
532
+ end
533
+
489
534
  # MySQL can combine multiple alter table ops into a single query.
490
535
  def supports_combining_alter_table_ops?
491
536
  true
@@ -531,15 +576,11 @@ module Sequel
531
576
 
532
577
  # MySQL has both datetime and timestamp classes, most people are going
533
578
  # to want datetime.
534
- def type_literal_generic_time(column)
535
- if column[:only_time]
536
- if supports_timestamp_usecs?
537
- :'time(6)'
538
- else
539
- :time
540
- end
579
+ def type_literal_generic_only_time(column)
580
+ if supports_timestamp_usecs?
581
+ :'time(6)'
541
582
  else
542
- type_literal_generic_datetime(column)
583
+ :time
543
584
  end
544
585
  end
545
586
 
@@ -556,99 +597,57 @@ module Sequel
556
597
 
557
598
  # Dataset methods shared by datasets that use MySQL databases.
558
599
  module DatasetMethods
559
- BOOL_TRUE = '1'.freeze
560
- BOOL_FALSE = '0'.freeze
561
- COMMA_SEPARATOR = ', '.freeze
562
- FOR_SHARE = ' LOCK IN SHARE MODE'.freeze
563
- SQL_CALC_FOUND_ROWS = ' SQL_CALC_FOUND_ROWS'.freeze
564
- APOS = Dataset::APOS
565
- APOS_RE = Dataset::APOS_RE
566
- DOUBLE_APOS = Dataset::DOUBLE_APOS
567
- SPACE = Dataset::SPACE
568
- PAREN_OPEN = Dataset::PAREN_OPEN
569
- PAREN_CLOSE = Dataset::PAREN_CLOSE
570
- NOT_SPACE = Dataset::NOT_SPACE
571
- FROM = Dataset::FROM
572
- COMMA = Dataset::COMMA
573
- LIMIT = Dataset::LIMIT
574
- GROUP_BY = Dataset::GROUP_BY
575
- ESCAPE = Dataset::ESCAPE
576
- BACKSLASH = Dataset::BACKSLASH
577
- REGEXP = 'REGEXP'.freeze
578
- LIKE = 'LIKE'.freeze
579
- BINARY = 'BINARY '.freeze
580
- CONCAT = "CONCAT".freeze
581
- CAST_BITCOMP_OPEN = "CAST(~".freeze
582
- CAST_BITCOMP_CLOSE = " AS SIGNED INTEGER)".freeze
583
- STRAIGHT_JOIN = 'STRAIGHT_JOIN'.freeze
584
- NATURAL_LEFT_JOIN = 'NATURAL LEFT JOIN'.freeze
585
- BACKTICK = '`'.freeze
586
- BACKTICK_RE = /`/.freeze
587
- DOUBLE_BACKTICK = '``'.freeze
588
- EMPTY_COLUMNS = " ()".freeze
589
- EMPTY_VALUES = " VALUES ()".freeze
590
- IGNORE = " IGNORE".freeze
591
- ON_DUPLICATE_KEY_UPDATE = " ON DUPLICATE KEY UPDATE ".freeze
592
- EQ_VALUES = '=VALUES('.freeze
593
- EQ = '='.freeze
594
- WITH_ROLLUP = ' WITH ROLLUP'.freeze
595
- MATCH_AGAINST = ["(MATCH ".freeze, " AGAINST (".freeze, "))".freeze].freeze
596
- MATCH_AGAINST_BOOLEAN = ["(MATCH ".freeze, " AGAINST (".freeze, " IN BOOLEAN MODE))".freeze].freeze
597
- EXPLAIN = 'EXPLAIN '.freeze
598
- EXPLAIN_EXTENDED = 'EXPLAIN EXTENDED '.freeze
599
- BACKSLASH_RE = /\\/.freeze
600
- QUAD_BACKSLASH = "\\\\\\\\".freeze
601
- BLOB_START = "0x".freeze
602
- EMPTY_BLOB = "''".freeze
603
- HSTAR = "H*".freeze
604
- CURRENT_TIMESTAMP_56 = 'CURRENT_TIMESTAMP(6)'.freeze
605
-
606
- # Comes directly from MySQL's documentation, used for queries with limits without offsets
607
- ONLY_OFFSET = ",18446744073709551615".freeze
608
-
609
- Dataset.def_sql_method(self, :delete, %w'delete from where order limit')
600
+ MATCH_AGAINST = ["MATCH ".freeze, " AGAINST (".freeze, ")".freeze].freeze
601
+ MATCH_AGAINST_BOOLEAN = ["MATCH ".freeze, " AGAINST (".freeze, " IN BOOLEAN MODE)".freeze].freeze
602
+
603
+ Dataset.def_sql_method(self, :delete, %w'with delete from where order limit')
610
604
  Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update')
611
- Dataset.def_sql_method(self, :select, %w'select distinct calc_found_rows columns from join where group having compounds order limit lock')
612
- Dataset.def_sql_method(self, :update, %w'update ignore table set where order limit')
605
+ Dataset.def_sql_method(self, :select, %w'with select distinct calc_found_rows columns from join where group having window compounds order limit lock')
606
+ Dataset.def_sql_method(self, :update, %w'with update ignore table set where order limit')
613
607
 
614
608
  include Sequel::Dataset::Replace
609
+ include UnmodifiedIdentifiers::DatasetMethods
615
610
 
616
- # MySQL specific syntax for LIKE/REGEXP searches, as well as
617
- # string concatenation.
618
611
  def complex_expression_sql_append(sql, op, args)
619
612
  case op
620
613
  when :IN, :"NOT IN"
621
- ds = args.at(1)
614
+ ds = args[1]
622
615
  if ds.is_a?(Sequel::Dataset) && ds.opts[:limit]
623
- super(sql, op, [args.at(0), ds.from_self])
616
+ super(sql, op, [args[0], ds.from_self])
624
617
  else
625
618
  super
626
619
  end
627
620
  when :~, :'!~', :'~*', :'!~*', :LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'
628
- sql << PAREN_OPEN
629
- literal_append(sql, args.at(0))
630
- sql << SPACE
621
+ if !db.mariadb? && db.server_version >= 80000 && [:~, :'!~'].include?(op)
622
+ func = Sequel.function(:REGEXP_LIKE, args[0], args[1], 'c')
623
+ func = ~func if op == :'!~'
624
+ return literal_append(sql, func)
625
+ end
626
+
627
+ sql << '('
628
+ literal_append(sql, args[0])
629
+ sql << ' '
631
630
  sql << 'NOT ' if [:'NOT LIKE', :'NOT ILIKE', :'!~', :'!~*'].include?(op)
632
- sql << ([:~, :'!~', :'~*', :'!~*'].include?(op) ? REGEXP : LIKE)
633
- sql << SPACE
634
- sql << BINARY if [:~, :'!~', :LIKE, :'NOT LIKE'].include?(op)
635
- literal_append(sql, args.at(1))
631
+ sql << ([:~, :'!~', :'~*', :'!~*'].include?(op) ? 'REGEXP' : 'LIKE')
632
+ sql << ' '
633
+ sql << 'BINARY ' if [:~, :'!~', :LIKE, :'NOT LIKE'].include?(op)
634
+ literal_append(sql, args[1])
636
635
  if [:LIKE, :'NOT LIKE', :ILIKE, :'NOT ILIKE'].include?(op)
637
- sql << ESCAPE
638
- literal_append(sql, BACKSLASH)
636
+ sql << " ESCAPE "
637
+ literal_append(sql, "\\")
639
638
  end
640
- sql << PAREN_CLOSE
639
+ sql << ')'
641
640
  when :'||'
642
641
  if args.length > 1
643
- sql << CONCAT
642
+ sql << "CONCAT"
644
643
  array_sql_append(sql, args)
645
644
  else
646
- literal_append(sql, args.at(0))
645
+ literal_append(sql, args[0])
647
646
  end
648
647
  when :'B~'
649
- sql << CAST_BITCOMP_OPEN
650
- literal_append(sql, args.at(0))
651
- sql << CAST_BITCOMP_CLOSE
648
+ sql << "CAST(~"
649
+ literal_append(sql, args[0])
650
+ sql << " AS SIGNED INTEGER)"
652
651
  else
653
652
  super
654
653
  end
@@ -660,7 +659,7 @@ module Sequel
660
659
  # fractional seconds.
661
660
  def constant_sql_append(sql, constant)
662
661
  if constant == :CURRENT_TIMESTAMP && supports_timestamp_usecs?
663
- sql << CURRENT_TIMESTAMP_56
662
+ sql << 'CURRENT_TIMESTAMP(6)'
664
663
  else
665
664
  super
666
665
  end
@@ -678,14 +677,26 @@ module Sequel
678
677
  def calc_found_rows
679
678
  clone(:calc_found_rows => true)
680
679
  end
680
+
681
+ # Sets up the select methods to delete from if deleting from a
682
+ # joined dataset:
683
+ #
684
+ # DB[:a].join(:b, a_id: :id).delete
685
+ # # DELETE a FROM a INNER JOIN b ON (b.a_id = a.id)
686
+ #
687
+ # DB[:a].join(:b, a_id: :id).delete_from(:a, :b).delete
688
+ # # DELETE a, b FROM a INNER JOIN b ON (b.a_id = a.id)
689
+ def delete_from(*tables)
690
+ clone(:delete_from=>tables)
691
+ end
681
692
 
682
693
  # Return the results of an EXPLAIN query as a string. Options:
683
- # :extended :: Use EXPLAIN EXPTENDED instead of EXPLAIN if true.
694
+ # :extended :: Use EXPLAIN EXTENDED instead of EXPLAIN if true.
684
695
  def explain(opts=OPTS)
685
696
  # Load the PrettyTable class, needed for explain output
686
697
  Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
687
698
 
688
- ds = db.send(:metadata_dataset).with_sql((opts[:extended] ? EXPLAIN_EXTENDED : EXPLAIN) + select_sql).naked
699
+ ds = db.send(:metadata_dataset).with_sql(((opts[:extended] && (db.mariadb? || db.server_version < 50700)) ? 'EXPLAIN EXTENDED ' : 'EXPLAIN ') + select_sql).naked
689
700
  rows = ds.all
690
701
  Sequel::PrettyTable.string(rows, ds.columns)
691
702
  end
@@ -697,7 +708,7 @@ module Sequel
697
708
 
698
709
  # Adds full text filter
699
710
  def full_text_search(cols, terms, opts = OPTS)
700
- filter(full_text_sql(cols, terms, opts))
711
+ where(full_text_sql(cols, terms, opts))
701
712
  end
702
713
 
703
714
  # MySQL specific full text search syntax.
@@ -706,33 +717,12 @@ module Sequel
706
717
  SQL::PlaceholderLiteralString.new((opts[:boolean] ? MATCH_AGAINST_BOOLEAN : MATCH_AGAINST), [Array(cols), terms])
707
718
  end
708
719
 
709
- # Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
710
- # Raises an error on use of :full_outer type, since MySQL doesn't support it.
711
- def join_table(type, table, expr=nil, opts=OPTS, &block)
712
- type = :inner if (type == :cross) && !expr.nil?
713
- raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN") if type == :full_outer
714
- super(type, table, expr, opts, &block)
715
- end
716
-
717
- # Transforms :natural_inner to NATURAL LEFT JOIN and straight to
718
- # STRAIGHT_JOIN.
719
- def join_type_sql(join_type)
720
- case join_type
721
- when :straight
722
- STRAIGHT_JOIN
723
- when :natural_inner
724
- NATURAL_LEFT_JOIN
725
- else
726
- super
727
- end
728
- end
729
-
730
720
  # Sets up the insert methods to use INSERT IGNORE.
731
721
  # Useful if you have a unique key and want to just skip
732
722
  # inserting rows that violate the unique key restriction.
733
723
  #
734
724
  # dataset.insert_ignore.multi_insert(
735
- # [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]
725
+ # [{name: 'a', value: 1}, {name: 'b', value: 2}]
736
726
  # )
737
727
  # # INSERT IGNORE INTO tablename (name, value) VALUES (a, 1), (b, 2)
738
728
  def insert_ignore
@@ -750,21 +740,21 @@ module Sequel
750
740
  # inserting rows that violate the unique key restriction.
751
741
  #
752
742
  # dataset.on_duplicate_key_update.multi_insert(
753
- # [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]
743
+ # [{name: 'a', value: 1}, {name: 'b', value: 2}]
754
744
  # )
755
745
  # # INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2)
756
746
  # # ON DUPLICATE KEY UPDATE name=VALUES(name), value=VALUES(value)
757
747
  #
758
748
  # dataset.on_duplicate_key_update(:value).multi_insert(
759
- # [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]
749
+ # [{name: 'a', value: 1}, {name: 'b', value: 2}]
760
750
  # )
761
751
  # # INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2)
762
752
  # # ON DUPLICATE KEY UPDATE value=VALUES(value)
763
753
  #
764
754
  # dataset.on_duplicate_key_update(
765
- # :value => Sequel.lit('value + VALUES(value)')
755
+ # value: Sequel.lit('value + VALUES(value)')
766
756
  # ).multi_insert(
767
- # [{:name => 'a', :value => 1}, {:name => 'b', :value => 2}]
757
+ # [{name: 'a', value: 1}, {name: 'b', value: 2}]
768
758
  # )
769
759
  # # INSERT INTO tablename (name, value) VALUES (a, 1), (b, 2)
770
760
  # # ON DUPLICATE KEY UPDATE value=value + VALUES(value)
@@ -774,7 +764,19 @@ module Sequel
774
764
 
775
765
  # MySQL uses the nonstandard ` (backtick) for quoting identifiers.
776
766
  def quoted_identifier_append(sql, c)
777
- sql << BACKTICK << c.to_s.gsub(BACKTICK_RE, DOUBLE_BACKTICK) << BACKTICK
767
+ sql << '`' << c.to_s.gsub('`', '``') << '`'
768
+ end
769
+
770
+ # MariaDB 10.2+ and MySQL 8+ support CTEs
771
+ def supports_cte?(type=:select)
772
+ if db.mariadb?
773
+ type == :select && db.server_version >= 100200
774
+ else
775
+ case type
776
+ when :select, :update, :delete
777
+ db.server_version >= 80000
778
+ end
779
+ end
778
780
  end
779
781
 
780
782
  # MySQL does not support derived column lists
@@ -793,9 +795,9 @@ module Sequel
793
795
  true
794
796
  end
795
797
 
796
- # MySQL does not support INTERSECT or EXCEPT
798
+ # MariaDB 10.3+ supports INTERSECT or EXCEPT
797
799
  def supports_intersect_except?
798
- false
800
+ db.mariadb? && db.server_version >= 100300
799
801
  end
800
802
 
801
803
  # MySQL does not support limits in correlated subqueries (or any subqueries that use IN).
@@ -808,8 +810,13 @@ module Sequel
808
810
  true
809
811
  end
810
812
 
813
+ # MySQL 8+ and MariaDB 10.3+ support NOWAIT.
814
+ def supports_nowait?
815
+ db.server_version >= (db.mariadb? ? 100300 : 80000)
816
+ end
817
+
811
818
  # MySQL's DISTINCT ON emulation using GROUP BY does not respect the
812
- # queries ORDER BY clause.
819
+ # query's ORDER BY clause.
813
820
  def supports_ordered_distinct_on?
814
821
  false
815
822
  end
@@ -819,18 +826,32 @@ module Sequel
819
826
  true
820
827
  end
821
828
 
822
- # MySQL does support fractional timestamps in literal timestamps, but it
823
- # ignores them. Also, using them seems to cause problems on 1.9. Since
824
- # they are ignored anyway, not using them is probably best.
829
+ # MySQL 8+ supports SKIP LOCKED.
830
+ def supports_skip_locked?
831
+ !db.mariadb? && db.server_version >= 80000
832
+ end
833
+
834
+ # Check the database setting for whether fractional timestamps
835
+ # are suppported.
825
836
  def supports_timestamp_usecs?
826
837
  db.supports_timestamp_usecs?
827
838
  end
828
-
839
+
840
+ # MySQL 8+ supports WINDOW clause.
841
+ def supports_window_clause?
842
+ !db.mariadb? && db.server_version >= 80000
843
+ end
844
+
845
+ # MariaDB 10.2+ and MySQL 8+ support window functions
846
+ def supports_window_functions?
847
+ db.server_version >= (db.mariadb? ? 100200 : 80000)
848
+ end
849
+
829
850
  # Sets up the update methods to use UPDATE IGNORE.
830
851
  # Useful if you have a unique key and want to just skip
831
852
  # updating rows that violate the unique key restriction.
832
853
  #
833
- # dataset.update_ignore.update({:name => 'a', :value => 1})
854
+ # dataset.update_ignore.update(name: 'a', value: 1)
834
855
  # # UPDATE IGNORE tablename SET name = 'a', value = 1
835
856
  def update_ignore
836
857
  clone(:update_ignore=>true)
@@ -838,13 +859,19 @@ module Sequel
838
859
 
839
860
  private
840
861
 
862
+ # Allow update and delete for limited datasets, unless there is an offset.
863
+ def check_not_limited!(type)
864
+ super if type == :truncate || @opts[:offset]
865
+ end
866
+
841
867
  # Consider the first table in the joined dataset is the table to delete
842
868
  # from, but include the others for the purposes of selecting rows.
843
869
  def delete_from_sql(sql)
844
870
  if joined_dataset?
845
- sql << SPACE
846
- source_list_append(sql, @opts[:from][0..0])
847
- sql << FROM
871
+ sql << ' '
872
+ tables = @opts[:delete_from] || @opts[:from][0..0]
873
+ source_list_append(sql, tables)
874
+ sql << ' FROM '
848
875
  source_list_append(sql, @opts[:from])
849
876
  select_join_sql(sql)
850
877
  else
@@ -856,7 +883,7 @@ module Sequel
856
883
  def insert_columns_sql(sql)
857
884
  values = opts[:values]
858
885
  if values.is_a?(Array) && values.empty?
859
- sql << EMPTY_COLUMNS
886
+ sql << " ()"
860
887
  else
861
888
  super
862
889
  end
@@ -864,12 +891,12 @@ module Sequel
864
891
 
865
892
  # MySQL supports INSERT IGNORE INTO
866
893
  def insert_ignore_sql(sql)
867
- sql << IGNORE if opts[:insert_ignore]
894
+ sql << " IGNORE" if opts[:insert_ignore]
868
895
  end
869
896
 
870
897
  # MySQL supports UPDATE IGNORE
871
898
  def update_ignore_sql(sql)
872
- sql << IGNORE if opts[:update_ignore]
899
+ sql << " IGNORE" if opts[:update_ignore]
873
900
  end
874
901
 
875
902
  # MySQL supports INSERT ... ON DUPLICATE KEY UPDATE
@@ -884,11 +911,11 @@ module Sequel
884
911
  update_cols = update_cols[0..-2]
885
912
  end
886
913
 
887
- sql << ON_DUPLICATE_KEY_UPDATE
914
+ sql << " ON DUPLICATE KEY UPDATE "
888
915
  c = false
889
- co = COMMA
890
- values = EQ_VALUES
891
- endp = PAREN_CLOSE
916
+ co = ', '
917
+ values = '=VALUES('
918
+ endp = ')'
892
919
  update_cols.each do |col|
893
920
  sql << co if c
894
921
  quote_identifier_append(sql, col)
@@ -898,7 +925,7 @@ module Sequel
898
925
  c ||= true
899
926
  end
900
927
  if update_vals
901
- eq = EQ
928
+ eq = '='
902
929
  update_vals.map do |col,v|
903
930
  sql << co if c
904
931
  quote_identifier_append(sql, col)
@@ -914,16 +941,25 @@ module Sequel
914
941
  def insert_values_sql(sql)
915
942
  values = opts[:values]
916
943
  if values.is_a?(Array) && values.empty?
917
- sql << EMPTY_VALUES
944
+ sql << " VALUES ()"
918
945
  else
919
946
  super
920
947
  end
921
948
  end
922
949
 
950
+ # Transforms :straight to STRAIGHT_JOIN.
951
+ def join_type_sql(join_type)
952
+ if join_type == :straight
953
+ 'STRAIGHT_JOIN'
954
+ else
955
+ super
956
+ end
957
+ end
958
+
923
959
  # MySQL allows a LIMIT in DELETE and UPDATE statements.
924
960
  def limit_sql(sql)
925
961
  if l = @opts[:limit]
926
- sql << LIMIT
962
+ sql << " LIMIT "
927
963
  literal_append(sql, l)
928
964
  end
929
965
  end
@@ -933,15 +969,15 @@ module Sequel
933
969
  # MySQL uses a preceding X for hex escaping strings
934
970
  def literal_blob_append(sql, v)
935
971
  if v.empty?
936
- sql << EMPTY_BLOB
972
+ sql << "''"
937
973
  else
938
- sql << BLOB_START << v.unpack(HSTAR).first
974
+ sql << "0x" << v.unpack("H*").first
939
975
  end
940
976
  end
941
977
 
942
978
  # Use 0 for false on MySQL
943
979
  def literal_false
944
- BOOL_FALSE
980
+ '0'
945
981
  end
946
982
 
947
983
  # Raise error for infinitate and NaN values
@@ -955,33 +991,65 @@ module Sequel
955
991
 
956
992
  # SQL fragment for String. Doubles \ and ' by default.
957
993
  def literal_string_append(sql, v)
958
- sql << APOS << v.gsub(BACKSLASH_RE, QUAD_BACKSLASH).gsub(APOS_RE, DOUBLE_APOS) << APOS
994
+ sql << "'" << v.gsub("\\", "\\\\\\\\").gsub("'", "''") << "'"
959
995
  end
960
996
 
961
997
  # Use 1 for true on MySQL
962
998
  def literal_true
963
- BOOL_TRUE
999
+ '1'
964
1000
  end
965
1001
 
966
- # MySQL supports multiple rows in INSERT.
1002
+ # MySQL supports multiple rows in VALUES in INSERT.
967
1003
  def multi_insert_sql_strategy
968
1004
  :values
969
1005
  end
970
1006
 
1007
+ def non_sql_option?(key)
1008
+ super || key == :insert_ignore || key == :update_ignore || key == :on_duplicate_key_update
1009
+ end
1010
+
1011
+ # MySQL does not natively support NULLS FIRST/LAST.
1012
+ def requires_emulating_nulls_first?
1013
+ true
1014
+ end
1015
+
971
1016
  def select_only_offset_sql(sql)
972
- sql << LIMIT
1017
+ sql << " LIMIT "
973
1018
  literal_append(sql, @opts[:offset])
974
- sql << ONLY_OFFSET
1019
+ sql << ",18446744073709551615"
975
1020
  end
976
1021
 
977
1022
  # Support FOR SHARE locking when using the :share lock style.
1023
+ # Use SKIP LOCKED if skipping locked rows.
978
1024
  def select_lock_sql(sql)
979
- @opts[:lock] == :share ? (sql << FOR_SHARE) : super
1025
+ lock = @opts[:lock]
1026
+ if lock == :share
1027
+ if !db.mariadb? && db.server_version >= 80000
1028
+ sql << ' FOR SHARE'
1029
+ else
1030
+ sql << ' LOCK IN SHARE MODE'
1031
+ end
1032
+ else
1033
+ super
1034
+ end
1035
+
1036
+ if lock
1037
+ if @opts[:skip_locked]
1038
+ sql << " SKIP LOCKED"
1039
+ elsif @opts[:nowait]
1040
+ sql << " NOWAIT"
1041
+ end
1042
+ end
980
1043
  end
981
1044
 
982
1045
  # MySQL specific SQL_CALC_FOUND_ROWS option
983
1046
  def select_calc_found_rows_sql(sql)
984
- sql << SQL_CALC_FOUND_ROWS if opts[:calc_found_rows]
1047
+ sql << ' SQL_CALC_FOUND_ROWS' if opts[:calc_found_rows]
1048
+ end
1049
+
1050
+ # Use WITH RECURSIVE instead of WITH if any of the CTEs is recursive
1051
+ def select_with_sql_base
1052
+ opts[:with].any?{|w| w[:recursive]} ? "WITH RECURSIVE " : super
985
1053
  end
986
1054
 
987
1055
  # MySQL uses WITH ROLLUP syntax.