sequel 4.26.0 → 5.37.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  11. data/doc/core_extensions.rdoc +104 -63
  12. data/doc/dataset_basics.rdoc +12 -21
  13. data/doc/dataset_filtering.rdoc +99 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,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