sequel 5.29.0 → 5.34.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 (387) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +70 -1922
  3. data/README.rdoc +1 -1
  4. data/doc/advanced_associations.rdoc +4 -4
  5. data/doc/association_basics.rdoc +3 -3
  6. data/doc/code_order.rdoc +12 -2
  7. data/doc/model_dataset_method_design.rdoc +1 -1
  8. data/doc/postgresql.rdoc +71 -0
  9. data/doc/release_notes/5.30.0.txt +20 -0
  10. data/doc/release_notes/5.31.0.txt +148 -0
  11. data/doc/release_notes/5.32.0.txt +46 -0
  12. data/doc/release_notes/5.33.0.txt +24 -0
  13. data/doc/release_notes/5.34.0.txt +40 -0
  14. data/doc/testing.rdoc +1 -1
  15. data/lib/sequel/adapters/shared/access.rb +6 -6
  16. data/lib/sequel/adapters/shared/mssql.rb +5 -5
  17. data/lib/sequel/adapters/shared/mysql.rb +9 -9
  18. data/lib/sequel/adapters/shared/oracle.rb +16 -16
  19. data/lib/sequel/adapters/shared/postgres.rb +169 -14
  20. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  21. data/lib/sequel/adapters/shared/sqlite.rb +32 -5
  22. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  23. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  24. data/lib/sequel/connection_pool/single.rb +1 -1
  25. data/lib/sequel/connection_pool/threaded.rb +2 -2
  26. data/lib/sequel/core.rb +318 -314
  27. data/lib/sequel/database/connecting.rb +1 -1
  28. data/lib/sequel/database/misc.rb +16 -10
  29. data/lib/sequel/database/query.rb +3 -1
  30. data/lib/sequel/database/schema_generator.rb +0 -1
  31. data/lib/sequel/database/schema_methods.rb +15 -16
  32. data/lib/sequel/database/transactions.rb +12 -13
  33. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  34. data/lib/sequel/dataset/query.rb +4 -3
  35. data/lib/sequel/deprecated.rb +2 -0
  36. data/lib/sequel/exceptions.rb +2 -0
  37. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  38. data/lib/sequel/extensions/connection_validator.rb +2 -2
  39. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  40. data/lib/sequel/extensions/index_caching.rb +9 -7
  41. data/lib/sequel/extensions/integer64.rb +2 -0
  42. data/lib/sequel/extensions/migration.rb +1 -1
  43. data/lib/sequel/extensions/pg_enum.rb +5 -2
  44. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  45. data/lib/sequel/extensions/pg_inet.rb +13 -5
  46. data/lib/sequel/extensions/pg_interval.rb +2 -0
  47. data/lib/sequel/extensions/pg_range.rb +2 -0
  48. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  49. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  50. data/lib/sequel/extensions/schema_dumper.rb +10 -4
  51. data/lib/sequel/extensions/server_block.rb +3 -3
  52. data/lib/sequel/model.rb +2 -0
  53. data/lib/sequel/model/associations.rb +30 -18
  54. data/lib/sequel/model/base.rb +64 -55
  55. data/lib/sequel/model/plugins.rb +3 -3
  56. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  57. data/lib/sequel/plugins/association_multi_add_remove.rb +2 -0
  58. data/lib/sequel/plugins/association_pks.rb +57 -16
  59. data/lib/sequel/plugins/association_proxies.rb +2 -0
  60. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  61. data/lib/sequel/plugins/class_table_inheritance.rb +26 -26
  62. data/lib/sequel/plugins/dirty.rb +13 -13
  63. data/lib/sequel/plugins/forbid_lazy_load.rb +214 -0
  64. data/lib/sequel/plugins/json_serializer.rb +3 -7
  65. data/lib/sequel/plugins/rcte_tree.rb +2 -2
  66. data/lib/sequel/plugins/single_table_inheritance.rb +15 -15
  67. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  68. data/lib/sequel/plugins/subclasses.rb +2 -0
  69. data/lib/sequel/timezones.rb +6 -4
  70. data/lib/sequel/version.rb +1 -1
  71. metadata +17 -368
  72. data/Rakefile +0 -151
  73. data/doc/release_notes/4.0.0.txt +0 -262
  74. data/doc/release_notes/4.1.0.txt +0 -85
  75. data/doc/release_notes/4.10.0.txt +0 -226
  76. data/doc/release_notes/4.11.0.txt +0 -147
  77. data/doc/release_notes/4.12.0.txt +0 -105
  78. data/doc/release_notes/4.13.0.txt +0 -169
  79. data/doc/release_notes/4.14.0.txt +0 -68
  80. data/doc/release_notes/4.15.0.txt +0 -56
  81. data/doc/release_notes/4.16.0.txt +0 -36
  82. data/doc/release_notes/4.17.0.txt +0 -38
  83. data/doc/release_notes/4.18.0.txt +0 -36
  84. data/doc/release_notes/4.19.0.txt +0 -45
  85. data/doc/release_notes/4.2.0.txt +0 -129
  86. data/doc/release_notes/4.20.0.txt +0 -79
  87. data/doc/release_notes/4.21.0.txt +0 -94
  88. data/doc/release_notes/4.22.0.txt +0 -72
  89. data/doc/release_notes/4.23.0.txt +0 -65
  90. data/doc/release_notes/4.24.0.txt +0 -99
  91. data/doc/release_notes/4.25.0.txt +0 -181
  92. data/doc/release_notes/4.26.0.txt +0 -44
  93. data/doc/release_notes/4.27.0.txt +0 -78
  94. data/doc/release_notes/4.28.0.txt +0 -57
  95. data/doc/release_notes/4.29.0.txt +0 -41
  96. data/doc/release_notes/4.3.0.txt +0 -40
  97. data/doc/release_notes/4.30.0.txt +0 -37
  98. data/doc/release_notes/4.31.0.txt +0 -57
  99. data/doc/release_notes/4.32.0.txt +0 -132
  100. data/doc/release_notes/4.33.0.txt +0 -88
  101. data/doc/release_notes/4.34.0.txt +0 -86
  102. data/doc/release_notes/4.35.0.txt +0 -130
  103. data/doc/release_notes/4.36.0.txt +0 -116
  104. data/doc/release_notes/4.37.0.txt +0 -50
  105. data/doc/release_notes/4.38.0.txt +0 -67
  106. data/doc/release_notes/4.39.0.txt +0 -127
  107. data/doc/release_notes/4.4.0.txt +0 -92
  108. data/doc/release_notes/4.40.0.txt +0 -179
  109. data/doc/release_notes/4.41.0.txt +0 -77
  110. data/doc/release_notes/4.42.0.txt +0 -221
  111. data/doc/release_notes/4.43.0.txt +0 -87
  112. data/doc/release_notes/4.44.0.txt +0 -125
  113. data/doc/release_notes/4.45.0.txt +0 -370
  114. data/doc/release_notes/4.46.0.txt +0 -404
  115. data/doc/release_notes/4.47.0.txt +0 -56
  116. data/doc/release_notes/4.48.0.txt +0 -293
  117. data/doc/release_notes/4.49.0.txt +0 -222
  118. data/doc/release_notes/4.5.0.txt +0 -34
  119. data/doc/release_notes/4.6.0.txt +0 -30
  120. data/doc/release_notes/4.7.0.txt +0 -103
  121. data/doc/release_notes/4.8.0.txt +0 -175
  122. data/doc/release_notes/4.9.0.txt +0 -190
  123. data/spec/adapter_spec.rb +0 -4
  124. data/spec/adapters/db2_spec.rb +0 -170
  125. data/spec/adapters/mssql_spec.rb +0 -828
  126. data/spec/adapters/mysql_spec.rb +0 -1060
  127. data/spec/adapters/oracle_spec.rb +0 -371
  128. data/spec/adapters/postgres_spec.rb +0 -4476
  129. data/spec/adapters/spec_helper.rb +0 -44
  130. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  131. data/spec/adapters/sqlite_spec.rb +0 -652
  132. data/spec/bin_spec.rb +0 -278
  133. data/spec/core/connection_pool_spec.rb +0 -1250
  134. data/spec/core/database_spec.rb +0 -2915
  135. data/spec/core/dataset_spec.rb +0 -5544
  136. data/spec/core/deprecated_spec.rb +0 -70
  137. data/spec/core/expression_filters_spec.rb +0 -1498
  138. data/spec/core/mock_adapter_spec.rb +0 -722
  139. data/spec/core/object_graph_spec.rb +0 -336
  140. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  141. data/spec/core/schema_generator_spec.rb +0 -214
  142. data/spec/core/schema_spec.rb +0 -1844
  143. data/spec/core/spec_helper.rb +0 -24
  144. data/spec/core/version_spec.rb +0 -14
  145. data/spec/core_extensions_spec.rb +0 -763
  146. data/spec/core_model_spec.rb +0 -2
  147. data/spec/core_spec.rb +0 -1
  148. data/spec/deprecation_helper.rb +0 -30
  149. data/spec/extensions/accessed_columns_spec.rb +0 -51
  150. data/spec/extensions/active_model_spec.rb +0 -99
  151. data/spec/extensions/after_initialize_spec.rb +0 -28
  152. data/spec/extensions/any_not_empty_spec.rb +0 -23
  153. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  154. data/spec/extensions/association_dependencies_spec.rb +0 -125
  155. data/spec/extensions/association_multi_add_remove_spec.rb +0 -1041
  156. data/spec/extensions/association_pks_spec.rb +0 -423
  157. data/spec/extensions/association_proxies_spec.rb +0 -100
  158. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  159. data/spec/extensions/auto_validations_spec.rb +0 -229
  160. data/spec/extensions/blacklist_security_spec.rb +0 -95
  161. data/spec/extensions/blank_spec.rb +0 -69
  162. data/spec/extensions/boolean_readers_spec.rb +0 -93
  163. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  164. data/spec/extensions/caching_spec.rb +0 -273
  165. data/spec/extensions/caller_logging_spec.rb +0 -52
  166. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  167. data/spec/extensions/column_conflicts_spec.rb +0 -75
  168. data/spec/extensions/column_select_spec.rb +0 -129
  169. data/spec/extensions/columns_introspection_spec.rb +0 -90
  170. data/spec/extensions/columns_updated_spec.rb +0 -35
  171. data/spec/extensions/composition_spec.rb +0 -248
  172. data/spec/extensions/connection_expiration_spec.rb +0 -151
  173. data/spec/extensions/connection_validator_spec.rb +0 -144
  174. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  175. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  176. data/spec/extensions/constraint_validations_spec.rb +0 -439
  177. data/spec/extensions/core_refinements_spec.rb +0 -528
  178. data/spec/extensions/csv_serializer_spec.rb +0 -183
  179. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  180. data/spec/extensions/dataset_associations_spec.rb +0 -365
  181. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  182. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  183. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  184. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  185. data/spec/extensions/defaults_setter_spec.rb +0 -150
  186. data/spec/extensions/delay_add_association_spec.rb +0 -73
  187. data/spec/extensions/dirty_spec.rb +0 -222
  188. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  189. data/spec/extensions/eager_each_spec.rb +0 -62
  190. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  191. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  192. data/spec/extensions/empty_failure_backtraces_spec.rb +0 -60
  193. data/spec/extensions/error_splitter_spec.rb +0 -18
  194. data/spec/extensions/error_sql_spec.rb +0 -20
  195. data/spec/extensions/escaped_like_spec.rb +0 -40
  196. data/spec/extensions/eval_inspect_spec.rb +0 -81
  197. data/spec/extensions/exclude_or_null_spec.rb +0 -15
  198. data/spec/extensions/finder_spec.rb +0 -260
  199. data/spec/extensions/force_encoding_spec.rb +0 -126
  200. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  201. data/spec/extensions/graph_each_spec.rb +0 -113
  202. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  203. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  204. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  205. data/spec/extensions/index_caching_spec.rb +0 -66
  206. data/spec/extensions/inflector_spec.rb +0 -183
  207. data/spec/extensions/input_transformer_spec.rb +0 -69
  208. data/spec/extensions/insert_conflict_spec.rb +0 -103
  209. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  210. data/spec/extensions/instance_filters_spec.rb +0 -79
  211. data/spec/extensions/instance_hooks_spec.rb +0 -246
  212. data/spec/extensions/integer64_spec.rb +0 -22
  213. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  214. data/spec/extensions/json_serializer_spec.rb +0 -346
  215. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  216. data/spec/extensions/list_spec.rb +0 -291
  217. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  218. data/spec/extensions/many_through_many_spec.rb +0 -2177
  219. data/spec/extensions/migration_spec.rb +0 -864
  220. data/spec/extensions/modification_detection_spec.rb +0 -93
  221. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  222. data/spec/extensions/named_timezones_spec.rb +0 -218
  223. data/spec/extensions/nested_attributes_spec.rb +0 -815
  224. data/spec/extensions/null_dataset_spec.rb +0 -85
  225. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  226. data/spec/extensions/pagination_spec.rb +0 -116
  227. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  228. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  229. data/spec/extensions/pg_array_spec.rb +0 -398
  230. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -209
  231. data/spec/extensions/pg_enum_spec.rb +0 -118
  232. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  233. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  234. data/spec/extensions/pg_hstore_spec.rb +0 -219
  235. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  236. data/spec/extensions/pg_inet_spec.rb +0 -72
  237. data/spec/extensions/pg_interval_spec.rb +0 -103
  238. data/spec/extensions/pg_json_ops_spec.rb +0 -356
  239. data/spec/extensions/pg_json_spec.rb +0 -451
  240. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  241. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  242. data/spec/extensions/pg_range_spec.rb +0 -600
  243. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  244. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  245. data/spec/extensions/pg_row_spec.rb +0 -363
  246. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  247. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  248. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  249. data/spec/extensions/prepared_statements_spec.rb +0 -177
  250. data/spec/extensions/pretty_table_spec.rb +0 -123
  251. data/spec/extensions/query_spec.rb +0 -94
  252. data/spec/extensions/rcte_tree_spec.rb +0 -387
  253. data/spec/extensions/round_timestamps_spec.rb +0 -39
  254. data/spec/extensions/s_spec.rb +0 -60
  255. data/spec/extensions/schema_caching_spec.rb +0 -64
  256. data/spec/extensions/schema_dumper_spec.rb +0 -870
  257. data/spec/extensions/select_remove_spec.rb +0 -38
  258. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  259. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  260. data/spec/extensions/serialization_spec.rb +0 -365
  261. data/spec/extensions/server_block_spec.rb +0 -135
  262. data/spec/extensions/server_logging_spec.rb +0 -45
  263. data/spec/extensions/sharding_spec.rb +0 -197
  264. data/spec/extensions/shared_caching_spec.rb +0 -151
  265. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  266. data/spec/extensions/singular_table_names_spec.rb +0 -22
  267. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  268. data/spec/extensions/spec_helper.rb +0 -70
  269. data/spec/extensions/split_array_nil_spec.rb +0 -24
  270. data/spec/extensions/split_values_spec.rb +0 -57
  271. data/spec/extensions/sql_comments_spec.rb +0 -33
  272. data/spec/extensions/sql_expr_spec.rb +0 -59
  273. data/spec/extensions/static_cache_cache_spec.rb +0 -35
  274. data/spec/extensions/static_cache_spec.rb +0 -471
  275. data/spec/extensions/string_agg_spec.rb +0 -90
  276. data/spec/extensions/string_date_time_spec.rb +0 -95
  277. data/spec/extensions/string_stripper_spec.rb +0 -68
  278. data/spec/extensions/subclasses_spec.rb +0 -79
  279. data/spec/extensions/subset_conditions_spec.rb +0 -38
  280. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  281. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  282. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  283. data/spec/extensions/table_select_spec.rb +0 -83
  284. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  285. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  286. data/spec/extensions/throw_failures_spec.rb +0 -74
  287. data/spec/extensions/timestamps_spec.rb +0 -209
  288. data/spec/extensions/to_dot_spec.rb +0 -153
  289. data/spec/extensions/touch_spec.rb +0 -226
  290. data/spec/extensions/tree_spec.rb +0 -334
  291. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  292. data/spec/extensions/unlimited_update_spec.rb +0 -21
  293. data/spec/extensions/update_or_create_spec.rb +0 -83
  294. data/spec/extensions/update_primary_key_spec.rb +0 -105
  295. data/spec/extensions/update_refresh_spec.rb +0 -59
  296. data/spec/extensions/uuid_spec.rb +0 -101
  297. data/spec/extensions/validate_associated_spec.rb +0 -52
  298. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  299. data/spec/extensions/validation_contexts_spec.rb +0 -31
  300. data/spec/extensions/validation_helpers_spec.rb +0 -525
  301. data/spec/extensions/whitelist_security_spec.rb +0 -157
  302. data/spec/extensions/xml_serializer_spec.rb +0 -213
  303. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  304. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  305. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  306. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  307. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  308. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  309. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  310. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  311. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  312. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  313. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  314. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  315. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  316. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  317. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  318. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  319. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  320. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  321. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  322. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  323. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  324. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  325. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  326. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  327. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  328. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  329. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  330. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  331. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  332. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  333. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  334. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  335. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  336. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  337. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  338. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  339. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  340. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  341. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  342. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  343. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  344. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  345. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  346. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  347. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  348. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  349. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  350. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  351. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  352. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  353. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  354. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  355. data/spec/guards_helper.rb +0 -59
  356. data/spec/integration/associations_test.rb +0 -2597
  357. data/spec/integration/database_test.rb +0 -113
  358. data/spec/integration/dataset_test.rb +0 -2037
  359. data/spec/integration/eager_loader_test.rb +0 -687
  360. data/spec/integration/migrator_test.rb +0 -262
  361. data/spec/integration/model_test.rb +0 -203
  362. data/spec/integration/plugin_test.rb +0 -2423
  363. data/spec/integration/prepared_statement_test.rb +0 -405
  364. data/spec/integration/schema_test.rb +0 -903
  365. data/spec/integration/spec_helper.rb +0 -71
  366. data/spec/integration/timezone_test.rb +0 -86
  367. data/spec/integration/transaction_test.rb +0 -603
  368. data/spec/integration/type_test.rb +0 -127
  369. data/spec/model/association_reflection_spec.rb +0 -803
  370. data/spec/model/associations_spec.rb +0 -4738
  371. data/spec/model/base_spec.rb +0 -875
  372. data/spec/model/class_dataset_methods_spec.rb +0 -146
  373. data/spec/model/dataset_methods_spec.rb +0 -198
  374. data/spec/model/eager_loading_spec.rb +0 -2377
  375. data/spec/model/hooks_spec.rb +0 -370
  376. data/spec/model/inflector_spec.rb +0 -26
  377. data/spec/model/model_spec.rb +0 -956
  378. data/spec/model/plugins_spec.rb +0 -429
  379. data/spec/model/record_spec.rb +0 -2118
  380. data/spec/model/spec_helper.rb +0 -46
  381. data/spec/model/validations_spec.rb +0 -220
  382. data/spec/model_no_assoc_spec.rb +0 -1
  383. data/spec/model_spec.rb +0 -1
  384. data/spec/plugin_spec.rb +0 -1
  385. data/spec/sequel_coverage.rb +0 -15
  386. data/spec/sequel_warning.rb +0 -5
  387. data/spec/spec_config.rb +0 -12
