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,20 +1,19 @@
1
- Sequel.require %w'emulate_offset_with_row_number split_alter_table', 'adapters/utils'
1
+ # frozen-string-literal: true
2
+
3
+ require_relative '../utils/emulate_offset_with_row_number'
4
+ require_relative '../utils/split_alter_table'
2
5
 
3
6
  module Sequel
4
- Dataset::NON_SQL_OPTIONS << :disable_insert_output
5
7
  module MSSQL
8
+ Sequel::Database.set_shared_adapter_scheme(:mssql, self)
9
+
10
+ def self.mock_adapter_setup(db)
11
+ db.instance_exec do
12
+ @server_version = 11000000
13
+ end
14
+ end
15
+
6
16
  module DatabaseMethods
7
- extend Sequel::Database::ResetIdentifierMangling
8
-
9
- AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
10
- SERVER_VERSION_RE = /^(\d+)\.(\d+)\.(\d+)/.freeze
11
- SERVER_VERSION_SQL = "SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)".freeze
12
- SQL_BEGIN = "BEGIN TRANSACTION".freeze
13
- SQL_COMMIT = "COMMIT TRANSACTION".freeze
14
- SQL_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION".freeze
15
- SQL_ROLLBACK_TO_SAVEPOINT = 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_%d'.freeze
16
- SQL_SAVEPOINT = 'SAVE TRANSACTION autopoint_%d'.freeze
17
- MSSQL_DEFAULT_RE = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/
18
17
  FOREIGN_KEY_ACTION_MAP = {0 => :no_action, 1 => :cascade, 2 => :set_null, 3 => :set_default}.freeze
19
18
 
20
19
  include Sequel::Database::SplitAlterTable
@@ -23,16 +22,7 @@ module Sequel
23
22
  # strings. True by default for compatibility, can be set to false for a possible
24
23
  # performance increase. This sets the default for all datasets created from this
25
24
  # Database object.
26
- attr_reader :mssql_unicode_strings
27
-
28
- def mssql_unicode_strings=(v)
29
- @mssql_unicode_strings = v
30
- reset_default_dataset
31
- end
32
-
33
- # The types to check for 0 scale to transform :decimal types
34
- # to :integer.
35
- DECIMAL_TYPE_RE = /number|numeric|decimal/io
25
+ attr_accessor :mssql_unicode_strings
36
26
 
37
27
  # Execute the given stored procedure with the given name.
38
28
  #
@@ -50,13 +40,19 @@ module Sequel
50
40
  # :numrows :: The number of rows affected by the stored procedure
51
41
  # output params :: Values for any output paramters, using the name given for the output parameter
52
42
  #
43
+ # Because Sequel datasets only support a single result set per query, and retrieving
44
+ # the result code and number of rows requires a query, this does not support
45
+ # stored procedures which also return result sets. To handle such stored procedures,
46
+ # you should drop down to the connection/driver level by using Sequel::Database#synchronize
47
+ # to get access to the underlying connection object.
48
+ #
53
49
  # Examples:
54
50
  #
55
- # DB.call_mssql_sproc(:SequelTest, {:args => ['input arg', :output]})
56
- # DB.call_mssql_sproc(:SequelTest, {:args => ['input arg', [:output, 'int', 'varname']]})
51
+ # DB.call_mssql_sproc(:SequelTest, {args: ['input arg', :output]})
52
+ # DB.call_mssql_sproc(:SequelTest, {args: ['input arg', [:output, 'int', 'varname']]})
57
53
  #
58
54
  # named params:
59
- # DB.call_mssql_sproc(:SequelTest, :args => {
55
+ # DB.call_mssql_sproc(:SequelTest, args: {
60
56
  # 'input_arg1_name' => 'input arg1 value',
61
57
  # 'input_arg2_name' => 'input arg2 value',
62
58
  # 'output_arg_name' => [:output, 'int', 'varname']
@@ -75,7 +71,7 @@ module Sequel
75
71
  method = :each_with_index
76
72
  end
77
73
 
78
- args.send(method) do |v, i|
74
+ args.public_send(method) do |v, i|
79
75
  if named_args
80
76
  k = v
81
77
  v, type, select = i
@@ -113,7 +109,6 @@ module Sequel
113
109
  ds.first
114
110
  end
115
111
 
116
- # Microsoft SQL Server uses the :mssql type.
117
112
  def database_type
118
113
  :mssql
119
114
  end
@@ -131,20 +126,22 @@ module Sequel
131
126
  schema, table = schema_and_table(table)
132
127
  current_schema = m.call(get(Sequel.function('schema_name')))
133
128
  fk_action_map = FOREIGN_KEY_ACTION_MAP
129
+ fk = Sequel[:fk]
130
+ fkc = Sequel[:fkc]
134
131
  ds = metadata_dataset.from(Sequel.lit('[sys].[foreign_keys]').as(:fk)).
135
132
  join(Sequel.lit('[sys].[foreign_key_columns]').as(:fkc), :constraint_object_id => :object_id).
