sequel 4.36.0 → 5.61.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 (760) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +548 -5749
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +265 -159
  5. data/bin/sequel +34 -12
  6. data/doc/advanced_associations.rdoc +228 -187
  7. data/doc/association_basics.rdoc +281 -291
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +86 -51
  10. data/doc/code_order.rdoc +25 -19
  11. data/doc/core_extensions.rdoc +104 -63
  12. data/doc/dataset_basics.rdoc +12 -21
  13. data/doc/dataset_filtering.rdoc +99 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/fork_safety.rdoc +84 -0
  16. data/doc/mass_assignment.rdoc +74 -31
  17. data/doc/migration.rdoc +59 -51
  18. data/doc/model_dataset_method_design.rdoc +129 -0
  19. data/doc/model_hooks.rdoc +15 -25
  20. data/doc/model_plugins.rdoc +12 -12
  21. data/doc/mssql_stored_procedures.rdoc +3 -3
  22. data/doc/object_model.rdoc +58 -68
  23. data/doc/opening_databases.rdoc +85 -95
  24. data/doc/postgresql.rdoc +263 -38
  25. data/doc/prepared_statements.rdoc +29 -24
  26. data/doc/querying.rdoc +189 -167
  27. data/doc/reflection.rdoc +5 -6
  28. data/doc/release_notes/5.0.0.txt +159 -0
  29. data/doc/release_notes/5.1.0.txt +31 -0
  30. data/doc/release_notes/5.10.0.txt +84 -0
  31. data/doc/release_notes/5.11.0.txt +83 -0
  32. data/doc/release_notes/5.12.0.txt +141 -0
  33. data/doc/release_notes/5.13.0.txt +27 -0
  34. data/doc/release_notes/5.14.0.txt +63 -0
  35. data/doc/release_notes/5.15.0.txt +39 -0
  36. data/doc/release_notes/5.16.0.txt +110 -0
  37. data/doc/release_notes/5.17.0.txt +31 -0
  38. data/doc/release_notes/5.18.0.txt +69 -0
  39. data/doc/release_notes/5.19.0.txt +28 -0
  40. data/doc/release_notes/5.2.0.txt +33 -0
  41. data/doc/release_notes/5.20.0.txt +89 -0
  42. data/doc/release_notes/5.21.0.txt +87 -0
  43. data/doc/release_notes/5.22.0.txt +48 -0
  44. data/doc/release_notes/5.23.0.txt +56 -0
  45. data/doc/release_notes/5.24.0.txt +56 -0
  46. data/doc/release_notes/5.25.0.txt +32 -0
  47. data/doc/release_notes/5.26.0.txt +35 -0
  48. data/doc/release_notes/5.27.0.txt +21 -0
  49. data/doc/release_notes/5.28.0.txt +16 -0
  50. data/doc/release_notes/5.29.0.txt +22 -0
  51. data/doc/release_notes/5.3.0.txt +121 -0
  52. data/doc/release_notes/5.30.0.txt +20 -0
  53. data/doc/release_notes/5.31.0.txt +148 -0
  54. data/doc/release_notes/5.32.0.txt +46 -0
  55. data/doc/release_notes/5.33.0.txt +24 -0
  56. data/doc/release_notes/5.34.0.txt +40 -0
  57. data/doc/release_notes/5.35.0.txt +56 -0
  58. data/doc/release_notes/5.36.0.txt +60 -0
  59. data/doc/release_notes/5.37.0.txt +30 -0
  60. data/doc/release_notes/5.38.0.txt +28 -0
  61. data/doc/release_notes/5.39.0.txt +19 -0
  62. data/doc/release_notes/5.4.0.txt +80 -0
  63. data/doc/release_notes/5.40.0.txt +40 -0
  64. data/doc/release_notes/5.41.0.txt +25 -0
  65. data/doc/release_notes/5.42.0.txt +136 -0
  66. data/doc/release_notes/5.43.0.txt +98 -0
  67. data/doc/release_notes/5.44.0.txt +32 -0
  68. data/doc/release_notes/5.45.0.txt +34 -0
  69. data/doc/release_notes/5.46.0.txt +87 -0
  70. data/doc/release_notes/5.47.0.txt +59 -0
  71. data/doc/release_notes/5.48.0.txt +14 -0
  72. data/doc/release_notes/5.49.0.txt +59 -0
  73. data/doc/release_notes/5.5.0.txt +61 -0
  74. data/doc/release_notes/5.50.0.txt +78 -0
  75. data/doc/release_notes/5.51.0.txt +47 -0
  76. data/doc/release_notes/5.52.0.txt +87 -0
  77. data/doc/release_notes/5.53.0.txt +23 -0
  78. data/doc/release_notes/5.54.0.txt +27 -0
  79. data/doc/release_notes/5.55.0.txt +21 -0
  80. data/doc/release_notes/5.56.0.txt +51 -0
  81. data/doc/release_notes/5.57.0.txt +23 -0
  82. data/doc/release_notes/5.58.0.txt +31 -0
  83. data/doc/release_notes/5.59.0.txt +73 -0
  84. data/doc/release_notes/5.6.0.txt +31 -0
  85. data/doc/release_notes/5.60.0.txt +22 -0
  86. data/doc/release_notes/5.61.0.txt +43 -0
  87. data/doc/release_notes/5.7.0.txt +108 -0
  88. data/doc/release_notes/5.8.0.txt +170 -0
  89. data/doc/release_notes/5.9.0.txt +99 -0
  90. data/doc/schema_modification.rdoc +95 -75
  91. data/doc/security.rdoc +109 -80
  92. data/doc/sharding.rdoc +74 -47
  93. data/doc/sql.rdoc +147 -122
  94. data/doc/testing.rdoc +43 -20
  95. data/doc/thread_safety.rdoc +2 -4
  96. data/doc/transactions.rdoc +97 -18
  97. data/doc/validations.rdoc +52 -50
  98. data/doc/virtual_rows.rdoc +90 -109
  99. data/lib/sequel/adapters/ado/access.rb +15 -17
  100. data/lib/sequel/adapters/ado/mssql.rb +6 -15
  101. data/lib/sequel/adapters/ado.rb +150 -20
  102. data/lib/sequel/adapters/amalgalite.rb +11 -23
  103. data/lib/sequel/adapters/ibmdb.rb +47 -55
  104. data/lib/sequel/adapters/jdbc/db2.rb +29 -39
  105. data/lib/sequel/adapters/jdbc/derby.rb +58 -54
  106. data/lib/sequel/adapters/jdbc/h2.rb +93 -35
  107. data/lib/sequel/adapters/jdbc/hsqldb.rb +24 -31
  108. data/lib/sequel/adapters/jdbc/jtds.rb +2 -10
  109. data/lib/sequel/adapters/jdbc/mssql.rb +3 -11
  110. data/lib/sequel/adapters/jdbc/mysql.rb +17 -20
  111. data/lib/sequel/adapters/jdbc/oracle.rb +22 -18
  112. data/lib/sequel/adapters/jdbc/postgresql.rb +69 -71
  113. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +11 -23
  114. data/lib/sequel/adapters/jdbc/sqlite.rb +47 -11
  115. data/lib/sequel/adapters/jdbc/sqlserver.rb +34 -9
  116. data/lib/sequel/adapters/jdbc/transactions.rb +22 -38
  117. data/lib/sequel/adapters/jdbc.rb +145 -130
  118. data/lib/sequel/adapters/mock.rb +100 -111
  119. data/lib/sequel/adapters/mysql.rb +114 -122
  120. data/lib/sequel/adapters/mysql2.rb +147 -63
  121. data/lib/sequel/adapters/odbc/db2.rb +1 -1
  122. data/lib/sequel/adapters/odbc/mssql.rb +8 -14
  123. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  124. data/lib/sequel/adapters/odbc.rb +20 -25
  125. data/lib/sequel/adapters/oracle.rb +50 -56
  126. data/lib/sequel/adapters/postgres.rb +305 -327
  127. data/lib/sequel/adapters/postgresql.rb +1 -1
  128. data/lib/sequel/adapters/shared/access.rb +74 -78
  129. data/lib/sequel/adapters/shared/db2.rb +118 -71
  130. data/lib/sequel/adapters/shared/mssql.rb +301 -220
  131. data/lib/sequel/adapters/shared/mysql.rb +299 -217
  132. data/lib/sequel/adapters/shared/oracle.rb +226 -65
  133. data/lib/sequel/adapters/shared/postgres.rb +935 -395
  134. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -126
  135. data/lib/sequel/adapters/shared/sqlite.rb +447 -173
  136. data/lib/sequel/adapters/sqlanywhere.rb +48 -35
  137. data/lib/sequel/adapters/sqlite.rb +156 -111
  138. data/lib/sequel/adapters/tinytds.rb +30 -38
  139. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  140. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +3 -6
  141. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +2 -2
  142. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  143. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  144. data/lib/sequel/adapters/utils/replace.rb +1 -4
  145. data/lib/sequel/adapters/utils/stored_procedures.rb +7 -22
  146. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  147. data/lib/sequel/ast_transformer.rb +17 -89
  148. data/lib/sequel/connection_pool/sharded_single.rb +18 -15
  149. data/lib/sequel/connection_pool/sharded_threaded.rb +130 -111
  150. data/lib/sequel/connection_pool/single.rb +18 -13
  151. data/lib/sequel/connection_pool/threaded.rb +121 -120
  152. data/lib/sequel/connection_pool.rb +48 -29
  153. data/lib/sequel/core.rb +351 -301
  154. data/lib/sequel/database/connecting.rb +69 -57
  155. data/lib/sequel/database/dataset.rb +13 -5
  156. data/lib/sequel/database/dataset_defaults.rb +18 -102
  157. data/lib/sequel/database/features.rb +18 -4
  158. data/lib/sequel/database/logging.rb +12 -11
  159. data/lib/sequel/database/misc.rb +180 -122
  160. data/lib/sequel/database/query.rb +47 -27
  161. data/lib/sequel/database/schema_generator.rb +178 -84
  162. data/lib/sequel/database/schema_methods.rb +172 -97
  163. data/lib/sequel/database/transactions.rb +205 -44
  164. data/lib/sequel/database.rb +17 -2
  165. data/lib/sequel/dataset/actions.rb +339 -155
  166. data/lib/sequel/dataset/dataset_module.rb +46 -0
  167. data/lib/sequel/dataset/features.rb +90 -35
  168. data/lib/sequel/dataset/graph.rb +80 -58
  169. data/lib/sequel/dataset/misc.rb +137 -47
  170. data/lib/sequel/dataset/placeholder_literalizer.rb +63 -25
  171. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  172. data/lib/sequel/dataset/query.rb +530 -222
  173. data/lib/sequel/dataset/sql.rb +590 -368
  174. data/lib/sequel/dataset.rb +26 -16
  175. data/lib/sequel/deprecated.rb +12 -2
  176. data/lib/sequel/exceptions.rb +46 -16
  177. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  178. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  179. data/lib/sequel/extensions/_pretty_table.rb +2 -5
  180. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  181. data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
  182. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  183. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  184. data/lib/sequel/extensions/blank.rb +8 -0
  185. data/lib/sequel/extensions/caller_logging.rb +79 -0
  186. data/lib/sequel/extensions/columns_introspection.rb +4 -3
  187. data/lib/sequel/extensions/connection_expiration.rb +20 -10
  188. data/lib/sequel/extensions/connection_validator.rb +11 -10
  189. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  190. data/lib/sequel/extensions/constraint_validations.rb +62 -39
  191. data/lib/sequel/extensions/core_extensions.rb +42 -48
  192. data/lib/sequel/extensions/core_refinements.rb +80 -59
  193. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -4
  194. data/lib/sequel/extensions/date_arithmetic.rb +98 -39
  195. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  196. data/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
  197. data/lib/sequel/extensions/duplicate_columns_handler.rb +21 -14
  198. data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
  199. data/lib/sequel/extensions/escaped_like.rb +100 -0
  200. data/lib/sequel/extensions/eval_inspect.rb +12 -15
  201. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  202. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  203. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  204. data/lib/sequel/extensions/from_block.rb +1 -34
  205. data/lib/sequel/extensions/graph_each.rb +4 -4
  206. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  207. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  208. data/lib/sequel/extensions/index_caching.rb +109 -0
  209. data/lib/sequel/extensions/inflector.rb +13 -5
  210. data/lib/sequel/extensions/integer64.rb +32 -0
  211. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  212. data/lib/sequel/extensions/looser_typecasting.rb +17 -8
  213. data/lib/sequel/extensions/migration.rb +119 -78
  214. data/lib/sequel/extensions/named_timezones.rb +88 -23
  215. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -82
  216. data/lib/sequel/extensions/null_dataset.rb +8 -8
  217. data/lib/sequel/extensions/pagination.rb +32 -29
  218. data/lib/sequel/extensions/pg_array.rb +221 -287
  219. data/lib/sequel/extensions/pg_array_ops.rb +17 -9
  220. data/lib/sequel/extensions/pg_enum.rb +63 -23
  221. data/lib/sequel/extensions/pg_extended_date_support.rb +241 -0
  222. data/lib/sequel/extensions/pg_hstore.rb +45 -54
  223. data/lib/sequel/extensions/pg_hstore_ops.rb +58 -6
  224. data/lib/sequel/extensions/pg_inet.rb +31 -12
  225. data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
  226. data/lib/sequel/extensions/pg_interval.rb +56 -29
  227. data/lib/sequel/extensions/pg_json.rb +417 -140
  228. data/lib/sequel/extensions/pg_json_ops.rb +270 -18
  229. data/lib/sequel/extensions/pg_loose_count.rb +4 -2
  230. data/lib/sequel/extensions/pg_multirange.rb +372 -0
  231. data/lib/sequel/extensions/pg_range.rb +131 -191
  232. data/lib/sequel/extensions/pg_range_ops.rb +42 -13
  233. data/lib/sequel/extensions/pg_row.rb +48 -81
  234. data/lib/sequel/extensions/pg_row_ops.rb +33 -14
  235. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  236. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  237. data/lib/sequel/extensions/query.rb +9 -7
  238. data/lib/sequel/extensions/round_timestamps.rb +0 -6
  239. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  240. data/lib/sequel/extensions/s.rb +60 -0
  241. data/lib/sequel/extensions/schema_caching.rb +10 -1
  242. data/lib/sequel/extensions/schema_dumper.rb +71 -48
  243. data/lib/sequel/extensions/select_remove.rb +4 -4
  244. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  245. data/lib/sequel/extensions/server_block.rb +51 -27
  246. data/lib/sequel/extensions/split_array_nil.rb +4 -4
  247. data/lib/sequel/extensions/sql_comments.rb +119 -7
  248. data/lib/sequel/extensions/sql_expr.rb +2 -1
  249. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  250. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  251. data/lib/sequel/extensions/string_agg.rb +11 -8
  252. data/lib/sequel/extensions/string_date_time.rb +19 -23
  253. data/lib/sequel/extensions/symbol_aref.rb +55 -0
  254. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  255. data/lib/sequel/extensions/symbol_as.rb +23 -0
  256. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  257. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  258. data/lib/sequel/extensions/to_dot.rb +10 -4
  259. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  260. data/lib/sequel/model/associations.rb +1006 -284
  261. data/lib/sequel/model/base.rb +560 -805
  262. data/lib/sequel/model/dataset_module.rb +11 -10
  263. data/lib/sequel/model/default_inflections.rb +1 -1
  264. data/lib/sequel/model/errors.rb +10 -3
  265. data/lib/sequel/model/exceptions.rb +8 -10
  266. data/lib/sequel/model/inflections.rb +7 -20
  267. data/lib/sequel/model/plugins.rb +114 -0
  268. data/lib/sequel/model.rb +32 -82
  269. data/lib/sequel/plugins/active_model.rb +30 -14
  270. data/lib/sequel/plugins/after_initialize.rb +1 -1
  271. data/lib/sequel/plugins/association_dependencies.rb +25 -18
  272. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  273. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  274. data/lib/sequel/plugins/association_pks.rb +147 -70
  275. data/lib/sequel/plugins/association_proxies.rb +33 -9
  276. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  277. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  278. data/lib/sequel/plugins/auto_validations.rb +95 -28
  279. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  280. data/lib/sequel/plugins/before_after_save.rb +0 -42
  281. data/lib/sequel/plugins/blacklist_security.rb +21 -12
  282. data/lib/sequel/plugins/boolean_readers.rb +5 -5
  283. data/lib/sequel/plugins/boolean_subsets.rb +13 -8
  284. data/lib/sequel/plugins/caching.rb +25 -16
  285. data/lib/sequel/plugins/class_table_inheritance.rb +179 -100
  286. data/lib/sequel/plugins/column_conflicts.rb +16 -3
  287. data/lib/sequel/plugins/column_encryption.rb +728 -0
  288. data/lib/sequel/plugins/column_select.rb +7 -5
  289. data/lib/sequel/plugins/columns_updated.rb +42 -0
  290. data/lib/sequel/plugins/composition.rb +42 -26
  291. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  292. data/lib/sequel/plugins/constraint_validations.rb +20 -14
  293. data/lib/sequel/plugins/csv_serializer.rb +56 -35
  294. data/lib/sequel/plugins/dataset_associations.rb +40 -17
  295. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  296. data/lib/sequel/plugins/defaults_setter.rb +65 -10
  297. data/lib/sequel/plugins/delay_add_association.rb +1 -1
  298. data/lib/sequel/plugins/dirty.rb +62 -24
  299. data/lib/sequel/plugins/eager_each.rb +3 -3
  300. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  301. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  302. data/lib/sequel/plugins/enum.rb +124 -0
  303. data/lib/sequel/plugins/error_splitter.rb +17 -12
  304. data/lib/sequel/plugins/finder.rb +246 -0
  305. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  306. data/lib/sequel/plugins/force_encoding.rb +7 -12
  307. data/lib/sequel/plugins/hook_class_methods.rb +37 -54
  308. data/lib/sequel/plugins/input_transformer.rb +18 -10
  309. data/lib/sequel/plugins/insert_conflict.rb +76 -0
  310. data/lib/sequel/plugins/insert_returning_select.rb +2 -2
  311. data/lib/sequel/plugins/instance_filters.rb +10 -8
  312. data/lib/sequel/plugins/instance_hooks.rb +34 -17
  313. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  314. data/lib/sequel/plugins/inverted_subsets.rb +22 -13
  315. data/lib/sequel/plugins/json_serializer.rb +124 -64
  316. data/lib/sequel/plugins/lazy_attributes.rb +21 -14
  317. data/lib/sequel/plugins/list.rb +35 -21
  318. data/lib/sequel/plugins/many_through_many.rb +134 -21
  319. data/lib/sequel/plugins/modification_detection.rb +15 -5
  320. data/lib/sequel/plugins/mssql_optimistic_locking.rb +6 -5
  321. data/lib/sequel/plugins/nested_attributes.rb +61 -31
  322. data/lib/sequel/plugins/optimistic_locking.rb +3 -3
  323. data/lib/sequel/plugins/pg_array_associations.rb +103 -53
  324. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +350 -0
  325. data/lib/sequel/plugins/pg_row.rb +5 -51
  326. data/lib/sequel/plugins/prepared_statements.rb +60 -72
  327. data/lib/sequel/plugins/prepared_statements_safe.rb +9 -4
  328. data/lib/sequel/plugins/rcte_tree.rb +68 -82
  329. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  330. data/lib/sequel/plugins/serialization.rb +43 -46
  331. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -2
  332. data/lib/sequel/plugins/sharding.rb +15 -10
  333. data/lib/sequel/plugins/single_table_inheritance.rb +67 -28
  334. data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
  335. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  336. data/lib/sequel/plugins/split_values.rb +11 -6
  337. data/lib/sequel/plugins/sql_comments.rb +189 -0
  338. data/lib/sequel/plugins/static_cache.rb +77 -53
  339. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  340. data/lib/sequel/plugins/string_stripper.rb +3 -3
  341. data/lib/sequel/plugins/subclasses.rb +43 -10
  342. data/lib/sequel/plugins/subset_conditions.rb +15 -5
  343. data/lib/sequel/plugins/table_select.rb +2 -2
  344. data/lib/sequel/plugins/tactical_eager_loading.rb +96 -12
  345. data/lib/sequel/plugins/throw_failures.rb +110 -0
  346. data/lib/sequel/plugins/timestamps.rb +20 -8
  347. data/lib/sequel/plugins/touch.rb +19 -8
  348. data/lib/sequel/plugins/tree.rb +62 -32
  349. data/lib/sequel/plugins/typecast_on_load.rb +12 -4
  350. data/lib/sequel/plugins/unlimited_update.rb +1 -7
  351. data/lib/sequel/plugins/unused_associations.rb +521 -0
  352. data/lib/sequel/plugins/update_or_create.rb +4 -4
  353. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  354. data/lib/sequel/plugins/update_refresh.rb +26 -15
  355. data/lib/sequel/plugins/uuid.rb +7 -11
  356. data/lib/sequel/plugins/validate_associated.rb +18 -0
  357. data/lib/sequel/plugins/validation_class_methods.rb +38 -19
  358. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  359. data/lib/sequel/plugins/validation_helpers.rb +57 -41
  360. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  361. data/lib/sequel/plugins/xml_serializer.rb +30 -31
  362. data/lib/sequel/sql.rb +471 -331
  363. data/lib/sequel/timezones.rb +78 -47
  364. data/lib/sequel/version.rb +7 -2
  365. data/lib/sequel.rb +1 -1
  366. metadata +217 -521
  367. data/Rakefile +0 -164
  368. data/doc/active_record.rdoc +0 -928
  369. data/doc/release_notes/1.0.txt +0 -38
  370. data/doc/release_notes/1.1.txt +0 -143
  371. data/doc/release_notes/1.3.txt +0 -101
  372. data/doc/release_notes/1.4.0.txt +0 -53
  373. data/doc/release_notes/1.5.0.txt +0 -155
  374. data/doc/release_notes/2.0.0.txt +0 -298
  375. data/doc/release_notes/2.1.0.txt +0 -271
  376. data/doc/release_notes/2.10.0.txt +0 -328
  377. data/doc/release_notes/2.11.0.txt +0 -215
  378. data/doc/release_notes/2.12.0.txt +0 -534
  379. data/doc/release_notes/2.2.0.txt +0 -253
  380. data/doc/release_notes/2.3.0.txt +0 -88
  381. data/doc/release_notes/2.4.0.txt +0 -106
  382. data/doc/release_notes/2.5.0.txt +0 -137
  383. data/doc/release_notes/2.6.0.txt +0 -157
  384. data/doc/release_notes/2.7.0.txt +0 -166
  385. data/doc/release_notes/2.8.0.txt +0 -171
  386. data/doc/release_notes/2.9.0.txt +0 -97
  387. data/doc/release_notes/3.0.0.txt +0 -221
  388. data/doc/release_notes/3.1.0.txt +0 -406
  389. data/doc/release_notes/3.10.0.txt +0 -286
  390. data/doc/release_notes/3.11.0.txt +0 -254
  391. data/doc/release_notes/3.12.0.txt +0 -304
  392. data/doc/release_notes/3.13.0.txt +0 -210
  393. data/doc/release_notes/3.14.0.txt +0 -118
  394. data/doc/release_notes/3.15.0.txt +0 -78
  395. data/doc/release_notes/3.16.0.txt +0 -45
  396. data/doc/release_notes/3.17.0.txt +0 -58
  397. data/doc/release_notes/3.18.0.txt +0 -120
  398. data/doc/release_notes/3.19.0.txt +0 -67
  399. data/doc/release_notes/3.2.0.txt +0 -268
  400. data/doc/release_notes/3.20.0.txt +0 -41
  401. data/doc/release_notes/3.21.0.txt +0 -87
  402. data/doc/release_notes/3.22.0.txt +0 -39
  403. data/doc/release_notes/3.23.0.txt +0 -172
  404. data/doc/release_notes/3.24.0.txt +0 -420
  405. data/doc/release_notes/3.25.0.txt +0 -88
  406. data/doc/release_notes/3.26.0.txt +0 -88
  407. data/doc/release_notes/3.27.0.txt +0 -82
  408. data/doc/release_notes/3.28.0.txt +0 -304
  409. data/doc/release_notes/3.29.0.txt +0 -459
  410. data/doc/release_notes/3.3.0.txt +0 -192
  411. data/doc/release_notes/3.30.0.txt +0 -135
  412. data/doc/release_notes/3.31.0.txt +0 -146
  413. data/doc/release_notes/3.32.0.txt +0 -202
  414. data/doc/release_notes/3.33.0.txt +0 -157
  415. data/doc/release_notes/3.34.0.txt +0 -671
  416. data/doc/release_notes/3.35.0.txt +0 -144
  417. data/doc/release_notes/3.36.0.txt +0 -245
  418. data/doc/release_notes/3.37.0.txt +0 -338
  419. data/doc/release_notes/3.38.0.txt +0 -234
  420. data/doc/release_notes/3.39.0.txt +0 -237
  421. data/doc/release_notes/3.4.0.txt +0 -325
  422. data/doc/release_notes/3.40.0.txt +0 -73
  423. data/doc/release_notes/3.41.0.txt +0 -155
  424. data/doc/release_notes/3.42.0.txt +0 -74
  425. data/doc/release_notes/3.43.0.txt +0 -105
  426. data/doc/release_notes/3.44.0.txt +0 -152
  427. data/doc/release_notes/3.45.0.txt +0 -179
  428. data/doc/release_notes/3.46.0.txt +0 -122
  429. data/doc/release_notes/3.47.0.txt +0 -270
  430. data/doc/release_notes/3.48.0.txt +0 -477
  431. data/doc/release_notes/3.5.0.txt +0 -510
  432. data/doc/release_notes/3.6.0.txt +0 -366
  433. data/doc/release_notes/3.7.0.txt +0 -179
  434. data/doc/release_notes/3.8.0.txt +0 -151
  435. data/doc/release_notes/3.9.0.txt +0 -233
  436. data/doc/release_notes/4.0.0.txt +0 -262
  437. data/doc/release_notes/4.1.0.txt +0 -85
  438. data/doc/release_notes/4.10.0.txt +0 -226
  439. data/doc/release_notes/4.11.0.txt +0 -147
  440. data/doc/release_notes/4.12.0.txt +0 -105
  441. data/doc/release_notes/4.13.0.txt +0 -169
  442. data/doc/release_notes/4.14.0.txt +0 -68
  443. data/doc/release_notes/4.15.0.txt +0 -56
  444. data/doc/release_notes/4.16.0.txt +0 -36
  445. data/doc/release_notes/4.17.0.txt +0 -38
  446. data/doc/release_notes/4.18.0.txt +0 -36
  447. data/doc/release_notes/4.19.0.txt +0 -45
  448. data/doc/release_notes/4.2.0.txt +0 -129
  449. data/doc/release_notes/4.20.0.txt +0 -79
  450. data/doc/release_notes/4.21.0.txt +0 -94
  451. data/doc/release_notes/4.22.0.txt +0 -72
  452. data/doc/release_notes/4.23.0.txt +0 -65
  453. data/doc/release_notes/4.24.0.txt +0 -99
  454. data/doc/release_notes/4.25.0.txt +0 -181
  455. data/doc/release_notes/4.26.0.txt +0 -44
  456. data/doc/release_notes/4.27.0.txt +0 -78
  457. data/doc/release_notes/4.28.0.txt +0 -57
  458. data/doc/release_notes/4.29.0.txt +0 -41
  459. data/doc/release_notes/4.3.0.txt +0 -40
  460. data/doc/release_notes/4.30.0.txt +0 -37
  461. data/doc/release_notes/4.31.0.txt +0 -57
  462. data/doc/release_notes/4.32.0.txt +0 -132
  463. data/doc/release_notes/4.33.0.txt +0 -88
  464. data/doc/release_notes/4.34.0.txt +0 -86
  465. data/doc/release_notes/4.35.0.txt +0 -130
  466. data/doc/release_notes/4.36.0.txt +0 -116
  467. data/doc/release_notes/4.4.0.txt +0 -92
  468. data/doc/release_notes/4.5.0.txt +0 -34
  469. data/doc/release_notes/4.6.0.txt +0 -30
  470. data/doc/release_notes/4.7.0.txt +0 -103
  471. data/doc/release_notes/4.8.0.txt +0 -175
  472. data/doc/release_notes/4.9.0.txt +0 -190
  473. data/lib/sequel/adapters/cubrid.rb +0 -144
  474. data/lib/sequel/adapters/do/mysql.rb +0 -66
  475. data/lib/sequel/adapters/do/postgres.rb +0 -44
  476. data/lib/sequel/adapters/do/sqlite3.rb +0 -42
  477. data/lib/sequel/adapters/do.rb +0 -158
  478. data/lib/sequel/adapters/jdbc/as400.rb +0 -84
  479. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -64
  480. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -36
  481. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -33
  482. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -33
  483. data/lib/sequel/adapters/odbc/progress.rb +0 -10
  484. data/lib/sequel/adapters/shared/cubrid.rb +0 -245
  485. data/lib/sequel/adapters/shared/firebird.rb +0 -247
  486. data/lib/sequel/adapters/shared/informix.rb +0 -54
  487. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -152
  488. data/lib/sequel/adapters/shared/progress.rb +0 -40
  489. data/lib/sequel/adapters/swift/mysql.rb +0 -49
  490. data/lib/sequel/adapters/swift/postgres.rb +0 -47
  491. data/lib/sequel/adapters/swift/sqlite.rb +0 -49
  492. data/lib/sequel/adapters/swift.rb +0 -160
  493. data/lib/sequel/adapters/utils/pg_types.rb +0 -70
  494. data/lib/sequel/dataset/mutation.rb +0 -111
  495. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -5
  496. data/lib/sequel/extensions/filter_having.rb +0 -63
  497. data/lib/sequel/extensions/hash_aliases.rb +0 -49
  498. data/lib/sequel/extensions/meta_def.rb +0 -35
  499. data/lib/sequel/extensions/query_literals.rb +0 -84
  500. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -24
  501. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -122
  502. data/lib/sequel/extensions/set_overrides.rb +0 -76
  503. data/lib/sequel/no_core_ext.rb +0 -3
  504. data/lib/sequel/plugins/association_autoreloading.rb +0 -9
  505. data/lib/sequel/plugins/identifier_columns.rb +0 -47
  506. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -9
  507. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -81
  508. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -119
  509. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -61
  510. data/lib/sequel/plugins/schema.rb +0 -82
  511. data/lib/sequel/plugins/scissors.rb +0 -35
  512. data/spec/adapter_spec.rb +0 -4
  513. data/spec/adapters/db2_spec.rb +0 -160
  514. data/spec/adapters/firebird_spec.rb +0 -411
  515. data/spec/adapters/informix_spec.rb +0 -100
  516. data/spec/adapters/mssql_spec.rb +0 -733
  517. data/spec/adapters/mysql_spec.rb +0 -1319
  518. data/spec/adapters/oracle_spec.rb +0 -313
  519. data/spec/adapters/postgres_spec.rb +0 -3790
  520. data/spec/adapters/spec_helper.rb +0 -49
  521. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  522. data/spec/adapters/sqlite_spec.rb +0 -688
  523. data/spec/bin_spec.rb +0 -258
  524. data/spec/core/connection_pool_spec.rb +0 -1045
  525. data/spec/core/database_spec.rb +0 -2636
  526. data/spec/core/dataset_spec.rb +0 -5175
  527. data/spec/core/deprecated_spec.rb +0 -70
  528. data/spec/core/expression_filters_spec.rb +0 -1247
  529. data/spec/core/mock_adapter_spec.rb +0 -464
  530. data/spec/core/object_graph_spec.rb +0 -303
  531. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  532. data/spec/core/schema_generator_spec.rb +0 -203
  533. data/spec/core/schema_spec.rb +0 -1676
  534. data/spec/core/spec_helper.rb +0 -34
  535. data/spec/core/version_spec.rb +0 -7
  536. data/spec/core_extensions_spec.rb +0 -699
  537. data/spec/core_model_spec.rb +0 -2
  538. data/spec/core_spec.rb +0 -1
  539. data/spec/extensions/accessed_columns_spec.rb +0 -51
  540. data/spec/extensions/active_model_spec.rb +0 -85
  541. data/spec/extensions/after_initialize_spec.rb +0 -24
  542. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  543. data/spec/extensions/association_dependencies_spec.rb +0 -117
  544. data/spec/extensions/association_pks_spec.rb +0 -405
  545. data/spec/extensions/association_proxies_spec.rb +0 -86
  546. data/spec/extensions/auto_validations_spec.rb +0 -192
  547. data/spec/extensions/before_after_save_spec.rb +0 -40
  548. data/spec/extensions/blacklist_security_spec.rb +0 -88
  549. data/spec/extensions/blank_spec.rb +0 -69
  550. data/spec/extensions/boolean_readers_spec.rb +0 -93
  551. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  552. data/spec/extensions/caching_spec.rb +0 -270
  553. data/spec/extensions/class_table_inheritance_spec.rb +0 -444
  554. data/spec/extensions/column_conflicts_spec.rb +0 -60
  555. data/spec/extensions/column_select_spec.rb +0 -108
  556. data/spec/extensions/columns_introspection_spec.rb +0 -91
  557. data/spec/extensions/composition_spec.rb +0 -242
  558. data/spec/extensions/connection_expiration_spec.rb +0 -121
  559. data/spec/extensions/connection_validator_spec.rb +0 -127
  560. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -288
  561. data/spec/extensions/constraint_validations_spec.rb +0 -389
  562. data/spec/extensions/core_refinements_spec.rb +0 -519
  563. data/spec/extensions/csv_serializer_spec.rb +0 -180
  564. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  565. data/spec/extensions/dataset_associations_spec.rb +0 -343
  566. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  567. data/spec/extensions/date_arithmetic_spec.rb +0 -167
  568. data/spec/extensions/defaults_setter_spec.rb +0 -102
  569. data/spec/extensions/delay_add_association_spec.rb +0 -74
  570. data/spec/extensions/dirty_spec.rb +0 -180
  571. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -110
  572. data/spec/extensions/eager_each_spec.rb +0 -66
  573. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  574. data/spec/extensions/error_splitter_spec.rb +0 -18
  575. data/spec/extensions/error_sql_spec.rb +0 -20
  576. data/spec/extensions/eval_inspect_spec.rb +0 -73
  577. data/spec/extensions/filter_having_spec.rb +0 -40
  578. data/spec/extensions/force_encoding_spec.rb +0 -114
  579. data/spec/extensions/from_block_spec.rb +0 -21
  580. data/spec/extensions/graph_each_spec.rb +0 -119
  581. data/spec/extensions/hash_aliases_spec.rb +0 -24
  582. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  583. data/spec/extensions/identifier_columns_spec.rb +0 -17
  584. data/spec/extensions/inflector_spec.rb +0 -183
  585. data/spec/extensions/input_transformer_spec.rb +0 -54
  586. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  587. data/spec/extensions/instance_filters_spec.rb +0 -79
  588. data/spec/extensions/instance_hooks_spec.rb +0 -276
  589. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  590. data/spec/extensions/json_serializer_spec.rb +0 -304
  591. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  592. data/spec/extensions/list_spec.rb +0 -278
  593. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  594. data/spec/extensions/many_through_many_spec.rb +0 -2172
  595. data/spec/extensions/meta_def_spec.rb +0 -21
  596. data/spec/extensions/migration_spec.rb +0 -728
  597. data/spec/extensions/modification_detection_spec.rb +0 -80
  598. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  599. data/spec/extensions/named_timezones_spec.rb +0 -108
  600. data/spec/extensions/nested_attributes_spec.rb +0 -697
  601. data/spec/extensions/no_auto_literal_strings_spec.rb +0 -65
  602. data/spec/extensions/null_dataset_spec.rb +0 -85
  603. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  604. data/spec/extensions/pagination_spec.rb +0 -118
  605. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  606. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  607. data/spec/extensions/pg_array_spec.rb +0 -390
  608. data/spec/extensions/pg_enum_spec.rb +0 -92
  609. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  610. data/spec/extensions/pg_hstore_spec.rb +0 -206
  611. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  612. data/spec/extensions/pg_inet_spec.rb +0 -52
  613. data/spec/extensions/pg_interval_spec.rb +0 -76
  614. data/spec/extensions/pg_json_ops_spec.rb +0 -275
  615. data/spec/extensions/pg_json_spec.rb +0 -218
  616. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  617. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  618. data/spec/extensions/pg_range_spec.rb +0 -473
  619. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  620. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  621. data/spec/extensions/pg_row_spec.rb +0 -360
  622. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  623. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  624. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  625. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  626. data/spec/extensions/prepared_statements_spec.rb +0 -103
  627. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  628. data/spec/extensions/pretty_table_spec.rb +0 -92
  629. data/spec/extensions/query_literals_spec.rb +0 -183
  630. data/spec/extensions/query_spec.rb +0 -102
  631. data/spec/extensions/rcte_tree_spec.rb +0 -392
  632. data/spec/extensions/round_timestamps_spec.rb +0 -43
  633. data/spec/extensions/schema_caching_spec.rb +0 -41
  634. data/spec/extensions/schema_dumper_spec.rb +0 -814
  635. data/spec/extensions/schema_spec.rb +0 -117
  636. data/spec/extensions/scissors_spec.rb +0 -26
  637. data/spec/extensions/select_remove_spec.rb +0 -38
  638. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  639. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  640. data/spec/extensions/serialization_spec.rb +0 -362
  641. data/spec/extensions/server_block_spec.rb +0 -90
  642. data/spec/extensions/server_logging_spec.rb +0 -45
  643. data/spec/extensions/set_overrides_spec.rb +0 -61
  644. data/spec/extensions/sharding_spec.rb +0 -198
  645. data/spec/extensions/shared_caching_spec.rb +0 -175
  646. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  647. data/spec/extensions/singular_table_names_spec.rb +0 -22
  648. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  649. data/spec/extensions/spec_helper.rb +0 -71
  650. data/spec/extensions/split_array_nil_spec.rb +0 -24
  651. data/spec/extensions/split_values_spec.rb +0 -22
  652. data/spec/extensions/sql_comments_spec.rb +0 -27
  653. data/spec/extensions/sql_expr_spec.rb +0 -60
  654. data/spec/extensions/static_cache_spec.rb +0 -361
  655. data/spec/extensions/string_agg_spec.rb +0 -85
  656. data/spec/extensions/string_date_time_spec.rb +0 -95
  657. data/spec/extensions/string_stripper_spec.rb +0 -68
  658. data/spec/extensions/subclasses_spec.rb +0 -66
  659. data/spec/extensions/subset_conditions_spec.rb +0 -38
  660. data/spec/extensions/table_select_spec.rb +0 -71
  661. data/spec/extensions/tactical_eager_loading_spec.rb +0 -136
  662. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  663. data/spec/extensions/timestamps_spec.rb +0 -175
  664. data/spec/extensions/to_dot_spec.rb +0 -154
  665. data/spec/extensions/touch_spec.rb +0 -203
  666. data/spec/extensions/tree_spec.rb +0 -274
  667. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  668. data/spec/extensions/unlimited_update_spec.rb +0 -20
  669. data/spec/extensions/update_or_create_spec.rb +0 -87
  670. data/spec/extensions/update_primary_key_spec.rb +0 -100
  671. data/spec/extensions/update_refresh_spec.rb +0 -53
  672. data/spec/extensions/uuid_spec.rb +0 -106
  673. data/spec/extensions/validate_associated_spec.rb +0 -52
  674. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  675. data/spec/extensions/validation_helpers_spec.rb +0 -554
  676. data/spec/extensions/xml_serializer_spec.rb +0 -207
  677. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  678. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  679. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  680. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  681. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  682. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  683. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  684. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  685. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  686. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  687. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  688. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  689. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  690. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  691. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  692. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  693. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  694. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  695. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  696. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  697. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  698. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  699. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  700. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  701. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  702. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  703. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  704. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  705. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  706. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  707. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  708. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  709. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  710. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  711. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  712. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  713. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  714. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  715. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  716. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  717. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  718. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  719. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  720. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  721. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  722. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  723. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  724. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  725. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  726. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  727. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  728. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  729. data/spec/guards_helper.rb +0 -55
  730. data/spec/integration/associations_test.rb +0 -2506
  731. data/spec/integration/database_test.rb +0 -113
  732. data/spec/integration/dataset_test.rb +0 -1858
  733. data/spec/integration/eager_loader_test.rb +0 -687
  734. data/spec/integration/migrator_test.rb +0 -262
  735. data/spec/integration/model_test.rb +0 -230
  736. data/spec/integration/plugin_test.rb +0 -2297
  737. data/spec/integration/prepared_statement_test.rb +0 -467
  738. data/spec/integration/schema_test.rb +0 -815
  739. data/spec/integration/spec_helper.rb +0 -56
  740. data/spec/integration/timezone_test.rb +0 -86
  741. data/spec/integration/transaction_test.rb +0 -406
  742. data/spec/integration/type_test.rb +0 -133
  743. data/spec/model/association_reflection_spec.rb +0 -565
  744. data/spec/model/associations_spec.rb +0 -4589
  745. data/spec/model/base_spec.rb +0 -759
  746. data/spec/model/class_dataset_methods_spec.rb +0 -150
  747. data/spec/model/dataset_methods_spec.rb +0 -149
  748. data/spec/model/eager_loading_spec.rb +0 -2197
  749. data/spec/model/hooks_spec.rb +0 -604
  750. data/spec/model/inflector_spec.rb +0 -26
  751. data/spec/model/model_spec.rb +0 -1097
  752. data/spec/model/plugins_spec.rb +0 -299
  753. data/spec/model/record_spec.rb +0 -2162
  754. data/spec/model/spec_helper.rb +0 -46
  755. data/spec/model/validations_spec.rb +0 -193
  756. data/spec/model_no_assoc_spec.rb +0 -1
  757. data/spec/model_spec.rb +0 -1
  758. data/spec/plugin_spec.rb +0 -1
  759. data/spec/sequel_coverage.rb +0 -15
  760. data/spec/spec_config.rb +0 -10