@@ -1,1060 +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
- end
555
-
556
- describe "MySQL foreign key support" do
557
- after do
558
- DB.drop_table?(:testfk, :testpk)
559
- end
560
-
561
- it "should create table without :key" do
562
- DB.create_table!(:testpk){primary_key :id}
563
- DB.create_table!(:testfk){foreign_key :fk, :testpk}
564
- end
565
-
566
- it "should create table with composite keys without :key" do
567
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
568
- DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
569
- end
570
-
571
- it "should create table with self referential without :key" do
572
- DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
573
- end
574
-
575
- it "should create table with self referential with non-autoincrementing key without :key" do
576
- DB.create_table!(:testfk){Integer :id, :primary_key=>true; foreign_key :fk, :testfk}
577
- end
578
-
579
- it "should create table with self referential with composite keys without :key" do
580
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
581
- end
582
-
583
- it "should alter table without :key" do
584
- DB.create_table!(:testpk){primary_key :id}
585
- DB.create_table!(:testfk){Integer :id}
586
- DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
587
- end
588
-
589
- it "should alter table with composite keys without :key" do
590
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
591
- DB.create_table!(:testfk){Integer :fk; Integer :fk2}
592
- DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
593
- end
594
-
595
- it "should alter table with self referential without :key" do
596
- DB.create_table!(:testfk){primary_key :id}
597
- DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
598
- end
599
-
600
- it "should alter table with self referential with composite keys without :key" do
601
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
602
- DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
603
- end
604
- end
605
-
606
- describe "A grouped MySQL dataset" do
607
- before do
608
- DB.create_table! :test2 do
609
- text :name
610
- integer :value
611
- end
612
- DB[:test2].insert(:name => '11', :value => 10)
613
- DB[:test2].insert(:name => '11', :value => 20)
614
- DB[:test2].insert(:name => '11', :value => 30)
615
- DB[:test2].insert(:name => '12', :value => 10)
616
- DB[:test2].insert(:name => '12', :value => 20)
617
- DB[:test2].insert(:name => '13', :value => 10)
618
- end
619
- after do
620
- DB.drop_table?(:test2)
621
- end
622
-
623
- it "should return the correct count for raw sql query" do
624
- ds = DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
625
- ds.count.must_equal 1
626
- end
627
-
628
- it "should return the correct count for a normal dataset" do
629
- ds = DB[:test2].select(:name).where(:name => '11').group(:name)
630
- ds.count.must_equal 1
631
- end
632
- end
633
-
634
- describe "A MySQL database" do
635
- before do
636
- @db = DB
637
- @db.drop_table?(:posts)
638
- end
639
- after do
640
- @db.drop_table?(:posts)
641
- end
642
-
643
- it "should support fulltext indexes and full_text_search" do
644
- @db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
645
-
646
- @db[:posts].insert(:title=>'ruby rails', :body=>'y')
647
- @db[:posts].insert(:title=>'sequel', :body=>'ruby')
648
- @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
649
-
650
- @db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
651
- @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
652
- @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.must_equal [{:title=>'ruby scooby', :body=>'x'}]
653
-
654
- @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
655
- @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
656
- end
657
-
658
- it "should support spatial indexes" do
659
- @db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
660
- end
661
-
662
- it "should support indexes with index type" do
663
- @db.create_table(:posts){Integer :id; index :id, :type => :btree}
664
- @db[:posts].insert(1)
665
- @db[:posts].where(:id=>1).count.must_equal 1
666
- end
667
-
668
- it "should support unique indexes with index type" do
669
- @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
670
- @db[:posts].insert(1)
671
- proc{@db[:posts].insert(1)}.must_raise Sequel::UniqueConstraintViolation
672
- end
673
-
674
- it "should not dump partial indexes" do
675
- @db.create_table(:posts){text :id}
676
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
677
- @db.indexes(:posts).must_equal({})
678
- end
679
-
680
- it "should dump partial indexes if :partial option is set to true" do
681
- @db.create_table(:posts){text :id}
682
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
683
- @db.indexes(:posts, :partial => true).must_equal(:posts_id_index => {:columns => [:id], :unique => false})
684
- end
685
- end
686
-
687
- describe "MySQL::Dataset#insert and related methods" do
688
- before do
689
- DB.create_table(:items){String :name, :unique=>true; Integer :value}
690
- @d = DB[:items].order(:name)
691
- end
692
- after do
693
- DB.drop_table?(:items)
694
- end
695
-
696
- it "#insert should insert record with default values when no arguments given" do
697
- @d.insert
698
- @d.all.must_equal [{:name => nil, :value => nil}]
699
- end
700
-
701
- it "#insert should insert record with default values when empty hash 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 array given" do
707
- @d.insert []
708
- @d.all.must_equal [{:name => nil, :value => nil}]
709
- end
710
-
711
- it "#on_duplicate_key_update should work with regular inserts" do
712
- DB.add_index :items, :name, :unique=>true
713
- @d.insert(:name => 'abc', :value => 1)
714
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'abc', :value => 1)
715
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
716
- @d.all.must_equal [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
717
- end
718
-
719
- it "#multi_replace should replace multiple records in a single statement" do
720
- @d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
721
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
722
- @d.multi_replace([{:name => 'abc', :value=>1}, {:name => 'ghi', :value=>3}])
723
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => nil}, {:name => 'ghi', :value=>3} ]
724
- end
725
-
726
- it "#multi_replace should support :commit_every option" do
727
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :commit_every => 2)
728
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
729
- end
730
-
731
- it "#multi_replace should support :slice option" do
732
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :slice => 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_insert should insert multiple records in a single statement" do
737
- @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
738
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
739
- end
740
-
741
- it "#multi_insert should support :commit_every option" do
742
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :commit_every => 2)
743
- @d.all.must_equal [ {:name => nil, :value => 1}, {:name => nil, :value => 2}, {:name => nil, :value => 3}, {:name => nil, :value => 4} ]
744
- end
745
-
746
- it "#multi_insert should support :slice option" do
747
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}], :slice => 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 "#import should support inserting using columns and values arrays" do
752
- @d.import([:name, :value], [['abc', 1], ['def', 2]])
753
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
754
- end
755
-
756
- it "#insert_ignore should ignore existing records when used with multi_insert" do
757
- @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
758
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil} ]
759
- @d.insert_ignore.multi_insert([{:name => 'abc', :value=>1}, {:name => 'ghi', :value=>3}])
760
- @d.all.must_equal [ {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}, {:name => 'ghi', :value=>3} ]
761
- end
762
-
763
- it "#insert_ignore should ignore single records when used with insert" do
764
- @d.insert_ignore.insert(:name => 'ghi')
765
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
766
- @d.insert_ignore.insert(:name => 'ghi', :value=>2)
767
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
768
- end
769
-
770
- it "#on_duplicate_key_update should handle inserts with duplicate keys" do
771
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
772
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
773
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 2], ['ghi',3]])
774
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
775
- end
776
-
777
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
778
- @d.on_duplicate_key_update(:value).import([:name,:value], [['abc', 1], ['def',2]])
779
- @d.all.must_equal [ {:name => 'abc', :value => 1}, {:name => 'def', :value => 2} ]
780
- @d.on_duplicate_key_update(:value).import([:name,:value], [['abc', 2], ['ghi',3]])
781
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
782
- @d.on_duplicate_key_update(:name).import([:name,:value], [['abc', 5], ['ghi',6]])
783
- @d.all.must_equal [ {:name => 'abc', :value => 2}, {:name => 'def', :value => 2}, {:name => 'ghi', :value=>3} ]
784
- end
785
- end
786
-
787
- describe "MySQL::Dataset#update and related methods" do
788
- before do
789
- DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
790
- @d = DB[:items]
791
- end
792
- after do
793
- DB.drop_table?(:items)
794
- end
795
-
796
- it "#update_ignore should not raise error where normal update would fail" do
797
- @d.insert(:name => 'cow', :value => 0)
798
- @d.insert(:name => 'cat', :value => 1)
799
- proc{@d.where(:value => 1).update(:name => 'cow')}.must_raise(Sequel::UniqueConstraintViolation)
800
- @d.update_ignore.where(:value => 1).update(:name => 'cow')
801
- @d.order(:name).all.must_equal [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
802
- end
803
- end
804
-
805
- describe "MySQL::Dataset#replace" do
806
- before do
807
- DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
808
- @d = DB[:items]
809
- end
810
- after do
811
- DB.drop_table?(:items)
812
- end
813
-
814
- it "should use default values if they exist" do
815
- DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
816
- @d.replace
817
- @d.all.must_equal [{:id=>1, :value=>2}]
818
- @d.replace([])
819
- @d.all.must_equal [{:id=>1, :value=>2}]
820
- @d.replace({})
821
- @d.all.must_equal [{:id=>1, :value=>2}]
822
- end
823
- end
824
-
825
- describe "MySQL::Dataset#complex_expression_sql" do
826
- before do
827
- @d = DB.dataset
828
- end
829
-
830
- it "should handle string concatenation with CONCAT if more than one record" do
831
- @d.literal(Sequel.join([:x, :y])).must_equal "CONCAT(`x`, `y`)"
832
- @d.literal(Sequel.join([:x, :y], ' ')).must_equal "CONCAT(`x`, ' ', `y`)"
833
- @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)"
834
- end
835
-
836
- it "should handle string concatenation as simple string if just one record" do
837
- @d.literal(Sequel.join([:x])).must_equal "`x`"
838
- @d.literal(Sequel.join([:x], ' ')).must_equal "`x`"
839
- end
840
- end
841
-
842
- describe "MySQL::Dataset#calc_found_rows" do
843
- before do
844
- DB.create_table!(:items){Integer :a}
845
- end
846
- after do
847
- DB.drop_table?(:items)
848
- end
849
-
850
- it "should count matching rows disregarding LIMIT clause" do
851
- DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
852
-
853
- DB.synchronize do
854
- DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.must_equal [{:a => 1}]
855
- DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.must_equal [{:rows => 2 }]
856
- end
857
- end
858
- end
859
-
860
- if DB.adapter_scheme == :mysql or DB.adapter_scheme == :jdbc or DB.adapter_scheme == :mysql2
861
- describe "MySQL Stored Procedures" do
862
- before do
863
- DB.create_table(:items){Integer :id; Integer :value}
864
- @d = DB[:items]
865
- end
866
- after do
867
- DB.drop_table?(:items)
868
- DB.execute('DROP PROCEDURE test_sproc')
869
- end
870
-
871
- it "should be callable on the database object" do
872
- DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
873
- DB[:items].delete
874
- DB[:items].insert(:value=>1)
875
- DB[:items].count.must_equal 1
876
- DB.call_sproc(:test_sproc)
877
- DB[:items].count.must_equal 0
878
- end
879
-
880
- # Mysql2 doesn't support stored procedures that return result sets, probably because
881
- # CLIENT_MULTI_RESULTS is not set.
882
- unless DB.adapter_scheme == :mysql2
883
- it "should be callable on the dataset object" do
884
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
885
- DB[:items].delete
886
- @d = DB[:items]
887
- @d.call_sproc(:select, :test_sproc, 3).must_equal []
888
- @d.insert(:value=>1)
889
- @d.call_sproc(:select, :test_sproc, 4).must_equal [{:id=>nil, :value=>1, :b=>4}]
890
- @d = @d.with_row_proc(proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r})
891
- @d.call_sproc(:select, :test_sproc, 3).must_equal [{:id=>nil, :value=>2, :b=>6}]
892
- end
893
-
894
- it "should be callable on the dataset object with multiple arguments" do
895
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
896
- DB[:items].delete
897
- @d = DB[:items]
898
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal []
899
- @d.insert(:value=>1)
900
- @d.call_sproc(:select, :test_sproc, 4, 5).must_equal [{:id=>nil, :value=>1, :b=>4, :d=>5}]
901
- @d = @d.with_row_proc(proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r})
902
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal [{:id=>nil, :value=>2, :b=>6, :d => 8}]
903
- end
904
- end
905
-
906
- it "should deal with nil values" do
907
- DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
908
- DB[:items].delete
909
- DB.call_sproc(:test_sproc, :args=>[1, nil])
910
- DB[:items].all.must_equal [{:id=>1, :value=>nil}]
911
- end
912
- end
913
- end
914
-
915
- if DB.adapter_scheme == :mysql
916
- describe "MySQL bad date/time conversions" do
917
- after do
918
- DB.convert_invalid_date_time = false
919
- end
920
-
921
- it "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
922
- DB.convert_invalid_date_time = false
923
- proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.must_raise(Sequel::InvalidValue)
924
- proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.must_raise(Sequel::InvalidValue)
925
- proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.must_raise(Sequel::InvalidValue)
926
- end
927
-
928
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
929
- DB.convert_invalid_date_time = nil
930
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_be_nil
931
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_be_nil
932
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_be_nil
933
- DB.convert_invalid_date_time = :nil
934
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_be_nil
935
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_be_nil
936
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_be_nil
937
- end
938
-
939
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
940
- DB.convert_invalid_date_time = :string
941
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal '0000-00-00'
942
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal '0000-00-00 00:00:00'
943
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal '25:00:00'
944
- end
945
- end
946
-
947
- describe "MySQL multiple result sets" do
948
- before do
949
- DB.create_table!(:a){Integer :a}
950
- DB.create_table!(:b){Integer :b}
951
- @ds = DB['SELECT * FROM a; SELECT * FROM b']
952
- DB[:a].insert(10)
953
- DB[:a].insert(15)
954
- DB[:b].insert(20)
955
- DB[:b].insert(25)
956
- end
957
- after do
958
- DB.drop_table?(:a, :b)
959
- end
960
-
961
- it "should combine all results by default" do
962
- @ds.all.must_equal [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
963
- end
964
-
965
- it "should work with Database#run" do
966
- DB.run('SELECT * FROM a; SELECT * FROM b')
967
- DB.run('SELECT * FROM a; SELECT * FROM b')
968
- end
969
-
970
- it "should work with Database#run and other statements" do
971
- DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')
972
- DB[:a].select_order_map(:a).must_equal [1, 1]
973
- DB[:b].all.must_equal []
974
- end
975
-
976
- it "should split results returned into arrays if split_multiple_result_sets is used" do
977
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
978
- end
979
-
980
- it "should have regular row_procs work when splitting multiple result sets" do
981
- @ds = @ds.with_row_proc(proc{|x| x[x.keys.first] *= 2; x})
982
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
983
- end
984
-
985
- it "should use the columns from the first result set when splitting result sets" do
986
- @ds.split_multiple_result_sets.columns.must_equal [:a]
987
- end
988
-
989
- it "should not allow graphing a dataset that splits multiple statements" do
990
- proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.must_raise(Sequel::Error)
991
- end
992
-
993
- it "should not allow splitting a graphed dataset" do
994
- proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.must_raise(Sequel::Error)
995
- end
996
- end
997
- end
998
-
999
- if DB.adapter_scheme == :mysql2
1000
- describe "Mysql2 streaming" do
1001
- before(:all) do
1002
- DB.create_table!(:a){Integer :a}
1003
- DB.transaction do
1004
- 1000.times do |i|
1005
- DB[:a].insert(i)
1006
- end
1007
- end
1008
- @ds = DB[:a].stream.order(:a)
1009
- end
1010
- after(:all) do
1011
- DB.drop_table?(:a)
1012
- end
1013
-
1014
- it "should correctly stream results" do
1015
- @ds.map(:a).must_equal((0...1000).to_a)
1016
- end
1017
-
1018
- it "should correctly handle early returning when streaming results" do
1019
- 3.times{@ds.each{|r| break r[:a]}.must_equal 0}
1020
- end
1021
-
1022
- it "#paged_each should bypass streaming when :stream => false passed in" do
1023
- DB[:a].order(:a).paged_each(:stream => false){|x| DB[:a].first; break}
1024
- end
1025
- end
1026
- end
1027
-
1028
- describe "MySQL joined datasets" do
1029
- before do
1030
- @db = DB
1031
- @db.create_table!(:a) do
1032
- Integer :id
1033
- end
1034
- @db.create_table!(:b) do
1035
- Integer :id
1036
- Integer :a_id
1037
- end
1038
- @db[:a].insert(1)
1039
- @db[:a].insert(2)
1040
- @db[:b].insert(3, 1)
1041
- @db[:b].insert(4, 1)
1042
- @db[:b].insert(5, 2)
1043
- @ds = @db[:a].join(:b, :a_id=>:id)
1044
- end
1045
- after do
1046
- @db.drop_table?(:a, :b)
1047
- end
1048
-
1049
- it "should support deletions from a single table" do
1050
- @ds.where(Sequel[:a][:id]=>1).delete
1051
- @db[:a].select_order_map(:id).must_equal [2]
1052
- @db[:b].select_order_map(:id).must_equal [3, 4, 5]
1053
- end
1054
-
1055
- it "should support deletions from multiple tables" do
1056
- @ds.delete_from(:a, :b).where(Sequel[:a][:id]=>1).delete
1057
- @db[:a].select_order_map(:id).must_equal [2]
1058
- @db[:b].select_order_map(:id).must_equal [5]
1059
- end
1060
- end