136
- join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => :fkc__parent_object_id, :column_id => :fkc__parent_column_id).
137
- join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => :fkc__referenced_object_id, :column_id => :fkc__referenced_column_id).
138
- where{{object_schema_name(:fk__parent_object_id) => im.call(schema || current_schema)}}.
139
- where{{object_name(:fk__parent_object_id) => im.call(table)}}.
140
- select{[:fk__name,
141
- :fk__delete_referential_action,
142
- :fk__update_referential_action,
143
- :pc__name___column,
144
- :rc__name___referenced_column,
145
- object_schema_name(:fk__referenced_object_id).as(:schema),
146
- object_name(:fk__referenced_object_id).as(:table)]}.
147
- order(:fk__name, :fkc__constraint_column_id)
133
+ join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => fkc[:parent_object_id], :column_id => fkc[:parent_column_id]).
134
+ join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => fkc[:referenced_object_id], :column_id => fkc[:referenced_column_id]).
135
+ where{{object_schema_name(fk[:parent_object_id]) => im.call(schema || current_schema)}}.
136
+ where{{object_name(fk[:parent_object_id]) => im.call(table)}}.
137
+ select{[fk[:name],
138
+ fk[:delete_referential_action],
139
+ fk[:update_referential_action],
140
+ pc[:name].as(:column),
141
+ rc[:name].as(:referenced_column),
142
+ object_schema_name(fk[:referenced_object_id]).as(:schema),
143
+ object_name(fk[:referenced_object_id]).as(:table)]}.
144
+ order(fk[:name], fkc[:constraint_column_id])
148
145
  h = {}
149
146
  ds.each do |row|
150
147
  if r = h[row[:name]]
@@ -164,22 +161,29 @@ module Sequel
164
161
  h.values
165
162
  end
166
163
 
164
+ def freeze
165
+ server_version
166
+ super
167
+ end
168
+
167
169
  # Use the system tables to get index information
168
170
  def indexes(table, opts=OPTS)
169
171
  m = output_identifier_meth
170
172
  im = input_identifier_meth
171
173
  indexes = {}
174
+ table = table.value if table.is_a?(Sequel::SQL::Identifier)
175
+ i = Sequel[:i]
172
176
  ds = metadata_dataset.from(Sequel.lit('[sys].[tables]').as(:t)).
173
177
  join(Sequel.lit('[sys].[indexes]').as(:i), :object_id=>:object_id).
174
178
  join(Sequel.lit('[sys].[index_columns]').as(:ic), :object_id=>:object_id, :index_id=>:index_id).
175
179
  join(Sequel.lit('[sys].[columns]').as(:c), :object_id=>:object_id, :column_id=>:column_id).
176
- select(:i__name, :i__is_unique, :c__name___column).
177
- where{{t__name=>im.call(table)}}.
178
- where(:i__is_primary_key=>0, :i__is_disabled=>0).
179
- order(:i__name, :ic__index_column_id)
180
+ select(i[:name], i[:is_unique], Sequel[:c][:name].as(:column)).
181
+ where{{t[:name]=>im.call(table)}}.
182
+ where(i[:is_primary_key]=>0, i[:is_disabled]=>0).
183
+ order(i[:name], Sequel[:ic][:index_column_id])
180
184
 
181
185
  if supports_partial_indexes?
182
- ds = ds.where(:i__has_filter=>0)
186
+ ds = ds.where(i[:has_filter]=>0)
183
187
  end
184
188
 
185
189
  ds.each do |r|
@@ -200,7 +204,7 @@ module Sequel
200
204
  (conn.server_version rescue nil) if conn.respond_to?(:server_version)
201
205
  end
202
206
  unless @server_version
203
- m = SERVER_VERSION_RE.match(fetch(SERVER_VERSION_SQL).single_value.to_s)
207
+ m = /^(\d+)\.(\d+)\.(\d+)/.match(fetch("SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)").single_value.to_s)
204
208
  @server_version = (m[1].to_i * 1000000) + (m[2].to_i * 10000) + m[3].to_i
205
209
  end
206
210
  @server_version
@@ -211,7 +215,7 @@ module Sequel
211
215
  dataset.send(:is_2008_or_later?)
212
216
  end
213
217
 
214
- # MSSQL supports savepoints, though it doesn't support committing/releasing them savepoint
218
+ # MSSQL supports savepoints, though it doesn't support releasing them
215
219
  def supports_savepoints?
216
220
  true
217
221
  end
@@ -250,10 +254,9 @@ module Sequel
250
254
 
251
255
  # MSSQL uses the IDENTITY(1,1) column for autoincrementing columns.
252
256
  def auto_increment_sql
253
- AUTO_INCREMENT
257
+ 'IDENTITY(1,1)'
254
258
  end
255
259
 
256
- # MSSQL specific syntax for altering tables.
257
260
  def alter_table_sql(table, op)
258
261
  case op[:op]
259
262
  when :add_column
@@ -263,7 +266,7 @@ module Sequel
263
266
  add_drop_default_constraint_sql(sqls, table, op[:name])
264
267
  sqls << super
265
268
  when :rename_column
266
- "sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(op[:new_name].to_s)}, 'COLUMN'"
269
+ "sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(metadata_dataset.with_quote_identifiers(false).quote_identifier(op[:new_name]))}, 'COLUMN'"
267
270
  when :set_column_type
268
271
  sqls = []
269
272
  if sch = schema(table)
@@ -276,49 +279,53 @@ module Sequel
276
279
  end
277
280
  end
278
281
  sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
279
- sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default)) if default
282
+ sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default, :skip_drop_default=>true)) if default
280
283
  sqls
281
284
  when :set_column_null
282
285
  sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
283
286
  type = sch[:db_type]
284
- if [:string, :decimal].include?(sch[:type]) and size = (sch[:max_chars] || sch[:column_size])
287
+ if [:string, :decimal].include?(sch[:type]) && !["text", "ntext"].include?(type) && (size = (sch[:max_chars] || sch[:column_size]))
288
+ size = "MAX" if size == -1
285
289
  type += "(#{size}#{", #{sch[:scale]}" if sch[:scale] && sch[:scale].to_i > 0})"
