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,1287 +0,0 @@
1
- SEQUEL_ADAPTER_TEST = :mysql
2
-
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
4
-
5
- unless defined?(MYSQL_SOCKET_FILE)
6
- MYSQL_SOCKET_FILE = '/tmp/mysql.sock'
7
- end
8
- MYSQL_URI = URI.parse(DB.uri)
9
-
10
- def DB.sqls
11
- (@sqls ||= [])
12
- end
13
- logger = Object.new
14
- def logger.method_missing(m, msg)
15
- DB.sqls << msg
16
- end
17
- DB.loggers = [logger]
18
- DB.drop_table?(:items, :dolls, :booltest)
19
-
20
- SQL_BEGIN = 'BEGIN'
21
- SQL_ROLLBACK = 'ROLLBACK'
22
- SQL_COMMIT = 'COMMIT'
23
-
24
- describe "MySQL", '#create_table' do
25
- before do
26
- @db = DB
27
- @db.test_connection
28
- DB.sqls.clear
29
- end
30
- after do
31
- @db.drop_table?(:dolls)
32
- end
33
-
34
- it "should allow to specify options for MySQL" do
35
- @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
36
- check_sqls do
37
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
38
- end
39
- end
40
-
41
- it "should create a temporary table" do
42
- @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
43
- check_sqls do
44
- @db.sqls.must_equal ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
45
- end
46
- end
47
-
48
- it "should not use a default for a String :text=>true type" do
49
- @db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
50
- check_sqls do
51
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text)"]
52
- end
53
- end
54
-
55
- it "should not use a default for a File type" do
56
- @db.create_table(:dolls){File :name, :default=>'blah'}
57
- check_sqls do
58
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` blob)"]
59
- end
60
- end
61
-
62
- it "should respect the size option for File type" do
63
- @db.create_table(:dolls) do
64
- File :n1
65
- File :n2, :size=>:tiny
66
- File :n3, :size=>:medium
67
- File :n4, :size=>:long
68
- File :n5, :size=>255
69
- end
70
- @db.schema(:dolls).map{|k, v| v[:db_type]}.must_equal %w"blob tinyblob mediumblob longblob blob"
71
- end
72
-
73
- it "should include an :auto_increment schema attribute if auto incrementing" do
74
- @db.create_table(:dolls) do
75
- primary_key :n4
76
- Integer :n2
77
- String :n3
78
- end
79
- @db.schema(:dolls).map{|k, v| v[:auto_increment]}.must_equal [true, nil, nil]
80
- end
81
-
82
- it "should support collate with various other column options" do
83
- @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
84
- @db[:dolls].insert
85
- @db[:dolls].select_map(:name).must_equal ["foo"]
86
- end
87
-
88
- it "should be able to parse the default value for set and enum types" do
89
- @db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
90
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'a,b'
91
- @db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
92
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'b'
93
- end
94
-
95
- it "should allow setting auto_increment for existing column" do
96
- @db.create_table(:dolls){Integer :a, :primary_key=>true}
97
- @db.schema(:dolls).first.last[:auto_increment].must_equal false
98
- @db.set_column_type :dolls, :a, Integer, :auto_increment=>true
99
- @db.schema(:dolls).first.last[:auto_increment].must_equal true
100
- end
101
- end
102
-
103
- if [:mysql, :mysql2].include?(DB.adapter_scheme)
104
- describe "Sequel::MySQL::Database#convert_tinyint_to_bool" do
105
- before do
106
- @db = DB
107
- @db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
108
- @ds = @db[:booltest]
109
- end
110
- after do
111
- @db.convert_tinyint_to_bool = true
112
- @db.drop_table?(:booltest)
113
- end
114
-
115
- it "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
116
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:boolean, :integer]
117
- @db.convert_tinyint_to_bool = false
118
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:integer, :integer]
119
- end
120
-
121
- it "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
122
- @db.convert_tinyint_to_bool = true
123
- @ds.delete
124
- @ds << {:b=>true, :i=>10}
125
- @ds.all.must_equal [{:b=>true, :i=>10}]
126
- @ds.delete
127
- @ds << {:b=>false, :i=>0}
128
- @ds.all.must_equal [{:b=>false, :i=>0}]
129
- @ds.delete
130
- @ds << {:b=>true, :i=>1}
131
- @ds.all.must_equal [{:b=>true, :i=>1}]
132
- end
133
-
134
- it "should return all tinyints as integers when unset" do
135
- @db.convert_tinyint_to_bool = false
136
- @ds.delete
137
- @ds << {:b=>true, :i=>10}
138
- @ds.all.must_equal [{:b=>1, :i=>10}]
139
- @ds.delete
140
- @ds << {:b=>false, :i=>0}
141
- @ds.all.must_equal [{:b=>0, :i=>0}]
142
-
143
- @ds.delete
144
- @ds << {:b=>1, :i=>10}
145
- @ds.all.must_equal [{:b=>1, :i=>10}]
146
- @ds.delete
147
- @ds << {:b=>0, :i=>0}
148
- @ds.all.must_equal [{:b=>0, :i=>0}]
149
- end
150
-
151
- it "should allow disabling the conversion on a per-dataset basis" do
152
- @db.convert_tinyint_to_bool = true
153
- ds = @ds.clone
154
- def ds.cast_tinyint_integer?(f) true end #mysql
155
- def ds.convert_tinyint_to_bool?() false end #mysql2
156
- ds.delete
157
- ds << {:b=>true, :i=>10}
158
- ds.all.must_equal [{:b=>1, :i=>10}]
159
- @ds.all.must_equal [{:b=>true, :i=>10}]
160
- end
161
- end
162
- end
163
-
164
- describe "A MySQL dataset" do
165
- before do
166
- DB.create_table(:items){String :name; Integer :value}
167
- @d = DB[:items]
168
- DB.sqls.clear
169
- end
170
- after do
171
- DB.drop_table?(:items)
172
- end
173
-
174
- it "should quote columns and tables using back-ticks if quoting identifiers" do
175
- @d.quote_identifiers = true
176
- @d.select(:name).sql.must_equal 'SELECT `name` FROM `items`'
177
- @d.select(Sequel.lit('COUNT(*)')).sql.must_equal 'SELECT COUNT(*) FROM `items`'
178
- @d.select(Sequel.function(:max, :value)).sql.must_equal 'SELECT max(`value`) FROM `items`'
179
- @d.select(Sequel.function(:NOW)).sql.must_equal 'SELECT NOW() FROM `items`'
180
- @d.select(Sequel.function(:max, :items__value)).sql.must_equal 'SELECT max(`items`.`value`) FROM `items`'
181
- @d.order(Sequel.expr(:name).desc).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
182
- @d.select(Sequel.lit('items.name AS item_name')).sql.must_equal 'SELECT items.name AS item_name FROM `items`'
183
- @d.select(Sequel.lit('`name`')).sql.must_equal 'SELECT `name` FROM `items`'
184
- @d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.must_equal 'SELECT max(items.`name`) AS `max_name` FROM `items`'
185
- @d.select(Sequel.function(:test, :abc, 'hello')).sql.must_equal "SELECT test(`abc`, 'hello') FROM `items`"
186
- @d.select(Sequel.function(:test, :abc__def, 'hello')).sql.must_equal "SELECT test(`abc`.`def`, 'hello') FROM `items`"
187
- @d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.must_equal "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
188
- @d.insert_sql(:value => 333).must_equal 'INSERT INTO `items` (`value`) VALUES (333)'
189
- @d.insert_sql(:x => :y).must_equal 'INSERT INTO `items` (`x`) VALUES (`y`)'
190
- end
191
-
192
- it "should quote fields correctly when reversing the order" do
193
- @d.quote_identifiers = true
194
- @d.reverse_order(:name).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
195
- @d.reverse_order(Sequel.desc(:name)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC'
196
- @d.reverse_order(:name, Sequel.desc(:test)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
197
- @d.reverse_order(Sequel.desc(:name), :test).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
198
- end
199
-
200
- it "should support ORDER clause in UPDATE statements" do
201
- @d.order(:name).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
202
- end
203
-
204
- it "should support LIMIT clause in UPDATE statements" do
205
- @d.limit(10).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 LIMIT 10'
206
- end
207
-
208
- it "should support regexps" do
209
- @d << {:name => 'abc', :value => 1}
210
- @d << {:name => 'bcd', :value => 2}
211
- @d.filter(:name => /bc/).count.must_equal 2
212
- @d.filter(:name => /^bc/).count.must_equal 1
213
- end
214
-
215
- it "should have explain output" do
216
- @d.explain.must_be_kind_of(String)
217
- @d.explain(:extended=>true).must_be_kind_of(String)
218
- @d.explain.wont_equal @d.explain(:extended=>true)
219
- end
220
-
221
- it "should correctly literalize strings with comment backslashes in them" do
222
- @d.delete
223
- @d << {:name => ':\\'}
224
-
225
- @d.first[:name].must_equal ':\\'
226
- end
227
-
228
- it "should handle prepared statements with on_duplicate_key_update" do
229
- @d.db.add_index :items, :value, :unique=>true
230
- ds = @d.on_duplicate_key_update
231
- ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
232
- ps.call(:v => 1, :n => 'a')
233
- ds.all.must_equal [{:value=>1, :name=>'a'}]
234
- ps.call(:v => 1, :n => 'b')
235
- ds.all.must_equal [{:value=>1, :name=>'b'}]
236
- end
237
- end
238
-
239
- describe "MySQL datasets" do
240
- before do
241
- @d = DB[:orders]
242
- end
243
-
244
- it "should correctly quote column references" do
245
- @d.quote_identifiers = true
246
- market = 'ICE'
247
- ack_stamp = Time.now - 15 * 60 # 15 minutes ago
248
- @d.select(:market, Sequel.function(:minute, Sequel.function(:from_unixtime, :ack)).as(:minute)).
249
- where{(ack > ack_stamp) & {:market => market}}.
250
- group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.must_equal \
251
- "SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
252
- end
253
- end
254
-
255
- describe "Dataset#distinct" do
256
- before do
257
- @db = DB
258
- @db.create_table!(:a) do
259
- Integer :a
260
- Integer :b
261
- end
262
- @ds = @db[:a]
263
- end
264
- after do
265
- @db.drop_table?(:a)
266
- end
267
-
268
- it "#distinct with arguments should return results distinct on those arguments" do
269
- @ds.insert(20, 10)
270
- @ds.insert(30, 10)
271
- @ds.order(:b, :a).distinct.map(:a).must_equal [20, 30]
272
- @ds.order(:b, Sequel.desc(:a)).distinct.map(:a).must_equal [30, 20]
273
- # MySQL doesn't respect orders when using the nonstandard GROUP BY
274
- [[20], [30]].must_include(@ds.order(:b, :a).distinct(:b).map(:a))
275
- end
276
- end
277
-
278
- describe "MySQL join expressions" do
279
- before do
280
- @ds = DB[:nodes]
281
- end
282
-
283
- it "should raise error for :full_outer join requests." do
284
- lambda{@ds.join_table(:full_outer, :nodes)}.must_raise(Sequel::Error)
285
- end
286
- it "should support natural left joins" do
287
- @ds.join_table(:natural_left, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
288
- end
289
- it "should support natural right joins" do
290
- @ds.join_table(:natural_right, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
291
- end
292
- it "should support natural left outer joins" do
293
- @ds.join_table(:natural_left_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
294
- end
295
- it "should support natural right outer joins" do
296
- @ds.join_table(:natural_right_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
297
- end
298
- it "should support natural inner joins" do
299
- @ds.join_table(:natural_inner, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
300
- end
301
- it "should support cross joins" do
302
- @ds.join_table(:cross, :nodes).sql.must_equal 'SELECT * FROM `nodes` CROSS JOIN `nodes`'
303
- end
304
- it "should support cross joins as inner joins if conditions are used" do
305
- @ds.join_table(:cross, :nodes, :id=>:id).sql.must_equal 'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
306
- end
307
- it "should support straight joins (force left table to be read before right)" do
308
- @ds.join_table(:straight, :nodes).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
309
- end
310
- it "should support natural joins on multiple tables." do
311
- @ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
312
- end
313
- it "should support straight joins on multiple tables." do
314
- @ds.join_table(:straight, [:nodes,:branches]).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
315
- end
316
- end
317
-
318
- describe "Joined MySQL dataset" do
319
- before do
320
- @ds = DB[:nodes]
321
- end
322
-
323
- it "should quote fields correctly" do
324
- @ds.quote_identifiers = true
325
- @ds.join(:attributes, :node_id => :id).sql.must_equal "SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
326
- end
327
-
328
- it "should allow a having clause on ungrouped datasets" do
329
- @ds.having('blah')
330
-
331
- @ds.having('blah').sql.must_equal "SELECT * FROM `nodes` HAVING (blah)"
332
- end
333
-
334
- it "should put a having clause before an order by clause" do
335
- @ds.order(:aaa).having(:bbb => :ccc).sql.must_equal "SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
336
- end
337
- end
338
-
339
- describe "A MySQL database" do
340
- after do
341
- DB.drop_table?(:test_innodb)
342
- end
343
-
344
- it "should handle the creation and dropping of an InnoDB table with foreign keys" do
345
- DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}
346
- end
347
- end
348
-
349
- describe "A MySQL database" do
350
- before(:all) do
351
- @db = DB
352
- @db.create_table! :test2 do
353
- text :name
354
- integer :value
355
- end
356
- end
357
- after(:all) do
358
- @db.drop_table?(:test2)
359
- end
360
-
361
- it "should provide the server version" do
362
- @db.server_version.must_be :>=, 40000
363
- end
364
-
365
- it "should cache the server version" do
366
- # warm cache:
367
- @db.server_version
368
- @db.sqls.clear
369
- 3.times{@db.server_version}
370
- @db.sqls.must_be :empty?
371
- end
372
-
373
- it "should support for_share" do
374
- @db[:test2].delete
375
- @db.transaction{@db[:test2].for_share.all.must_equal []}
376
- end
377
-
378
- it "should support column operations" do
379
- @db.add_column :test2, :xyz, :text
380
-
381
- @db[:test2].columns.must_equal [:name, :value, :xyz]
382
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => '000'}
383
- @db[:test2].first[:xyz].must_equal '000'
384
-
385
- @db[:test2].columns.must_equal [:name, :value, :xyz]
386
- @db.drop_column :test2, :xyz
387
-
388
- @db[:test2].columns.must_equal [:name, :value]
389
-
390
- @db[:test2].delete
391
- @db.add_column :test2, :xyz, :text
392
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
393
-
394
- @db[:test2].columns.must_equal [:name, :value, :xyz]
395
- @db.rename_column :test2, :xyz, :zyx, :type => :text
396
- @db[:test2].columns.must_equal [:name, :value, :zyx]
397
- @db[:test2].first[:zyx].must_equal 'qqqq'
398
-
399
- @db[:test2].delete
400
- @db.add_column :test2, :tre, :text
401
- @db[:test2] << {:name => 'mmm', :value => 111, :tre => 'qqqq'}
402
-
403
- @db[:test2].columns.must_equal [:name, :value, :zyx, :tre]
404
- @db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
405
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert]
406
- @db[:test2].first[:ert].must_equal 'qqqq'
407
-
408
- @db.add_column :test2, :xyz, :float
409
- @db[:test2].delete
410
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
411
- @db.set_column_type :test2, :xyz, :integer
412
-
413
- @db[:test2].first[:xyz].must_equal 57
414
-
415
- @db.alter_table :test2 do
416
- add_index :value, :unique=>true
417
- add_foreign_key :value2, :test2, :key=>:value
418
- end
419
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert, :xyz, :value2]
420
-
421
- @db.alter_table :test2 do
422
- drop_foreign_key :value2
423
- drop_index :value
424
- end
425
- end
426
- end
427
-
428
- describe "A MySQL database with table options" do
429
- before do
430
- @options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
431
-
432
- Sequel::MySQL.default_engine = 'InnoDB'
433
- Sequel::MySQL.default_charset = 'utf8'
434
- Sequel::MySQL.default_collate = 'utf8_general_ci'
435
-
436
- @db = DB
437
- @db.drop_table?(:items)
438
-
439
- DB.sqls.clear
440
- end
441
- after do
442
- @db.drop_table?(:items)
443
-
444
- Sequel::MySQL.default_engine = nil
445
- Sequel::MySQL.default_charset = nil
446
- Sequel::MySQL.default_collate = nil
447
- end
448
-
449
- it "should allow to pass custom options (engine, charset, collate) for table creation" do
450
- @db.create_table(:items, @options){Integer :size; text :name}
451
- check_sqls do
452
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
453
- end
454
- end
455
-
456
- it "should use default options if specified (engine, charset, collate) for table creation" do
457
- @db.create_table(:items){Integer :size; text :name}
458
- check_sqls do
459
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
460
- end
461
- end
462
-
463
- it "should not use default if option has a nil value" do
464
- @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
465
- check_sqls do
466
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text)"]
467
- end
468
- end
469
- end
470
-
471
- describe "A MySQL database" do
472
- before do
473
- @db = DB
474
- @db.drop_table?(:items)
475
- DB.sqls.clear
476
- end
477
- after do
478
- @db.drop_table?(:items, :users)
479
- end
480
-
481
- it "should support defaults for boolean columns" do
482
- @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
483
- check_sqls do
484
- @db.sqls.must_equal ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
485
- end
486
- end
487
-
488
- it "should correctly format CREATE TABLE statements with foreign keys" do
489
- @db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
490
- check_sqls do
491
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
492
- end
493
- end
494
-
495
- it "should correctly format CREATE TABLE statements with foreign keys, when :key != the default (:id)" do
496
- @db.create_table(:items){primary_key :id; Integer :other_than_id; foreign_key :p_id, :items, :key => :other_than_id, :null => false, :on_delete => :cascade}
497
- check_sqls do
498
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `other_than_id` integer, `p_id` integer NOT NULL, UNIQUE (`other_than_id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`other_than_id`) ON DELETE CASCADE)"]
499
- end
500
- end
501
-
502
- it "should correctly format ALTER TABLE statements with foreign keys" do
503
- @db.create_table(:items){Integer :id}
504
- @db.create_table(:users){primary_key :id}
505
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
506
- check_sqls do
507
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
508
- "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
509
- "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
510
- end
511
- end
512
-
513
- it "should correctly format ALTER TABLE statements with named foreign keys" do
514
- @db.create_table(:items){Integer :id}
515
- @db.create_table(:users){primary_key :id}
516
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade, :foreign_key_constraint_name => :pk_items__users }
517
- check_sqls do
518
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
519
- "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
520
- "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD CONSTRAINT `pk_items__users` FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
521
- end
522
- end
523
-
524
- it "should have rename_column support keep existing options" do
525
- @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
526
- @db.alter_table(:items){rename_column :id, :nid}
527
- check_sqls do
528
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
529
- end
530
- @db[:items].insert
531
- @db[:items].all.must_equal [{:nid=>'blah'}]
532
- proc{@db[:items].insert(:nid=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
533
- end
534
-
535
- it "should have set_column_type support keep existing options" do
536
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
537
- @db.alter_table(:items){set_column_type :id, Bignum}
538
- check_sqls do
539
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
540
- end
541
- @db[:items].insert
542
- @db[:items].all.must_equal [{:id=>5}]
543
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
544
- @db[:items].delete
545
- @db[:items].insert(2**40)
546
- @db[:items].all.must_equal [{:id=>2**40}]
547
- end
548
-
549
- it "should have set_column_type pass through options" do
550
- @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
551
- @db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
552
- check_sqls do
553
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
554
- end
555
- end
556
-
557
- it "should have set_column_default support keep existing options" do
558
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
559
- @db.alter_table(:items){set_column_default :id, 6}
560
- check_sqls do
561
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
562
- end
563
- @db[:items].insert
564
- @db[:items].all.must_equal [{:id=>6}]
565
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
566
- end
567
-
568
- it "should have set_column_allow_null support keep existing options" do
569
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
570
- @db.alter_table(:items){set_column_allow_null :id, true}
571
- check_sqls do
572
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
573
- end
574
- @db[:items].insert
575
- @db[:items].all.must_equal [{:id=>5}]
576
- @db[:items].insert(:id=>nil)
577
- end
578
-
579
- it "should accept repeated raw sql statements using Database#<<" do
580
- @db.create_table(:items){String :name; Integer :value}
581
- @db << 'DELETE FROM items'
582
- @db[:items].count.must_equal 0
583
-
584
- @db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
585
- @db[:items].first.must_equal(:name => 'tutu', :value => 1234)
586
-
587
- @db << 'DELETE FROM items'
588
- @db[:items].first.must_equal nil
589
- end
590
- end
591
-
592
- # Socket tests should only be run if the MySQL server is on localhost
593
- if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and DB.adapter_scheme == :mysql
594
- describe "A MySQL database" do
595
- it "should accept a socket option" do
596
- db = Sequel.mysql(DB.opts[:database], :host => 'localhost', :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
597
- db.test_connection
598
- end
599
-
600
- it "should accept a socket option without host option" do
601
- db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
602
- db.test_connection
603
- end
604
-
605
- it "should fail to connect with invalid socket" do
606
- db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket =>'blah')
607
- proc{db.test_connection}.must_raise Sequel::DatabaseConnectionError
608
- end
609
- end
610
- end
611
-
612
- describe "A MySQL database" do
613
- it "should accept a read_timeout option when connecting" do
614
- db = Sequel.connect(DB.opts.merge(:read_timeout=>22342))
615
- db.test_connection
616
- end
617
-
618
- it "should accept a connect_timeout option when connecting" do
619
- db = Sequel.connect(DB.opts.merge(:connect_timeout=>22342))
620
- db.test_connection
621
- end
622
- end
623
-
624
- describe "MySQL foreign key support" do
625
- after do
626
- DB.drop_table?(:testfk, :testpk)
627
- end
628
-
629
- it "should create table without :key" do
630
- DB.create_table!(:testpk){primary_key :id}
631
- DB.create_table!(:testfk){foreign_key :fk, :testpk}
632
- end
633
-
634
- it "should create table with composite keys without :key" do
635
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
636
- DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
637
- end
638
-
639
- it "should create table with self referential without :key" do
640
- DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
641
- end
642
-
643
- it "should create table with self referential with composite keys without :key" do
644
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
645
- end
646
-
647
- it "should alter table without :key" do
648
- DB.create_table!(:testpk){primary_key :id}
649
- DB.create_table!(:testfk){Integer :id}
650
- DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
651
- end
652
-
653
- it "should alter table with composite keys without :key" do
654
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
655
- DB.create_table!(:testfk){Integer :fk; Integer :fk2}
656
- DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
657
- end
658
-
659
- it "should alter table with self referential without :key" do
660
- DB.create_table!(:testfk){primary_key :id}
661
- DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
662
- end
663
-
664
- it "should alter table with self referential with composite keys without :key" do
665
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
666
- DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
667
- end
668
- end
669
-
670
- describe "A grouped MySQL dataset" do
671
- before do
672
- DB.create_table! :test2 do
673
- text :name
674
- integer :value
675
- end
676
- DB[:test2] << {:name => '11', :value => 10}
677
- DB[:test2] << {:name => '11', :value => 20}
678
- DB[:test2] << {:name => '11', :value => 30}
679
- DB[:test2] << {:name => '12', :value => 10}
680
- DB[:test2] << {:name => '12', :value => 20}
681
- DB[:test2] << {:name => '13', :value => 10}
682
- end
683
- after do
684
- DB.drop_table?(:test2)
685
- end
686
-
687
- it "should return the correct count for raw sql query" do
688
- ds = DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
689
- ds.count.must_equal 1
690
- end
691
-
692
- it "should return the correct count for a normal dataset" do
693
- ds = DB[:test2].select(:name).where(:name => '11').group(:name)
694
- ds.count.must_equal 1
695
- end
696
- end
697
-
698
- describe "A MySQL database" do
699
- before do
700
- @db = DB
701
- @db.drop_table?(:posts)
702
- @db.sqls.clear
703
- end
704
- after do
705
- @db.drop_table?(:posts)
706
- end
707
-
708
- it "should support fulltext indexes and full_text_search" do
709
- @db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
710
- check_sqls do
711
- @db.sqls.must_equal [
712
- "CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
713
- "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
714
- "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
715
- ]
716
- end
717
-
718
- @db[:posts].insert(:title=>'ruby rails', :body=>'y')
719
- @db[:posts].insert(:title=>'sequel', :body=>'ruby')
720
- @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
721
- @db.sqls.clear
722
-
723
- @db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
724
- @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
725
- @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.must_equal [{:title=>'ruby scooby', :body=>'x'}]
726
- check_sqls do
727
- @db.sqls.must_equal [
728
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
729
- "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
730
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
731
- end
732
-
733
- @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
734
- @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
735
- end
736
-
737
- it "should support spatial indexes" do
738
- @db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
739
- check_sqls do
740
- @db.sqls.must_equal [
741
- "CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
742
- "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
743
- ]
744
- end
745
- end
746
-
747
- it "should support indexes with index type" do
748
- @db.create_table(:posts){Integer :id; index :id, :type => :btree}
749
- check_sqls do
750
- @db.sqls.must_equal [
751
- "CREATE TABLE `posts` (`id` integer)",
752
- "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
753
- ]
754
- end
755
- end
756
-
757
- it "should support unique indexes with index type" do
758
- @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
759
- check_sqls do
760
- @db.sqls.must_equal [
761
- "CREATE TABLE `posts` (`id` integer)",
762
- "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
763
- ]
764
- end
765
- end
766
-
767
- it "should not dump partial indexes" do
768
- @db.create_table(:posts){text :id}
769
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
770
- @db.indexes(:posts).must_equal({})
771
- end
772
-
773
- it "should dump partial indexes if :partial option is set to true" do
774
- @db.create_table(:posts){text :id}
775
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
776
- @db.indexes(:posts, :partial => true).must_equal(:posts_id_index => {:columns => [:id], :unique => false})
777
- end
778
- end
779
-
780
- describe "MySQL::Dataset#insert and related methods" do
781
- before do
782
- DB.create_table(:items){String :name; Integer :value}
783
- @d = DB[:items]
784
- DB.sqls.clear
785
- end
786
- after do
787
- DB.drop_table?(:items)
788
- end
789
-
790
- it "#insert should insert record with default values when no arguments given" do
791
- @d.insert
792
- check_sqls do
793
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
794
- end
795
- @d.all.must_equal [{:name => nil, :value => nil}]
796
- end
797
-
798
- it "#insert should insert record with default values when empty hash given" do
799
- @d.insert({})
800
- check_sqls do
801
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
802
- end
803
- @d.all.must_equal [{:name => nil, :value => nil}]
804
- end
805
-
806
- it "#insert should insert record with default values when empty array given" do
807
- @d.insert []
808
- check_sqls do
809
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
810
- end
811
- @d.all.must_equal [{:name => nil, :value => nil}]
812
- end
813
-
814
- it "#on_duplicate_key_update should work with regular inserts" do
815
- DB.add_index :items, :name, :unique=>true
816
- DB.sqls.clear
817
- @d.insert(:name => 'abc', :value => 1)
818
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'abc', :value => 1)
819
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
820
-
821
- check_sqls do
822
- DB.sqls.length.must_equal 3
823
- DB.sqls[0].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/)
824
- DB.sqls[1].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
825
- DB.sqls[2].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
826
- end
827
-
828
- @d.all.must_equal [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
829
- end
830
-
831
- it "#multi_replace should insert multiple records in a single statement" do
832
- @d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
833
-
834
- check_sqls do
835
- DB.sqls.must_equal [
836
- SQL_BEGIN,
837
- "REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
838
- SQL_COMMIT
839
- ]
840
- end
841
-
842
- @d.all.must_equal [
843
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
844
- ]
845
- end
846
-
847
- it "#multi_replace should split the list of records into batches if :commit_every option is given" do
848
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
849
- :commit_every => 2)
850
-
851
- check_sqls do
852
- DB.sqls.must_equal [
853
- SQL_BEGIN,
854
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
855
- SQL_COMMIT,
856
- SQL_BEGIN,
857
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
858
- SQL_COMMIT
859
- ]
860
- end
861
-
862
- @d.all.must_equal [
863
- {:name => nil, :value => 1},
864
- {:name => nil, :value => 2},
865
- {:name => nil, :value => 3},
866
- {:name => nil, :value => 4}
867
- ]
868
- end
869
-
870
- it "#multi_replace should split the list of records into batches if :slice option is given" do
871
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
872
- :slice => 2)
873
-
874
- check_sqls do
875
- DB.sqls.must_equal [
876
- SQL_BEGIN,
877
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
878
- SQL_COMMIT,
879
- SQL_BEGIN,
880
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
881
- SQL_COMMIT
882
- ]
883
- end
884
-
885
- @d.all.must_equal [
886
- {:name => nil, :value => 1},
887
- {:name => nil, :value => 2},
888
- {:name => nil, :value => 3},
889
- {:name => nil, :value => 4}
890
- ]
891
- end
892
-
893
- it "#multi_insert should insert multiple records in a single statement" do
894
- @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
895
-
896
- check_sqls do
897
- DB.sqls.must_equal [
898
- SQL_BEGIN,
899
- "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
900
- SQL_COMMIT
901
- ]
902
- end
903
-
904
- @d.all.must_equal [
905
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
906
- ]
907
- end
908
-
909
- it "#multi_insert should split the list of records into batches if :commit_every option is given" do
910
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
911
- :commit_every => 2)
912
-
913
- check_sqls do
914
- DB.sqls.must_equal [
915
- SQL_BEGIN,
916
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
917
- SQL_COMMIT,
918
- SQL_BEGIN,
919
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
920
- SQL_COMMIT
921
- ]
922
- end
923
-
924
- @d.all.must_equal [
925
- {:name => nil, :value => 1},
926
- {:name => nil, :value => 2},
927
- {:name => nil, :value => 3},
928
- {:name => nil, :value => 4}
929
- ]
930
- end
931
-
932
- it "#multi_insert should split the list of records into batches if :slice option is given" do
933
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
934
- :slice => 2)
935
-
936
- check_sqls do
937
- DB.sqls.must_equal [
938
- SQL_BEGIN,
939
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
940
- SQL_COMMIT,
941
- SQL_BEGIN,
942
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
943
- SQL_COMMIT
944
- ]
945
- end
946
-
947
- @d.all.must_equal [
948
- {:name => nil, :value => 1},
949
- {:name => nil, :value => 2},
950
- {:name => nil, :value => 3},
951
- {:name => nil, :value => 4}
952
- ]
953
- end
954
-
955
- it "#import should support inserting using columns and values arrays" do
956
- @d.import([:name, :value], [['abc', 1], ['def', 2]])
957
-
958
- check_sqls do
959
- DB.sqls.must_equal [
960
- SQL_BEGIN,
961
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
962
- SQL_COMMIT
963
- ]
964
- end
965
-
966
- @d.all.must_equal [
967
- {:name => 'abc', :value => 1},
968
- {:name => 'def', :value => 2}
969
- ]
970
- end
971
-
972
- it "#insert_ignore should add the IGNORE keyword when inserting" do
973
- @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
974
-
975
- check_sqls do
976
- DB.sqls.must_equal [
977
- SQL_BEGIN,
978
- "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
979
- SQL_COMMIT
980
- ]
981
- end
982
-
983
- @d.all.must_equal [
984
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
985
- ]
986
- end
987
-
988
- it "#insert_ignore should add the IGNORE keyword for single inserts" do
989
- @d.insert_ignore.insert(:name => 'ghi')
990
- check_sqls do
991
- DB.sqls.must_equal ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
992
- end
993
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
994
- end
995
-
996
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
997
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
998
-
999
- check_sqls do
1000
- DB.sqls.must_equal [
1001
- "SELECT * FROM `items` LIMIT 1",
1002
- SQL_BEGIN,
1003
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
1004
- SQL_COMMIT
1005
- ]
1006
- end
1007
-
1008
- @d.all.must_equal [
1009
- {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
1010
- ]
1011
- end
1012
-
1013
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
1014
- @d.on_duplicate_key_update(:value).import([:name,:value],
1015
- [['abc', 1], ['def',2]]
1016
- )
1017
-
1018
- check_sqls do
1019
- DB.sqls.must_equal [
1020
- SQL_BEGIN,
1021
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
1022
- SQL_COMMIT
1023
- ]
1024
- end
1025
-
1026
- @d.all.must_equal [
1027
- {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
1028
- ]
1029
- end
1030
-
1031
- end
1032
-
1033
- describe "MySQL::Dataset#update and related methods" do
1034
- before do
1035
- DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
1036
- @d = DB[:items]
1037
- end
1038
- after do
1039
- DB.drop_table?(:items)
1040
- end
1041
-
1042
- it "#update_ignore should not raise error where normal update would fail" do
1043
- @d.insert(:name => 'cow', :value => 0)
1044
- @d.insert(:name => 'cat', :value => 1)
1045
- proc{@d.where(:value => 1).update(:name => 'cow')}.must_raise(Sequel::UniqueConstraintViolation)
1046
- DB.sqls.clear
1047
- @d.update_ignore.where(:value => 1).update(:name => 'cow')
1048
- check_sqls do
1049
- DB.sqls.must_equal ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
1050
- end
1051
- @d.order(:name).all.must_equal [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
1052
- end
1053
- end
1054
-
1055
- describe "MySQL::Dataset#replace" do
1056
- before do
1057
- DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
1058
- @d = DB[:items]
1059
- DB.sqls.clear
1060
- end
1061
- after do
1062
- DB.drop_table?(:items)
1063
- end
1064
-
1065
- it "should use default values if they exist" do
1066
- DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
1067
- @d.replace
1068
- @d.all.must_equal [{:id=>1, :value=>2}]
1069
- @d.replace([])
1070
- @d.all.must_equal [{:id=>1, :value=>2}]
1071
- @d.replace({})
1072
- @d.all.must_equal [{:id=>1, :value=>2}]
1073
- end
1074
- end
1075
-
1076
- describe "MySQL::Dataset#complex_expression_sql" do
1077
- before do
1078
- @d = DB.dataset
1079
- end
1080
-
1081
- it "should handle string concatenation with CONCAT if more than one record" do
1082
- @d.literal(Sequel.join([:x, :y])).must_equal "CONCAT(`x`, `y`)"
1083
- @d.literal(Sequel.join([:x, :y], ' ')).must_equal "CONCAT(`x`, ' ', `y`)"
1084
- @d.literal(Sequel.join([Sequel.function(:x, :y), 1, Sequel.lit('z')], Sequel.subscript(:y, 1))).must_equal "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
1085
- end
1086
-
1087
- it "should handle string concatenation as simple string if just one record" do
1088
- @d.literal(Sequel.join([:x])).must_equal "`x`"
1089
- @d.literal(Sequel.join([:x], ' ')).must_equal "`x`"
1090
- end
1091
- end
1092
-
1093
- describe "MySQL::Dataset#calc_found_rows" do
1094
- before do
1095
- DB.create_table!(:items){Integer :a}
1096
- end
1097
- after do
1098
- DB.drop_table?(:items)
1099
- end
1100
-
1101
- it "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
1102
- DB[:items].select(:a).calc_found_rows.limit(1).sql.must_equal \
1103
- 'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
1104
- end
1105
-
1106
- it "should count matching rows disregarding LIMIT clause" do
1107
- DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
1108
- DB.sqls.clear
1109
-
1110
- DB.synchronize do
1111
- DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.must_equal [{:a => 1}]
1112
- DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.must_equal [{:rows => 2 }]
1113
- end
1114
-
1115
- check_sqls do
1116
- DB.sqls.must_equal [
1117
- 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
1118
- 'SELECT FOUND_ROWS() AS `rows`',
1119
- ]
1120
- end
1121
- end
1122
- end
1123
-
1124
- if DB.adapter_scheme == :mysql or DB.adapter_scheme == :jdbc or DB.adapter_scheme == :mysql2
1125
- describe "MySQL Stored Procedures" do
1126
- before do
1127
- DB.create_table(:items){Integer :id; Integer :value}
1128
- @d = DB[:items]
1129
- DB.sqls.clear
1130
- end
1131
- after do
1132
- DB.drop_table?(:items)
1133
- DB.execute('DROP PROCEDURE test_sproc')
1134
- end
1135
-
1136
- it "should be callable on the database object" do
1137
- DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
1138
- DB[:items].delete
1139
- DB[:items].insert(:value=>1)
1140
- DB[:items].count.must_equal 1
1141
- DB.call_sproc(:test_sproc)
1142
- DB[:items].count.must_equal 0
1143
- end
1144
-
1145
- # Mysql2 doesn't support stored procedures that return result sets, probably because
1146
- # CLIENT_MULTI_RESULTS is not set.
1147
- unless DB.adapter_scheme == :mysql2
1148
- it "should be callable on the dataset object" do
1149
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
1150
- DB[:items].delete
1151
- @d = DB[:items]
1152
- @d.call_sproc(:select, :test_sproc, 3).must_equal []
1153
- @d.insert(:value=>1)
1154
- @d.call_sproc(:select, :test_sproc, 4).must_equal [{:id=>nil, :value=>1, :b=>4}]
1155
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1156
- @d.call_sproc(:select, :test_sproc, 3).must_equal [{:id=>nil, :value=>2, :b=>6}]
1157
- end
1158
-
1159
- it "should be callable on the dataset object with multiple arguments" do
1160
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
1161
- DB[:items].delete
1162
- @d = DB[:items]
1163
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal []
1164
- @d.insert(:value=>1)
1165
- @d.call_sproc(:select, :test_sproc, 4, 5).must_equal [{:id=>nil, :value=>1, :b=>4, :d=>5}]
1166
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1167
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal [{:id=>nil, :value=>2, :b=>6, :d => 8}]
1168
- end
1169
- end
1170
-
1171
- it "should deal with nil values" do
1172
- DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
1173
- DB[:items].delete
1174
- DB.call_sproc(:test_sproc, :args=>[1, nil])
1175
- DB[:items].all.must_equal [{:id=>1, :value=>nil}]
1176
- end
1177
- end
1178
- end
1179
-
1180
- if DB.adapter_scheme == :mysql
1181
- describe "MySQL bad date/time conversions" do
1182
- after do
1183
- DB.convert_invalid_date_time = false
1184
- end
1185
-
1186
- it "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
1187
- DB.convert_invalid_date_time = false
1188
- proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.must_raise(Sequel::InvalidValue)
1189
- proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.must_raise(Sequel::InvalidValue)
1190
- proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.must_raise(Sequel::InvalidValue)
1191
- end
1192
-
1193
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
1194
- DB.convert_invalid_date_time = nil
1195
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
1196
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
1197
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
1198
- DB.convert_invalid_date_time = :nil
1199
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
1200
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
1201
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
1202
- end
1203
-
1204
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
1205
- DB.convert_invalid_date_time = :string
1206
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal '0000-00-00'
1207
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal '0000-00-00 00:00:00'
1208
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal '25:00:00'
1209
- end
1210
- end
1211
-
1212
- describe "MySQL multiple result sets" do
1213
- before do
1214
- DB.create_table!(:a){Integer :a}
1215
- DB.create_table!(:b){Integer :b}
1216
- @ds = DB['SELECT * FROM a; SELECT * FROM b']
1217
- DB[:a].insert(10)
1218
- DB[:a].insert(15)
1219
- DB[:b].insert(20)
1220
- DB[:b].insert(25)
1221
- end
1222
- after do
1223
- DB.drop_table?(:a, :b)
1224
- end
1225
-
1226
- it "should combine all results by default" do
1227
- @ds.all.must_equal [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
1228
- end
1229
-
1230
- it "should work with Database#run" do
1231
- DB.run('SELECT * FROM a; SELECT * FROM b')
1232
- DB.run('SELECT * FROM a; SELECT * FROM b')
1233
- end
1234
-
1235
- it "should work with Database#run and other statements" do
1236
- DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')
1237
- DB[:a].select_order_map(:a).must_equal [1, 1]
1238
- DB[:b].all.must_equal []
1239
- end
1240
-
1241
- it "should split results returned into arrays if split_multiple_result_sets is used" do
1242
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
1243
- end
1244
-
1245
- it "should have regular row_procs work when splitting multiple result sets" do
1246
- @ds.row_proc = proc{|x| x[x.keys.first] *= 2; x}
1247
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
1248
- end
1249
-
1250
- it "should use the columns from the first result set when splitting result sets" do
1251
- @ds.split_multiple_result_sets.columns.must_equal [:a]
1252
- end
1253
-
1254
- it "should not allow graphing a dataset that splits multiple statements" do
1255
- proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.must_raise(Sequel::Error)
1256
- end
1257
-
1258
- it "should not allow splitting a graphed dataset" do
1259
- proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.must_raise(Sequel::Error)
1260
- end
1261
- end
1262
- end
1263
-
1264
- if DB.adapter_scheme == :mysql2
1265
- describe "Mysql2 streaming" do
1266
- before(:all) do
1267
- DB.create_table!(:a){Integer :a}
1268
- DB.transaction do
1269
- 1000.times do |i|
1270
- DB[:a].insert(i)
1271
- end
1272
- end
1273
- @ds = DB[:a].stream.order(:a)
1274
- end
1275
- after(:all) do
1276
- DB.drop_table?(:a)
1277
- end
1278
-
1279
- it "should correctly stream results" do
1280
- @ds.map(:a).must_equal((0...1000).to_a)
1281
- end
1282
-
1283
- it "should correctly handle early returning when streaming results" do
1284
- 3.times{@ds.each{|r| break r[:a]}.must_equal 0}
1285
- end
1286
- end
1287
- end