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