286
290
  end
287
291
  "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
288
292
  when :set_column_default
289
- "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
293
+ sqls = []
294
+ add_drop_default_constraint_sql(sqls, table, op[:name]) unless op[:skip_drop_default]
295
+ sqls << "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
290
296
  else
291
297
  super(table, op)
292
298
  end
293
299
  end
294
300
 
295
- # SQL to start a new savepoint
296
301
  def begin_savepoint_sql(depth)
297
- SQL_SAVEPOINT % depth
302
+ "SAVE TRANSACTION autopoint_#{depth}"
298
303
  end
299
304
 
300
- # SQL to BEGIN a transaction.
301
305
  def begin_transaction_sql
302
- SQL_BEGIN
306
+ "BEGIN TRANSACTION"
307
+ end
308
+
309
+ # MSSQL does not allow adding primary key constraints to NULLable columns.
310
+ def can_add_primary_key_constraint_on_nullable_columns?
311
+ false
303
312
  end
304
313
 
305
314
  # Handle MSSQL specific default format.
306
315
  def column_schema_normalize_default(default, type)
307
- if m = MSSQL_DEFAULT_RE.match(default)
316
+ if m = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/.match(default)
308
317
  default = m[1] || m[2]
309
318
  end
310
319
  super(default, type)
311
320
  end
312
321
 
313
- # Commit the active transaction on the connection, does not commit/release
314
- # savepoints.
322
+ # Commit the active transaction on the connection, does not release savepoints.
315
323
  def commit_transaction(conn, opts=OPTS)
316
324
  log_connection_execute(conn, commit_transaction_sql) unless savepoint_level(conn) > 1
317
325
  end
318
326
 
319
- # SQL to COMMIT a transaction.
320
327
  def commit_transaction_sql
321
- SQL_COMMIT
328
+ "COMMIT TRANSACTION"
322
329
  end
323
330
 
324
331
  # MSSQL uses the name of the table to decide the difference between
@@ -338,11 +345,12 @@ module Sequel
338
345
  end
339
346
 
340
347
  DATABASE_ERROR_REGEXPS = {
341
- /Violation of UNIQUE KEY constraint|Violation of PRIMARY KEY constraint.+Cannot insert duplicate key/ => UniqueConstraintViolation,
348
+ /Violation of UNIQUE KEY constraint|(Violation of PRIMARY KEY constraint.+)?Cannot insert duplicate key/ => UniqueConstraintViolation,
342
349
  /conflicted with the (FOREIGN KEY.*|REFERENCE) constraint/ => ForeignKeyConstraintViolation,
343
350
  /conflicted with the CHECK constraint/ => CheckConstraintViolation,
344
351
  /column does not allow nulls/ => NotNullConstraintViolation,
345
352
  /was deadlocked on lock resources with another process and has been chosen as the deadlock victim/ => SerializationFailure,
353
+ /Lock request time out period exceeded\./ => DatabaseLockTimeout,
346
354
  }.freeze
347
355
  def database_error_regexps
348
356
  DATABASE_ERROR_REGEXPS
@@ -354,18 +362,16 @@ module Sequel
354
362
  def default_constraint_name(table, column_name)
355
363
  if server_version >= 9000000
356
364
  table_name = schema_and_table(table).compact.join('.')
357
- self[:sys__default_constraints].
365
+ self[Sequel[:sys][:default_constraints]].
358
366
  where{{:parent_object_id => Sequel::SQL::Function.new(:object_id, table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
359
367
  get(:name)
360
368
  end
361
369
  end
362
370
 
363
- # The SQL to drop an index for the table.
364
371
  def drop_index_sql(table, op)
365
372
  "DROP INDEX #{quote_identifier(op[:name] || default_index_name(table, op[:columns]))} ON #{quote_schema_table(table)}"
366
373
  end
367
374
 
368
- # support for clustered index type
369
375
  def index_definition_sql(table_name, index)
370
376
  index_name = index[:name] || default_index_name(table_name, index[:columns])
371
377
  raise Error, "Partial indexes are not supported for this database" if index[:where] && !supports_partial_indexes?
@@ -379,17 +385,15 @@ module Sequel
379
385
  # Backbone of the tables and views support.
380
386
  def information_schema_tables(type, opts)
381
387
  m = output_identifier_meth
382
- metadata_dataset.from(:information_schema__tables___t).
388
+ metadata_dataset.from(Sequel[:information_schema][:tables].as(:t)).
383
389
  select(:table_name).
384
- filter(:table_type=>type, :table_schema=>(opts[:schema]||'dbo').to_s).
390
+ where(:table_type=>type, :table_schema=>(opts[:schema]||'dbo').to_s).
385
391
  map{|x| m.call(x[:table_name])}
386
392
  end
387
393
 
388
394
  # Always quote identifiers in the metadata_dataset, so schema parsing works.
389
- def metadata_dataset
390
- ds = super
391
- ds.quote_identifiers = true
392
- ds
395
+ def _metadata_dataset
396
+ super.with_quote_identifiers(true)
393
397
  end
394
398
 
395
399
  # Use sp_rename to rename the table
@@ -397,17 +401,14 @@ module Sequel
397
401
  "sp_rename #{literal(quote_schema_table(name))}, #{quote_identifier(schema_and_table(new_name).pop)}"
398
402
  end
399
403
 
400
- # SQL to rollback to a savepoint
401
404
  def rollback_savepoint_sql(depth)
402
- SQL_ROLLBACK_TO_SAVEPOINT % depth
405
+ "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_#{depth}"
403
406
  end
404
407
 
405
- # SQL to ROLLBACK a transaction.
406
408
  def rollback_transaction_sql
407
- SQL_ROLLBACK
409
+ "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
408
410
  end
409
411
 
410
- # The closest MSSQL equivalent of a boolean datatype is the bit type.
411
412
  def schema_column_type(db_type)
412
413
  case db_type
413
414
  when /\A(?:bit)\z/io
@@ -428,31 +429,30 @@ module Sequel
428
429
  m = output_identifier_meth(opts[:dataset])
429
430
  m2 = input_identifier_meth(opts[:dataset])
430
431
  tn = m2.call(table_name.to_s)
431
- table_id = get(Sequel.function(:object_id, tn))
432
432
  info_sch_sch = opts[:information_schema_schema]
433
- inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel.expr(s)}
434
- sys_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, Sequel.qualify(Sequel.lit(''), s)) : Sequel.expr(s)}
433
+ inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel[s]}
434
+ table_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:objects])).where(:name => tn).select_map(:object_id).first
435
435
 
