sequel 5.20.0 → 5.49.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 (511) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +398 -1922
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/doc/advanced_associations.rdoc +4 -4
  6. data/doc/association_basics.rdoc +80 -16
  7. data/doc/cheat_sheet.rdoc +6 -5
  8. data/doc/code_order.rdoc +10 -12
  9. data/doc/dataset_filtering.rdoc +17 -2
  10. data/doc/fork_safety.rdoc +84 -0
  11. data/doc/migration.rdoc +11 -5
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +10 -2
  15. data/doc/postgresql.rdoc +82 -3
  16. data/doc/querying.rdoc +4 -4
  17. data/doc/release_notes/5.21.0.txt +87 -0
  18. data/doc/release_notes/5.22.0.txt +48 -0
  19. data/doc/release_notes/5.23.0.txt +56 -0
  20. data/doc/release_notes/5.24.0.txt +56 -0
  21. data/doc/release_notes/5.25.0.txt +32 -0
  22. data/doc/release_notes/5.26.0.txt +35 -0
  23. data/doc/release_notes/5.27.0.txt +21 -0
  24. data/doc/release_notes/5.28.0.txt +16 -0
  25. data/doc/release_notes/5.29.0.txt +22 -0
  26. data/doc/release_notes/5.30.0.txt +20 -0
  27. data/doc/release_notes/5.31.0.txt +148 -0
  28. data/doc/release_notes/5.32.0.txt +46 -0
  29. data/doc/release_notes/5.33.0.txt +24 -0
  30. data/doc/release_notes/5.34.0.txt +40 -0
  31. data/doc/release_notes/5.35.0.txt +56 -0
  32. data/doc/release_notes/5.36.0.txt +60 -0
  33. data/doc/release_notes/5.37.0.txt +30 -0
  34. data/doc/release_notes/5.38.0.txt +28 -0
  35. data/doc/release_notes/5.39.0.txt +19 -0
  36. data/doc/release_notes/5.40.0.txt +40 -0
  37. data/doc/release_notes/5.41.0.txt +25 -0
  38. data/doc/release_notes/5.42.0.txt +136 -0
  39. data/doc/release_notes/5.43.0.txt +98 -0
  40. data/doc/release_notes/5.44.0.txt +32 -0
  41. data/doc/release_notes/5.45.0.txt +34 -0
  42. data/doc/release_notes/5.46.0.txt +87 -0
  43. data/doc/release_notes/5.47.0.txt +59 -0
  44. data/doc/release_notes/5.48.0.txt +14 -0
  45. data/doc/release_notes/5.49.0.txt +59 -0
  46. data/doc/sharding.rdoc +2 -0
  47. data/doc/sql.rdoc +13 -1
  48. data/doc/testing.rdoc +20 -7
  49. data/doc/transactions.rdoc +0 -8
  50. data/doc/validations.rdoc +1 -1
  51. data/doc/virtual_rows.rdoc +1 -1
  52. data/lib/sequel/adapters/ado/access.rb +1 -1
  53. data/lib/sequel/adapters/ado.rb +43 -35
  54. data/lib/sequel/adapters/ibmdb.rb +2 -2
  55. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  56. data/lib/sequel/adapters/jdbc/postgresql.rb +11 -17
  57. data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
  58. data/lib/sequel/adapters/jdbc.rb +24 -6
  59. data/lib/sequel/adapters/mysql.rb +1 -1
  60. data/lib/sequel/adapters/mysql2.rb +2 -3
  61. data/lib/sequel/adapters/odbc.rb +8 -6
  62. data/lib/sequel/adapters/oracle.rb +5 -4
  63. data/lib/sequel/adapters/postgres.rb +15 -9
  64. data/lib/sequel/adapters/shared/access.rb +6 -6
  65. data/lib/sequel/adapters/shared/mssql.rb +66 -21
  66. data/lib/sequel/adapters/shared/mysql.rb +27 -10
  67. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  68. data/lib/sequel/adapters/shared/postgres.rb +271 -32
  69. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  70. data/lib/sequel/adapters/shared/sqlite.rb +161 -19
  71. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  72. data/lib/sequel/adapters/sqlite.rb +1 -1
  73. data/lib/sequel/adapters/tinytds.rb +15 -2
  74. data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -1
  75. data/lib/sequel/ast_transformer.rb +6 -0
  76. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  77. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  78. data/lib/sequel/connection_pool/single.rb +1 -1
  79. data/lib/sequel/connection_pool/threaded.rb +2 -2
  80. data/lib/sequel/core.rb +333 -319
  81. data/lib/sequel/database/connecting.rb +3 -4
  82. data/lib/sequel/database/logging.rb +7 -1
  83. data/lib/sequel/database/misc.rb +31 -12
  84. data/lib/sequel/database/query.rb +3 -1
  85. data/lib/sequel/database/schema_generator.rb +53 -51
  86. data/lib/sequel/database/schema_methods.rb +38 -23
  87. data/lib/sequel/database/transactions.rb +17 -18
  88. data/lib/sequel/dataset/actions.rb +14 -9
  89. data/lib/sequel/dataset/features.rb +16 -0
  90. data/lib/sequel/dataset/misc.rb +2 -2
  91. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  92. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  93. data/lib/sequel/dataset/query.rb +26 -9
  94. data/lib/sequel/dataset/sql.rb +76 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/deprecated.rb +3 -1
  97. data/lib/sequel/exceptions.rb +2 -0
  98. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  99. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  100. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  101. data/lib/sequel/extensions/blank.rb +8 -0
  102. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  103. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  104. data/lib/sequel/extensions/connection_validator.rb +2 -2
  105. data/lib/sequel/extensions/core_refinements.rb +2 -0
  106. data/lib/sequel/extensions/date_arithmetic.rb +36 -24
  107. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
  108. data/lib/sequel/extensions/eval_inspect.rb +2 -0
  109. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  110. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  111. data/lib/sequel/extensions/index_caching.rb +9 -7
  112. data/lib/sequel/extensions/inflector.rb +9 -1
  113. data/lib/sequel/extensions/integer64.rb +2 -0
  114. data/lib/sequel/extensions/migration.rb +11 -3
  115. data/lib/sequel/extensions/named_timezones.rb +56 -8
  116. data/lib/sequel/extensions/pagination.rb +1 -1
  117. data/lib/sequel/extensions/pg_array.rb +5 -0
  118. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  119. data/lib/sequel/extensions/pg_enum.rb +11 -3
  120. data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
  121. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  122. data/lib/sequel/extensions/pg_hstore_ops.rb +54 -2
  123. data/lib/sequel/extensions/pg_inet.rb +15 -5
  124. data/lib/sequel/extensions/pg_interval.rb +36 -8
  125. data/lib/sequel/extensions/pg_json.rb +387 -123
  126. data/lib/sequel/extensions/pg_json_ops.rb +238 -0
  127. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  128. data/lib/sequel/extensions/pg_range.rb +17 -9
  129. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  130. data/lib/sequel/extensions/pg_row.rb +4 -2
  131. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  132. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  133. data/lib/sequel/extensions/query.rb +3 -0
  134. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  135. data/lib/sequel/extensions/s.rb +2 -0
  136. data/lib/sequel/extensions/schema_dumper.rb +24 -7
  137. data/lib/sequel/extensions/server_block.rb +18 -7
  138. data/lib/sequel/extensions/sql_comments.rb +2 -2
  139. data/lib/sequel/extensions/string_agg.rb +1 -1
  140. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  141. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  142. data/lib/sequel/extensions/to_dot.rb +9 -3
  143. data/lib/sequel/model/associations.rb +356 -117
  144. data/lib/sequel/model/base.rb +107 -68
  145. data/lib/sequel/model/errors.rb +10 -1
  146. data/lib/sequel/model/inflections.rb +1 -1
  147. data/lib/sequel/model/plugins.rb +9 -3
  148. data/lib/sequel/model.rb +3 -1
  149. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  150. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  151. data/lib/sequel/plugins/association_pks.rb +60 -18
  152. data/lib/sequel/plugins/association_proxies.rb +8 -2
  153. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  154. data/lib/sequel/plugins/auto_validations.rb +39 -5
  155. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  156. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  157. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  158. data/lib/sequel/plugins/caching.rb +3 -0
  159. data/lib/sequel/plugins/class_table_inheritance.rb +33 -28
  160. data/lib/sequel/plugins/column_encryption.rb +728 -0
  161. data/lib/sequel/plugins/composition.rb +7 -2
  162. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  163. data/lib/sequel/plugins/constraint_validations.rb +2 -1
  164. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  165. data/lib/sequel/plugins/dataset_associations.rb +4 -1
  166. data/lib/sequel/plugins/dirty.rb +60 -22
  167. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  168. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  169. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  170. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  171. data/lib/sequel/plugins/json_serializer.rb +57 -35
  172. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  173. data/lib/sequel/plugins/many_through_many.rb +108 -9
  174. data/lib/sequel/plugins/nested_attributes.rb +15 -3
  175. data/lib/sequel/plugins/pg_array_associations.rb +58 -41
  176. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +91 -30
  177. data/lib/sequel/plugins/prepared_statements.rb +15 -12
  178. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  179. data/lib/sequel/plugins/rcte_tree.rb +43 -35
  180. data/lib/sequel/plugins/serialization.rb +8 -3
  181. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  182. data/lib/sequel/plugins/sharding.rb +11 -5
  183. data/lib/sequel/plugins/single_table_inheritance.rb +22 -15
  184. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  185. data/lib/sequel/plugins/static_cache.rb +9 -4
  186. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  187. data/lib/sequel/plugins/string_stripper.rb +1 -1
  188. data/lib/sequel/plugins/subclasses.rb +2 -0
  189. data/lib/sequel/plugins/throw_failures.rb +1 -1
  190. data/lib/sequel/plugins/timestamps.rb +1 -1
  191. data/lib/sequel/plugins/tree.rb +9 -4
  192. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  193. data/lib/sequel/plugins/unused_associations.rb +521 -0
  194. data/lib/sequel/plugins/update_or_create.rb +1 -1
  195. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  196. data/lib/sequel/plugins/validation_helpers.rb +18 -11
  197. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  198. data/lib/sequel/sql.rb +20 -5
  199. data/lib/sequel/timezones.rb +63 -17
  200. data/lib/sequel/version.rb +1 -1
  201. metadata +113 -381
  202. data/Rakefile +0 -151
  203. data/doc/release_notes/4.0.0.txt +0 -262
  204. data/doc/release_notes/4.1.0.txt +0 -85
  205. data/doc/release_notes/4.10.0.txt +0 -226
  206. data/doc/release_notes/4.11.0.txt +0 -147
  207. data/doc/release_notes/4.12.0.txt +0 -105
  208. data/doc/release_notes/4.13.0.txt +0 -169
  209. data/doc/release_notes/4.14.0.txt +0 -68
  210. data/doc/release_notes/4.15.0.txt +0 -56
  211. data/doc/release_notes/4.16.0.txt +0 -36
  212. data/doc/release_notes/4.17.0.txt +0 -38
  213. data/doc/release_notes/4.18.0.txt +0 -36
  214. data/doc/release_notes/4.19.0.txt +0 -45
  215. data/doc/release_notes/4.2.0.txt +0 -129
  216. data/doc/release_notes/4.20.0.txt +0 -79
  217. data/doc/release_notes/4.21.0.txt +0 -94
  218. data/doc/release_notes/4.22.0.txt +0 -72
  219. data/doc/release_notes/4.23.0.txt +0 -65
  220. data/doc/release_notes/4.24.0.txt +0 -99
  221. data/doc/release_notes/4.25.0.txt +0 -181
  222. data/doc/release_notes/4.26.0.txt +0 -44
  223. data/doc/release_notes/4.27.0.txt +0 -78
  224. data/doc/release_notes/4.28.0.txt +0 -57
  225. data/doc/release_notes/4.29.0.txt +0 -41
  226. data/doc/release_notes/4.3.0.txt +0 -40
  227. data/doc/release_notes/4.30.0.txt +0 -37
  228. data/doc/release_notes/4.31.0.txt +0 -57
  229. data/doc/release_notes/4.32.0.txt +0 -132
  230. data/doc/release_notes/4.33.0.txt +0 -88
  231. data/doc/release_notes/4.34.0.txt +0 -86
  232. data/doc/release_notes/4.35.0.txt +0 -130
  233. data/doc/release_notes/4.36.0.txt +0 -116
  234. data/doc/release_notes/4.37.0.txt +0 -50
  235. data/doc/release_notes/4.38.0.txt +0 -67
  236. data/doc/release_notes/4.39.0.txt +0 -127
  237. data/doc/release_notes/4.4.0.txt +0 -92
  238. data/doc/release_notes/4.40.0.txt +0 -179
  239. data/doc/release_notes/4.41.0.txt +0 -77
  240. data/doc/release_notes/4.42.0.txt +0 -221
  241. data/doc/release_notes/4.43.0.txt +0 -87
  242. data/doc/release_notes/4.44.0.txt +0 -125
  243. data/doc/release_notes/4.45.0.txt +0 -370
  244. data/doc/release_notes/4.46.0.txt +0 -404
  245. data/doc/release_notes/4.47.0.txt +0 -56
  246. data/doc/release_notes/4.48.0.txt +0 -293
  247. data/doc/release_notes/4.49.0.txt +0 -222
  248. data/doc/release_notes/4.5.0.txt +0 -34
  249. data/doc/release_notes/4.6.0.txt +0 -30
  250. data/doc/release_notes/4.7.0.txt +0 -103
  251. data/doc/release_notes/4.8.0.txt +0 -175
  252. data/doc/release_notes/4.9.0.txt +0 -190
  253. data/spec/adapter_spec.rb +0 -4
  254. data/spec/adapters/db2_spec.rb +0 -170
  255. data/spec/adapters/mssql_spec.rb +0 -804
  256. data/spec/adapters/mysql_spec.rb +0 -1065
  257. data/spec/adapters/oracle_spec.rb +0 -371
  258. data/spec/adapters/postgres_spec.rb +0 -4125
  259. data/spec/adapters/spec_helper.rb +0 -44
  260. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  261. data/spec/adapters/sqlite_spec.rb +0 -652
  262. data/spec/bin_spec.rb +0 -278
  263. data/spec/core/connection_pool_spec.rb +0 -1250
  264. data/spec/core/database_spec.rb +0 -2865
  265. data/spec/core/dataset_spec.rb +0 -5515
  266. data/spec/core/deprecated_spec.rb +0 -70
  267. data/spec/core/expression_filters_spec.rb +0 -1455
  268. data/spec/core/mock_adapter_spec.rb +0 -722
  269. data/spec/core/object_graph_spec.rb +0 -336
  270. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  271. data/spec/core/schema_generator_spec.rb +0 -214
  272. data/spec/core/schema_spec.rb +0 -1826
  273. data/spec/core/spec_helper.rb +0 -24
  274. data/spec/core/version_spec.rb +0 -14
  275. data/spec/core_extensions_spec.rb +0 -763
  276. data/spec/core_model_spec.rb +0 -2
  277. data/spec/core_spec.rb +0 -1
  278. data/spec/deprecation_helper.rb +0 -30
  279. data/spec/extensions/accessed_columns_spec.rb +0 -51
  280. data/spec/extensions/active_model_spec.rb +0 -99
  281. data/spec/extensions/after_initialize_spec.rb +0 -28
  282. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  283. data/spec/extensions/association_dependencies_spec.rb +0 -125
  284. data/spec/extensions/association_pks_spec.rb +0 -423
  285. data/spec/extensions/association_proxies_spec.rb +0 -100
  286. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  287. data/spec/extensions/auto_validations_spec.rb +0 -229
  288. data/spec/extensions/blacklist_security_spec.rb +0 -95
  289. data/spec/extensions/blank_spec.rb +0 -69
  290. data/spec/extensions/boolean_readers_spec.rb +0 -93
  291. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  292. data/spec/extensions/caching_spec.rb +0 -273
  293. data/spec/extensions/caller_logging_spec.rb +0 -52
  294. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  295. data/spec/extensions/column_conflicts_spec.rb +0 -75
  296. data/spec/extensions/column_select_spec.rb +0 -129
  297. data/spec/extensions/columns_introspection_spec.rb +0 -90
  298. data/spec/extensions/columns_updated_spec.rb +0 -35
  299. data/spec/extensions/composition_spec.rb +0 -248
  300. data/spec/extensions/connection_expiration_spec.rb +0 -151
  301. data/spec/extensions/connection_validator_spec.rb +0 -144
  302. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  303. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  304. data/spec/extensions/constraint_validations_spec.rb +0 -439
  305. data/spec/extensions/core_refinements_spec.rb +0 -528
  306. data/spec/extensions/csv_serializer_spec.rb +0 -183
  307. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  308. data/spec/extensions/dataset_associations_spec.rb +0 -365
  309. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  310. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  311. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  312. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  313. data/spec/extensions/defaults_setter_spec.rb +0 -150
  314. data/spec/extensions/delay_add_association_spec.rb +0 -73
  315. data/spec/extensions/dirty_spec.rb +0 -189
  316. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  317. data/spec/extensions/eager_each_spec.rb +0 -62
  318. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  319. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  320. data/spec/extensions/error_splitter_spec.rb +0 -18
  321. data/spec/extensions/error_sql_spec.rb +0 -20
  322. data/spec/extensions/escaped_like_spec.rb +0 -40
  323. data/spec/extensions/eval_inspect_spec.rb +0 -81
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -291
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -864
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -111
  348. data/spec/extensions/nested_attributes_spec.rb +0 -767
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -172
  356. data/spec/extensions/pg_enum_spec.rb +0 -118
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -519
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -177
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -870
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -63
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -471
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/throw_failures_spec.rb +0 -74
  411. data/spec/extensions/timestamps_spec.rb +0 -209
  412. data/spec/extensions/to_dot_spec.rb +0 -153
  413. data/spec/extensions/touch_spec.rb +0 -226
  414. data/spec/extensions/tree_spec.rb +0 -334
  415. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  416. data/spec/extensions/unlimited_update_spec.rb +0 -21
  417. data/spec/extensions/update_or_create_spec.rb +0 -83
  418. data/spec/extensions/update_primary_key_spec.rb +0 -105
  419. data/spec/extensions/update_refresh_spec.rb +0 -59
  420. data/spec/extensions/uuid_spec.rb +0 -101
  421. data/spec/extensions/validate_associated_spec.rb +0 -52
  422. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  423. data/spec/extensions/validation_contexts_spec.rb +0 -31
  424. data/spec/extensions/validation_helpers_spec.rb +0 -525
  425. data/spec/extensions/whitelist_security_spec.rb +0 -157
  426. data/spec/extensions/xml_serializer_spec.rb +0 -213
  427. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  428. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  429. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  431. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  432. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  433. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  434. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  436. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  437. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  438. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  439. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  440. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  441. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  443. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  444. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  446. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  447. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  448. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  449. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  450. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  451. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  452. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  453. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  457. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  458. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  459. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  460. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  461. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  462. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  466. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  468. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  469. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  471. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  473. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  474. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  475. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  476. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  478. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  479. data/spec/guards_helper.rb +0 -59
  480. data/spec/integration/associations_test.rb +0 -2597
  481. data/spec/integration/database_test.rb +0 -113
  482. data/spec/integration/dataset_test.rb +0 -1981
  483. data/spec/integration/eager_loader_test.rb +0 -687
  484. data/spec/integration/migrator_test.rb +0 -262
  485. data/spec/integration/model_test.rb +0 -203
  486. data/spec/integration/plugin_test.rb +0 -2396
  487. data/spec/integration/prepared_statement_test.rb +0 -405
  488. data/spec/integration/schema_test.rb +0 -889
  489. data/spec/integration/spec_helper.rb +0 -65
  490. data/spec/integration/timezone_test.rb +0 -86
  491. data/spec/integration/transaction_test.rb +0 -603
  492. data/spec/integration/type_test.rb +0 -127
  493. data/spec/model/association_reflection_spec.rb +0 -803
  494. data/spec/model/associations_spec.rb +0 -4738
  495. data/spec/model/base_spec.rb +0 -875
  496. data/spec/model/class_dataset_methods_spec.rb +0 -146
  497. data/spec/model/dataset_methods_spec.rb +0 -198
  498. data/spec/model/eager_loading_spec.rb +0 -2377
  499. data/spec/model/hooks_spec.rb +0 -370
  500. data/spec/model/inflector_spec.rb +0 -26
  501. data/spec/model/model_spec.rb +0 -956
  502. data/spec/model/plugins_spec.rb +0 -429
  503. data/spec/model/record_spec.rb +0 -2118
  504. data/spec/model/spec_helper.rb +0 -46
  505. data/spec/model/validations_spec.rb +0 -220
  506. data/spec/model_no_assoc_spec.rb +0 -1
  507. data/spec/model_spec.rb +0 -1
  508. data/spec/plugin_spec.rb +0 -1
  509. data/spec/sequel_coverage.rb +0 -15
  510. data/spec/sequel_warning.rb +0 -4
  511. data/spec/spec_config.rb +0 -12
