sequel 4.26.0 → 5.37.0

Sign up to get free protection for your applications and to get access to all the features.
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.