436
- identity_cols = metadata_dataset.from(Sequel.lit('[sys].[columns]')).
436
+ identity_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:columns])).
437
437
  where(:object_id=>table_id, :is_identity=>true).
438
438
  select_map(:name)
439
439
 
440
- pk_index_id = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexes'))).
440
+ pk_index_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexes])).
441
441
  where(:id=>table_id, :indid=>1..254){{(status & 2048)=>2048}}.
442
442
  get(:indid)
443
- pk_cols = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexkeys')).as(:sik)).
444
- join(sys_qual.call(Sequel.lit('syscolumns')).as(:sc), :id=>:id, :colid=>:colid).
445
- where(:sik__id=>table_id, :sik__indid=>pk_index_id).
446
- select_order_map(:sc__name)
443
+ pk_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexkeys]).as(:sik)).
444
+ join(inf_sch_qual.call(Sequel[:sys][:syscolumns]).as(:sc), :id=>:id, :colid=>:colid).
445
+ where{{sik[:id]=>table_id, sik[:indid]=>pk_index_id}}.
446
+ select_order_map{sc[:name]}
447
447
 
448
- ds = metadata_dataset.from(inf_sch_qual.call(:information_schema__tables).as(:t)).
449
- join(inf_sch_qual.call(:information_schema__columns).as(:c), :table_catalog=>:table_catalog,
448
+ ds = metadata_dataset.from(inf_sch_qual.call(Sequel[:information_schema][:tables]).as(:t)).
449
+ join(inf_sch_qual.call(Sequel[:information_schema][:columns]).as(:c), :table_catalog=>:table_catalog,
450
450
  :table_schema => :table_schema, :table_name => :table_name).
451
- select(:column_name___column, :data_type___db_type, :character_maximum_length___max_chars, :column_default___default, :is_nullable___allow_null, :numeric_precision___column_size, :numeric_scale___scale).
452
- filter(:c__table_name=>tn)
451
+ select{[column_name.as(:column), data_type.as(:db_type), character_maximum_length.as(:max_chars), column_default.as(:default), is_nullable.as(:allow_null), numeric_precision.as(:column_size), numeric_scale.as(:scale)]}.
452
+ where{{c[:table_name]=>tn}}
453
453
 
454
454
  if schema = opts[:schema]
455
- ds.filter!(:c__table_schema=>schema)
455
+ ds = ds.where{{c[:table_schema]=>schema}}
456
456
  end
457
457
 
458
458
  ds.map do |row|
@@ -461,7 +461,7 @@ module Sequel
461
461
  end
462
462
  row[:allow_null] = row[:allow_null] == 'YES' ? true : false
463
463
  row[:default] = nil if blank_object?(row[:default])
464
- row[:type] = if row[:db_type] =~ DECIMAL_TYPE_RE && row[:scale] == 0
464
+ row[:type] = if row[:db_type] =~ /number|numeric|decimal/i && row[:scale] == 0
465
465
  :integer
466
466
  else
467
467
  schema_column_type(row[:db_type])
@@ -482,12 +482,6 @@ module Sequel
482
482
  :datetime
483
483
  end
484
484
 
485
- # MSSQL has both datetime and timestamp classes, most people are going
486
- # to want datetime
487
- def type_literal_generic_time(column)
488
- column[:only_time] ? :time : :datetime
489
- end
490
-
491
485
  # MSSQL doesn't have a true boolean class, so it uses bit
492
486
  def type_literal_generic_trueclass(column)
493
487
  :bit
@@ -506,93 +500,53 @@ module Sequel
506
500
 
507
501
  module DatasetMethods
508
502
  include(Module.new do
509
- Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from lock join where group having order compounds')
503
+ Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from lock join where group having compounds order')
510
504
  end)
511
505
  include EmulateOffsetWithRowNumber
512
506
 
513
- BOOL_TRUE = '1'.freeze
514
- BOOL_FALSE = '0'.freeze
515
- COMMA_SEPARATOR = ', '.freeze
516
- NOLOCK = ' WITH (NOLOCK)'.freeze
517
- UPDLOCK = ' WITH (UPDLOCK)'.freeze
518
- WILDCARD = LiteralString.new('*').freeze
519
- CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}
520
- EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}
521
- BRACKET_CLOSE = Dataset::BRACKET_CLOSE
522
- BRACKET_OPEN = Dataset::BRACKET_OPEN
523
- COMMA = Dataset::COMMA
524
- PAREN_CLOSE = Dataset::PAREN_CLOSE
525
- PAREN_SPACE_OPEN = Dataset::PAREN_SPACE_OPEN
526
- SPACE = Dataset::SPACE
527
- FROM = Dataset::FROM
528
- APOS = Dataset::APOS
529
- APOS_RE = Dataset::APOS_RE
530
- DOUBLE_APOS = Dataset::DOUBLE_APOS
531
- INTO = Dataset::INTO
532
- DOUBLE_BRACKET_CLOSE = ']]'.freeze
533
- DATEPART_SECOND_OPEN = "CAST((datepart(".freeze
534
- DATEPART_SECOND_MIDDLE = ') + datepart(ns, '.freeze
535
- DATEPART_SECOND_CLOSE = ")/1000000000.0) AS double precision)".freeze
536
- DATEPART_OPEN = "datepart(".freeze
537
- OUTPUT_INSERTED = " OUTPUT INSERTED.*".freeze
538
- HEX_START = '0x'.freeze
539
- UNICODE_STRING_START = "N'".freeze
540
- BACKSLASH_CRLF_RE = /\\((?:\r\n)|\n)/.freeze
541
- BACKSLASH_CRLF_REPLACE = '\\\\\\\\\\1\\1'.freeze
542
- TOP_PAREN = " TOP (".freeze
543
- TOP = " TOP ".freeze
544
- OUTPUT = " OUTPUT ".freeze
545
- HSTAR = "H*".freeze
546
- CASE_SENSITIVE_COLLATION = 'Latin1_General_CS_AS'.freeze
547
- CASE_INSENSITIVE_COLLATION = 'Latin1_General_CI_AS'.freeze
548
- DEFAULT_TIMESTAMP_FORMAT = "'%Y-%m-%dT%H:%M:%S%N%z'".freeze
549
- FORMAT_DATE = "'%Y%m%d'".freeze
550
- CROSS_APPLY = 'CROSS APPLY'.freeze
551
- OUTER_APPLY = 'OUTER APPLY'.freeze
552
- OFFSET = " OFFSET ".freeze
553
- ROWS = " ROWS".freeze
554
- ROWS_ONLY = " ROWS ONLY".freeze
555
- FETCH_NEXT = " FETCH NEXT ".freeze
556
-
557
- Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
558
- Dataset.def_sql_method(self, :delete, %w'with delete from output from2 where')
507
+ CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}.freeze
508
+ EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}.freeze
509
+ EXTRACT_MAP.each_value(&:freeze)
510
+ LIMIT_ALL = Object.new.freeze
511
+
512
+ Dataset.def_sql_method(self, :delete, %w'with delete limit from output from2 where')
559
513
  Dataset.def_sql_method(self, :insert, %w'with insert into columns output values')
