sequel 5.28.0 → 5.33.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 (380) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +64 -1922
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/doc/advanced_associations.rdoc +4 -4
  6. data/doc/association_basics.rdoc +3 -3
  7. data/doc/code_order.rdoc +12 -2
  8. data/doc/model_dataset_method_design.rdoc +1 -1
  9. data/doc/postgresql.rdoc +71 -0
  10. data/doc/release_notes/5.29.0.txt +22 -0
  11. data/doc/release_notes/5.30.0.txt +20 -0
  12. data/doc/release_notes/5.31.0.txt +148 -0
  13. data/doc/release_notes/5.32.0.txt +46 -0
  14. data/doc/release_notes/5.33.0.txt +24 -0
  15. data/doc/testing.rdoc +1 -1
  16. data/lib/sequel/adapters/postgres.rb +5 -1
  17. data/lib/sequel/adapters/shared/access.rb +6 -6
  18. data/lib/sequel/adapters/shared/mssql.rb +5 -5
  19. data/lib/sequel/adapters/shared/mysql.rb +10 -10
  20. data/lib/sequel/adapters/shared/oracle.rb +16 -16
  21. data/lib/sequel/adapters/shared/postgres.rb +169 -14
  22. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  23. data/lib/sequel/adapters/shared/sqlite.rb +32 -5
  24. data/lib/sequel/adapters/tinytds.rb +1 -1
  25. data/lib/sequel/connection_pool/sharded_threaded.rb +2 -2
  26. data/lib/sequel/connection_pool/threaded.rb +1 -1
  27. data/lib/sequel/core.rb +318 -314
  28. data/lib/sequel/database/query.rb +1 -1
  29. data/lib/sequel/database/schema_generator.rb +1 -1
  30. data/lib/sequel/database/transactions.rb +8 -12
  31. data/lib/sequel/dataset/misc.rb +2 -2
  32. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  33. data/lib/sequel/extensions/connection_validator.rb +2 -2
  34. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  35. data/lib/sequel/extensions/index_caching.rb +9 -7
  36. data/lib/sequel/extensions/integer64.rb +2 -0
  37. data/lib/sequel/extensions/migration.rb +1 -1
  38. data/lib/sequel/extensions/pg_enum.rb +5 -2
  39. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  40. data/lib/sequel/extensions/pg_inet.rb +13 -5
  41. data/lib/sequel/extensions/pg_interval.rb +2 -0
  42. data/lib/sequel/extensions/pg_range.rb +2 -0
  43. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  44. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  45. data/lib/sequel/extensions/schema_dumper.rb +10 -4
  46. data/lib/sequel/extensions/server_block.rb +3 -3
  47. data/lib/sequel/model/associations.rb +18 -5
  48. data/lib/sequel/model/base.rb +60 -53
  49. data/lib/sequel/model/plugins.rb +1 -0
  50. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  51. data/lib/sequel/plugins/association_multi_add_remove.rb +2 -0
  52. data/lib/sequel/plugins/association_proxies.rb +2 -0
  53. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  54. data/lib/sequel/plugins/class_table_inheritance.rb +26 -26
  55. data/lib/sequel/plugins/dirty.rb +13 -13
  56. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  57. data/lib/sequel/plugins/forbid_lazy_load.rb +214 -0
  58. data/lib/sequel/plugins/json_serializer.rb +18 -11
  59. data/lib/sequel/plugins/single_table_inheritance.rb +15 -15
  60. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  61. data/lib/sequel/plugins/subclasses.rb +2 -0
  62. data/lib/sequel/plugins/throw_failures.rb +1 -1
  63. data/lib/sequel/timezones.rb +6 -4
  64. data/lib/sequel/version.rb +1 -1
  65. metadata +18 -367
  66. data/Rakefile +0 -151
  67. data/doc/release_notes/4.0.0.txt +0 -262
  68. data/doc/release_notes/4.1.0.txt +0 -85
  69. data/doc/release_notes/4.10.0.txt +0 -226
  70. data/doc/release_notes/4.11.0.txt +0 -147
  71. data/doc/release_notes/4.12.0.txt +0 -105
  72. data/doc/release_notes/4.13.0.txt +0 -169
  73. data/doc/release_notes/4.14.0.txt +0 -68
  74. data/doc/release_notes/4.15.0.txt +0 -56
  75. data/doc/release_notes/4.16.0.txt +0 -36
  76. data/doc/release_notes/4.17.0.txt +0 -38
  77. data/doc/release_notes/4.18.0.txt +0 -36
  78. data/doc/release_notes/4.19.0.txt +0 -45
  79. data/doc/release_notes/4.2.0.txt +0 -129
  80. data/doc/release_notes/4.20.0.txt +0 -79
  81. data/doc/release_notes/4.21.0.txt +0 -94
  82. data/doc/release_notes/4.22.0.txt +0 -72
  83. data/doc/release_notes/4.23.0.txt +0 -65
  84. data/doc/release_notes/4.24.0.txt +0 -99
  85. data/doc/release_notes/4.25.0.txt +0 -181
  86. data/doc/release_notes/4.26.0.txt +0 -44
  87. data/doc/release_notes/4.27.0.txt +0 -78
  88. data/doc/release_notes/4.28.0.txt +0 -57
  89. data/doc/release_notes/4.29.0.txt +0 -41
  90. data/doc/release_notes/4.3.0.txt +0 -40
  91. data/doc/release_notes/4.30.0.txt +0 -37
  92. data/doc/release_notes/4.31.0.txt +0 -57
  93. data/doc/release_notes/4.32.0.txt +0 -132
  94. data/doc/release_notes/4.33.0.txt +0 -88
  95. data/doc/release_notes/4.34.0.txt +0 -86
  96. data/doc/release_notes/4.35.0.txt +0 -130
  97. data/doc/release_notes/4.36.0.txt +0 -116
  98. data/doc/release_notes/4.37.0.txt +0 -50
  99. data/doc/release_notes/4.38.0.txt +0 -67
  100. data/doc/release_notes/4.39.0.txt +0 -127
  101. data/doc/release_notes/4.4.0.txt +0 -92
  102. data/doc/release_notes/4.40.0.txt +0 -179
  103. data/doc/release_notes/4.41.0.txt +0 -77
  104. data/doc/release_notes/4.42.0.txt +0 -221
  105. data/doc/release_notes/4.43.0.txt +0 -87
  106. data/doc/release_notes/4.44.0.txt +0 -125
  107. data/doc/release_notes/4.45.0.txt +0 -370
  108. data/doc/release_notes/4.46.0.txt +0 -404
  109. data/doc/release_notes/4.47.0.txt +0 -56
  110. data/doc/release_notes/4.48.0.txt +0 -293
  111. data/doc/release_notes/4.49.0.txt +0 -222
  112. data/doc/release_notes/4.5.0.txt +0 -34
  113. data/doc/release_notes/4.6.0.txt +0 -30
  114. data/doc/release_notes/4.7.0.txt +0 -103
  115. data/doc/release_notes/4.8.0.txt +0 -175
  116. data/doc/release_notes/4.9.0.txt +0 -190
  117. data/spec/adapter_spec.rb +0 -4
  118. data/spec/adapters/db2_spec.rb +0 -170
  119. data/spec/adapters/mssql_spec.rb +0 -828
  120. data/spec/adapters/mysql_spec.rb +0 -1060
  121. data/spec/adapters/oracle_spec.rb +0 -371
  122. data/spec/adapters/postgres_spec.rb +0 -4476
  123. data/spec/adapters/spec_helper.rb +0 -44
  124. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  125. data/spec/adapters/sqlite_spec.rb +0 -652
  126. data/spec/bin_spec.rb +0 -278
  127. data/spec/core/connection_pool_spec.rb +0 -1250
  128. data/spec/core/database_spec.rb +0 -2915
  129. data/spec/core/dataset_spec.rb +0 -5547
  130. data/spec/core/deprecated_spec.rb +0 -70
  131. data/spec/core/expression_filters_spec.rb +0 -1498
  132. data/spec/core/mock_adapter_spec.rb +0 -722
  133. data/spec/core/object_graph_spec.rb +0 -336
  134. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  135. data/spec/core/schema_generator_spec.rb +0 -214
  136. data/spec/core/schema_spec.rb +0 -1844
  137. data/spec/core/spec_helper.rb +0 -24
  138. data/spec/core/version_spec.rb +0 -14
  139. data/spec/core_extensions_spec.rb +0 -763
  140. data/spec/core_model_spec.rb +0 -2
  141. data/spec/core_spec.rb +0 -1
  142. data/spec/deprecation_helper.rb +0 -30
  143. data/spec/extensions/accessed_columns_spec.rb +0 -51
  144. data/spec/extensions/active_model_spec.rb +0 -99
  145. data/spec/extensions/after_initialize_spec.rb +0 -28
  146. data/spec/extensions/any_not_empty_spec.rb +0 -23
  147. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  148. data/spec/extensions/association_dependencies_spec.rb +0 -125
  149. data/spec/extensions/association_multi_add_remove_spec.rb +0 -1041
  150. data/spec/extensions/association_pks_spec.rb +0 -423
  151. data/spec/extensions/association_proxies_spec.rb +0 -100
  152. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  153. data/spec/extensions/auto_validations_spec.rb +0 -229
  154. data/spec/extensions/blacklist_security_spec.rb +0 -95
  155. data/spec/extensions/blank_spec.rb +0 -69
  156. data/spec/extensions/boolean_readers_spec.rb +0 -93
  157. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  158. data/spec/extensions/caching_spec.rb +0 -273
  159. data/spec/extensions/caller_logging_spec.rb +0 -52
  160. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  161. data/spec/extensions/column_conflicts_spec.rb +0 -75
  162. data/spec/extensions/column_select_spec.rb +0 -129
  163. data/spec/extensions/columns_introspection_spec.rb +0 -90
  164. data/spec/extensions/columns_updated_spec.rb +0 -35
  165. data/spec/extensions/composition_spec.rb +0 -248
  166. data/spec/extensions/connection_expiration_spec.rb +0 -151
  167. data/spec/extensions/connection_validator_spec.rb +0 -144
  168. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  169. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  170. data/spec/extensions/constraint_validations_spec.rb +0 -439
  171. data/spec/extensions/core_refinements_spec.rb +0 -528
  172. data/spec/extensions/csv_serializer_spec.rb +0 -183
  173. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  174. data/spec/extensions/dataset_associations_spec.rb +0 -365
  175. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  176. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  177. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  178. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  179. data/spec/extensions/defaults_setter_spec.rb +0 -150
  180. data/spec/extensions/delay_add_association_spec.rb +0 -73
  181. data/spec/extensions/dirty_spec.rb +0 -222
  182. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  183. data/spec/extensions/eager_each_spec.rb +0 -62
  184. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  185. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  186. data/spec/extensions/error_splitter_spec.rb +0 -18
  187. data/spec/extensions/error_sql_spec.rb +0 -20
  188. data/spec/extensions/escaped_like_spec.rb +0 -40
  189. data/spec/extensions/eval_inspect_spec.rb +0 -81
  190. data/spec/extensions/exclude_or_null_spec.rb +0 -15
  191. data/spec/extensions/finder_spec.rb +0 -260
  192. data/spec/extensions/force_encoding_spec.rb +0 -126
  193. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  194. data/spec/extensions/graph_each_spec.rb +0 -113
  195. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  196. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  197. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  198. data/spec/extensions/index_caching_spec.rb +0 -66
  199. data/spec/extensions/inflector_spec.rb +0 -183
  200. data/spec/extensions/input_transformer_spec.rb +0 -69
  201. data/spec/extensions/insert_conflict_spec.rb +0 -103
  202. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  203. data/spec/extensions/instance_filters_spec.rb +0 -79
  204. data/spec/extensions/instance_hooks_spec.rb +0 -246
  205. data/spec/extensions/integer64_spec.rb +0 -22
  206. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  207. data/spec/extensions/json_serializer_spec.rb +0 -336
  208. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  209. data/spec/extensions/list_spec.rb +0 -291
  210. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  211. data/spec/extensions/many_through_many_spec.rb +0 -2177
  212. data/spec/extensions/migration_spec.rb +0 -864
  213. data/spec/extensions/modification_detection_spec.rb +0 -93
  214. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  215. data/spec/extensions/named_timezones_spec.rb +0 -218
  216. data/spec/extensions/nested_attributes_spec.rb +0 -815
  217. data/spec/extensions/null_dataset_spec.rb +0 -85
  218. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  219. data/spec/extensions/pagination_spec.rb +0 -116
  220. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  221. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  222. data/spec/extensions/pg_array_spec.rb +0 -398
  223. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -209
  224. data/spec/extensions/pg_enum_spec.rb +0 -118
  225. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  226. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  227. data/spec/extensions/pg_hstore_spec.rb +0 -219
  228. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  229. data/spec/extensions/pg_inet_spec.rb +0 -72
  230. data/spec/extensions/pg_interval_spec.rb +0 -103
  231. data/spec/extensions/pg_json_ops_spec.rb +0 -356
  232. data/spec/extensions/pg_json_spec.rb +0 -451
  233. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  234. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  235. data/spec/extensions/pg_range_spec.rb +0 -600
  236. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  237. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  238. data/spec/extensions/pg_row_spec.rb +0 -363
  239. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  240. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  241. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  242. data/spec/extensions/prepared_statements_spec.rb +0 -177
  243. data/spec/extensions/pretty_table_spec.rb +0 -123
  244. data/spec/extensions/query_spec.rb +0 -94
  245. data/spec/extensions/rcte_tree_spec.rb +0 -387
  246. data/spec/extensions/round_timestamps_spec.rb +0 -39
  247. data/spec/extensions/s_spec.rb +0 -60
  248. data/spec/extensions/schema_caching_spec.rb +0 -64
  249. data/spec/extensions/schema_dumper_spec.rb +0 -870
  250. data/spec/extensions/select_remove_spec.rb +0 -38
  251. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  252. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  253. data/spec/extensions/serialization_spec.rb +0 -365
  254. data/spec/extensions/server_block_spec.rb +0 -135
  255. data/spec/extensions/server_logging_spec.rb +0 -45
  256. data/spec/extensions/sharding_spec.rb +0 -197
  257. data/spec/extensions/shared_caching_spec.rb +0 -151
  258. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  259. data/spec/extensions/singular_table_names_spec.rb +0 -22
  260. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  261. data/spec/extensions/spec_helper.rb +0 -70
  262. data/spec/extensions/split_array_nil_spec.rb +0 -24
  263. data/spec/extensions/split_values_spec.rb +0 -57
  264. data/spec/extensions/sql_comments_spec.rb +0 -33
  265. data/spec/extensions/sql_expr_spec.rb +0 -59
  266. data/spec/extensions/static_cache_cache_spec.rb +0 -35
  267. data/spec/extensions/static_cache_spec.rb +0 -471
  268. data/spec/extensions/string_agg_spec.rb +0 -90
  269. data/spec/extensions/string_date_time_spec.rb +0 -95
  270. data/spec/extensions/string_stripper_spec.rb +0 -68
  271. data/spec/extensions/subclasses_spec.rb +0 -79
  272. data/spec/extensions/subset_conditions_spec.rb +0 -38
  273. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  274. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  275. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  276. data/spec/extensions/table_select_spec.rb +0 -83
  277. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  278. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  279. data/spec/extensions/throw_failures_spec.rb +0 -74
  280. data/spec/extensions/timestamps_spec.rb +0 -209
  281. data/spec/extensions/to_dot_spec.rb +0 -153
  282. data/spec/extensions/touch_spec.rb +0 -226
  283. data/spec/extensions/tree_spec.rb +0 -334
  284. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  285. data/spec/extensions/unlimited_update_spec.rb +0 -21
  286. data/spec/extensions/update_or_create_spec.rb +0 -83
  287. data/spec/extensions/update_primary_key_spec.rb +0 -105
  288. data/spec/extensions/update_refresh_spec.rb +0 -59
  289. data/spec/extensions/uuid_spec.rb +0 -101
  290. data/spec/extensions/validate_associated_spec.rb +0 -52
  291. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  292. data/spec/extensions/validation_contexts_spec.rb +0 -31
  293. data/spec/extensions/validation_helpers_spec.rb +0 -525
  294. data/spec/extensions/whitelist_security_spec.rb +0 -157
  295. data/spec/extensions/xml_serializer_spec.rb +0 -213
  296. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  297. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  298. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  299. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  300. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  301. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  302. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  303. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  304. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  305. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  306. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  307. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  308. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  309. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  310. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  311. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  312. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  313. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  314. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  315. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  316. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  317. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  318. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  319. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  320. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  321. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  322. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  323. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  324. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  325. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  326. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  327. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  328. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  329. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  330. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  331. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  332. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  333. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  334. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  335. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  336. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  337. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  338. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  339. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  340. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  341. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  342. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  343. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  344. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  345. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  346. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  347. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  348. data/spec/guards_helper.rb +0 -59
  349. data/spec/integration/associations_test.rb +0 -2597
  350. data/spec/integration/database_test.rb +0 -113
  351. data/spec/integration/dataset_test.rb +0 -2037
  352. data/spec/integration/eager_loader_test.rb +0 -687
  353. data/spec/integration/migrator_test.rb +0 -262
  354. data/spec/integration/model_test.rb +0 -203
  355. data/spec/integration/plugin_test.rb +0 -2423
  356. data/spec/integration/prepared_statement_test.rb +0 -405
  357. data/spec/integration/schema_test.rb +0 -903
  358. data/spec/integration/spec_helper.rb +0 -71
  359. data/spec/integration/timezone_test.rb +0 -86
  360. data/spec/integration/transaction_test.rb +0 -603
  361. data/spec/integration/type_test.rb +0 -127
  362. data/spec/model/association_reflection_spec.rb +0 -803
  363. data/spec/model/associations_spec.rb +0 -4738
  364. data/spec/model/base_spec.rb +0 -875
  365. data/spec/model/class_dataset_methods_spec.rb +0 -146
  366. data/spec/model/dataset_methods_spec.rb +0 -198
  367. data/spec/model/eager_loading_spec.rb +0 -2377
  368. data/spec/model/hooks_spec.rb +0 -370
  369. data/spec/model/inflector_spec.rb +0 -26
  370. data/spec/model/model_spec.rb +0 -956
  371. data/spec/model/plugins_spec.rb +0 -429
  372. data/spec/model/record_spec.rb +0 -2118
  373. data/spec/model/spec_helper.rb +0 -46
  374. data/spec/model/validations_spec.rb +0 -220
  375. data/spec/model_no_assoc_spec.rb +0 -1
  376. data/spec/model_spec.rb +0 -1
  377. data/spec/plugin_spec.rb +0 -1
  378. data/spec/sequel_coverage.rb +0 -15
  379. data/spec/sequel_warning.rb +0 -4
  380. 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