@@ -1,1319 +0,0 @@
1
- SEQUEL_ADAPTER_TEST = :mysql
2
-
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
4
-
5
- unless defined?(MYSQL_SOCKET_FILE)
6
- MYSQL_SOCKET_FILE = '/tmp/mysql.sock'
7
- end
8
- MYSQL_URI = URI.parse(DB.uri)
9
-
10
- def DB.sqls
11
- (@sqls ||= [])
12
- end
13
- logger = Object.new
14
- def logger.method_missing(m, msg)
15
- DB.sqls << msg
16
- end
17
- DB.loggers = [logger]
18
- DB.drop_table?(:items, :dolls, :booltest)
19
-
20
- SQL_BEGIN = 'BEGIN'
21
- SQL_ROLLBACK = 'ROLLBACK'
22
- SQL_COMMIT = 'COMMIT'
23
-
24
- describe "MySQL", '#create_table' do
25
- before do
26
- @db = DB
27
- @db.test_connection
28
- DB.sqls.clear
29
- end
30
- after do
31
- @db.drop_table?(:dolls)
32
- end
33
-
34
- it "should allow to specify options for MySQL" do
35
- @db.create_table(:dolls, :engine => 'MyISAM', :charset => 'latin2'){text :name}
36
- check_sqls do
37
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
38
- end
39
- end
40
-
41
- it "should create a temporary table" do
42
- @db.create_table(:tmp_dolls, :temp => true, :engine => 'MyISAM', :charset => 'latin2'){text :name}
43
- check_sqls do
44
- @db.sqls.must_equal ["CREATE TEMPORARY TABLE `tmp_dolls` (`name` text) ENGINE=MyISAM DEFAULT CHARSET=latin2"]
45
- end
46
- end
47
-
48
- it "should not use a default for a String :text=>true type" do
49
- @db.create_table(:dolls){String :name, :text=>true, :default=>'blah'}
50
- check_sqls do
51
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` text)"]
52
- end
53
- end
54
-
55
- it "should not use a default for a File type" do
56
- @db.create_table(:dolls){File :name, :default=>'blah'}
57
- check_sqls do
58
- @db.sqls.must_equal ["CREATE TABLE `dolls` (`name` blob)"]
59
- end
60
- end
61
-
62
- it "should respect the size option for File type" do
63
- @db.create_table(:dolls) do
64
- File :n1
65
- File :n2, :size=>:tiny
66
- File :n3, :size=>:medium
67
- File :n4, :size=>:long
68
- File :n5, :size=>255
69
- end
70
- @db.schema(:dolls).map{|k, v| v[:db_type]}.must_equal %w"blob tinyblob mediumblob longblob blob"
71
- end
72
-
73
- it "should include an :auto_increment schema attribute if auto incrementing" do
74
- @db.create_table(:dolls) do
75
- primary_key :n4
76
- Integer :n2
77
- String :n3
78
- end
79
- @db.schema(:dolls).map{|k, v| v[:auto_increment]}.must_equal [true, nil, nil]
80
- end
81
-
82
- it "should support collate with various other column options" do
83
- @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
84
- @db[:dolls].insert
85
- @db[:dolls].select_map(:name).must_equal ["foo"]
86
- end
87
-
88
- it "should be able to parse the default value for set and enum types" do
89
- @db.create_table!(:dolls){column :t, "set('a', 'b', 'c', 'd')", :default=>'a,b'}
90
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'a,b'
91
- @db.create_table!(:dolls){column :t, "enum('a', 'b', 'c', 'd')", :default=>'b'}
92
- @db.schema(:dolls).first.last[:ruby_default].must_equal 'b'
93
- end
94
-
95
- it "should allow setting auto_increment for existing column" do
96
- @db.create_table(:dolls){Integer :a, :primary_key=>true}
97
- @db.schema(:dolls).first.last[:auto_increment].must_equal false
98
- @db.set_column_type :dolls, :a, Integer, :auto_increment=>true
99
- @db.schema(:dolls).first.last[:auto_increment].must_equal true
100
- end
101
- end
102
-
103
- if [:mysql, :mysql2].include?(DB.adapter_scheme)
104
- describe "Sequel::MySQL::Database#convert_tinyint_to_bool" do
105
- before do
106
- @db = DB
107
- @db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
108
- @ds = @db[:booltest]
109
- end
110
- after do
111
- @db.convert_tinyint_to_bool = true
112
- @db.drop_table?(:booltest)
113
- end
114
-
115
- it "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
116
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:boolean, :integer]
117
- @db.convert_tinyint_to_bool = false
118
- @db.schema(:booltest, :reload=>true).map{|_, s| s[:type]}.must_equal [:integer, :integer]
119
- end
120
-
121
- it "should return tinyint(1)s as bools and tinyint(4)s as integers when set" do
122
- @db.convert_tinyint_to_bool = true
123
- @ds.delete
124
- @ds << {:b=>true, :i=>10}
125
- @ds.all.must_equal [{:b=>true, :i=>10}]
126
- @ds.delete
127
- @ds << {:b=>false, :i=>0}
128
- @ds.all.must_equal [{:b=>false, :i=>0}]
129
- @ds.delete
130
- @ds << {:b=>true, :i=>1}
131
- @ds.all.must_equal [{:b=>true, :i=>1}]
132
- end
133
-
134
- it "should return all tinyints as integers when unset" do
135
- @db.convert_tinyint_to_bool = false
136
- @ds.delete
137
- @ds << {:b=>true, :i=>10}
138
- @ds.all.must_equal [{:b=>1, :i=>10}]
139
- @ds.delete
140
- @ds << {:b=>false, :i=>0}
141
- @ds.all.must_equal [{:b=>0, :i=>0}]
142
-
143
- @ds.delete
144
- @ds << {:b=>1, :i=>10}
145
- @ds.all.must_equal [{:b=>1, :i=>10}]
146
- @ds.delete
147
- @ds << {:b=>0, :i=>0}
148
- @ds.all.must_equal [{:b=>0, :i=>0}]
149
- end
150
-
151
- it "should allow disabling the conversion on a per-dataset basis" do
152
- @db.convert_tinyint_to_bool = true
153
- ds = @ds.clone
154
- def ds.cast_tinyint_integer?(f) true end #mysql
155
- def ds.convert_tinyint_to_bool?() false end #mysql2
156
- ds.delete
157
- ds << {:b=>true, :i=>10}
158
- ds.all.must_equal [{:b=>1, :i=>10}]
159
- @ds.all.must_equal [{:b=>true, :i=>10}]
160
- end
161
- end
162
- end
163
-
164
- describe "A MySQL dataset" do
165
- before do
166
- DB.create_table(:items){String :name; Integer :value}
167
- @d = DB[:items]
168
- DB.sqls.clear
169
- end
170
- after do
171
- DB.drop_table?(:items)
172
- end
173
-
174
- it "should quote columns and tables using back-ticks if quoting identifiers" do
175
- @d.quote_identifiers = true
176
- @d.select(:name).sql.must_equal 'SELECT `name` FROM `items`'
177
- @d.select(Sequel.lit('COUNT(*)')).sql.must_equal 'SELECT COUNT(*) FROM `items`'
178
- @d.select(Sequel.function(:max, :value)).sql.must_equal 'SELECT max(`value`) FROM `items`'
179
- @d.select(Sequel.function(:NOW)).sql.must_equal 'SELECT NOW() FROM `items`'
180
- @d.select(Sequel.function(:max, :items__value)).sql.must_equal 'SELECT max(`items`.`value`) FROM `items`'
181
- @d.order(Sequel.expr(:name).desc).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
182
- @d.select(Sequel.lit('items.name AS item_name')).sql.must_equal 'SELECT items.name AS item_name FROM `items`'
183
- @d.select(Sequel.lit('`name`')).sql.must_equal 'SELECT `name` FROM `items`'
184
- @d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.must_equal 'SELECT max(items.`name`) AS `max_name` FROM `items`'
185
- @d.select(Sequel.function(:test, :abc, 'hello')).sql.must_equal "SELECT test(`abc`, 'hello') FROM `items`"
186
- @d.select(Sequel.function(:test, :abc__def, 'hello')).sql.must_equal "SELECT test(`abc`.`def`, 'hello') FROM `items`"
187
- @d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.must_equal "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
188
- @d.insert_sql(:value => 333).must_equal 'INSERT INTO `items` (`value`) VALUES (333)'
189
- @d.insert_sql(:x => :y).must_equal 'INSERT INTO `items` (`x`) VALUES (`y`)'
190
- end
191
-
192
- it "should quote fields correctly when reversing the order" do
193
- @d.quote_identifiers = true
194
- @d.reverse_order(:name).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC'
195
- @d.reverse_order(Sequel.desc(:name)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC'
196
- @d.reverse_order(:name, Sequel.desc(:test)).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
197
- @d.reverse_order(Sequel.desc(:name), :test).sql.must_equal 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
198
- end
199
-
200
- it "should support ORDER clause in UPDATE statements" do
201
- @d.order(:name).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
202
- end
203
-
204
- it "should support LIMIT clause in UPDATE statements" do
205
- @d.limit(10).update_sql(:value => 1).must_equal 'UPDATE `items` SET `value` = 1 LIMIT 10'
206
- end
207
-
208
- it "should support regexps" do
209
- @d << {:name => 'abc', :value => 1}
210
- @d << {:name => 'bcd', :value => 2}
211
- @d.filter(:name => /bc/).count.must_equal 2
212
- @d.filter(:name => /^bc/).count.must_equal 1
213
- end
214
-
215
- it "should have explain output" do
216
- @d.explain.must_be_kind_of(String)
217
- @d.explain(:extended=>true).must_be_kind_of(String)
218
- @d.explain.wont_equal @d.explain(:extended=>true)
219
- end
220
-
221
- it "should correctly literalize strings with comment backslashes in them" do
222
- @d.delete
223
- @d << {:name => ':\\'}
224
-
225
- @d.first[:name].must_equal ':\\'
226
- end
227
-
228
- it "should handle prepared statements with on_duplicate_key_update" do
229
- @d.db.add_index :items, :value, :unique=>true
230
- ds = @d.on_duplicate_key_update
231
- ps = ds.prepare(:insert, :insert_user_id_feature_name, :value => :$v, :name => :$n)
232
- ps.call(:v => 1, :n => 'a')
233
- ds.all.must_equal [{:value=>1, :name=>'a'}]
234
- ps.call(:v => 1, :n => 'b')
235
- ds.all.must_equal [{:value=>1, :name=>'b'}]
236
- end
237
- end
238
-
239
- describe "MySQL datasets" do
240
- before do
241
- @d = DB[:orders]
242
- end
243
-
244
- it "should correctly quote column references" do
245
- @d.quote_identifiers = true
246
- market = 'ICE'
247
- ack_stamp = Time.now - 15 * 60 # 15 minutes ago
248
- @d.select(:market, Sequel.function(:minute, Sequel.function(:from_unixtime, :ack)).as(:minute)).
249
- where{(ack > ack_stamp) & {:market => market}}.
250
- group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.must_equal \
251
- "SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
252
- end
253
- end
254
-
255
- describe "Dataset#distinct" do
256
- before do
257
- @db = DB
258
- @db.create_table!(:a) do
259
- Integer :a
260
- Integer :b
261
- end
262
- @ds = @db[:a]
263
- end
264
- after do
265
- @db.drop_table?(:a)
266
- end
267
-
268
- it "#distinct with arguments should return results distinct on those arguments" do
269
- @ds.insert(20, 10)
270
- @ds.insert(30, 10)
271
- @ds.order(:b, :a).distinct.map(:a).must_equal [20, 30]
272
- @ds.order(:b, Sequel.desc(:a)).distinct.map(:a).must_equal [30, 20]
273
- # MySQL doesn't respect orders when using the nonstandard GROUP BY
274
- [[20], [30]].must_include(@ds.order(:b, :a).distinct(:b).map(:a))
275
- end
276
- end
277
-
278
- describe "MySQL join expressions" do
279
- before do
280
- @ds = DB[:nodes]
281
- end
282
-
283
- it "should raise error for :full_outer join requests." do
284
- lambda{@ds.join_table(:full_outer, :nodes)}.must_raise(Sequel::Error)
285
- end
286
- it "should support natural left joins" do
287
- @ds.join_table(:natural_left, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
288
- end
289
- it "should support natural right joins" do
290
- @ds.join_table(:natural_right, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT JOIN `nodes`'
291
- end
292
- it "should support natural left outer joins" do
293
- @ds.join_table(:natural_left_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN `nodes`'
294
- end
295
- it "should support natural right outer joins" do
296
- @ds.join_table(:natural_right_outer, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL RIGHT OUTER JOIN `nodes`'
297
- end
298
- it "should support natural inner joins" do
299
- @ds.join_table(:natural_inner, :nodes).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT JOIN `nodes`'
300
- end
301
- it "should support cross joins" do
302
- @ds.join_table(:cross, :nodes).sql.must_equal 'SELECT * FROM `nodes` CROSS JOIN `nodes`'
303
- end
304
- it "should support cross joins as inner joins if conditions are used" do
305
- @ds.join_table(:cross, :nodes, :id=>:id).sql.must_equal 'SELECT * FROM `nodes` INNER JOIN `nodes` ON (`nodes`.`id` = `nodes`.`id`)'
306
- end
307
- it "should support straight joins (force left table to be read before right)" do
308
- @ds.join_table(:straight, :nodes).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN `nodes`'
309
- end
310
- it "should support natural joins on multiple tables." do
311
- @ds.join_table(:natural_left_outer, [:nodes, :branches]).sql.must_equal 'SELECT * FROM `nodes` NATURAL LEFT OUTER JOIN (`nodes`, `branches`)'
312
- end
313
- it "should support straight joins on multiple tables." do
314
- @ds.join_table(:straight, [:nodes,:branches]).sql.must_equal 'SELECT * FROM `nodes` STRAIGHT_JOIN (`nodes`, `branches`)'
315
- end
316
- end
317
-
318
- describe "Joined MySQL dataset" do
319
- before do
320
- @ds = DB[:nodes]
321
- end
322
-
323
- it "should quote fields correctly" do
324
- @ds.quote_identifiers = true
325
- @ds.join(:attributes, :node_id => :id).sql.must_equal "SELECT * FROM `nodes` INNER JOIN `attributes` ON (`attributes`.`node_id` = `nodes`.`id`)"
326
- end
327
-
328
- it "should put a having clause before an order by clause" do
329
- @ds.order(:aaa).having(:bbb => :ccc).sql.must_equal "SELECT * FROM `nodes` HAVING (`bbb` = `ccc`) ORDER BY `aaa`"
330
- end
331
- end
332
-
333
- describe "A MySQL database" do
334
- after do
335
- DB.drop_table?(:test_innodb)
336
- end
337
-
338
- it "should handle the creation and dropping of an InnoDB table with foreign keys" do
339
- DB.create_table!(:test_innodb, :engine=>:InnoDB){primary_key :id; foreign_key :fk, :test_innodb, :key=>:id}
340
- end
341
- end
342
-
343
- describe "A MySQL database" do
344
- before(:all) do
345
- @db = DB
346
- @db.create_table! :test2 do
347
- text :name
348
- integer :value
349
- end
350
- end
351
- after(:all) do
352
- @db.drop_table?(:test2)
353
- end
354
-
355
- it "should provide the server version" do
356
- @db.server_version.must_be :>=, 40000
357
- end
358
-
359
- it "should cache the server version" do
360
- # warm cache:
361
- @db.server_version
362
- @db.sqls.clear
363
- 3.times{@db.server_version}
364
- @db.sqls.must_be :empty?
365
- end
366
-
367
- it "should support for_share" do
368
- @db[:test2].delete
369
- @db.transaction{@db[:test2].for_share.all.must_equal []}
370
- end
371
-
372
- it "should support column operations" do
373
- @db.add_column :test2, :xyz, :text
374
-
375
- @db[:test2].columns.must_equal [:name, :value, :xyz]
376
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => '000'}
377
- @db[:test2].first[:xyz].must_equal '000'
378
-
379
- @db[:test2].columns.must_equal [:name, :value, :xyz]
380
- @db.drop_column :test2, :xyz
381
-
382
- @db[:test2].columns.must_equal [:name, :value]
383
-
384
- @db[:test2].delete
385
- @db.add_column :test2, :xyz, :text
386
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
387
-
388
- @db[:test2].columns.must_equal [:name, :value, :xyz]
389
- @db.rename_column :test2, :xyz, :zyx, :type => :text
390
- @db[:test2].columns.must_equal [:name, :value, :zyx]
391
- @db[:test2].first[:zyx].must_equal 'qqqq'
392
-
393
- @db[:test2].delete
394
- @db.add_column :test2, :tre, :text
395
- @db[:test2] << {:name => 'mmm', :value => 111, :tre => 'qqqq'}
396
-
397
- @db[:test2].columns.must_equal [:name, :value, :zyx, :tre]
398
- @db.rename_column :test2, :tre, :ert, :type => :varchar, :size=>255
399
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert]
400
- @db[:test2].first[:ert].must_equal 'qqqq'
401
-
402
- @db.add_column :test2, :xyz, :float
403
- @db[:test2].delete
404
- @db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
405
- @db.set_column_type :test2, :xyz, :integer
406
-
407
- @db[:test2].first[:xyz].must_equal 57
408
-
409
- @db.alter_table :test2 do
410
- add_index :value, :unique=>true
411
- add_foreign_key :value2, :test2, :key=>:value
412
- end
413
- @db[:test2].columns.must_equal [:name, :value, :zyx, :ert, :xyz, :value2]
414
-
415
- @db.alter_table :test2 do
416
- drop_foreign_key :value2
417
- drop_index :value
418
- end
419
- end
420
- end
421
-
422
- describe "A MySQL database with table options" do
423
- before do
424
- @options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
425
-
426
- Sequel::MySQL.default_engine = 'InnoDB'
427
- Sequel::MySQL.default_charset = 'utf8'
428
- Sequel::MySQL.default_collate = 'utf8_general_ci'
429
-
430
- @db = DB
431
- @db.drop_table?(:items)
432
-
433
- DB.sqls.clear
434
- end
435
- after do
436
- @db.drop_table?(:items)
437
-
438
- Sequel::MySQL.default_engine = nil
439
- Sequel::MySQL.default_charset = nil
440
- Sequel::MySQL.default_collate = nil
441
- end
442
-
443
- it "should allow to pass custom options (engine, charset, collate) for table creation" do
444
- @db.create_table(:items, @options){Integer :size; text :name}
445
- check_sqls do
446
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=MyISAM DEFAULT CHARSET=latin1 DEFAULT COLLATE=latin1_swedish_ci"]
447
- end
448
- end
449
-
450
- it "should use default options if specified (engine, charset, collate) for table creation" do
451
- @db.create_table(:items){Integer :size; text :name}
452
- check_sqls do
453
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_general_ci"]
454
- end
455
- end
456
-
457
- it "should not use default if option has a nil value" do
458
- @db.create_table(:items, :engine=>nil, :charset=>nil, :collate=>nil){Integer :size; text :name}
459
- check_sqls do
460
- @db.sqls.must_equal ["CREATE TABLE `items` (`size` integer, `name` text)"]
461
- end
462
- end
463
- end
464
-
465
- describe "A MySQL database" do
466
- before do
467
- @db = DB
468
- @db.drop_table?(:items)
469
- DB.sqls.clear
470
- end
471
- after do
472
- @db.drop_table?(:items, :users)
473
- end
474
-
475
- it "should support defaults for boolean columns" do
476
- @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
477
- check_sqls do
478
- @db.sqls.must_equal ["CREATE TABLE `items` (`active1` tinyint(1) DEFAULT 1, `active2` tinyint(1) DEFAULT 0)"]
479
- end
480
- end
481
-
482
- it "should correctly format CREATE TABLE statements with foreign keys" do
483
- @db.create_table(:items){primary_key :id; foreign_key :p_id, :items, :key => :id, :null => false, :on_delete => :cascade}
484
- check_sqls do
485
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `p_id` integer NOT NULL, UNIQUE (`id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`id`) ON DELETE CASCADE)"]
486
- end
487
- end
488
-
489
- it "should correctly format CREATE TABLE statements with foreign keys, when :key != the default (:id)" do
490
- @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}
491
- check_sqls do
492
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer PRIMARY KEY AUTO_INCREMENT, `other_than_id` integer, `p_id` integer NOT NULL, UNIQUE (`other_than_id`), FOREIGN KEY (`p_id`) REFERENCES `items`(`other_than_id`) ON DELETE CASCADE)"]
493
- end
494
- end
495
-
496
- it "should correctly format ALTER TABLE statements with foreign keys" do
497
- @db.create_table(:items){Integer :id}
498
- @db.create_table(:users){primary_key :id}
499
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade}
500
- check_sqls do
501
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
502
- "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
503
- "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
504
- end
505
- end
506
-
507
- it "should correctly format ALTER TABLE statements with named foreign keys" do
508
- @db.create_table(:items){Integer :id}
509
- @db.create_table(:users){primary_key :id}
510
- @db.alter_table(:items){add_foreign_key :p_id, :users, :key => :id, :null => false, :on_delete => :cascade, :foreign_key_constraint_name => :pk_items__users }
511
- check_sqls do
512
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer)",
513
- "CREATE TABLE `users` (`id` integer PRIMARY KEY AUTO_INCREMENT)",
514
- "ALTER TABLE `items` ADD COLUMN `p_id` integer NOT NULL, ADD CONSTRAINT `pk_items__users` FOREIGN KEY (`p_id`) REFERENCES `users`(`id`) ON DELETE CASCADE"]
515
- end
516
- end
517
-
518
- it "should have rename_column support keep existing options" do
519
- @db.create_table(:items){String :id, :null=>false, :default=>'blah'}
520
- @db.alter_table(:items){rename_column :id, :nid}
521
- check_sqls do
522
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` varchar(255) NOT NULL DEFAULT 'blah')", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `nid` varchar(255) NOT NULL DEFAULT 'blah'"]
523
- end
524
- @db[:items].insert
525
- @db[:items].all.must_equal [{:nid=>'blah'}]
526
- proc{@db[:items].insert(:nid=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
527
- end
528
-
529
- it "should have set_column_type support keep existing options" do
530
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
531
- @db.alter_table(:items){set_column_type :id, :Bignum}
532
- check_sqls do
533
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` bigint NOT NULL DEFAULT 5"]
534
- end
535
- @db[:items].insert
536
- @db[:items].all.must_equal [{:id=>5}]
537
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
538
- @db[:items].delete
539
- @db[:items].insert(2**40)
540
- @db[:items].all.must_equal [{:id=>2**40}]
541
- end
542
-
543
- it "should have set_column_type pass through options" do
544
- @db.create_table(:items){integer :id; enum :list, :elements=>%w[one]}
545
- @db.alter_table(:items){set_column_type :id, :int, :unsigned=>true, :size=>8; set_column_type :list, :enum, :elements=>%w[two]}
546
- check_sqls do
547
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer, `list` enum('one'))", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(8) UNSIGNED NULL, CHANGE COLUMN `list` `list` enum('two') NULL"]
548
- end
549
- end
550
-
551
- it "should have set_column_default support keep existing options" do
552
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
553
- @db.alter_table(:items){set_column_default :id, 6}
554
- check_sqls do
555
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NOT NULL DEFAULT 6"]
556
- end
557
- @db[:items].insert
558
- @db[:items].all.must_equal [{:id=>6}]
559
- proc{@db[:items].insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation)
560
- end
561
-
562
- it "should have set_column_allow_null support keep existing options" do
563
- @db.create_table(:items){Integer :id, :null=>false, :default=>5}
564
- @db.alter_table(:items){set_column_allow_null :id, true}
565
- check_sqls do
566
- @db.sqls.must_equal ["CREATE TABLE `items` (`id` integer NOT NULL DEFAULT 5)", "DESCRIBE `items`", "ALTER TABLE `items` CHANGE COLUMN `id` `id` int(11) NULL DEFAULT 5"]
567
- end
568
- @db[:items].insert
569
- @db[:items].all.must_equal [{:id=>5}]
570
- @db[:items].insert(:id=>nil)
571
- end
572
-
573
- it "should accept repeated raw sql statements using Database#<<" do
574
- @db.create_table(:items){String :name; Integer :value}
575
- @db << 'DELETE FROM items'
576
- @db[:items].count.must_equal 0
577
-
578
- @db << "INSERT INTO items (name, value) VALUES ('tutu', 1234)"
579
- @db[:items].first.must_equal(:name => 'tutu', :value => 1234)
580
-
581
- @db << 'DELETE FROM items'
582
- @db[:items].first.must_equal nil
583
- end
584
- end
585
-
586
- # Socket tests should only be run if the MySQL server is on localhost
587
- if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and DB.adapter_scheme == :mysql
588
- describe "A MySQL database" do
589
- it "should accept a socket option" do
590
- db = Sequel.mysql(DB.opts[:database], :host => 'localhost', :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
591
- db.test_connection
592
- end
593
-
594
- it "should accept a socket option without host option" do
595
- db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
596
- db.test_connection
597
- end
598
-
599
- it "should fail to connect with invalid socket" do
600
- db = Sequel.mysql(DB.opts[:database], :user => DB.opts[:user], :password => DB.opts[:password], :socket =>'blah')
601
- proc{db.test_connection}.must_raise Sequel::DatabaseConnectionError
602
- end
603
- end
604
- end
605
-
606
- describe "A MySQL database" do
607
- it "should accept a read_timeout option when connecting" do
608
- db = Sequel.connect(DB.opts.merge(:read_timeout=>22342))
609
- db.test_connection
610
- end
611
-
612
- it "should accept a connect_timeout option when connecting" do
613
- db = Sequel.connect(DB.opts.merge(:connect_timeout=>22342))
614
- db.test_connection
615
- end
616
- end
617
-
618
- describe "MySQL foreign key support" do
619
- after do
620
- DB.drop_table?(:testfk, :testpk)
621
- end
622
-
623
- it "should create table without :key" do
624
- DB.create_table!(:testpk){primary_key :id}
625
- DB.create_table!(:testfk){foreign_key :fk, :testpk}
626
- end
627
-
628
- it "should create table with composite keys without :key" do
629
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
630
- DB.create_table!(:testfk){Integer :fk; Integer :fk2; foreign_key([:fk, :fk2], :testpk)}
631
- end
632
-
633
- it "should create table with self referential without :key" do
634
- DB.create_table!(:testfk){primary_key :id; foreign_key :fk, :testfk}
635
- end
636
-
637
- it "should create table with self referential with non-autoincrementing key without :key" do
638
- DB.create_table!(:testfk){Integer :id, :primary_key=>true; foreign_key :fk, :testfk}
639
- end
640
-
641
- it "should create table with self referential with composite keys without :key" do
642
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2]); foreign_key([:fk, :fk2], :testfk)}
643
- end
644
-
645
- it "should alter table without :key" do
646
- DB.create_table!(:testpk){primary_key :id}
647
- DB.create_table!(:testfk){Integer :id}
648
- DB.alter_table(:testfk){add_foreign_key :fk, :testpk}
649
- end
650
-
651
- it "should alter table with composite keys without :key" do
652
- DB.create_table!(:testpk){Integer :id; Integer :id2; primary_key([:id, :id2])}
653
- DB.create_table!(:testfk){Integer :fk; Integer :fk2}
654
- DB.alter_table(:testfk){add_foreign_key([:fk, :fk2], :testpk)}
655
- end
656
-
657
- it "should alter table with self referential without :key" do
658
- DB.create_table!(:testfk){primary_key :id}
659
- DB.alter_table(:testfk){add_foreign_key :fk, :testfk}
660
- end
661
-
662
- it "should alter table with self referential with composite keys without :key" do
663
- DB.create_table!(:testfk){Integer :id; Integer :id2; Integer :fk; Integer :fk2; primary_key([:id, :id2])}
664
- DB.alter_table(:testfk){add_foreign_key [:fk, :fk2], :testfk}
665
- end
666
- end
667
-
668
- describe "A grouped MySQL dataset" do
669
- before do
670
- DB.create_table! :test2 do
671
- text :name
672
- integer :value
673
- end
674
- DB[:test2] << {:name => '11', :value => 10}
675
- DB[:test2] << {:name => '11', :value => 20}
676
- DB[:test2] << {:name => '11', :value => 30}
677
- DB[:test2] << {:name => '12', :value => 10}
678
- DB[:test2] << {:name => '12', :value => 20}
679
- DB[:test2] << {:name => '13', :value => 10}
680
- end
681
- after do
682
- DB.drop_table?(:test2)
683
- end
684
-
685
- it "should return the correct count for raw sql query" do
686
- ds = DB["select name FROM test2 WHERE name = '11' GROUP BY name"]
687
- ds.count.must_equal 1
688
- end
689
-
690
- it "should return the correct count for a normal dataset" do
691
- ds = DB[:test2].select(:name).where(:name => '11').group(:name)
692
- ds.count.must_equal 1
693
- end
694
- end
695
-
696
- describe "A MySQL database" do
697
- before do
698
- @db = DB
699
- @db.drop_table?(:posts)
700
- @db.sqls.clear
701
- end
702
- after do
703
- @db.drop_table?(:posts)
704
- end
705
-
706
- it "should support fulltext indexes and full_text_search" do
707
- @db.create_table(:posts, :engine=>:MyISAM){text :title; text :body; full_text_index :title; full_text_index [:title, :body]}
708
- check_sqls do
709
- @db.sqls.must_equal [
710
- "CREATE TABLE `posts` (`title` text, `body` text) ENGINE=MyISAM",
711
- "CREATE FULLTEXT INDEX `posts_title_index` ON `posts` (`title`)",
712
- "CREATE FULLTEXT INDEX `posts_title_body_index` ON `posts` (`title`, `body`)"
713
- ]
714
- end
715
-
716
- @db[:posts].insert(:title=>'ruby rails', :body=>'y')
717
- @db[:posts].insert(:title=>'sequel', :body=>'ruby')
718
- @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
719
- @db.sqls.clear
720
-
721
- @db[:posts].full_text_search(:title, 'rails').all.must_equal [{:title=>'ruby rails', :body=>'y'}]
722
- @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.must_equal [{:title=>'sequel', :body=>'ruby'}]
723
- @db[:posts].full_text_search(:title, '+ruby -rails', :boolean => true).all.must_equal [{:title=>'ruby scooby', :body=>'x'}]
724
- check_sqls do
725
- @db.sqls.must_equal [
726
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
727
- "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
728
- "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
729
- end
730
-
731
- @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
732
- @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').must_equal [{:title=>'ruby rails', :body=>'y'}]
733
- end
734
-
735
- it "should support spatial indexes" do
736
- @db.create_table(:posts, :engine=>:MyISAM){point :geom, :null=>false; spatial_index [:geom]}
737
- check_sqls do
738
- @db.sqls.must_equal [
739
- "CREATE TABLE `posts` (`geom` point NOT NULL) ENGINE=MyISAM",
740
- "CREATE SPATIAL INDEX `posts_geom_index` ON `posts` (`geom`)"
741
- ]
742
- end
743
- end
744
-
745
- it "should support indexes with index type" do
746
- @db.create_table(:posts){Integer :id; index :id, :type => :btree}
747
- check_sqls do
748
- @db.sqls.must_equal [
749
- "CREATE TABLE `posts` (`id` integer)",
750
- "CREATE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
751
- ]
752
- end
753
- end
754
-
755
- it "should support unique indexes with index type" do
756
- @db.create_table(:posts){Integer :id; index :id, :type => :btree, :unique => true}
757
- check_sqls do
758
- @db.sqls.must_equal [
759
- "CREATE TABLE `posts` (`id` integer)",
760
- "CREATE UNIQUE INDEX `posts_id_index` USING btree ON `posts` (`id`)"
761
- ]
762
- end
763
- end
764
-
765
- it "should not dump partial indexes" do
766
- @db.create_table(:posts){text :id}
767
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
768
- @db.indexes(:posts).must_equal({})
769
- end
770
-
771
- it "should dump partial indexes if :partial option is set to true" do
772
- @db.create_table(:posts){text :id}
773
- @db << "CREATE INDEX posts_id_index ON posts (id(10))"
774
- @db.indexes(:posts, :partial => true).must_equal(:posts_id_index => {:columns => [:id], :unique => false})
775
- end
776
- end
777
-
778
- describe "MySQL::Dataset#insert and related methods" do
779
- before do
780
- DB.create_table(:items){String :name; Integer :value}
781
- @d = DB[:items]
782
- DB.sqls.clear
783
- end
784
- after do
785
- DB.drop_table?(:items)
786
- end
787
-
788
- it "#insert should insert record with default values when no arguments given" do
789
- @d.insert
790
- check_sqls do
791
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
792
- end
793
- @d.all.must_equal [{:name => nil, :value => nil}]
794
- end
795
-
796
- it "#insert should insert record with default values when empty hash given" do
797
- @d.insert({})
798
- check_sqls do
799
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
800
- end
801
- @d.all.must_equal [{:name => nil, :value => nil}]
802
- end
803
-
804
- it "#insert should insert record with default values when empty array given" do
805
- @d.insert []
806
- check_sqls do
807
- DB.sqls.must_equal ["INSERT INTO `items` () VALUES ()"]
808
- end
809
- @d.all.must_equal [{:name => nil, :value => nil}]
810
- end
811
-
812
- it "#on_duplicate_key_update should work with regular inserts" do
813
- DB.add_index :items, :name, :unique=>true
814
- DB.sqls.clear
815
- @d.insert(:name => 'abc', :value => 1)
816
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'abc', :value => 1)
817
- @d.on_duplicate_key_update(:name, :value => 6).insert(:name => 'def', :value => 2)
818
-
819
- check_sqls do
820
- DB.sqls.length.must_equal 3
821
- DB.sqls[0].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\)\z/)
822
- DB.sqls[1].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('abc'|1), (1|'abc')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
823
- DB.sqls[2].must_match(/\AINSERT INTO `items` \(`(name|value)`, `(name|value)`\) VALUES \(('def'|2), (2|'def')\) ON DUPLICATE KEY UPDATE `name`=VALUES\(`name`\), `value`=6\z/)
824
- end
825
-
826
- @d.all.must_equal [{:name => 'abc', :value => 6}, {:name => 'def', :value => 2}]
827
- end
828
-
829
- it "#multi_replace should insert multiple records in a single statement" do
830
- @d.multi_replace([{:name => 'abc'}, {:name => 'def'}])
831
-
832
- check_sqls do
833
- DB.sqls.must_equal [
834
- SQL_BEGIN,
835
- "REPLACE INTO `items` (`name`) VALUES ('abc'), ('def')",
836
- SQL_COMMIT
837
- ]
838
- end
839
-
840
- @d.all.must_equal [
841
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
842
- ]
843
- end
844
-
845
- it "#multi_replace should split the list of records into batches if :commit_every option is given" do
846
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
847
- :commit_every => 2)
848
-
849
- check_sqls do
850
- DB.sqls.must_equal [
851
- SQL_BEGIN,
852
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
853
- SQL_COMMIT,
854
- SQL_BEGIN,
855
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
856
- SQL_COMMIT
857
- ]
858
- end
859
-
860
- @d.all.must_equal [
861
- {:name => nil, :value => 1},
862
- {:name => nil, :value => 2},
863
- {:name => nil, :value => 3},
864
- {:name => nil, :value => 4}
865
- ]
866
- end
867
-
868
- it "#multi_replace should split the list of records into batches if :slice option is given" do
869
- @d.multi_replace([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
870
- :slice => 2)
871
-
872
- check_sqls do
873
- DB.sqls.must_equal [
874
- SQL_BEGIN,
875
- "REPLACE INTO `items` (`value`) VALUES (1), (2)",
876
- SQL_COMMIT,
877
- SQL_BEGIN,
878
- "REPLACE INTO `items` (`value`) VALUES (3), (4)",
879
- SQL_COMMIT
880
- ]
881
- end
882
-
883
- @d.all.must_equal [
884
- {:name => nil, :value => 1},
885
- {:name => nil, :value => 2},
886
- {:name => nil, :value => 3},
887
- {:name => nil, :value => 4}
888
- ]
889
- end
890
-
891
- it "#multi_insert should insert multiple records in a single statement" do
892
- @d.multi_insert([{:name => 'abc'}, {:name => 'def'}])
893
-
894
- check_sqls do
895
- DB.sqls.must_equal [
896
- SQL_BEGIN,
897
- "INSERT INTO `items` (`name`) VALUES ('abc'), ('def')",
898
- SQL_COMMIT
899
- ]
900
- end
901
-
902
- @d.all.must_equal [
903
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
904
- ]
905
- end
906
-
907
- it "#multi_insert should split the list of records into batches if :commit_every option is given" do
908
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
909
- :commit_every => 2)
910
-
911
- check_sqls do
912
- DB.sqls.must_equal [
913
- SQL_BEGIN,
914
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
915
- SQL_COMMIT,
916
- SQL_BEGIN,
917
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
918
- SQL_COMMIT
919
- ]
920
- end
921
-
922
- @d.all.must_equal [
923
- {:name => nil, :value => 1},
924
- {:name => nil, :value => 2},
925
- {:name => nil, :value => 3},
926
- {:name => nil, :value => 4}
927
- ]
928
- end
929
-
930
- it "#multi_insert should split the list of records into batches if :slice option is given" do
931
- @d.multi_insert([{:value => 1}, {:value => 2}, {:value => 3}, {:value => 4}],
932
- :slice => 2)
933
-
934
- check_sqls do
935
- DB.sqls.must_equal [
936
- SQL_BEGIN,
937
- "INSERT INTO `items` (`value`) VALUES (1), (2)",
938
- SQL_COMMIT,
939
- SQL_BEGIN,
940
- "INSERT INTO `items` (`value`) VALUES (3), (4)",
941
- SQL_COMMIT
942
- ]
943
- end
944
-
945
- @d.all.must_equal [
946
- {:name => nil, :value => 1},
947
- {:name => nil, :value => 2},
948
- {:name => nil, :value => 3},
949
- {:name => nil, :value => 4}
950
- ]
951
- end
952
-
953
- it "#import should support inserting using columns and values arrays" do
954
- @d.import([:name, :value], [['abc', 1], ['def', 2]])
955
-
956
- check_sqls do
957
- DB.sqls.must_equal [
958
- SQL_BEGIN,
959
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2)",
960
- SQL_COMMIT
961
- ]
962
- end
963
-
964
- @d.all.must_equal [
965
- {:name => 'abc', :value => 1},
966
- {:name => 'def', :value => 2}
967
- ]
968
- end
969
-
970
- it "#insert_ignore should add the IGNORE keyword when inserting" do
971
- @d.insert_ignore.multi_insert([{:name => 'abc'}, {:name => 'def'}])
972
-
973
- check_sqls do
974
- DB.sqls.must_equal [
975
- SQL_BEGIN,
976
- "INSERT IGNORE INTO `items` (`name`) VALUES ('abc'), ('def')",
977
- SQL_COMMIT
978
- ]
979
- end
980
-
981
- @d.all.must_equal [
982
- {:name => 'abc', :value => nil}, {:name => 'def', :value => nil}
983
- ]
984
- end
985
-
986
- it "#insert_ignore should add the IGNORE keyword for single inserts" do
987
- @d.insert_ignore.insert(:name => 'ghi')
988
- check_sqls do
989
- DB.sqls.must_equal ["INSERT IGNORE INTO `items` (`name`) VALUES ('ghi')"]
990
- end
991
- @d.all.must_equal [{:name => 'ghi', :value => nil}]
992
- end
993
-
994
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and ALL columns when no args given" do
995
- @d.on_duplicate_key_update.import([:name,:value], [['abc', 1], ['def',2]])
996
-
997
- check_sqls do
998
- DB.sqls.must_equal [
999
- "SELECT * FROM `items` LIMIT 1",
1000
- SQL_BEGIN,
1001
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`), `value`=VALUES(`value`)",
1002
- SQL_COMMIT
1003
- ]
1004
- end
1005
-
1006
- @d.all.must_equal [
1007
- {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
1008
- ]
1009
- end
1010
-
1011
- it "#on_duplicate_key_update should add the ON DUPLICATE KEY UPDATE and columns specified when args are given" do
1012
- @d.on_duplicate_key_update(:value).import([:name,:value],
1013
- [['abc', 1], ['def',2]]
1014
- )
1015
-
1016
- check_sqls do
1017
- DB.sqls.must_equal [
1018
- SQL_BEGIN,
1019
- "INSERT INTO `items` (`name`, `value`) VALUES ('abc', 1), ('def', 2) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)",
1020
- SQL_COMMIT
1021
- ]
1022
- end
1023
-
1024
- @d.all.must_equal [
1025
- {:name => 'abc', :value => 1}, {:name => 'def', :value => 2}
1026
- ]
1027
- end
1028
-
1029
- end
1030
-
1031
- describe "MySQL::Dataset#update and related methods" do
1032
- before do
1033
- DB.create_table(:items){String :name; Integer :value; index :name, :unique=>true}
1034
- @d = DB[:items]
1035
- end
1036
- after do
1037
- DB.drop_table?(:items)
1038
- end
1039
-
1040
- it "#update_ignore should not raise error where normal update would fail" do
1041
- @d.insert(:name => 'cow', :value => 0)
1042
- @d.insert(:name => 'cat', :value => 1)
1043
- proc{@d.where(:value => 1).update(:name => 'cow')}.must_raise(Sequel::UniqueConstraintViolation)
1044
- DB.sqls.clear
1045
- @d.update_ignore.where(:value => 1).update(:name => 'cow')
1046
- check_sqls do
1047
- DB.sqls.must_equal ["UPDATE IGNORE `items` SET `name` = 'cow' WHERE (`value` = 1)"]
1048
- end
1049
- @d.order(:name).all.must_equal [{:name => 'cat', :value => 1}, {:name => 'cow', :value => 0}]
1050
- end
1051
- end
1052
-
1053
- describe "MySQL::Dataset#replace" do
1054
- before do
1055
- DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
1056
- @d = DB[:items]
1057
- DB.sqls.clear
1058
- end
1059
- after do
1060
- DB.drop_table?(:items)
1061
- end
1062
-
1063
- it "should use default values if they exist" do
1064
- DB.alter_table(:items){set_column_default :id, 1; set_column_default :value, 2}
1065
- @d.replace
1066
- @d.all.must_equal [{:id=>1, :value=>2}]
1067
- @d.replace([])
1068
- @d.all.must_equal [{:id=>1, :value=>2}]
1069
- @d.replace({})
1070
- @d.all.must_equal [{:id=>1, :value=>2}]
1071
- end
1072
- end
1073
-
1074
- describe "MySQL::Dataset#complex_expression_sql" do
1075
- before do
1076
- @d = DB.dataset
1077
- end
1078
-
1079
- it "should handle string concatenation with CONCAT if more than one record" do
1080
- @d.literal(Sequel.join([:x, :y])).must_equal "CONCAT(`x`, `y`)"
1081
- @d.literal(Sequel.join([:x, :y], ' ')).must_equal "CONCAT(`x`, ' ', `y`)"
1082
- @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)"
1083
- end
1084
-
1085
- it "should handle string concatenation as simple string if just one record" do
1086
- @d.literal(Sequel.join([:x])).must_equal "`x`"
1087
- @d.literal(Sequel.join([:x], ' ')).must_equal "`x`"
1088
- end
1089
- end
1090
-
1091
- describe "MySQL::Dataset#calc_found_rows" do
1092
- before do
1093
- DB.create_table!(:items){Integer :a}
1094
- end
1095
- after do
1096
- DB.drop_table?(:items)
1097
- end
1098
-
1099
- it "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
1100
- DB[:items].select(:a).calc_found_rows.limit(1).sql.must_equal \
1101
- 'SELECT SQL_CALC_FOUND_ROWS `a` FROM `items` LIMIT 1'
1102
- end
1103
-
1104
- it "should count matching rows disregarding LIMIT clause" do
1105
- DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
1106
- DB.sqls.clear
1107
-
1108
- DB.synchronize do
1109
- DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.must_equal [{:a => 1}]
1110
- DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.must_equal [{:rows => 2 }]
1111
- end
1112
-
1113
- check_sqls do
1114
- DB.sqls.must_equal [
1115
- 'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',
1116
- 'SELECT FOUND_ROWS() AS `rows`',
1117
- ]
1118
- end
1119
- end
1120
- end
1121
-
1122
- if DB.adapter_scheme == :mysql or DB.adapter_scheme == :jdbc or DB.adapter_scheme == :mysql2
1123
- describe "MySQL Stored Procedures" do
1124
- before do
1125
- DB.create_table(:items){Integer :id; Integer :value}
1126
- @d = DB[:items]
1127
- DB.sqls.clear
1128
- end
1129
- after do
1130
- DB.drop_table?(:items)
1131
- DB.execute('DROP PROCEDURE test_sproc')
1132
- end
1133
-
1134
- it "should be callable on the database object" do
1135
- DB.execute_ddl('CREATE PROCEDURE test_sproc() BEGIN DELETE FROM items; END')
1136
- DB[:items].delete
1137
- DB[:items].insert(:value=>1)
1138
- DB[:items].count.must_equal 1
1139
- DB.call_sproc(:test_sproc)
1140
- DB[:items].count.must_equal 0
1141
- end
1142
-
1143
- # Mysql2 doesn't support stored procedures that return result sets, probably because
1144
- # CLIENT_MULTI_RESULTS is not set.
1145
- unless DB.adapter_scheme == :mysql2
1146
- it "should be callable on the dataset object" do
1147
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
1148
- DB[:items].delete
1149
- @d = DB[:items]
1150
- @d.call_sproc(:select, :test_sproc, 3).must_equal []
1151
- @d.insert(:value=>1)
1152
- @d.call_sproc(:select, :test_sproc, 4).must_equal [{:id=>nil, :value=>1, :b=>4}]
1153
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1154
- @d.call_sproc(:select, :test_sproc, 3).must_equal [{:id=>nil, :value=>2, :b=>6}]
1155
- end
1156
-
1157
- it "should be callable on the dataset object with multiple arguments" do
1158
- DB.execute_ddl('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
1159
- DB[:items].delete
1160
- @d = DB[:items]
1161
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal []
1162
- @d.insert(:value=>1)
1163
- @d.call_sproc(:select, :test_sproc, 4, 5).must_equal [{:id=>nil, :value=>1, :b=>4, :d=>5}]
1164
- @d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
1165
- @d.call_sproc(:select, :test_sproc, 3, 4).must_equal [{:id=>nil, :value=>2, :b=>6, :d => 8}]
1166
- end
1167
- end
1168
-
1169
- it "should deal with nil values" do
1170
- DB.execute_ddl('CREATE PROCEDURE test_sproc(i INTEGER, v INTEGER) BEGIN INSERT INTO items VALUES (i, v); END')
1171
- DB[:items].delete
1172
- DB.call_sproc(:test_sproc, :args=>[1, nil])
1173
- DB[:items].all.must_equal [{:id=>1, :value=>nil}]
1174
- end
1175
- end
1176
- end
1177
-
1178
- if DB.adapter_scheme == :mysql
1179
- describe "MySQL bad date/time conversions" do
1180
- after do
1181
- DB.convert_invalid_date_time = false
1182
- end
1183
-
1184
- it "should raise an exception when a bad date/time is used and convert_invalid_date_time is false" do
1185
- DB.convert_invalid_date_time = false
1186
- proc{DB["SELECT CAST('0000-00-00' AS date)"].single_value}.must_raise(Sequel::InvalidValue)
1187
- proc{DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value}.must_raise(Sequel::InvalidValue)
1188
- proc{DB["SELECT CAST('25:00:00' AS time)"].single_value}.must_raise(Sequel::InvalidValue)
1189
- end
1190
-
1191
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is nil or :nil" do
1192
- DB.convert_invalid_date_time = nil
1193
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
1194
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
1195
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
1196
- DB.convert_invalid_date_time = :nil
1197
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal nil
1198
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal nil
1199
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal nil
1200
- end
1201
-
1202
- it "should not use a nil value bad date/time is used and convert_invalid_date_time is :string" do
1203
- DB.convert_invalid_date_time = :string
1204
- DB["SELECT CAST('0000-00-00' AS date)"].single_value.must_equal '0000-00-00'
1205
- DB["SELECT CAST('0000-00-00 00:00:00' AS datetime)"].single_value.must_equal '0000-00-00 00:00:00'
1206
- DB["SELECT CAST('25:00:00' AS time)"].single_value.must_equal '25:00:00'
1207
- end
1208
- end
1209
-
1210
- describe "MySQL multiple result sets" do
1211
- before do
1212
- DB.create_table!(:a){Integer :a}
1213
- DB.create_table!(:b){Integer :b}
1214
- @ds = DB['SELECT * FROM a; SELECT * FROM b']
1215
- DB[:a].insert(10)
1216
- DB[:a].insert(15)
1217
- DB[:b].insert(20)
1218
- DB[:b].insert(25)
1219
- end
1220
- after do
1221
- DB.drop_table?(:a, :b)
1222
- end
1223
-
1224
- it "should combine all results by default" do
1225
- @ds.all.must_equal [{:a=>10}, {:a=>15}, {:b=>20}, {:b=>25}]
1226
- end
1227
-
1228
- it "should work with Database#run" do
1229
- DB.run('SELECT * FROM a; SELECT * FROM b')
1230
- DB.run('SELECT * FROM a; SELECT * FROM b')
1231
- end
1232
-
1233
- it "should work with Database#run and other statements" do
1234
- DB.run('UPDATE a SET a = 1; SELECT * FROM a; DELETE FROM b')
1235
- DB[:a].select_order_map(:a).must_equal [1, 1]
1236
- DB[:b].all.must_equal []
1237
- end
1238
-
1239
- it "should split results returned into arrays if split_multiple_result_sets is used" do
1240
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>10}, {:a=>15}], [{:b=>20}, {:b=>25}]]
1241
- end
1242
-
1243
- it "should have regular row_procs work when splitting multiple result sets" do
1244
- @ds.row_proc = proc{|x| x[x.keys.first] *= 2; x}
1245
- @ds.split_multiple_result_sets.all.must_equal [[{:a=>20}, {:a=>30}], [{:b=>40}, {:b=>50}]]
1246
- end
1247
-
1248
- it "should use the columns from the first result set when splitting result sets" do
1249
- @ds.split_multiple_result_sets.columns.must_equal [:a]
1250
- end
1251
-
1252
- it "should not allow graphing a dataset that splits multiple statements" do
1253
- proc{@ds.split_multiple_result_sets.graph(:b, :b=>:a)}.must_raise(Sequel::Error)
1254
- end
1255
-
1256
- it "should not allow splitting a graphed dataset" do
1257
- proc{DB[:a].graph(:b, :b=>:a).split_multiple_result_sets}.must_raise(Sequel::Error)
1258
- end
1259
- end
1260
- end
1261
-
1262
- if DB.adapter_scheme == :mysql2
1263
- describe "Mysql2 streaming" do
1264
- before(:all) do
1265
- DB.create_table!(:a){Integer :a}
1266
- DB.transaction do
1267
- 1000.times do |i|
1268
- DB[:a].insert(i)
1269
- end
1270
- end
1271
- @ds = DB[:a].stream.order(:a)
1272
- end
1273
- after(:all) do
1274
- DB.drop_table?(:a)
1275
- end
1276
-
1277
- it "should correctly stream results" do
1278
- @ds.map(:a).must_equal((0...1000).to_a)
1279
- end
1280
-
1281
- it "should correctly handle early returning when streaming results" do
1282
- 3.times{@ds.each{|r| break r[:a]}.must_equal 0}
1283
- end
1284
- end
1285
- end
1286
-
1287
- describe "MySQL joined datasets" do
1288
- before do
1289
- @db = DB
1290
- @db.create_table!(:a) do
1291
- Integer :id
1292
- end
1293
- @db.create_table!(:b) do
1294
- Integer :id
1295
- Integer :a_id
1296
- end
1297
- @db[:a].insert(1)
1298
- @db[:a].insert(2)
1299
- @db[:b].insert(3, 1)
1300
- @db[:b].insert(4, 1)
1301
- @db[:b].insert(5, 2)
1302
- @ds = @db[:a].join(:b, :a_id=>:id)
1303
- end
1304
- after do
1305
- @db.drop_table?(:a, :b)
1306
- end
1307
-
1308
- it "should support deletions from a single table" do
1309
- @ds.where(:a__id=>1).delete
1310
- @db[:a].select_order_map(:id).must_equal [2]
1311
- @db[:b].select_order_map(:id).must_equal [3, 4, 5]
1312
- end
1313
-
1314
- it "should support deletions from multiple tables" do
1315
- @ds.delete_from(:a, :b).where(:a__id=>1).delete
1316
- @db[:a].select_order_map(:id).must_equal [2]
1317
- @db[:b].select_order_map(:id).must_equal [5]
1318
- end
1319
- end