560
514
  Dataset.def_sql_method(self, :update, [['if is_2005_or_later?', %w'with update limit table set output from where'], ['else', %w'update table set output from where']])
561
515
 
562
-
563
- # Allow overriding of the mssql_unicode_strings option at the dataset level.
564
- attr_writer :mssql_unicode_strings
565
-
566
516
  # Use the database's mssql_unicode_strings setting if the dataset hasn't overridden it.
567
517
  def mssql_unicode_strings
568
- defined?(@mssql_unicode_strings) ? @mssql_unicode_strings : (@mssql_unicode_strings = db.mssql_unicode_strings)
518
+ opts.has_key?(:mssql_unicode_strings) ? opts[:mssql_unicode_strings] : db.mssql_unicode_strings
519
+ end
520
+
521
+ # Return a cloned dataset with the mssql_unicode_strings option set.
522
+ def with_mssql_unicode_strings(v)
523
+ clone(:mssql_unicode_strings=>v)
569
524
  end
570
525
 
571
- # MSSQL uses + for string concatenation, and LIKE is case insensitive by default.
572
526
  def complex_expression_sql_append(sql, op, args)
573
527
  case op
574
528
  when :'||'
575
529
  super(sql, :+, args)
576
530
  when :LIKE, :"NOT LIKE"
577
- super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE #{CASE_SENSITIVE_COLLATION})"], a)})
531
+ super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CS_AS)"], a)})
578
532
  when :ILIKE, :"NOT ILIKE"
579
- super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE #{CASE_INSENSITIVE_COLLATION})"], a)})
533
+ super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CI_AS)"], a)})
580
534
  when :<<, :>>
581
535
  complex_expression_emulate_append(sql, op, args)
582
536
  when :extract
583
- part = args.at(0)
537
+ part = args[0]
584
538
  raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
585
539
  if part == :second
586
- expr = args.at(1)
587
- sql << DATEPART_SECOND_OPEN << format.to_s << COMMA
540
+ expr = args[1]
541
+ sql << "CAST((datepart(" << format.to_s << ', '
588
542
  literal_append(sql, expr)
589
- sql << DATEPART_SECOND_MIDDLE
543
+ sql << ') + datepart(ns, '
590
544
  literal_append(sql, expr)
591
- sql << DATEPART_SECOND_CLOSE
545
+ sql << ")/1000000000.0) AS double precision)"
592
546
  else