@@ -1,1065 +0,0 @@
1
- SEQUEL_ADAPTER_TEST = :mysql
2
-
3
- require_relative 'spec_helper'
4
-
5
- describe "MySQL", '#create_table' do
6
- before do
7
- @db = DB
8
- @db.test_connection
9
- end
10
- after do
11
- @db.drop_table?(:dolls)
12
- end
13
-
14
- it "should create a temporary table" do
15
- @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
16
- @db.table_exists?(:tmp_dolls).must_equal true
17
- @db.disconnect
18
- @db.table_exists?(:tmp_dolls).must_equal false
19
- end
20
-
21
- it "should not use a default for a String :text=>true type" do
22
- @db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
23
- @db[:dolls].insert
24
- @db[:dolls].all.must_equal [{:name=>nil}]
25
- end
26
-
27
- it "should not use a default for a File type" do
28
- @db.create_table(:dolls){File :name, :default=>'blah'}
29
- @db[:dolls].insert
30
- @db[:dolls].all.must_equal [{:name=>nil}]
31
- end
32
-
33
- it "should respect the size option for File type" do
34
- @db.create_table(:dolls) do
35
- File :n1
36
- File :n2, :size=>:tiny
37
- File :n3, :size=>:medium
38
- File :n4, :size=>:long
39
- File :n5, :size=>255
40
- end
41
- @db.schema(:dolls).map{|k, v| v[:db_type]}.must_equal %w"blob tinyblob mediumblob longblob blob"
42
- end
43
-
44
- it "should include an :auto_increment schema attribute if auto incrementing" do
45
- @db.create_table(:dolls) do
46
- primary_key :n4
47
- Integer :n2
48
- String :n3
49
- end
50
- @db.schema(:dolls).map{|k, v| v[:auto_increment]}.must_equal [true, nil, nil]
51
- end
52
-
53
- it "should support collate with various other column options" do
54
- @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
55
- @db[:dolls].insert
56
- @db[:dolls].select_map(:name).must_equal ["foo"]
57
- end
58
-
59
- it "should be able to parse the default value for set and enum types" do
60
- @db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
61
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'a,b'
62
- @db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
63
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'b'
64
- end
65
-
66
- it "should allow setting auto_increment for existing column" do
67
- @db.create_table(:dolls){Integer :a, :primary_key=>true}
68
- @db.schema(:dolls).first.last[:auto_increment].must_equal false
69
- @db.set_column_type :dolls, :a, Integer, :auto_increment=>true
70
- @db.schema(:dolls).first.last[:auto_increment].must_equal true
71
- end
72
-
73
- it "should create generated column" do
74
- skip("generated columns not supported, skipping test") unless @db.supports_generated_columns?
75
- @db.create_table(:dolls){String :a; String :b, generated_always_as: Sequel.function(:CONCAT, :a, 'plus')}
76
- @db.schema(:dolls)[1][1][:generated].must_equal true
77
- end
78
- end
79
-
80
- if [:mysql, :mysql2].include?(DB.adapter_scheme)
81
- describe "Sequel::MySQL::Database#convert_tinyint_to_bool" do
82
- before do
83
- @db = DB
84
- @db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
85
- @ds = @db[:booltest]
86
- end
87
- after do
88
- @db.convert_tinyint_to_bool = true
89
- @db.drop_table?(:booltest)
90
- end
91
-
92
- it "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
93
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:boolean, :integer]
94
- @db.convert_tinyint_to_bool = false
95
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:integer, :integer]
96
- end
97
-
98
- it "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
99
- @db.convert_tinyint_to_bool = true
100
- @ds.delete
101
- @ds.insert(:b=>true, :i=>10)
102
- @ds.all.must_equal [{:b=>true, :i=>10}]
103
- @ds.delete
104
- @ds.insert(:b=>false, :i=>0)
105
- @ds.all.must_equal [{:b=>false, :i=>0}]
106
- @ds.delete
107
- @ds.insert(:b=>true, :i=>1)
108
- @ds.all.must_equal [{:b=>true, :i=>1}]
109
- end
110
-
111
- it "should return all tinyints as integers when unset" do
112
- @db.convert_tinyint_to_bool = false
113
- @ds.delete
114
- @ds.insert(:b=>true, :i=>10)
115
- @ds.all.must_equal [{:b=>1, :i=>10}]
116
- @ds.delete
117
- @ds.insert(:b=>false, :i=>0)
118
- @ds.all.must_equal [{:b=>0, :i=>0}]
119
-
120
- @ds.delete
121
- @ds.insert(:b=>1, :i=>10)
122
- @ds.all.must_equal [{:b=>1, :i=>10}]
123
- @ds.delete
124
- @ds.insert(:b=>0, :i=>0)
125
- @ds.all.must_equal [{:b=>0, :i=>0}]
126
- end
127
-
128
- it "should allow disabling the conversion on a per-dataset basis" do
129
- @db.convert_tinyint_to_bool = true
130
- ds = @ds.with_extend do
131
- def cast_tinyint_integer?(f) true end #mysql
132
- def convert_tinyint_to_bool?() false end #mysql2
133
- end
134
- ds.delete
135
- ds.insert(:b=>true, :i=>10)
136
- ds.all.must_equal [{:b=>1, :i=>10}]
137
- @ds.all.must_equal [{:b=>true, :i=>10}]
138
- end
139
- end
140
- end
141
-
142
- describe "A MySQL dataset" do
143
- before do
144
- DB.create_table(:items){String :name; Integer :value}
145
- @d = DB[:items]
146
- end
147
- after do
148
- DB.drop_table?(:items)
149
- end
150
-
151
- it "should handle large unsigned smallint/integer values" do
152
- DB.alter_table(:items){set_column_type :value, 'smallint unsigned'}
153
- @d.insert(:value=>(1 << 15) + 1)
154
- @d.get(:value).must_equal((1 << 15) + 1)
155
- DB.alter_table(:items){set_column_type :value, 'integer unsigned'}
156
- @d.update(:value=>(1 << 31) + 1)
157
- @d.get(:value).must_equal((1 << 31) + 1)
158
- DB.alter_table(:items){set_column_type :value, 'bigint unsigned'}
159
- @d.update(:value=>(1 << 63) + 1)
160
- @d.get(:value).must_equal((1 << 63) + 1)
161
- end
162
-
163
- it "should support ORDER clause in UPDATE statements" do
164
- @d.order(:name).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
165
- end
166
-
167
- it "should support updating a limited dataset" do
168
- @d.import [:value], [[2], [3]]
169
- @d.limit(1).update(:value => 4).must_equal 1
170
- [[2,4], [3,4]].must_include @d.select_order_map(:value)
171
- end
172
-
173
- it "should support updating a ordered, limited dataset" do
174
- @d.import [:value], [[2], [3]]
175
- @d.order(:value).limit(1).update(:value => 4).must_equal 1
176
- @d.select_order_map(:value).must_equal [3,4]
177
- end
178
-
179
- it "should raise error for updating a dataset with an offset" do
180
- proc{@d.offset(1).update(:value => 4)}.must_raise Sequel::InvalidOperation
181
- proc{@d.order(:value).offset(1).update(:value => 4)}.must_raise Sequel::InvalidOperation
182
- end
183
-
184
- it "should support regexps" do
185
- @d.insert(:name => 'abc', :value => 1)
186
- @d.insert(:name => 'bcd', :value => 2)
187
- @d.filter(:name => /bc/).count.must_equal 2
188
- @d.filter(:name => /^bc/).count.must_equal 1
189
- end
190
-
191
- it "should have explain output" do
192
- @d.explain.must_be_kind_of(String)
193
- @d.explain(:extended=>true).must_be_kind_of(String)
194
- end
195
-
196
- it "should correctly literalize strings with comment backslashes in them" do
197
- @d.delete
198
- @d.insert(:name => ':\\')
199
-
200
- @d.first[:name].must_equal ':\\'
201
- end
202
-
203
- it "should handle prepared statements with on_duplicate_key_update" do
204
- @d.db.add_index :items, :value, :unique=>true
205
- ds = @d.on_duplicate_key_update
206
- ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
207
- ps.call(:v => 1, :n => 'a')
208
- ds.all.must_equal [{:value=>1, :name=>'a'}]
209
- ps.call(:v => 1, :n => 'b')
210
- ds.all.must_equal [{:value=>1, :name=>'b'}]
211
- end
212
-
213
- it "should support generated columns" do
214
- skip("generated columns not supported, skipping test") unless DB.supports_generated_columns?
215
- DB.alter_table(:items) {add_column :b, String, :generated_always_as => Sequel.function(:CONCAT, :name, 'plus')}
216
- @d.insert(name: 'hello')
217
- @d.first[:b].must_equal 'helloplus'
218
- end
219
- end
220
-
221
- describe "Dataset#distinct" do
222
- before do
223
- @db = DB
224
- @db.create_table!(:a) do
225
- Integer :a
226
- Integer :b
227
- end
228
- @ds = @db[:a]
229
- end
230
- after do
231
- @db.drop_table?(:a)
232
- end
233
-
234
- it "#distinct with arguments should return results distinct on those arguments" do
235
- skip("ONLY_FULL_GROUP_BY sql_mode set, skipping DISTINCT ON emulation test") if @db.get(Sequel.lit '@@sql_mode').include?('ONLY_FULL_GROUP_BY')
236
-
237
- @ds.insert(20, 10)
238
- @ds.insert(30, 10)
239
- @ds.order(:b, :a).distinct.map(:a).must_equal [20, 30]
240
- @ds.order(:b, Sequel.desc(:a)).distinct.map(:a).must_equal [30, 20]
241
- # MySQL doesn't respect orders when using the nonstandard GROUP BY
242
- [[20], [30]].must_include(@ds.order(:b, :a).distinct(:b).map(:a))
243
- end
244
- end
245
-
246
- describe "MySQL join expressions" do
247
- before(:all) do
248
- @ds = DB[:nodes]
249
- DB.create_table!(:nodes){Integer :id; Integer :y}
250
- DB.create_table!(:n1){Integer :id}
251
- DB.create_table!(:n2){Integer :y}
252
- @ds.insert(:id=>1, :y=>2)
253
- DB[:n1].insert(1)
254
- DB[:n2].insert(2)
255
- end
256
- after(:all) do
257
- DB.drop_table?(:n2, :n1, :nodes)
258
- end
259
-
260
- it "should support straight joins (force left table to be read before right)" do
261
- @ds.join_table(:straight, :n1).all.must_equal [{:id=>1, :y=>2}]
262
- end
263
- it "should support natural joins on multiple tables." do
264
- @ds.join_table(:natural_left_outer, [:n1, :n2]).all.must_equal [{:id=>1, :y=>2}]
265
- end
266
- it "should support straight joins on multiple tables." do
267
- @ds.join_table(:straight, [:n1, :n2]).all.must_equal [{:id=>1, :y=>2}]
268
- end
269
- end
270
-
271
- describe "A MySQL database" do
272
- after do
273
- DB.drop_table?(:test_innodb)
274
- end
275
-
276
- it "should handle the creation and dropping of an InnoDB table with foreign keys" do
277
- DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}
278
- end
279
-
280
- it "should handle qualified tables in #indexes" do
281
- DB.create_table!(:test_innodb){primary_key :id; String :name; index :name, :unique=>true, :name=>:test_innodb_name_idx}
282
- DB.indexes(Sequel.qualify(DB.get{database.function}, :test_innodb)).must_equal(:test_innodb_name_idx=>{:unique=>true, :columns=>[:name]})
283
- end
284
- end
285
-
286
- describe "A MySQL database" do
287
- before(:all) do
288
- @db = DB
289
- @db.create_table! :test2 do
290
- text :name
291
- Integer :value
292
- end
293
- end
294
- after(:all) do
295
- @db.drop_table?(:test2)
296
- end
297
-
298
- it "should provide the server version" do
299
- @db.server_version.must_be :>=, 40000
300
- end
301
-
302
- it "should support for_share" do
303
- @db[:test2].delete
304
- @db.transaction{@db[:test2].for_share.all.must_equal []}
305
- end
306
-
307
- it "should support column operations" do
308
- @db.add_column :test2, :xyz, :text
309
-
310
- @db[:test2].columns.must_equal [:name, :value, :xyz]
311
- @db[:test2].insert(:name => 'mmm', :value => 111, :xyz => '000')
312
- @db[:test2].first[:xyz].must_equal '000'
313
-
314
- @db[:test2].columns.must_equal [:name, :value, :xyz]
315
- @db.drop_column :test2, :xyz
316
-
317
- @db[:test2].columns.must_equal [:name, :value]
318
-
319
- @db[:test2].delete
320
- @db.add_column :test2, :xyz, :text
321
- @db[:test2].insert(:name => 'mmm', :value => 111, :xyz => 'qqqq')
322
-
323
- @db[:test2].columns.must_equal [:name, :value, :xyz]
324
- @db.rename_column :test2, :xyz, :zyx, :type => :text
325
- @db[:test2].columns.must_equal [:name, :value, :zyx]
326
- @db[:test2].first[:zyx].must_equal 'qqqq'
327
-
328
- @db[:test2].delete
329
- @db.add_column :test2, :tre, :text
330
- @db[:test2].insert(:name => 'mmm', :value => 111, :tre => 'qqqq')
331
-
332
- @db[:test2].columns.must_equal [:name, :value, :zyx, :tre]
333
- @db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
334
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert]
335
- @db[:test2].first[:ert].must_equal 'qqqq'
336
-
337
- @db.add_column :test2, :xyz, :float
338
- @db[:test2].delete
339
- @db[:test2].insert(:name => 'mmm', :value => 111, :xyz => 56.78)
340
- @db.set_column_type :test2, :xyz, :integer
341
-
342
- @db[:test2].first[:xyz].must_equal 57
343
-
344
- @db.alter_table :test2 do
345
- add_index :value, :unique=>true
346
- add_foreign_key :value2, :test2, :key=>:value
347
- end
348
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert, :xyz, :value2]
349
-
350
- @db.alter_table :test2 do
351
- drop_foreign_key :value2
352
- drop_index :value
353
- end
354
- end
355
- end
356
-
357
- describe "A MySQL database with table options" do
358
- before do
359
- @options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
360
-
361
- @db = DB
362
- @db.default_engine = 'InnoDB'
363
- @db.default_charset = 'utf8'
364
- @db.default_collate = 'utf8_general_ci'
365
- @db.drop_table?(:items)
366
- end
367
- after do
368
- @db.drop_table?(:items)
369
-
370
- @db.default_engine = nil
371
- @db.default_charset = nil
372
- @db.default_collate = nil
373
- end
374
-
375
- it "should allow to pass custom options (engine, charset, collate) for table creation" do
376
- @db.create_table(:items, @options){Integer :size; text :name}
377
- @db.transaction(:rollback=>:always) do
378
- @db[:items].insert(:size=>1)
379
- end
380
- @db[:items].all.must_equal [{:size=>1, :name=>nil}]
381
- end
382
-
383
- it "should use default options if specified (engine, charset, collate) for table creation" do
384
- @db.create_table(:items){Integer :size; text :name}
385
- @db.transaction(:rollback=>:always) do
386
- @db[:items].insert(:size=>1)
387
- end
388
- @db[:items].all.must_equal []
389
- end
390
-
391
- it "should not use default if option has a nil value" do
392
- @db.default_engine = 'non_existent_engine'
393
- @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
394
- end
395
- end
396
-
397
- describe "A MySQL database" do
398
- before do
399
- @db = DB
400
- @db.drop_table?(:items)
401
- end
402
- after do
403
- @db.drop_table?(:items, :users)
404
- end
405
-
406
- it "should support defaults for boolean columns" do
407
- @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
408
- @db[:items].insert
409
- @db[:items].get([:active1, :active2]).must_equal [true, false]
410
- @db[:items].get([Sequel.cast(:active1, Integer).as(:v1), Sequel.cast(:active2, Integer).as(:v2)]).must_equal [1, 0]
411
- end
412
-
413
- it "should correctly handle CREATE TABLE statements with foreign keys" do
414
- @db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
415
- @db[:items].insert(:id=>1, :p_id=>1)
416
- @db[:items].insert(:id=>2, :p_id=>1)
417
- @db[:items].where(:id=>1).delete
418
- @db[:items].count.must_equal 0
419
- end
420
-
421
- it "should correctly handle CREATE TABLE statements with foreign keys, when :key != the default (:id)" do
422
- @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}
423
- @db[:items].insert(:id=>1, :other_than_id=>2, :p_id=>2)
424
- @db[:items].insert(:id=>2, :other_than_id=>3, :p_id=>2)
425
- @db[:items].where(:id=>1).delete
426
- @db[:items].count.must_equal 0
427
- end
428
-
429
- it "should correctly handle ALTER TABLE statements with foreign keys" do
430
- @db.create_table(:items){Integer :id}
431
- @db.create_table(:users){primary_key :id}
432
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
433
- @db[:users].insert(:id=>1)
434
- @db[:items].insert(:id=>2, :p_id=>1)
435
- @db[:users].where(:id=>1).delete
436
- @db[:items].count.must_equal 0
437
- end
438
-
439
- it "should correctly format ALTER TABLE statements with named foreign keys" do
440
- @db.create_table(:items){Integer :id}
441
- @db.create_table(:users){primary_key :id}
442
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade, :foreign_key_constraint_name => :pk_items__users }
443
- @db[:users].insert(:id=>1)
444
- @db[:items].insert(:id=>2, :p_id=>1)
445
- @db[:users].where(:id=>1).delete
446
- @db[:items].count.must_equal 0
447
- end
448
-
449
- it "should correctly handle add_column :after option" do
450
- @db.create_table(:items){Integer :id; Integer :value}
451
- @db.alter_table(:items){add_column :name, String, :after=>:id}
452
- @db[:items].columns.must_equal [:id, :name, :value]
453
- end
454
-
455
- it "should correctly handle add_column :first option" do
456
- @db.create_table(:items){Integer :id; Integer :value}
457
- @db.alter_table(:items){add_column :name, String, :first => true}
458
- @db[:items].columns.must_equal [:name, :id, :value]
459
- end
460
-
461
- it "should correctly handle add_foreign_key :first option" do
462
- @db.create_table(:items){primary_key :id; Integer :value}
463
- @db.alter_table(:items){add_foreign_key :parent_id, :items, :first => true}
464
- @db[:items].columns.must_equal [:parent_id, :id, :value]
465
- end
466
-
467
- it "should have rename_column support keep existing options" do
468
- @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
469
- @db.alter_table(:items){rename_column :id, :nid}
470
- @db[:items].insert
471
- @db[:items].all.must_equal [{:nid=>'blah'}]
472
- proc{@db[:items].insert(:nid=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
473
- end
474
-
475
- it "should have set_column_type support keep existing options" do
476
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
477
- @db.alter_table(:items){set_column_type :id, :Bignum}
478
- @db[:items].insert
479
- @db[:items].all.must_equal [{:id=>5}]
480
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
481
- @db[:items].delete
482
- @db[:items].insert(2**40)
483
- @db[:items].all.must_equal [{:id=>2**40}]
484
- end
485
-
486
- it "should have set_column_type pass through options" do
487
- @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
488
- @db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
489
- @db.schema(:items)[1][1][:db_type].must_equal "enum('two')"
490
- end
491
-
492
- it "should have set_column_default support keep existing options" do
493
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
494
- @db.alter_table(:items){set_column_default :id, 6}
495
- @db[:items].insert
496
- @db[:items].all.must_equal [{:id=>6}]
497
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
498
- end
499
-
500
- it "should have set_column_allow_null support keep existing options" do
501
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
502
- @db.alter_table(:items){set_column_allow_null :id, true}
503
- @db[:items].insert
504
- @db[:items].all.must_equal [{:id=>5}]
505
- @db[:items].insert(:id=>nil)
506
- end
507
-
508
- it "should accept repeated raw sql statements using Database#<<" do
509
- @db.create_table(:items){String :name; Integer :value}
510
- @db << 'DELETE FROM items'
511
- @db[:items].count.must_equal 0
512
-
513
- @db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
514
- @db[:items].first.must_equal(:name => 'tutu', :value => 1234)
515
-
516
- @db << 'DELETE FROM items'
517
- @db[:items].first.must_be_nil
518
- end
519
-
520
- it "should have schema handle generated columns" do
521
- skip("generated columns not supported, skipping test") unless @db.supports_generated_columns?
522
- @db.create_table(:items) {String :a}
523
- @db.alter_table(:items){add_column :b, String, :generated_always_as=>Sequel.function(:CONCAT, :a, 'plus'), :generated_type=>:stored, :unique=>true}
524
- @db.schema(:items)[1][1][:generated].must_equal true
525
- @db.alter_table(:items){add_column :c, String, :generated_always_as=>Sequel.function(:CONCAT, :a, 'minus'), :generated_type=>:virtual}
526
- @db.schema(:items)[2][1][:generated].must_equal true
527
- end
528
- end
529
-
530
- # Socket tests should only be run if the MySQL server is on localhost
531
- if DB.adapter_scheme == :mysql && %w'localhost 127.0.0.1 ::1'.include?(URI.parse(DB.uri).host)
532
- describe "A MySQL database" do
533
- socket_file = defined?(MYSQL_SOCKET_FILE) ? MYSQL_SOCKET_FILE : '/tmp/mysql.sock'
534
-
535
- it "should accept a socket option" do
536
- Sequel.mysql(DB.opts[:database], :host => 'localhost', :user => DB.opts[:user], :password => DB.opts[:password], :socket => socket_file, :keep_reference=>false)
537
- end
538
-
539
- it "should accept a socket option without host option" do
540
- Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket => socket_file, :keep_reference=>false)
541
- end
542
-
543
- it "should fail to connect with invalid socket" do
544
- proc{Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket =>'blah', :keep_reference=>false)}.must_raise Sequel::DatabaseConnectionError
545
- end
546
- end
547
- end
548
-
549
- describe "A MySQL database" do
550
- it "should accept a read_timeout option when connecting" do
551
- db = Sequel.connect(DB.opts.merge(:read_timeout=>22342))
552
- db.test_connection
553
- end
554
-
555
- it "should accept a connect_timeout option when connecting" do
556
- db = Sequel.connect(DB.opts.merge(:connect_timeout=>22342))
557
- db.test_connection
558
- end
559
- end
560
-
561
- describe "MySQL foreign key support" do
562
- after do
563
- DB.drop_table?(:testfk, :testpk)
564
- end
565
-
566
- it "should create table without :key" do
567
- DB.create_table!(:testpk){primary_key :id}
568
- DB.create_table!(:testfk){foreign_key :fk, :testpk}
569
- end
570
-
571
- it "should create table with composite keys without :key" do
572
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
573
- DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
574
- end
575
-
576
- it "should create table with self referential without :key" do
577
- DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
578
- end
579
-
580
- it "should create table with self referential with non-autoincrementing key without :key" do
581
- DB.create_table!(:testfk){Integer :id, :primary_key=>true; foreign_key :fk, :testfk}
582
- end
583
-
584
- it "should create table with self referential with composite keys without :key" do
585
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
586
- end
587
-
588
- it "should alter table without :key" do
589
- DB.create_table!(:testpk){primary_key :id}
590
- DB.create_table!(:testfk){Integer :id}
591
- DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
592
- end
593
-
594
- it "should alter table with composite keys without :key" do
595
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
596
- DB.create_table!(:testfk){Integer :fk; Integer :fk2}
597
- DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
598
- end
599
-
600
- it "should alter table with self referential without :key" do
601
- DB.create_table!(:testfk){primary_key :id}
602
- DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
603
- end
604
-
605
- it "should alter table with self referential with composite keys without :key" do
606
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
607
- DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
608
- end
609
- end
610
-
611
- describe "A grouped MySQL dataset" do
612
- before do
613
- DB.create_table! :test2 do
614
- text :name
615
- integer :value
616
- end
617
- DB[:test2].insert(:name => '11', :value => 10)
618
- DB[:test2].insert(:name => '11', :value => 20)
619
- DB[:test2].insert(:name => '11', :value => 30)
620
- DB[:test2].insert(:name => '12', :value => 10)
621
- DB[:test2].insert(:name => '12', :value => 20)
622
- DB[:test2].insert(:name => '13', :value => 10)
623
- end
624
- after do
625
- DB.drop_table?(:test2)
626
- end
627
-
628
- it "should return the correct count for raw sql query" do
629
- ds = DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
630
- ds.count.must_equal 1
631
- end
632
-
633
- it "should return the correct count for a normal dataset" do
634
- ds = DB[:test2].select(:name).where(:name => '11').group(:name)
635
- ds.count.must_equal 1
636
- end
637
- end
638
-
639
- describe "A MySQL database" do
640
- before do
641
- @db = DB
642
- @db.drop_table?(:posts)
643
- end
644
- after do
645
- @db.drop_table?(:posts)
646
- end
647
-
648
- it "should support fulltext indexes and full_text_search" do
649
- @db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
650
-
651
- @db[:posts].insert(:title=>'ruby rails', :body=>'y')
652
- @db[:posts].insert(:title=>'sequel', :body=>'ruby')
653
- @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
654
-
655
- @db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
656
- @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
657
- @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.must_equal [{:title=>'ruby scooby', :body=>'x'}]
658
-
659
- @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
660
- @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
661
- end
662
-
663
- it "should support spatial indexes" do
664
- @db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
665
- end
666
-
667
- it "should support indexes with index type" do
668
- @db.create_table(:posts){Integer :id; index :id, :type => :btree}
669
- @db[:posts].insert(1)
670
- @db[:posts].where(:id=>1).count.must_equal 1
671
- end
672
-
673
- it "should support unique indexes with index type" do
674
- @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
675
- @db[:posts].insert(1)
676
- proc{@db[:posts].insert(1)}.must_raise Sequel::UniqueConstraintViolation
677
- end
678
-
679
- it "should not dump partial indexes" do
680
- @db.create_table(:posts){text :id}
681
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
682
- @db.indexes(:posts).must_equal({})
683
- end
684
-
685
- it "should dump partial indexes if :partial option is set to true" do
686
- @db.create_table(:posts){text :id}
687
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
688
- @db.indexes(:posts, :partial => true).must_equal(:posts_id_index => {:columns => [:id], :unique => false})
689
- end
690
- end
691
-
692
- describe "MySQL::Dataset#insert and related methods" do
693
- before do
694
- DB.create_table(:items){String :name, :unique=>true; Integer :value}
695
- @d = DB[:items].order(:name)
696
- end
697
- after do
698
- DB.drop_table?(:items)
699
- end
700
-
701
- it "#insert should insert record with default values when no arguments given" do
702
- @d.insert
703
- @d.all.must_equal [{:name => nil, :value => nil}]
704
- end
705
-
706
- it "#insert should insert record with default values when empty hash given" do
707
- @d.insert({})
708
- @d.all.must_equal [{:name => nil, :value => nil}]
709
- end
710
-
711
- it "#insert should insert record with default values when empty array given" do
712
- @d.insert []
713
- @d.all.must_equal [{:name => nil, :value => nil}]
714
- end
715
-
716
- it "#on_duplicate_key_update should work with regular inserts" do
717
- DB.add_index :items, :name, :unique=>true
718
- @d.insert(:name => 'abc', :value => 1)
719
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'abc', :value => 1)
720
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
721
- @d.all.must_equal [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
722
- end
723
-
724
- it "#multi_replace should replace multiple records in a single statement" do
725
- @d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
726
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
727
- @d.multi_replace([{:name => 'abc', :value=>1}, {:name => 'ghi', :value=>3}])
728
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => nil}, {:name => 'ghi', :value=>3} ]
729
- end
730
-
731
- it "#multi_replace should support :commit_every option" do
732
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :commit_every => 2)
733
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
734
- end
735
-
736
- it "#multi_replace should support :slice option" do
737
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :slice => 2)
738
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
739
- end
740
-
741
- it "#multi_insert should insert multiple records in a single statement" do
742
- @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
743
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
744
- end
745
-
746
- it "#multi_insert should support :commit_every option" do
747
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :commit_every => 2)
748
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
749
- end
750
-
751
- it "#multi_insert should support :slice option" do
752
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :slice => 2)
753
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
754
- end
755
-
756
- it "#import should support inserting using columns and values arrays" do
757
- @d.import([:name, :value], [['abc', 1], ['def', 2]])
758
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
759
- end
760
-
761
- it "#insert_ignore should ignore existing records when used with multi_insert" do
762
- @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
763
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
764
- @d.insert_ignore.multi_insert([{:name => 'abc', :value=>1}, {:name => 'ghi', :value=>3}])
765
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}, {:name => 'ghi', :value=>3} ]
766
- end
767
-
768
- it "#insert_ignore should ignore single records when used with insert" do
769
- @d.insert_ignore.insert(:name => 'ghi')
770
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
771
- @d.insert_ignore.insert(:name => 'ghi', :value=>2)
772
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
773
- end
774
-
775
- it "#on_duplicate_key_update should handle inserts with duplicate keys" do
776
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
777
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
778
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 2], ['ghi',3]])
779
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
780
- end
781
-
782
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
783
- @d.on_duplicate_key_update(:value).import([:name,:value], [['abc', 1], ['def',2]])
784
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
785
- @d.on_duplicate_key_update(:value).import([:name,:value], [['abc', 2], ['ghi',3]])
786
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
787
- @d.on_duplicate_key_update(:name).import([:name,:value], [['abc', 5], ['ghi',6]])
788
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
789
- end
790
- end
791
-
792
- describe "MySQL::Dataset#update and related methods" do
793
- before do
794
- DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
795
- @d = DB[:items]
796
- end
797
- after do
798
- DB.drop_table?(:items)
799
- end
800
-
801
- it "#update_ignore should not raise error where normal update would fail" do
802
- @d.insert(:name => 'cow', :value => 0)
803
- @d.insert(:name => 'cat', :value => 1)
804
- proc{@d.where(:value => 1).update(:name => 'cow')}.must_raise(Sequel::UniqueConstraintViolation)
805
- @d.update_ignore.where(:value => 1).update(:name => 'cow')
806
- @d.order(:name).all.must_equal [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
807
- end
808
- end
809
-
810
- describe "MySQL::Dataset#replace" do
811
- before do
812
- DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
813
- @d = DB[:items]
814
- end
815
- after do
816
- DB.drop_table?(:items)
817
- end
818
-
819
- it "should use default values if they exist" do
820
- DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
821
- @d.replace
822
- @d.all.must_equal [{:id=>1, :value=>2}]
823
- @d.replace([])
824
- @d.all.must_equal [{:id=>1, :value=>2}]
825
- @d.replace({})
826
- @d.all.must_equal [{:id=>1, :value=>2}]
827
- end
828
- end
829
-
830
- describe "MySQL::Dataset#complex_expression_sql" do
831
- before do
832
- @d = DB.dataset
833
- end
834
-
835
- it "should handle string concatenation with CONCAT if more than one record" do
836
- @d.literal(Sequel.join([:x, :y])).must_equal "CONCAT(`x`, `y`)"
837
- @d.literal(Sequel.join([:x, :y], ' ')).must_equal "CONCAT(`x`, ' ', `y`)"
838
- @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)"
839
- end
840
-
841
- it "should handle string concatenation as simple string if just one record" do
842
- @d.literal(Sequel.join([:x])).must_equal "`x`"
843
- @d.literal(Sequel.join([:x], ' ')).must_equal "`x`"
844
- end
845
- end
846
-
847
- describe "MySQL::Dataset#calc_found_rows" do
848
- before do
849
- DB.create_table!(:items){Integer :a}
850
- end
851
- after do
852
- DB.drop_table?(:items)
853
- end
854
-
855
- it "should count matching rows disregarding LIMIT clause" do
856
- DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
857
-
858
- DB.synchronize do
859
- DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.must_equal [{:a => 1}]
860
- DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.must_equal [{:rows => 2 }]
861
- end
862
- end
863
- end
864
-
865
- if DB.adapter_scheme == :mysql or DB.adapter_scheme == :jdbc or DB.adapter_scheme == :mysql2
866
- describe "MySQL Stored Procedures" do
867
- before do
868
- DB.create_table(:items){Integer :id; Integer :value}
869
- @d = DB[:items]
870
- end
871
- after do
872
- DB.drop_table?(:items)
873
- DB.execute('DROP PROCEDURE test_sproc')
874
- end
875
-
876
- it "should be callable on the database object" do
877
- DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
878
- DB[:items].delete
879
- DB[:items].insert(:value=>1)
880
- DB[:items].count.must_equal 1
881
- DB.call_sproc(:test_sproc)
882
- DB[:items].count.must_equal 0
883
- end
884
-
885
- # Mysql2 doesn't support stored procedures that return result sets, probably because
886
- # CLIENT_MULTI_RESULTS is not set.
887
- unless DB.adapter_scheme == :mysql2
888
- it "should be callable on the dataset object" do
889
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
890
- DB[:items].delete
891
- @d = DB[:items]
892
- @d.call_sproc(:select, :test_sproc, 3).must_equal []
893
- @d.insert(:value=>1)
894
- @d.call_sproc(:select, :test_sproc, 4).must_equal [{:id=>nil, :value=>1, :b=>4}]
895
- @d = @d.with_row_proc(proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r})
896
- @d.call_sproc(:select, :test_sproc, 3).must_equal [{:id=>nil, :value=>2, :b=>6}]
897
- end
898
-
899
- it "should be callable on the dataset object with multiple arguments" do
900
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
901
- DB[:items].delete
902
- @d = DB[:items]
903
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal []
904
- @d.insert(:value=>1)
905
- @d.call_sproc(:select, :test_sproc, 4, 5).must_equal [{:id=>nil, :value=>1, :b=>4, :d=>5}]
906
- @d = @d.with_row_proc(proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r})
907
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal [{:id=>nil, :value=>2, :b=>6, :d => 8}]
908
- end
909
- end
910
-
911
- it "should deal with nil values" do
912
- DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
913
- DB[:items].delete
914
- DB.call_sproc(:test_sproc, :args=>[1, nil])
915
- DB[:items].all.must_equal [{:id=>1, :value=>nil}]
916
- end
917
- end
918
- end
919
-
920
- if DB.adapter_scheme == :mysql
921
- describe "MySQL bad date/time conversions" do
922
- after do
923
- DB.convert_invalid_date_time = false
924
- end
925
-
926
- it "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
927
- DB.convert_invalid_date_time = false
928
- proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.must_raise(Sequel::InvalidValue)
929
- proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.must_raise(Sequel::InvalidValue)
930
- proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.must_raise(Sequel::InvalidValue)
931
- end
932
-
933
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
934
- DB.convert_invalid_date_time = nil
935
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_be_nil
936
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_be_nil
937
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_be_nil
938
- DB.convert_invalid_date_time = :nil
939
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_be_nil
940
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_be_nil
941
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_be_nil
942
- end
943
-
944
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
945
- DB.convert_invalid_date_time = :string
946
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal '0000-00-00'
947
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal '0000-00-00 00:00:00'
948
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal '25:00:00'
949
- end
950
- end
951
-
952
- describe "MySQL multiple result sets" do
953
- before do
954
- DB.create_table!(:a){Integer :a}
955
- DB.create_table!(:b){Integer :b}
956
- @ds = DB['SELECT * FROM a; SELECT * FROM b']
957
- DB[:a].insert(10)
958
- DB[:a].insert(15)
959
- DB[:b].insert(20)
960
- DB[:b].insert(25)
961
- end
962
- after do
963
- DB.drop_table?(:a, :b)
964
- end
965
-
966
- it "should combine all results by default" do
967
- @ds.all.must_equal [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
968
- end
969
-
970
- it "should work with Database#run" do
971
- DB.run('SELECT * FROM a; SELECT * FROM b')
972
- DB.run('SELECT * FROM a; SELECT * FROM b')
973
- end
974
-
975
- it "should work with Database#run and other statements" do
976
- DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')
977
- DB[:a].select_order_map(:a).must_equal [1, 1]
978
- DB[:b].all.must_equal []
979
- end
980
-
981
- it "should split results returned into arrays if split_multiple_result_sets is used" do
982
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
983
- end
984
-
985
- it "should have regular row_procs work when splitting multiple result sets" do
986
- @ds = @ds.with_row_proc(proc{|x| x[x.keys.first] *= 2; x})
987
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
988
- end
989
-
990
- it "should use the columns from the first result set when splitting result sets" do
991
- @ds.split_multiple_result_sets.columns.must_equal [:a]
992
- end
993
-
994
- it "should not allow graphing a dataset that splits multiple statements" do
995
- proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.must_raise(Sequel::Error)
996
- end
997
-
998
- it "should not allow splitting a graphed dataset" do
999
- proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.must_raise(Sequel::Error)
1000
- end
1001
- end
1002
- end
1003
-
1004
- if DB.adapter_scheme == :mysql2
1005
- describe "Mysql2 streaming" do
1006
- before(:all) do
1007
- DB.create_table!(:a){Integer :a}
1008
- DB.transaction do
1009
- 1000.times do |i|
1010
- DB[:a].insert(i)
1011
- end
1012
- end
1013
- @ds = DB[:a].stream.order(:a)
1014
- end
1015
- after(:all) do
1016
- DB.drop_table?(:a)
1017
- end
1018
-
1019
- it "should correctly stream results" do
1020
- @ds.map(:a).must_equal((0...1000).to_a)
1021
- end
1022
-
1023
- it "should correctly handle early returning when streaming results" do
1024
- 3.times{@ds.each{|r| break r[:a]}.must_equal 0}
1025
- end
1026
-
1027
- it "#paged_each should bypass streaming when :stream => false passed in" do
1028
- DB[:a].order(:a).paged_each(:stream => false){|x| DB[:a].first; break}
1029
- end
1030
- end
1031
- end
1032
-
1033
- describe "MySQL joined datasets" do
1034
- before do
1035
- @db = DB
1036
- @db.create_table!(:a) do
1037
- Integer :id
1038
- end
1039
- @db.create_table!(:b) do
1040
- Integer :id
1041
- Integer :a_id
1042
- end
1043
- @db[:a].insert(1)
1044
- @db[:a].insert(2)
1045
- @db[:b].insert(3, 1)
1046
- @db[:b].insert(4, 1)
1047
- @db[:b].insert(5, 2)
1048
- @ds = @db[:a].join(:b, :a_id=>:id)
1049
- end
1050
- after do
1051
- @db.drop_table?(:a, :b)
1052
- end
1053
-
1054
- it "should support deletions from a single table" do
1055
- @ds.where(Sequel[:a][:id]=>1).delete
1056
- @db[:a].select_order_map(:id).must_equal [2]
1057
- @db[:b].select_order_map(:id).must_equal [3, 4, 5]
1058
- end
1059
-
1060
- it "should support deletions from multiple tables" do
1061
- @ds.delete_from(:a, :b).where(Sequel[:a][:id]=>1).delete
1062
- @db[:a].select_order_map(:id).must_equal [2]
1063
- @db[:b].select_order_map(:id).must_equal [5]
1064
- end
1065
- end