sequel 5.8.0 → 5.38.0

Sign up to get free protection for your applications and to get access to all the features.
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