593
- sql << DATEPART_OPEN << format.to_s << COMMA
594
- literal_append(sql, args.at(1))
595
- sql << PAREN_CLOSE
547
+ sql << "datepart(" << format.to_s << ', '
548
+ literal_append(sql, args[1])
549
+ sql << ')'
596
550
  end
597
551
  else
598
552
  super
@@ -626,13 +580,15 @@ module Sequel
626
580
  # MSSQL uses the CONTAINS keyword for full text search
627
581
  def full_text_search(cols, terms, opts = OPTS)
628
582
  terms = "\"#{terms.join('" OR "')}\"" if terms.is_a?(Array)
629
- filter("CONTAINS (?, ?)", cols, terms)
583
+ where(Sequel.lit("CONTAINS (?, ?)", cols, terms))
630
584
  end
631
585
 
632
- # Use the OUTPUT clause to get the value of all columns for the newly inserted record.
586
+ # Insert a record, returning the record inserted, using OUTPUT. Always returns nil without
587
+ # running an INSERT statement if disable_insert_output is used. If the query runs
588
+ # but returns no values, returns false.
633
589
  def insert_select(*values)
634
590
  return unless supports_insert_select?
635
- with_sql_first(insert_select_sql(*values))
591
+ with_sql_first(insert_select_sql(*values)) || false
636
592
  end
637
593
 
638
594
  # Add OUTPUT clause unless there is already an existing output clause, then return
@@ -667,8 +623,8 @@ module Sequel
667
623
  #
668
624
  # Examples:
669
625
  #
670
- # dataset.output(:output_table, [:deleted__id, :deleted__name])
671
- # dataset.output(:output_table, :id => :inserted__id, :name => :inserted__name)
626
+ # dataset.output(:output_table, [Sequel[:deleted][:id], Sequel[:deleted][:name]])
627
+ # dataset.output(:output_table, id: Sequel[:inserted][:id], name: Sequel[:inserted][:name])
672
628
  def output(into, values)
673
629
  raise(Error, "SQL Server versions 2000 and earlier do not support the OUTPUT clause") unless supports_output_clause?
674
630
  output = {}
@@ -684,7 +640,7 @@ module Sequel
684
640
 
685
641
  # MSSQL uses [] to quote identifiers.
686
642
  def quoted_identifier_append(sql, name)
687
- sql << BRACKET_OPEN << name.to_s.gsub(/\]/, DOUBLE_BRACKET_CLOSE) << BRACKET_CLOSE
643
+ sql << '[' << name.to_s.gsub(/\]/, ']]') << ']'
688
644
  end
689
645
 
690
646
  # Emulate RETURNING using the output clause. This only handles values that are simple column references.
@@ -703,11 +659,11 @@ module Sequel
703
659
  # case by default, and that also adds a default order, so it's better to just
704
660
  # avoid the subquery.
705
661
  def select_sql
706
- if @opts[:offset] && !@opts[:order] && is_2012_or_later?
707
- order(1).select_sql
708
- else
709
- super
662
+ if @opts[:offset]
663
+ raise(Error, "Using with_ties is not supported with an offset on Microsoft SQL Server") if @opts[:limit_with_ties]
664
+ return order(1).select_sql if is_2012_or_later? && !@opts[:order]
710
665
  end
666
+ super
711
667
  end
712
668
 
713
669
  # The version of the database server.
@@ -729,7 +685,7 @@ module Sequel
729
685
  is_2005_or_later?
730
686
  end
731
687
 
732
- # MSSQL 2005+ supports GROUPING SETS
688
+ # MSSQL 2008+ supports GROUPING SETS
733
689
  def supports_grouping_sets?
734
690
  is_2008_or_later?
735
691
  end
@@ -764,6 +720,11 @@ module Sequel
764
720
  false
765
721
  end
766
722
 
723
+ # MSSQL supports NOWAIT.
724
+ def supports_nowait?
725
+ true
726
+ end
727
+
767
728
  # MSSQL 2012+ supports offsets in correlated subqueries.
768
729
  def supports_offsets_in_correlated_subqueries?
769
730
  is_2012_or_later?
@@ -779,6 +740,11 @@ module Sequel
779
740
  supports_insert_select?
780
741
  end
781
742
 
743
+ # MSSQL uses READPAST to skip locked rows.
744
+ def supports_skip_locked?
745
+ true
746
+ end
747
+
782
748
  # MSSQL 2005+ supports window functions
783
749
  def supports_window_functions?
784
750
  true
@@ -789,6 +755,12 @@ module Sequel
789
755
  false
790
756
  end
791
757
 
758
+ # Use WITH TIES when limiting the result set to also include additional
759
+ # rows matching the last row.
760
+ def with_ties
761
+ clone(:limit_with_ties=>true)
762
+ end
763
+
792
764
  protected
793
765
 
794
766
  # If returned primary keys are requested, use OUTPUT unless already set on the
@@ -800,20 +772,45 @@ module Sequel
800
772
  output(nil, [SQL::QualifiedIdentifier.new(:inserted, first_primary_key)])._import(columns, values, opts)
801
773
  elsif @opts[:output]
802
774
  statements = multi_insert_sql(columns, values)
775
+ ds = naked
803
776
  @db.transaction(opts.merge(:server=>@opts[:server])) do
804
- statements.map{|st| with_sql(st)}
777
+ statements.map{|st| ds.with_sql(st)}
805
778
  end.first.map{|v| v.length == 1 ? v.values.first : v}
806
779
  else
807
780
  super
808
781
  end
809
782
  end
810
783
 
811
- # MSSQL does not allow ordering in sub-clauses unless 'top' (limit) is specified
784
+ # If the dataset using a order without a limit or offset or custom SQL,
785
+ # remove the order. Compounds on Microsoft SQL Server have undefined
786
+ # order unless the result is specifically ordered. Applying the current
787
+ # order before the compound doesn't work in all cases, such as when
788
+ # qualified identifiers are used. If you want to ensure a order
789
+ # for a compound dataset, apply the order after all compounds have been
790
+ # added.
791
+ def compound_from_self
792
+ if @opts[:offset] && !@opts[:limit] && !is_2012_or_later?
793
+ clone(:limit=>LIMIT_ALL).from_self
794
+ elsif @opts[:order] && !(@opts[:sql] || @opts[:limit] || @opts[:offset])
795
+ unordered
796
+ else
797
+ super
798
+ end
799
+ end
800
+
801
+ private
802
+
803
+ # MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
812
804
  def aggregate_dataset
813
805
  (options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
814
806
  end
815
807
 
816
- private
808
+ # Allow update and delete for unordered, limited datasets only.
809
+ def check_not_limited!(type)
810
+ return if @opts[:skip_limit_check] && type != :truncate
811
+ raise Sequel::InvalidOperation, "Dataset##{type} not suppored on ordered, limited datasets" if opts[:order] && opts[:limit]
812
+ super if type == :truncate || @opts[:offset]
813
+ end
817
814
 
818
815
  # Whether we are using SQL Server 2005 or later.
819
816
  def is_2005_or_later?
@@ -834,12 +831,12 @@ module Sequel
834
831
  # since that is the format that is multilanguage and not
835
832
  # DATEFORMAT dependent.
836
833
  def default_timestamp_format
837
- DEFAULT_TIMESTAMP_FORMAT
834
+ "'%Y-%m-%dT%H:%M:%S%N%z'"
838
835
  end
839
836
 
840
837
  # Only include the primary table in the main delete clause
841
838
  def delete_from_sql(sql)
842
- sql << FROM
839
+ sql << ' FROM '
843
840
  source_list_append(sql, @opts[:from][0..0])
844
841
  end
845
842
 
@@ -873,7 +870,7 @@ module Sequel
873
870
  end
874
871
  end
875
872
 
876
- # Microsoft SQL Server 2012 has native support for offsets, but only for ordered datasets.
873
+ # Microsoft SQL Server 2012+ has native support for offsets, but only for ordered datasets.
877
874
  def emulate_offset_with_row_number?
878
875
  super && !(is_2012_or_later? && @opts[:order])
879
876
  end
@@ -893,9 +890,9 @@ module Sequel
893
890
  def join_type_sql(join_type)
894
891
  case join_type
895
892
  when :cross_apply
896
- CROSS_APPLY
893
+ 'CROSS APPLY'
897
894
  when :outer_apply
898
- OUTER_APPLY
895
+ 'OUTER APPLY'
899
896
  else
900
897
  super
901
898
  end
@@ -903,30 +900,30 @@ module Sequel
903
900
 
904
901
  # MSSQL uses a literal hexidecimal number for blob strings
905
902
  def literal_blob_append(sql, v)
906
- sql << HEX_START << v.unpack(HSTAR).first
903
+ sql << '0x' << v.unpack("H*").first
907
904
  end
908
905
 
909
- # Use YYYYmmdd format, since that's the only want that is
906
+ # Use YYYYmmdd format, since that's the only format that is
910
907
  # multilanguage and not DATEFORMAT dependent.
911
908
  def literal_date(v)
912
- v.strftime(FORMAT_DATE)
909
+ v.strftime("'%Y%m%d'")
913
910
  end
914
911
 
915
912
  # Use 0 for false on MSSQL
916
913
  def literal_false
917
- BOOL_FALSE
914
+ '0'
918
915
  end
919
916
 
920
917
  # Optionally use unicode string syntax for all strings. Don't double
921
918
  # backslashes.
922
919
  def literal_string_append(sql, v)
923
- sql << (mssql_unicode_strings ? UNICODE_STRING_START : APOS)
924
- sql << v.gsub(APOS_RE, DOUBLE_APOS).gsub(BACKSLASH_CRLF_RE, BACKSLASH_CRLF_REPLACE) << APOS
920
+ sql << (mssql_unicode_strings ? "N'" : "'")
921
+ sql << v.gsub("'", "''").gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
925
922
  end
926
923
 
927
924
  # Use 1 for true on MSSQL
928
925
  def literal_true
929
- BOOL_TRUE
926
+ '1'
930
927
  end
931
928
 
932
929
  # MSSQL 2008+ supports multiple rows in the VALUES clause, older versions
@@ -935,38 +932,74 @@ module Sequel
935
932
  is_2008_or_later? ? :values : :union
936
933
  end
937
934
 
935
+ def non_sql_option?(key)
936
+ super || key == :disable_insert_output || key == :mssql_unicode_strings
937
+ end
938
+
938
939
  def select_into_sql(sql)
939
940
  if i = @opts[:into]
940
- sql << INTO
941
+ sql << " INTO "
941
942
  identifier_append(sql, i)
942
943
  end
943
944
  end
944
945
 
945
- # MSSQL uses TOP N for limit. For MSSQL 2005+ TOP (N) is used
946
+ # MSSQL 2000 uses TOP N for limit. For MSSQL 2005+ TOP (N) is used
946
947
  # to allow the limit to be a bound variable.
947
948
  def select_limit_sql(sql)
948
949
  if l = @opts[:limit]
949
950
  return if is_2012_or_later? && @opts[:order] && @opts[:offset]
951
+ shared_limit_sql(sql, l)
952
+ end
953
+ end
950
954
 
951
- if is_2005_or_later?
952
- sql << TOP_PAREN
953
- literal_append(sql, l)
954
- sql << PAREN_CLOSE
955
+ def shared_limit_sql(sql, l)
956
+ if is_2005_or_later?
957
+ if l == LIMIT_ALL
958
+ sql << " TOP (100) PERCENT"
955
959
  else
956
- sql << TOP
960
+ sql << " TOP ("
957
961
  literal_append(sql, l)
962
+ sql << ')'
958
963
  end
964
+ else
965
+ sql << " TOP "
966
+ literal_append(sql, l)
967
+ end
968
+
969
+ if @opts[:limit_with_ties]
970
+ sql << " WITH TIES"
971
+ end
972
+ end
973
+
974
+ def update_limit_sql(sql)
975
+ if l = @opts[:limit]
976
+ shared_limit_sql(sql, l)
959
977
  end
960
978
  end
961
- alias update_limit_sql select_limit_sql
979
+ alias delete_limit_sql update_limit_sql
962
980
 
963
- # Support different types of locking styles
981
+ # Handle dirty, skip locked, and for update locking
964
982
  def select_lock_sql(sql)
965
- case @opts[:lock]
966
- when :update
967
- sql << UPDLOCK
968
- when :dirty
969
- sql << NOLOCK
983
+ lock = @opts[:lock]
984
+ skip_locked = @opts[:skip_locked]
985
+ nowait = @opts[:nowait]
986
+ for_update = lock == :update
987
+ dirty = lock == :dirty
988
+ lock_hint = for_update || dirty
989
+
990
+ if lock_hint || skip_locked
991
+ sql << " WITH ("
992
+
993
+ if lock_hint
994
+ sql << (for_update ? 'UPDLOCK' : 'NOLOCK')
995
+ end
996
+
997
+ if skip_locked || nowait
998
+ sql << ', ' if lock_hint
999
+ sql << (skip_locked ? "READPAST" : "NOWAIT")
1000
+ end
1001
+
1002
+ sql << ')'
970
1003
  else
971
1004
  super
972
1005
  end
@@ -978,20 +1011,19 @@ module Sequel
978
1011
  super
979
1012
  if is_2012_or_later? && @opts[:order]
980
1013
  if o = @opts[:offset]
981
- sql << OFFSET
1014
+ sql << " OFFSET "
982
1015
  literal_append(sql, o)
983
- sql << ROWS
1016
+ sql << " ROWS"
984
1017
 
985
1018
  if l = @opts[:limit]
986
- sql << FETCH_NEXT
1019
+ sql << " FETCH NEXT "
987
1020
  literal_append(sql, l)
988
- sql << ROWS_ONLY
1021
+ sql << " ROWS ONLY"
989
1022
  end
990
1023
  end
991
1024
  end
992
1025
  end
993
1026
 
994
- # SQL fragment for MSSQL's OUTPUT clause.
995
1027
  def output_sql(sql, type)
996
1028
  return unless supports_output_clause?
997
1029
  if output = @opts[:output]
@@ -1002,21 +1034,21 @@ module Sequel
1002
1034
  end
1003
1035
 
1004
1036
  def output_list_sql(sql, output)
1005
- sql << OUTPUT
1037
+ sql << " OUTPUT "
1006
1038
  column_list_append(sql, output[:select_list])
1007
1039
  if into = output[:into]
1008
- sql << INTO
1040
+ sql << " INTO "
1009
1041
  identifier_append(sql, into)
1010
1042
  if column_list = output[:column_list]
1011
- sql << PAREN_SPACE_OPEN
1043
+ sql << ' ('
1012
1044
  source_list_append(sql, column_list)
1013
- sql << PAREN_CLOSE
1045
+ sql << ')'
1014
1046
  end
1015
1047
  end
1016
1048
  end
1017
1049
 
1018
1050
  def output_returning_sql(sql, type, values)
1019
- sql << OUTPUT
1051
+ sql << " OUTPUT "
1020
1052
  if values.empty?
1021
1053
  literal_append(sql, SQL::ColumnAll.new(type))
1022
1054
  else
@@ -1032,14 +1064,27 @@ module Sequel
1032
1064
  end
1033
1065
  end
1034
1066
 
1035
- # MSSQL supports millisecond timestamp precision.
1067
+ # MSSQL does not natively support NULLS FIRST/LAST.
1068
+ def requires_emulating_nulls_first?
1069
+ true
1070
+ end
1071
+
1072
+ # MSSQL supports 100-nsec precision for time columns, but ruby by
1073
+ # default only supports usec precision.
1074
+ def sqltime_precision
1075
+ 6
1076
+ end
1077
+
1078
+ # MSSQL supports millisecond timestamp precision for datetime columns.
1079
+ # 100-nsec precision is supported for datetime2 columns, but Sequel does
1080
+ # not know what the column type is when formatting values.
1036
1081
  def timestamp_precision
1037
1082
  3
1038
1083
  end
1039
1084
 
1040
1085
  # Only include the primary table in the main update clause
1041
1086
  def update_table_sql(sql)
1042
- sql << SPACE
1087
+ sql << ' '
1043
1088
  source_list_append(sql, @opts[:from][0..0])
1044
1089
  end
1045
1090