sequel 4.26.0 → 5.37.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  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/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,2531 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
-
3
- describe "A new Database" do
4
- before do
5
- @db = Sequel::Database.new(1 => 2, :logger => 3)
6
- end
7
- after do
8
- Sequel.quote_identifiers = false
9
- Sequel.identifier_input_method = nil
10
- Sequel.identifier_output_method = nil
11
- end
12
-
13
- it "should receive options" do
14
- @db.opts[1].must_equal 2
15
- @db.opts[:logger].must_equal 3
16
- end
17
-
18
- it "should set the logger from opts[:logger] and opts[:loggers]" do
19
- @db.loggers.must_equal [3]
20
- Sequel::Database.new(1 => 2, :loggers => 3).loggers.must_equal [3]
21
- Sequel::Database.new(1 => 2, :loggers => [3]).loggers.must_equal [3]
22
- Sequel::Database.new(1 => 2, :logger => 4, :loggers => 3).loggers.must_equal [4,3]
23
- Sequel::Database.new(1 => 2, :logger => [4], :loggers => [3]).loggers.must_equal [4,3]
24
- end
25
-
26
- it "should support :preconnect option to preconnect to database" do
27
- @db.pool.size.must_equal 0
28
- c = Class.new(Sequel::Database) do
29
- def connect(_)
30
- :connect
31
- end
32
- end
33
- db = c.new(1 => 2, :logger => 3, :preconnect=>true)
34
- db.pool.size.must_equal db.pool.max_size
35
- end
36
-
37
- it "should handle the default string column size" do
38
- @db.default_string_column_size.must_equal 255
39
- db = Sequel::Database.new(:default_string_column_size=>50)
40
- db.default_string_column_size.must_equal 50
41
- db.default_string_column_size = 2
42
- db.default_string_column_size.must_equal 2
43
- end
44
-
45
- it "should set the sql_log_level from opts[:sql_log_level]" do
46
- Sequel::Database.new(1 => 2, :sql_log_level=>:debug).sql_log_level.must_equal :debug
47
- Sequel::Database.new(1 => 2, :sql_log_level=>'debug').sql_log_level.must_equal :debug
48
- end
49
-
50
- it "should create a connection pool" do
51
- @db.pool.must_be_kind_of(Sequel::ConnectionPool)
52
- @db.pool.max_size.must_equal 4
53
-
54
- Sequel::Database.new(:max_connections => 10).pool.max_size.must_equal 10
55
- end
56
-
57
- it "should have the connection pool use the connect method to get connections" do
58
- cc = nil
59
- d = Sequel::Database.new
60
- meta_def(d, :connect){|c| 1234}
61
- d.synchronize {|c| cc = c}
62
- cc.must_equal 1234
63
- end
64
-
65
- it "should respect the :single_threaded option" do
66
- db = Sequel::Database.new(:single_threaded=>true){123}
67
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
68
- db = Sequel::Database.new(:single_threaded=>'t'){123}
69
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
70
- db = Sequel::Database.new(:single_threaded=>'1'){123}
71
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
72
- db = Sequel::Database.new(:single_threaded=>false){123}
73
- db.pool.must_be_kind_of(Sequel::ConnectionPool)
74
- db = Sequel::Database.new(:single_threaded=>'f'){123}
75
- db.pool.must_be_kind_of(Sequel::ConnectionPool)
76
- db = Sequel::Database.new(:single_threaded=>'0'){123}
77
- db.pool.must_be_kind_of(Sequel::ConnectionPool)
78
- end
79
-
80
- it "should respect the :quote_identifiers option" do
81
- db = Sequel::Database.new(:quote_identifiers=>false)
82
- db.quote_identifiers?.must_equal false
83
- db = Sequel::Database.new(:quote_identifiers=>true)
84
- db.quote_identifiers?.must_equal true
85
- end
86
-
87
- it "should upcase on input and downcase on output by default" do
88
- db = Sequel::Database.new
89
- db.send(:identifier_input_method_default).must_equal :upcase
90
- db.send(:identifier_output_method_default).must_equal :downcase
91
- end
92
-
93
- it "should respect the :identifier_input_method option" do
94
- Sequel.identifier_input_method = nil
95
- Sequel::Database.identifier_input_method.must_equal false
96
- db = Sequel::Database.new(:identifier_input_method=>nil)
97
- db.identifier_input_method.must_equal nil
98
- db.identifier_input_method = :downcase
99
- db.identifier_input_method.must_equal :downcase
100
- db = Sequel::Database.new(:identifier_input_method=>:upcase)
101
- db.identifier_input_method.must_equal :upcase
102
- db.identifier_input_method = nil
103
- db.identifier_input_method.must_equal nil
104
- Sequel.identifier_input_method = :downcase
105
- Sequel::Database.identifier_input_method.must_equal :downcase
106
- db = Sequel::Database.new(:identifier_input_method=>nil)
107
- db.identifier_input_method.must_equal nil
108
- db.identifier_input_method = :upcase
109
- db.identifier_input_method.must_equal :upcase
110
- db = Sequel::Database.new(:identifier_input_method=>:upcase)
111
- db.identifier_input_method.must_equal :upcase
112
- db.identifier_input_method = nil
113
- db.identifier_input_method.must_equal nil
114
- end
115
-
116
- it "should respect the :identifier_output_method option" do
117
- Sequel.identifier_output_method = nil
118
- Sequel::Database.identifier_output_method.must_equal false
119
- db = Sequel::Database.new(:identifier_output_method=>nil)
120
- db.identifier_output_method.must_equal nil
121
- db.identifier_output_method = :downcase
122
- db.identifier_output_method.must_equal :downcase
123
- db = Sequel::Database.new(:identifier_output_method=>:upcase)
124
- db.identifier_output_method.must_equal :upcase
125
- db.identifier_output_method = nil
126
- db.identifier_output_method.must_equal nil
127
- Sequel.identifier_output_method = :downcase
128
- Sequel::Database.identifier_output_method.must_equal :downcase
129
- db = Sequel::Database.new(:identifier_output_method=>nil)
130
- db.identifier_output_method.must_equal nil
131
- db.identifier_output_method = :upcase
132
- db.identifier_output_method.must_equal :upcase
133
- db = Sequel::Database.new(:identifier_output_method=>:upcase)
134
- db.identifier_output_method.must_equal :upcase
135
- db.identifier_output_method = nil
136
- db.identifier_output_method.must_equal nil
137
- end
138
-
139
- it "should use the default Sequel.quote_identifiers value" do
140
- Sequel.quote_identifiers = true
141
- Sequel::Database.new({}).quote_identifiers?.must_equal true
142
- Sequel.quote_identifiers = false
143
- Sequel::Database.new({}).quote_identifiers?.must_equal false
144
- Sequel::Database.quote_identifiers = true
145
- Sequel::Database.new({}).quote_identifiers?.must_equal true
146
- Sequel::Database.quote_identifiers = false
147
- Sequel::Database.new({}).quote_identifiers?.must_equal false
148
- end
149
-
150
- it "should use the default Sequel.identifier_input_method value" do
151
- Sequel.identifier_input_method = :downcase
152
- Sequel::Database.new({}).identifier_input_method.must_equal :downcase
153
- Sequel.identifier_input_method = :upcase
154
- Sequel::Database.new({}).identifier_input_method.must_equal :upcase
155
- Sequel::Database.identifier_input_method = :downcase
156
- Sequel::Database.new({}).identifier_input_method.must_equal :downcase
157
- Sequel::Database.identifier_input_method = :upcase
158
- Sequel::Database.new({}).identifier_input_method.must_equal :upcase
159
- end
160
-
161
- it "should use the default Sequel.identifier_output_method value" do
162
- Sequel.identifier_output_method = :downcase
163
- Sequel::Database.new({}).identifier_output_method.must_equal :downcase
164
- Sequel.identifier_output_method = :upcase
165
- Sequel::Database.new({}).identifier_output_method.must_equal :upcase
166
- Sequel::Database.identifier_output_method = :downcase
167
- Sequel::Database.new({}).identifier_output_method.must_equal :downcase
168
- Sequel::Database.identifier_output_method = :upcase
169
- Sequel::Database.new({}).identifier_output_method.must_equal :upcase
170
- end
171
-
172
- it "should respect the quote_indentifiers_default method if Sequel.quote_identifiers = nil" do
173
- Sequel.quote_identifiers = nil
174
- Sequel::Database.new({}).quote_identifiers?.must_equal true
175
- x = Class.new(Sequel::Database){def quote_identifiers_default; false end}
176
- x.new({}).quote_identifiers?.must_equal false
177
- y = Class.new(Sequel::Database){def quote_identifiers_default; true end}
178
- y.new({}).quote_identifiers?.must_equal true
179
- end
180
-
181
- it "should respect the identifier_input_method_default method" do
182
- class Sequel::Database
183
- @identifier_input_method = nil
184
- end
185
- x = Class.new(Sequel::Database){def identifier_input_method_default; :downcase end}
186
- x.new({}).identifier_input_method.must_equal :downcase
187
- y = Class.new(Sequel::Database){def identifier_input_method_default; :camelize end}
188
- y.new({}).identifier_input_method.must_equal :camelize
189
- end
190
-
191
- it "should respect the identifier_output_method_default method if Sequel.identifier_output_method is not called" do
192
- class Sequel::Database
193
- @identifier_output_method = nil
194
- end
195
- x = Class.new(Sequel::Database){def identifier_output_method_default; :upcase end}
196
- x.new({}).identifier_output_method.must_equal :upcase
197
- y = Class.new(Sequel::Database){def identifier_output_method_default; :underscore end}
198
- y.new({}).identifier_output_method.must_equal :underscore
199
- end
200
-
201
- it "should just use a :uri option for jdbc with the full connection string" do
202
- db = Sequel::Database.stub(:adapter_class, Sequel::Database) do
203
- Sequel.connect('jdbc:test://host/db_name')
204
- end
205
- db.must_be_kind_of(Sequel::Database)
206
- db.opts[:uri].must_equal 'jdbc:test://host/db_name'
207
- end
208
-
209
- it "should just use a :uri option for do with the full connection string" do
210
- db = Sequel::Database.stub(:adapter_class, Sequel::Database) do
211
- Sequel.connect('do:test://host/db_name')
212
- end
213
- db.must_be_kind_of(Sequel::Database)
214
- db.opts[:uri].must_equal 'do:test://host/db_name'
215
- end
216
-
217
- it "should populate :adapter option when using connection string" do
218
- Sequel.connect('mock:/').opts[:adapter].must_equal "mock"
219
- end
220
-
221
- it "should respect the :keep_reference option for not keeping a reference in Sequel::DATABASES" do
222
- db = Sequel.connect('mock:///?keep_reference=f')
223
- Sequel::DATABASES.wont_include(db)
224
- end
225
- end
226
-
227
- describe "Database#disconnect" do
228
- it "should call pool.disconnect" do
229
- d = Sequel::Database.new
230
- p = d.pool
231
- def p.disconnect(h)
232
- raise unless h == {}
233
- 2
234
- end
235
- d.disconnect.must_equal 2
236
- end
237
- end
238
-
239
- describe "Sequel.extension" do
240
- it "should attempt to load the given extension" do
241
- proc{Sequel.extension :blah}.must_raise(LoadError)
242
- end
243
- end
244
-
245
- describe "Database#log_info" do
246
- before do
247
- @o = Object.new
248
- def @o.logs; @logs || []; end
249
- def @o.to_ary; [self]; end
250
- def @o.method_missing(*args); (@logs ||= []) << args; end
251
- @db = Sequel::Database.new(:logger=>@o)
252
- end
253
-
254
- it "should log message at info level to all loggers" do
255
- @db.log_info('blah')
256
- @o.logs.must_equal [[:info, 'blah']]
257
- end
258
-
259
- it "should log message with args at info level to all loggers" do
260
- @db.log_info('blah', [1, 2])
261
- @o.logs.must_equal [[:info, 'blah; [1, 2]']]
262
- end
263
- end
264
-
265
- describe "Database#log_yield" do
266
- before do
267
- @o = Object.new
268
- def @o.logs; @logs || []; end
269
- def @o.warn(*args); (@logs ||= []) << [:warn] + args; end
270
- def @o.method_missing(*args); (@logs ||= []) << args; end
271
- def @o.to_ary; [self]; end
272
- @db = Sequel::Database.new(:logger=>@o)
273
- end
274
-
275
- it "should yield to the passed block" do
276
- a = nil
277
- @db.log_yield('blah'){a = 1}
278
- a.must_equal 1
279
- end
280
-
281
- it "should raise an exception if a block is not passed" do
282
- proc{@db.log_yield('blah')}.must_raise LocalJumpError
283
- end
284
-
285
- it "should log message with duration at info level to all loggers" do
286
- @db.log_yield('blah'){}
287
- @o.logs.length.must_equal 1
288
- @o.logs.first.length.must_equal 2
289
- @o.logs.first.first.must_equal :info
290
- @o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
291
- end
292
-
293
- it "should respect sql_log_level setting" do
294
- @db.sql_log_level = :debug
295
- @db.log_yield('blah'){}
296
- @o.logs.length.must_equal 1
297
- @o.logs.first.length.must_equal 2
298
- @o.logs.first.first.must_equal :debug
299
- @o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
300
- end
301
-
302
- it "should log message with duration at warn level if duration greater than log_warn_duration" do
303
- @db.log_warn_duration = 0
304
- @db.log_yield('blah'){}
305
- @o.logs.length.must_equal 1
306
- @o.logs.first.length.must_equal 2
307
- @o.logs.first.first.must_equal :warn
308
- @o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
309
- end
310
-
311
- it "should log message with duration at info level if duration less than log_warn_duration" do
312
- @db.log_warn_duration = 1000
313
- @db.log_yield('blah'){}
314
- @o.logs.length.must_equal 1
315
- @o.logs.first.length.must_equal 2
316
- @o.logs.first.first.must_equal :info
317
- @o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah\z/)
318
- end
319
-
320
- it "should log message at error level if block raises an error" do
321
- @db.log_warn_duration = 0
322
- proc{@db.log_yield('blah'){raise Sequel::Error, 'adsf'}}.must_raise Sequel::Error
323
- @o.logs.length.must_equal 1
324
- @o.logs.first.length.must_equal 2
325
- @o.logs.first.first.must_equal :error
326
- @o.logs.first.last.must_match(/\ASequel::Error: adsf: blah\z/)
327
- end
328
-
329
- it "should include args with message if args passed" do
330
- @db.log_yield('blah', [1, 2]){}
331
- @o.logs.length.must_equal 1
332
- @o.logs.first.length.must_equal 2
333
- @o.logs.first.first.must_equal :info
334
- @o.logs.first.last.must_match(/\A\(\d\.\d{6}s\) blah; \[1, 2\]\z/)
335
- end
336
- end
337
-
338
- describe "Database#uri" do
339
- before do
340
- @c = Class.new(Sequel::Database) do
341
- set_adapter_scheme :mau
342
- end
343
-
344
- @db = Sequel.connect('mau://user:pass@localhost:9876/maumau')
345
- end
346
-
347
- it "should return the connection URI for the database" do
348
- @db.uri.must_equal 'mau://user:pass@localhost:9876/maumau'
349
- end
350
-
351
- it "should return nil if a connection uri was not used" do
352
- Sequel.mock.uri.must_equal nil
353
- end
354
-
355
- it "should be aliased as #url" do
356
- @db.url.must_equal 'mau://user:pass@localhost:9876/maumau'
357
- end
358
- end
359
-
360
- describe "Database.adapter_scheme and #adapter_scheme" do
361
- it "should return the database scheme" do
362
- Sequel::Database.adapter_scheme.must_equal nil
363
-
364
- @c = Class.new(Sequel::Database) do
365
- set_adapter_scheme :mau
366
- end
367
-
368
- @c.adapter_scheme.must_equal :mau
369
- @c.new({}).adapter_scheme.must_equal :mau
370
- end
371
- end
372
-
373
- describe "Database#dataset" do
374
- before do
375
- @db = Sequel::Database.new
376
- @ds = @db.dataset
377
- end
378
-
379
- it "should provide a blank dataset through #dataset" do
380
- @ds.must_be_kind_of(Sequel::Dataset)
381
- @ds.opts.must_equal({})
382
- @ds.db.must_be_same_as(@db)
383
- end
384
-
385
- it "should provide a #from dataset" do
386
- d = @db.from(:mau)
387
- d.must_be_kind_of(Sequel::Dataset)
388
- d.sql.must_equal 'SELECT * FROM mau'
389
-
390
- e = @db[:miu]
391
- e.must_be_kind_of(Sequel::Dataset)
392
- e.sql.must_equal 'SELECT * FROM miu'
393
- end
394
-
395
- it "should provide a filtered #from dataset if a block is given" do
396
- d = @db.from(:mau){x.sql_number > 100}
397
- d.must_be_kind_of(Sequel::Dataset)
398
- d.sql.must_equal 'SELECT * FROM mau WHERE (x > 100)'
399
- end
400
-
401
- it "should provide a #select dataset" do
402
- d = @db.select(:a, :b, :c).from(:mau)
403
- d.must_be_kind_of(Sequel::Dataset)
404
- d.sql.must_equal 'SELECT a, b, c FROM mau'
405
- end
406
-
407
- it "should allow #select to take a block" do
408
- d = @db.select(:a, :b){c}.from(:mau)
409
- d.must_be_kind_of(Sequel::Dataset)
410
- d.sql.must_equal 'SELECT a, b, c FROM mau'
411
- end
412
- end
413
-
414
- describe "Database#dataset_class" do
415
- before do
416
- @db = Sequel::Database.new
417
- @dsc = Class.new(Sequel::Dataset)
418
- end
419
-
420
- it "should have setter set the class to use to create datasets" do
421
- @db.dataset_class = @dsc
422
- ds = @db.dataset
423
- ds.must_be_kind_of(@dsc)
424
- ds.opts.must_equal({})
425
- ds.db.must_be_same_as(@db)
426
- end
427
-
428
- it "should have getter return the class to use to create datasets" do
429
- [@db.dataset_class, @db.dataset_class.superclass].must_include(Sequel::Dataset)
430
- @db.dataset_class = @dsc
431
- [@db.dataset_class, @db.dataset_class.superclass].must_include(@dsc)
432
- end
433
- end
434
-
435
- describe "Database#extend_datasets" do
436
- before do
437
- @db = Sequel::Database.new
438
- @m = Module.new{def foo() [3] end}
439
- @m2 = Module.new{def foo() [4] + super end}
440
- @db.extend_datasets(@m)
441
- end
442
-
443
- it "should clear a cached dataset" do
444
- @db = Sequel::Database.new
445
- @db.literal(1).must_equal '1'
446
- @db.extend_datasets{def literal(v) '2' end}
447
- @db.literal(1).must_equal '2'
448
- end
449
-
450
- it "should change the dataset class to a subclass the first time it is called" do
451
- @db.dataset_class.superclass.must_equal Sequel::Dataset
452
- end
453
-
454
- it "should not create a subclass of the dataset class if called more than once" do
455
- @db.extend_datasets(@m2)
456
- @db.dataset_class.superclass.must_equal Sequel::Dataset
457
- end
458
-
459
- it "should make the dataset class include the module" do
460
- @db.dataset_class.ancestors.must_include(@m)
461
- @db.dataset_class.ancestors.wont_include(@m2)
462
- @db.extend_datasets(@m2)
463
- @db.dataset_class.ancestors.must_include(@m)
464
- @db.dataset_class.ancestors.must_include(@m2)
465
- end
466
-
467
- it "should have datasets respond to the module's methods" do
468
- @db.dataset.foo.must_equal [3]
469
- @db.extend_datasets(@m2)
470
- @db.dataset.foo.must_equal [4, 3]
471
- end
472
-
473
- it "should take a block and create a module from it to use" do
474
- @db.dataset.foo.must_equal [3]
475
- @db.extend_datasets{def foo() [5] + super end}
476
- @db.dataset.foo.must_equal [5, 3]
477
- end
478
-
479
- it "should raise an error if both a module and a block are provided" do
480
- proc{@db.extend_datasets(@m2){def foo() [5] + super end}}.must_raise(Sequel::Error)
481
- end
482
-
483
- it "should be able to override methods defined in the original Dataset class" do
484
- @db.extend_datasets(Module.new{def select(*a, &block) super.order(*a, &block) end})
485
- @db[:t].select(:a, :b).sql.must_equal 'SELECT a, b FROM t ORDER BY a, b'
486
- end
487
-
488
- it "should reapply settings if dataset_class is changed" do
489
- c = Class.new(Sequel::Dataset)
490
- @db.dataset_class = c
491
- @db.dataset_class.superclass.must_equal c
492
- @db.dataset_class.ancestors.must_include(@m)
493
- @db.dataset.foo.must_equal [3]
494
- end
495
- end
496
-
497
- describe "Database#disconnect_connection" do
498
- it "should call close on the connection" do
499
- o = Object.new
500
- def o.close() @closed=true end
501
- Sequel::Database.new.disconnect_connection(o)
502
- o.instance_variable_get(:@closed).must_equal true
503
- end
504
- end
505
-
506
- describe "Database#valid_connection?" do
507
- it "should issue a query to validate the connection" do
508
- db = Sequel.mock
509
- db.synchronize{|c| db.valid_connection?(c)}.must_equal true
510
- db.synchronize do |c|
511
- def c.execute(*) raise Sequel::DatabaseError, "error" end
512
- db.valid_connection?(c)
513
- end.must_equal false
514
- end
515
- end
516
-
517
- describe "Database#run" do
518
- before do
519
- @db = Sequel.mock(:servers=>{:s1=>{}})
520
- end
521
-
522
- it "should execute the code on the database" do
523
- @db.run("DELETE FROM items")
524
- @db.sqls.must_equal ["DELETE FROM items"]
525
- end
526
-
527
- it "should handle placeholder literal strings" do
528
- @db.run(Sequel.lit("DELETE FROM ?", :items))
529
- @db.sqls.must_equal ["DELETE FROM items"]
530
- end
531
-
532
- it "should return nil" do
533
- @db.run("DELETE FROM items").must_equal nil
534
- end
535
-
536
- it "should accept options passed to execute_ddl" do
537
- @db.run("DELETE FROM items", :server=>:s1)
538
- @db.sqls.must_equal ["DELETE FROM items -- s1"]
539
- end
540
- end
541
-
542
- describe "Database#<<" do
543
- before do
544
- @db = Sequel.mock
545
- end
546
-
547
- it "should execute the code on the database" do
548
- @db << "DELETE FROM items"
549
- @db.sqls.must_equal ["DELETE FROM items"]
550
- end
551
-
552
- it "should handle placeholder literal strings" do
553
- @db << Sequel.lit("DELETE FROM ?", :items)
554
- @db.sqls.must_equal ["DELETE FROM items"]
555
- end
556
-
557
- it "should be chainable" do
558
- @db << "DELETE FROM items" << "DELETE FROM items2"
559
- @db.sqls.must_equal ["DELETE FROM items", "DELETE FROM items2"]
560
- end
561
- end
562
-
563
- describe "Database#synchronize" do
564
- before do
565
- @db = Sequel::Database.new(:max_connections => 1)
566
- meta_def(@db, :connect){|c| 12345}
567
- end
568
-
569
- it "should wrap the supplied block in pool.hold" do
570
- q, q1, q2 = Queue.new, Queue.new, Queue.new
571
- c1, c2 = nil
572
- t1 = Thread.new{@db.synchronize{|c| c1 = c; q.push nil; q1.pop}; q.push nil}
573
- q.pop
574
- c1.must_equal 12345
575
- t2 = Thread.new{@db.synchronize{|c| c2 = c; q2.push nil}}
576
- @db.pool.available_connections.must_be :empty?
577
- c2.must_equal nil
578
- q1.push nil
579
- q.pop
580
- q2.pop
581
- c2.must_equal 12345
582
- t1.join
583
- t2.join
584
- end
585
- end
586
-
587
- describe "Database#test_connection" do
588
- before do
589
- @db = Sequel::Database.new
590
- pr = proc{@test = rand(100)}
591
- meta_def(@db, :connect){|c| pr.call}
592
- end
593
-
594
- it "should attempt to get a connection" do
595
- @db.test_connection
596
- @test.wont_equal nil
597
- end
598
-
599
- it "should return true if successful" do
600
- @db.test_connection.must_equal true
601
- end
602
-
603
- it "should raise an error if the attempting to connect raises an error" do
604
- def @db.connect(*) raise Sequel::Error end
605
- proc{@db.test_connection}.must_raise(Sequel::DatabaseConnectionError)
606
- end
607
- end
608
-
609
- describe "Database#table_exists?" do
610
- it "should test existence by selecting a row from the table's dataset" do
611
- db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
612
- db.table_exists?(:a).must_equal false
613
- db.sqls.must_equal ["SELECT NULL AS nil FROM a LIMIT 1"]
614
- db.table_exists?(:b).must_equal true
615
- db.table_exists?(:c).must_equal true
616
- end
617
- end
618
-
619
- DatabaseTransactionSpecs = shared_description do
620
- it "should wrap the supplied block with BEGIN + COMMIT statements" do
621
- @db.transaction{@db.execute 'DROP TABLE test;'}
622
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
623
- end
624
-
625
- it "should support transaction isolation levels" do
626
- meta_def(@db, :supports_transaction_isolation_levels?){true}
627
- [:uncommitted, :committed, :repeatable, :serializable].each do |l|
628
- @db.transaction(:isolation=>l){@db.run "DROP TABLE #{l}"}
629
- end
630
- @db.sqls.must_equal ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
631
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
632
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
633
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
634
- end
635
-
636
- it "should allow specifying a default transaction isolation level" do
637
- meta_def(@db, :supports_transaction_isolation_levels?){true}
638
- [:uncommitted, :committed, :repeatable, :serializable].each do |l|
639
- @db.transaction_isolation_level = l
640
- @db.transaction{@db.run "DROP TABLE #{l}"}
641
- end
642
- @db.sqls.must_equal ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
643
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
644
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
645
- 'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
646
- end
647
-
648
- it "should support :retry_on option for automatically retrying transactions" do
649
- a = []
650
- @db.transaction(:retry_on=>Sequel::DatabaseDisconnectError){a << 1; raise Sequel::DatabaseDisconnectError if a.length < 2}
651
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
652
- a.must_equal [1, 1]
653
-
654
- a = []
655
- @db.transaction(:retry_on=>[Sequel::ConstraintViolation, Sequel::SerializationFailure]) do
656
- a << 1
657
- raise Sequel::SerializationFailure if a.length == 1
658
- raise Sequel::ConstraintViolation if a.length == 2
659
- end
660
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
661
- a.must_equal [1, 1, 1]
662
- end
663
-
664
- it "should support :num_retries option for limiting the number of retry times" do
665
- a = []
666
- lambda do
667
- @db.transaction(:num_retries=>1, :retry_on=>[Sequel::ConstraintViolation, Sequel::SerializationFailure]) do
668
- a << 1
669
- raise Sequel::SerializationFailure if a.length == 1
670
- raise Sequel::ConstraintViolation if a.length == 2
671
- end
672
- end.must_raise(Sequel::ConstraintViolation)
673
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK']
674
- a.must_equal [1, 1]
675
- end
676
-
677
- it "should support :num_retries=>nil option to retry indefinitely" do
678
- a = []
679
- lambda do
680
- @db.transaction(:num_retries=>nil, :retry_on=>[Sequel::ConstraintViolation]) do
681
- a << 1
682
- raise Sequel::SerializationFailure if a.length >= 100
683
- raise Sequel::ConstraintViolation
684
- end
685
- end.must_raise(Sequel::SerializationFailure)
686
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK'] * 100
687
- a.must_equal [1] * 100
688
- end
689
-
690
- it "should support :before_retry option for invoking callback before retrying" do
691
- a, errs, calls = [], [], []
692
- retryer = proc{|n, err| calls << n; errs << err }
693
- @db.transaction(:retry_on=>Sequel::DatabaseDisconnectError, :before_retry => retryer) do
694
- a << 1; raise Sequel::DatabaseDisconnectError if a.length < 3
695
- end
696
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'ROLLBACK', 'BEGIN', 'COMMIT']
697
- a.must_equal [1, 1, 1]
698
- errs.count.must_equal 2
699
- errs.each { |e| e.class.must_equal Sequel::DatabaseDisconnectError }
700
- calls.must_equal [1, 2]
701
- end
702
-
703
- it "should raise an error if attempting to use :retry_on inside another transaction" do
704
- proc{@db.transaction{@db.transaction(:retry_on=>Sequel::ConstraintViolation){}}}.must_raise(Sequel::Error)
705
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
706
- end
707
-
708
- it "should handle returning inside of the block by committing" do
709
- def @db.ret_commit
710
- transaction do
711
- execute 'DROP TABLE test;'
712
- return
713
- end
714
- end
715
- @db.ret_commit
716
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
717
- end
718
-
719
- it "should issue ROLLBACK if an exception is raised, and re-raise" do
720
- @db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
721
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
722
-
723
- proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
724
- end
725
-
726
- it "should handle errors when sending BEGIN" do
727
- ec = Class.new(StandardError)
728
- meta_def(@db, :database_error_classes){[ec]}
729
- meta_def(@db, :log_connection_execute){|c, sql| sql =~ /BEGIN/ ? raise(ec, 'bad') : super(c, sql)}
730
- begin
731
- @db.transaction{@db.execute 'DROP TABLE test;'}
732
- rescue Sequel::DatabaseError => e
733
- end
734
- e.wont_equal nil
735
- e.wrapped_exception.must_be_kind_of(ec)
736
- @db.sqls.must_equal ['ROLLBACK']
737
- end
738
-
739
- it "should handle errors when sending COMMIT" do
740
- ec = Class.new(StandardError)
741
- meta_def(@db, :database_error_classes){[ec]}
742
- meta_def(@db, :log_connection_execute){|c, sql| sql =~ /COMMIT/ ? raise(ec, 'bad') : super(c, sql)}
743
- begin
744
- @db.transaction{@db.execute 'DROP TABLE test;'}
745
- rescue Sequel::DatabaseError => e
746
- end
747
- e.wont_equal nil
748
- e.wrapped_exception.must_be_kind_of(ec)
749
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'ROLLBACK']
750
- end
751
-
752
- it "should raise original exception if there is an exception raised when rolling back" do
753
- ec = Class.new(StandardError)
754
- meta_def(@db, :database_error_classes){[ec]}
755
- meta_def(@db, :log_connection_execute){|c, sql| sql =~ /ROLLBACK/ ? raise(ec, 'bad') : super(c, sql)}
756
- begin
757
- @db.transaction{raise ArgumentError, 'asdf'}
758
- rescue => e
759
- end
760
- e.must_be_kind_of(ArgumentError)
761
- @db.sqls.must_equal ['BEGIN']
762
- end
763
-
764
- it "should issue ROLLBACK if Sequel::Rollback is called in the transaction" do
765
- @db.transaction do
766
- @db.drop_table(:a)
767
- raise Sequel::Rollback
768
- @db.drop_table(:b)
769
- end
770
-
771
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
772
- end
773
-
774
- it "should have in_transaction? return true if inside a transaction" do
775
- c = nil
776
- @db.transaction{c = @db.in_transaction?}
777
- c.must_equal true
778
- end
779
-
780
- it "should have in_transaction? handle sharding correctly" do
781
- c = []
782
- @db.transaction(:server=>:test){c << @db.in_transaction?}
783
- @db.transaction(:server=>:test){c << @db.in_transaction?(:server=>:test)}
784
- c.must_equal [false, true]
785
- end
786
-
787
- it "should have in_transaction? return false if not in a transaction" do
788
- @db.in_transaction?.must_equal false
789
- end
790
-
791
- it "should return nil if Sequel::Rollback is called in the transaction" do
792
- @db.transaction{raise Sequel::Rollback}.must_equal nil
793
- end
794
-
795
- it "should reraise Sequel::Rollback errors when using :rollback=>:reraise option is given" do
796
- proc {@db.transaction(:rollback=>:reraise){raise Sequel::Rollback}}.must_raise(Sequel::Rollback)
797
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
798
- proc {@db.transaction(:rollback=>:reraise){raise ArgumentError}}.must_raise(ArgumentError)
799
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
800
- @db.transaction(:rollback=>:reraise){1}.must_equal 1
801
- @db.sqls.must_equal ['BEGIN', 'COMMIT']
802
- end
803
-
804
- it "should always rollback if :rollback=>:always option is given" do
805
- proc {@db.transaction(:rollback=>:always){raise ArgumentError}}.must_raise(ArgumentError)
806
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
807
- @db.transaction(:rollback=>:always){raise Sequel::Rollback}.must_equal nil
808
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
809
- @db.transaction(:rollback=>:always){1}.must_equal 1
810
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
811
- catch(:foo) do
812
- @db.transaction(:rollback=>:always){throw :foo}
813
- end
814
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
815
- end
816
-
817
- it "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
818
- meta_def(@db, :commit_transaction){raise ArgumentError}
819
- lambda{@db.transaction{}}.must_raise(ArgumentError)
820
-
821
- meta_def(@db, :database_error_classes){[ArgumentError]}
822
- lambda{@db.transaction{}}.must_raise(Sequel::DatabaseError)
823
- end
824
-
825
- it "should be re-entrant" do
826
- q, q1 = Queue.new, Queue.new
827
- cc = nil
828
- t = Thread.new do
829
- @db.transaction {@db.transaction {@db.transaction {|c|
830
- cc = c
831
- q.pop
832
- q1.push nil
833
- q.pop
834
- }}}
835
- end
836
- q.push nil
837
- q1.pop
838
- cc.must_be_kind_of(Sequel::Mock::Connection)
839
- tr = @db.instance_variable_get(:@transactions)
840
- tr.keys.must_equal [cc]
841
- q.push nil
842
- t.join
843
- tr.must_be :empty?
844
- end
845
-
846
- it "should correctly handle nested transacation use with separate shards" do
847
- @db.transaction do |c1|
848
- @db.transaction(:server=>:test) do |c2|
849
- c1.wont_equal c2
850
- @db.execute 'DROP TABLE test;'
851
- end
852
- end
853
- @db.sqls.must_equal ['BEGIN', 'BEGIN -- test', 'DROP TABLE test;', 'COMMIT -- test', 'COMMIT']
854
- end
855
-
856
- if (!defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby') and !RUBY_VERSION.start_with?('1.9')
857
- it "should handle Thread#kill for transactions inside threads" do
858
- q = Queue.new
859
- q1 = Queue.new
860
- t = Thread.new do
861
- @db.transaction do
862
- @db.execute 'DROP TABLE test'
863
- q1.push nil
864
- q.pop
865
- @db.execute 'DROP TABLE test2'
866
- end
867
- end
868
- q1.pop
869
- t.kill
870
- t.join
871
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
872
- end
873
- end
874
-
875
- it "should raise an Error if after_commit or after_rollback is called without a block" do
876
- proc{@db.after_commit}.must_raise(Sequel::Error)
877
- proc{@db.after_rollback}.must_raise(Sequel::Error)
878
- end
879
-
880
- it "should have after_commit and after_rollback respect :server option" do
881
- @db.transaction(:server=>:test){@db.after_commit(:server=>:test){@db.execute('foo', :server=>:test)}}
882
- @db.sqls.must_equal ['BEGIN -- test', 'COMMIT -- test', 'foo -- test']
883
- @db.transaction(:server=>:test){@db.after_rollback(:server=>:test){@db.execute('foo', :server=>:test)}; raise Sequel::Rollback}
884
- @db.sqls.must_equal ['BEGIN -- test', 'ROLLBACK -- test', 'foo -- test']
885
- end
886
-
887
- it "should execute after_commit outside transactions" do
888
- @db.after_commit{@db.execute('foo')}
889
- @db.sqls.must_equal ['foo']
890
- end
891
-
892
- it "should ignore after_rollback outside transactions" do
893
- @db.after_rollback{@db.execute('foo')}
894
- @db.sqls.must_equal []
895
- end
896
-
897
- it "should support after_commit inside transactions" do
898
- @db.transaction{@db.after_commit{@db.execute('foo')}}
899
- @db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo']
900
- end
901
-
902
- it "should support after_rollback inside transactions" do
903
- @db.transaction{@db.after_rollback{@db.execute('foo')}}
904
- @db.sqls.must_equal ['BEGIN', 'COMMIT']
905
- end
906
-
907
- it "should have transaction inside after_commit work correctly" do
908
- @db.transaction{@db.after_commit{@db.transaction{@db.execute('foo')}}}
909
- @db.sqls.must_equal ['BEGIN', 'COMMIT', 'BEGIN', 'foo', 'COMMIT']
910
- end
911
-
912
- it "should have transaction inside after_rollback work correctly" do
913
- @db.transaction(:rollback=>:always){@db.after_rollback{@db.transaction{@db.execute('foo')}}}
914
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'BEGIN', 'foo', 'COMMIT']
915
- end
916
-
917
- it "should not call after_commit if the transaction rolls back" do
918
- @db.transaction{@db.after_commit{@db.execute('foo')}; raise Sequel::Rollback}
919
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
920
- end
921
-
922
- it "should call after_rollback if the transaction rolls back" do
923
- @db.transaction{@db.after_rollback{@db.execute('foo')}; raise Sequel::Rollback}
924
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo']
925
- end
926
-
927
- it "should call multiple after_commit blocks in order if called inside transactions" do
928
- @db.transaction{@db.after_commit{@db.execute('foo')}; @db.after_commit{@db.execute('bar')}}
929
- @db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo', 'bar']
930
- end
931
-
932
- it "should call multiple after_rollback blocks in order if called inside transactions" do
933
- @db.transaction{@db.after_rollback{@db.execute('foo')}; @db.after_rollback{@db.execute('bar')}; raise Sequel::Rollback}
934
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo', 'bar']
935
- end
936
-
937
- it "should support after_commit inside nested transactions" do
938
- @db.transaction{@db.transaction{@db.after_commit{@db.execute('foo')}}}
939
- @db.sqls.must_equal ['BEGIN', 'COMMIT', 'foo']
940
- end
941
-
942
- it "should support after_rollback inside nested transactions" do
943
- @db.transaction{@db.transaction{@db.after_rollback{@db.execute('foo')}}; raise Sequel::Rollback}
944
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK', 'foo']
945
- end
946
-
947
- it "should raise an error if you attempt to use after_commit inside a prepared transaction" do
948
- meta_def(@db, :supports_prepared_transactions?){true}
949
- proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{@db.execute('foo')}}}.must_raise(Sequel::Error)
950
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
951
- end
952
-
953
- it "should raise an error if you attempt to use after_rollback inside a prepared transaction" do
954
- meta_def(@db, :supports_prepared_transactions?){true}
955
- proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{@db.execute('foo')}}}.must_raise(Sequel::Error)
956
- @db.sqls.must_equal ['BEGIN', 'ROLLBACK']
957
- end
958
- end
959
-
960
- describe "Database#transaction with savepoint support" do
961
- before do
962
- @db = Sequel.mock(:servers=>{:test=>{}})
963
- end
964
-
965
- include DatabaseTransactionSpecs
966
-
967
- it "should support after_commit inside savepoints" do
968
- @db.transaction do
969
- @db.after_commit{@db.execute('foo')}
970
- @db.transaction(:savepoint=>true){@db.after_commit{@db.execute('bar')}}
971
- @db.after_commit{@db.execute('baz')}
972
- end
973
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT', 'foo', 'bar', 'baz']
974
- end
975
-
976
- it "should support after_rollback inside savepoints" do
977
- @db.transaction do
978
- @db.after_rollback{@db.execute('foo')}
979
- @db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('bar')}}
980
- @db.after_rollback{@db.execute('baz')}
981
- raise Sequel::Rollback
982
- end
983
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'ROLLBACK', 'foo', 'bar', 'baz']
984
- end
985
-
986
- it "should raise an error if you attempt to use after_commit inside a savepoint in a prepared transaction" do
987
- meta_def(@db, :supports_prepared_transactions?){true}
988
- proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('foo')}}}}.must_raise(Sequel::Error)
989
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
990
- end
991
-
992
- it "should raise an error if you attempt to use after_rollback inside a savepoint in a prepared transaction" do
993
- meta_def(@db, :supports_prepared_transactions?){true}
994
- proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('foo')}}}}.must_raise(Sequel::Error)
995
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
996
- end
997
- end
998
-
999
- describe "Database#transaction without savepoint support" do
1000
- before do
1001
- @db = Sequel.mock(:servers=>{:test=>{}})
1002
- meta_def(@db, :supports_savepoints?){false}
1003
- end
1004
-
1005
- include DatabaseTransactionSpecs
1006
- end
1007
-
1008
- describe "Sequel.transaction" do
1009
- before do
1010
- @sqls = []
1011
- @db1 = Sequel.mock(:append=>'1', :sqls=>@sqls)
1012
- @db2 = Sequel.mock(:append=>'2', :sqls=>@sqls)
1013
- @db3 = Sequel.mock(:append=>'3', :sqls=>@sqls)
1014
- end
1015
-
1016
- it "should run the block inside transacitons on all three databases" do
1017
- Sequel.transaction([@db1, @db2, @db3]){1}.must_equal 1
1018
- @sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
1019
- end
1020
-
1021
- it "should pass options to all the blocks" do
1022
- Sequel.transaction([@db1, @db2, @db3], :rollback=>:always){1}.must_equal 1
1023
- @sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
1024
- end
1025
-
1026
- it "should handle Sequel::Rollback exceptions raised by the block to rollback on all databases" do
1027
- Sequel.transaction([@db1, @db2, @db3]){raise Sequel::Rollback}.must_equal nil
1028
- @sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
1029
- end
1030
-
1031
- it "should handle nested transactions" do
1032
- Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3]){1}}.must_equal 1
1033
- @sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
1034
- end
1035
-
1036
- it "should handle savepoints" do
1037
- Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3], :savepoint=>true){1}}.must_equal 1
1038
- @sqls.must_equal ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3',
1039
- 'SAVEPOINT autopoint_1 -- 1', 'SAVEPOINT autopoint_1 -- 2', 'SAVEPOINT autopoint_1 -- 3',
1040
- 'RELEASE SAVEPOINT autopoint_1 -- 3', 'RELEASE SAVEPOINT autopoint_1 -- 2', 'RELEASE SAVEPOINT autopoint_1 -- 1',
1041
- 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
1042
- end
1043
- end
1044
-
1045
- describe "Database#transaction with savepoints" do
1046
- before do
1047
- @db = Sequel.mock
1048
- end
1049
-
1050
- it "should wrap the supplied block with BEGIN + COMMIT statements" do
1051
- @db.transaction {@db.execute 'DROP TABLE test;'}
1052
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
1053
- end
1054
-
1055
- it "should use savepoints if given the :savepoint option" do
1056
- @db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}}
1057
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1058
- end
1059
-
1060
- it "should use savepoints if surrounding transaction uses :auto_savepoint option" do
1061
- @db.transaction(:auto_savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}
1062
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1063
-
1064
- @db.transaction(:auto_savepoint=>true){@db.transaction{@db.transaction{@db.execute 'DROP TABLE test;'}}}
1065
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1066
-
1067
- @db.transaction(:auto_savepoint=>true){@db.transaction(:auto_savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}}
1068
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'SAVEPOINT autopoint_2', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_2', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1069
-
1070
- @db.transaction{@db.transaction(:auto_savepoint=>true, :savepoint=>true){@db.transaction{@db.execute 'DROP TABLE test;'}}}
1071
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'SAVEPOINT autopoint_2', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_2', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1072
- end
1073
-
1074
- it "should not use savepoints if surrounding transaction uses :auto_savepoint and current transaction uses :savepoint=>false option" do
1075
- @db.transaction(:auto_savepoint=>true){@db.transaction(:savepoint=>false){@db.execute 'DROP TABLE test;'}}
1076
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
1077
- end
1078
-
1079
- it "should not use a savepoint if no transaction is in progress" do
1080
- @db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}
1081
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
1082
- end
1083
-
1084
- it "should reuse the current transaction if no :savepoint option is given" do
1085
- @db.transaction{@db.transaction{@db.execute 'DROP TABLE test;'}}
1086
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
1087
- end
1088
-
1089
- it "should handle returning inside of the block by committing" do
1090
- def @db.ret_commit
1091
- transaction do
1092
- execute 'DROP TABLE test;'
1093
- return
1094
- end
1095
- end
1096
- @db.ret_commit
1097
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test;', 'COMMIT']
1098
- end
1099
-
1100
- it "should handle returning inside of a savepoint by committing" do
1101
- def @db.ret_commit
1102
- transaction do
1103
- transaction(:savepoint=>true) do
1104
- execute 'DROP TABLE test;'
1105
- return
1106
- end
1107
- end
1108
- end
1109
- @db.ret_commit
1110
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
1111
- end
1112
-
1113
- it "should issue ROLLBACK if an exception is raised, and re-raise" do
1114
- @db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
1115
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
1116
-
1117
- proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
1118
- end
1119
-
1120
- it "should issue ROLLBACK SAVEPOINT if an exception is raised inside a savepoint, and re-raise" do
1121
- @db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test'; raise RuntimeError}} rescue nil
1122
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test', 'ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
1123
-
1124
- proc {@db.transaction {raise RuntimeError}}.must_raise(RuntimeError)
1125
- end
1126
-
1127
- it "should issue ROLLBACK if Sequel::Rollback is raised in the transaction" do
1128
- @db.transaction do
1129
- @db.drop_table(:a)
1130
- raise Sequel::Rollback
1131
- @db.drop_table(:b)
1132
- end
1133
-
1134
- @db.sqls.must_equal ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
1135
- end
1136
-
1137
- it "should issue ROLLBACK SAVEPOINT if Sequel::Rollback is raised in a savepoint" do
1138
- @db.transaction do
1139
- @db.transaction(:savepoint=>true) do
1140
- @db.drop_table(:a)
1141
- raise Sequel::Rollback
1142
- end
1143
- @db.drop_table(:b)
1144
- end
1145
-
1146
- @db.sqls.must_equal ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE a', 'ROLLBACK TO SAVEPOINT autopoint_1', 'DROP TABLE b', 'COMMIT']
1147
- end
1148
-
1149
- it "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
1150
- meta_def(@db, :commit_transaction){raise ArgumentError}
1151
- lambda{@db.transaction{}}.must_raise(ArgumentError)
1152
- lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.must_raise(ArgumentError)
1153
-
1154
- meta_def(@db, :database_error_classes){[ArgumentError]}
1155
- lambda{@db.transaction{}}.must_raise(Sequel::DatabaseError)
1156
- lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.must_raise(Sequel::DatabaseError)
1157
- end
1158
- end
1159
-
1160
- describe "A Database adapter with a scheme" do
1161
- before do
1162
- require 'sequel/adapters/mock'
1163
- @ccc = Class.new(Sequel::Mock::Database)
1164
- @ccc.send(:set_adapter_scheme, :ccc)
1165
- end
1166
-
1167
- it "should be registered in the ADAPTER_MAP" do
1168
- Sequel::ADAPTER_MAP[:ccc].must_equal @ccc
1169
- end
1170
-
1171
- it "should give the database_type as the adapter scheme by default" do
1172
- @ccc.new.database_type.must_equal :ccc
1173
- end
1174
-
1175
- it "should be instantiated when its scheme is specified" do
1176
- c = Sequel::Database.connect('ccc://localhost/db')
1177
- c.must_be_kind_of(@ccc)
1178
- c.opts[:host].must_equal 'localhost'
1179
- c.opts[:database].must_equal 'db'
1180
- end
1181
-
1182
- it "should be accessible through Sequel.connect" do
1183
- c = Sequel.connect 'ccc://localhost/db'
1184
- c.must_be_kind_of(@ccc)
1185
- c.opts[:host].must_equal 'localhost'
1186
- c.opts[:database].must_equal 'db'
1187
- end
1188
-
1189
- it "should be accessible through Sequel.connect via a block" do
1190
- x = nil
1191
- y = nil
1192
- z = nil
1193
- returnValue = 'anything'
1194
-
1195
- p = proc do |c|
1196
- c.must_be_kind_of(@ccc)
1197
- c.opts[:host].must_equal 'localhost'
1198
- c.opts[:database].must_equal 'db'
1199
- z = y
1200
- y = x
1201
- x = c
1202
- returnValue
1203
- end
1204
-
1205
- @ccc.class_eval do
1206
- self::DISCONNECTS = []
1207
- def disconnect
1208
- self.class::DISCONNECTS << self
1209
- end
1210
- end
1211
- Sequel::Database.connect('ccc://localhost/db', &p).must_equal returnValue
1212
- @ccc::DISCONNECTS.must_equal [x]
1213
-
1214
- Sequel.connect('ccc://localhost/db', &p).must_equal returnValue
1215
- @ccc::DISCONNECTS.must_equal [y, x]
1216
-
1217
- Sequel.send(:def_adapter_method, :ccc)
1218
- Sequel.ccc('db', :host=>'localhost', &p).must_equal returnValue
1219
- @ccc::DISCONNECTS.must_equal [z, y, x]
1220
- class << Sequel; remove_method(:ccc) end
1221
- end
1222
-
1223
- it "should be accessible through Sequel.<adapter>" do
1224
- Sequel.send(:def_adapter_method, :ccc)
1225
-
1226
- # invalid parameters
1227
- proc {Sequel.ccc('abc', 'def')}.must_raise(Sequel::Error)
1228
- proc {Sequel.ccc(1)}.must_raise(Sequel::Error)
1229
-
1230
- c = Sequel.ccc('mydb')
1231
- c.must_be_kind_of(@ccc)
1232
- c.opts.values_at(:adapter, :database, :adapter_class).must_equal [:ccc, 'mydb', @ccc]
1233
-
1234
- c = Sequel.ccc('mydb', :host => 'localhost')
1235
- c.must_be_kind_of(@ccc)
1236
- c.opts.values_at(:adapter, :database, :host, :adapter_class).must_equal [:ccc, 'mydb', 'localhost', @ccc]
1237
-
1238
- c = Sequel.ccc
1239
- c.must_be_kind_of(@ccc)
1240
- c.opts.values_at(:adapter, :adapter_class).must_equal [:ccc, @ccc]
1241
-
1242
- c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
1243
- c.must_be_kind_of(@ccc)
1244
- c.opts.values_at(:adapter, :database, :host, :adapter_class).must_equal [:ccc, 'mydb', 'localhost', @ccc]
1245
- class << Sequel; remove_method(:ccc) end
1246
- end
1247
-
1248
- it "should be accessible through Sequel.connect with options" do
1249
- c = Sequel.connect(:adapter => :ccc, :database => 'mydb')
1250
- c.must_be_kind_of(@ccc)
1251
- c.opts[:adapter].must_equal :ccc
1252
- end
1253
-
1254
- it "should be accessible through Sequel.connect with URL parameters" do
1255
- c = Sequel.connect 'ccc:///db?host=/tmp&user=test'
1256
- c.must_be_kind_of(@ccc)
1257
- c.opts[:host].must_equal '/tmp'
1258
- c.opts[:database].must_equal 'db'
1259
- c.opts[:user].must_equal 'test'
1260
- end
1261
-
1262
- it "should have URL parameters take precedence over fixed URL parts" do
1263
- c = Sequel.connect 'ccc://localhost/db?host=a&database=b'
1264
- c.must_be_kind_of(@ccc)
1265
- c.opts[:host].must_equal 'a'
1266
- c.opts[:database].must_equal 'b'
1267
- end
1268
-
1269
- it "should have hash options take predence over URL parameters or parts" do
1270
- c = Sequel.connect 'ccc://localhost/db?host=/tmp', :host=>'a', :database=>'b', :user=>'c'
1271
- c.must_be_kind_of(@ccc)
1272
- c.opts[:host].must_equal 'a'
1273
- c.opts[:database].must_equal 'b'
1274
- c.opts[:user].must_equal 'c'
1275
- end
1276
-
1277
- it "should unescape values of URL parameters and parts" do
1278
- c = Sequel.connect 'ccc:///d%5bb%5d?host=domain%5cinstance'
1279
- c.must_be_kind_of(@ccc)
1280
- c.opts[:database].must_equal 'd[b]'
1281
- c.opts[:host].must_equal 'domain\\instance'
1282
- end
1283
-
1284
- it "should test the connection if test parameter is truthy" do
1285
- @ccc.send(:define_method, :connect){}
1286
- proc{Sequel.connect 'ccc:///d%5bb%5d?test=t'}.must_raise(Sequel::DatabaseConnectionError)
1287
- proc{Sequel.connect 'ccc:///d%5bb%5d?test=1'}.must_raise(Sequel::DatabaseConnectionError)
1288
- proc{Sequel.connect 'ccc:///d%5bb%5d', :test=>true}.must_raise(Sequel::DatabaseConnectionError)
1289
- proc{Sequel.connect 'ccc:///d%5bb%5d', :test=>'t'}.must_raise(Sequel::DatabaseConnectionError)
1290
- end
1291
-
1292
- it "should not test the connection if test parameter is not truthy" do
1293
- Sequel.connect 'ccc:///d%5bb%5d?test=f'
1294
- Sequel.connect 'ccc:///d%5bb%5d?test=0'
1295
- Sequel.connect 'ccc:///d%5bb%5d', :test=>false
1296
- Sequel.connect 'ccc:///d%5bb%5d', :test=>'f'
1297
- end
1298
- end
1299
-
1300
- describe "Sequel::Database.connect" do
1301
- it "should raise an Error if not given a String or Hash" do
1302
- proc{Sequel::Database.connect(nil)}.must_raise(Sequel::Error)
1303
- proc{Sequel::Database.connect(Object.new)}.must_raise(Sequel::Error)
1304
- end
1305
- end
1306
-
1307
- describe "An unknown database scheme" do
1308
- it "should raise an error in Sequel::Database.connect" do
1309
- proc {Sequel::Database.connect('ddd://localhost/db')}.must_raise(Sequel::AdapterNotFound)
1310
- end
1311
-
1312
- it "should raise an error in Sequel.connect" do
1313
- proc {Sequel.connect('ddd://localhost/db')}.must_raise(Sequel::AdapterNotFound)
1314
- end
1315
- end
1316
-
1317
- describe "A broken adapter (lib is there but the class is not)" do
1318
- before do
1319
- @fn = File.join(File.dirname(__FILE__), '../../lib/sequel/adapters/blah.rb')
1320
- File.open(@fn,'a'){}
1321
- end
1322
-
1323
- after do
1324
- File.delete(@fn)
1325
- end
1326
-
1327
- it "should raise an error" do
1328
- proc {Sequel.connect('blah://blow')}.must_raise(Sequel::AdapterNotFound)
1329
- end
1330
- end
1331
-
1332
- describe "Sequel::Database.load_adapter" do
1333
- it "should not raise an error if subadapter does not exist" do
1334
- Sequel::Database.load_adapter(:foo, :subdir=>'bar').must_equal nil
1335
- end
1336
- end
1337
-
1338
- describe "A single threaded database" do
1339
- after do
1340
- Sequel::Database.single_threaded = false
1341
- end
1342
-
1343
- it "should use a SingleConnectionPool instead of a ConnectionPool" do
1344
- db = Sequel::Database.new(:single_threaded => true){123}
1345
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
1346
- end
1347
-
1348
- it "should be constructable using :single_threaded => true option" do
1349
- db = Sequel::Database.new(:single_threaded => true){123}
1350
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
1351
- end
1352
-
1353
- it "should be constructable using Database.single_threaded = true" do
1354
- Sequel::Database.single_threaded = true
1355
- db = Sequel::Database.new{123}
1356
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
1357
- end
1358
-
1359
- it "should be constructable using Sequel.single_threaded = true" do
1360
- Sequel.single_threaded = true
1361
- db = Sequel::Database.new{123}
1362
- db.pool.must_be_kind_of(Sequel::SingleConnectionPool)
1363
- end
1364
- end
1365
-
1366
- describe "A single threaded database" do
1367
- before do
1368
- conn = 1234567
1369
- @db = Sequel::Database.new(:single_threaded => true)
1370
- meta_def(@db, :connect) do |c|
1371
- conn += 1
1372
- end
1373
- end
1374
-
1375
- it "should invoke connection_proc only once" do
1376
- @db.pool.hold {|c| c.must_equal 1234568}
1377
- @db.pool.hold {|c| c.must_equal 1234568}
1378
- end
1379
-
1380
- it "should disconnect correctly" do
1381
- def @db.disconnect_connection(c); @dc = c end
1382
- def @db.dc; @dc end
1383
- x = nil
1384
- @db.pool.hold{|c| x = c}
1385
- @db.pool.hold{|c| c.must_equal x}
1386
- @db.disconnect
1387
- @db.dc.must_equal x
1388
- end
1389
-
1390
- it "should convert an Exception on connection into a DatabaseConnectionError" do
1391
- db = Sequel::Database.new(:single_threaded => true, :servers=>{})
1392
- def db.connect(*) raise Exception end
1393
- proc {db.pool.hold {|c|}}.must_raise(Sequel::DatabaseConnectionError)
1394
- end
1395
-
1396
- it "should raise a DatabaseConnectionError if the connection proc returns nil" do
1397
- db = Sequel.mock(:single_threaded => true, :servers=>{})
1398
- def db.connect(*) end
1399
- proc {db.pool.hold {|c|}}.must_raise(Sequel::DatabaseConnectionError)
1400
- end
1401
- end
1402
-
1403
- describe "A database" do
1404
- after do
1405
- Sequel::Database.single_threaded = false
1406
- end
1407
-
1408
- it "should have single_threaded? respond to true if in single threaded mode" do
1409
- db = Sequel::Database.new(:single_threaded => true){1234}
1410
- db.must_be :single_threaded?
1411
-
1412
- db = Sequel::Database.new(:max_options => 1)
1413
- db.wont_be :single_threaded?
1414
-
1415
- db = Sequel::Database.new
1416
- db.wont_be :single_threaded?
1417
-
1418
- Sequel::Database.single_threaded = true
1419
-
1420
- db = Sequel::Database.new{123}
1421
- db.must_be :single_threaded?
1422
-
1423
- db = Sequel::Database.new(:max_options => 4){123}
1424
- db.must_be :single_threaded?
1425
- end
1426
-
1427
- it "should be able to set loggers via the logger= and loggers= methods" do
1428
- db = Sequel::Database.new
1429
- s = "I'm a logger"
1430
- db.logger = s
1431
- db.loggers.must_equal [s]
1432
- db.logger = nil
1433
- db.loggers.must_equal []
1434
-
1435
- db.loggers = [s]
1436
- db.loggers.must_equal [s]
1437
- db.loggers = []
1438
- db.loggers.must_equal []
1439
-
1440
- t = "I'm also a logger"
1441
- db.loggers = [s, t]
1442
- db.loggers.must_equal [s,t]
1443
- end
1444
- end
1445
-
1446
- describe "Database#fetch" do
1447
- before do
1448
- @db = Sequel.mock(:fetch=>proc{|sql| {:sql => sql}})
1449
- end
1450
-
1451
- it "should create a dataset and invoke its fetch_rows method with the given sql" do
1452
- sql = nil
1453
- @db.fetch('select * from xyz') {|r| sql = r[:sql]}
1454
- sql.must_equal 'select * from xyz'
1455
- end
1456
-
1457
- it "should format the given sql with any additional arguments" do
1458
- sql = nil
1459
- @db.fetch('select * from xyz where x = ? and y = ?', 15, 'abc') {|r| sql = r[:sql]}
1460
- sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
1461
-
1462
- @db.fetch('select name from table where name = ? or id in ?', 'aman', [3,4,7]) {|r| sql = r[:sql]}
1463
- sql.must_equal "select name from table where name = 'aman' or id in (3, 4, 7)"
1464
- end
1465
-
1466
- it "should format the given sql with named arguments" do
1467
- sql = nil
1468
- @db.fetch('select * from xyz where x = :x and y = :y', :x=>15, :y=>'abc') {|r| sql = r[:sql]}
1469
- sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
1470
- end
1471
-
1472
- it "should return the dataset if no block is given" do
1473
- @db.fetch('select * from xyz').must_be_kind_of(Sequel::Dataset)
1474
-
1475
- @db.fetch('select a from b').map {|r| r[:sql]}.must_equal ['select a from b']
1476
-
1477
- @db.fetch('select c from d').inject([]) {|m, r| m << r; m}.must_equal \
1478
- [{:sql => 'select c from d'}]
1479
- end
1480
-
1481
- it "should return a dataset that always uses the given sql for SELECTs" do
1482
- ds = @db.fetch('select * from xyz')
1483
- ds.select_sql.must_equal 'select * from xyz'
1484
- ds.sql.must_equal 'select * from xyz'
1485
-
1486
- ds.filter!{price.sql_number < 100}
1487
- ds.select_sql.must_equal 'select * from xyz'
1488
- ds.sql.must_equal 'select * from xyz'
1489
- end
1490
- end
1491
-
1492
-
1493
- describe "Database#[]" do
1494
- before do
1495
- @db = Sequel.mock
1496
- end
1497
-
1498
- it "should return a dataset when symbols are given" do
1499
- ds = @db[:items]
1500
- ds.must_be_kind_of(Sequel::Dataset)
1501
- ds.opts[:from].must_equal [:items]
1502
- end
1503
-
1504
- it "should return a dataset when a string is given" do
1505
- @db.fetch = proc{|sql| {:sql=>sql}}
1506
- sql = nil
1507
- @db['select * from xyz where x = ? and y = ?', 15, 'abc'].each {|r| sql = r[:sql]}
1508
- sql.must_equal "select * from xyz where x = 15 and y = 'abc'"
1509
- end
1510
- end
1511
-
1512
- describe "Database#inspect" do
1513
- it "should include the class name and the connection url" do
1514
- Sequel.connect('mock://foo/bar').inspect.must_equal '#<Sequel::Mock::Database: "mock://foo/bar">'
1515
- end
1516
-
1517
- it "should include the class name and the connection options if an options hash was given" do
1518
- Sequel.connect(:adapter=>:mock).inspect.must_match(/#<Sequel::Mock::Database: \{:adapter=>:mock\}>/)
1519
- end
1520
-
1521
- it "should include the class name, uri, and connection options if uri and options hash was given" do
1522
- Sequel.connect('mock://foo', :database=>'bar').inspect.must_match(/#<Sequel::Mock::Database: "mock:\/\/foo" \{:database=>"bar"\}>/)
1523
- end
1524
- end
1525
-
1526
- describe "Database#get" do
1527
- before do
1528
- @db = Sequel.mock(:fetch=>{:a=>1})
1529
- end
1530
-
1531
- it "should use Dataset#get to get a single value" do
1532
- @db.get(:a).must_equal 1
1533
- @db.sqls.must_equal ['SELECT a LIMIT 1']
1534
-
1535
- @db.get(Sequel.function(:version).as(:version))
1536
- @db.sqls.must_equal ['SELECT version() AS version LIMIT 1']
1537
- end
1538
-
1539
- it "should accept a block" do
1540
- @db.get{a}
1541
- @db.sqls.must_equal ['SELECT a LIMIT 1']
1542
-
1543
- @db.get{version(a).as(version)}
1544
- @db.sqls.must_equal ['SELECT version(a) AS version LIMIT 1']
1545
- end
1546
-
1547
- it "should work when an alias cannot be determined" do
1548
- @db.get(1).must_equal 1
1549
- @db.sqls.must_equal ['SELECT 1 AS v LIMIT 1']
1550
- end
1551
- end
1552
-
1553
- describe "Database#call" do
1554
- it "should call the prepared statement with the given name" do
1555
- db = Sequel.mock(:fetch=>{:id => 1, :x => 1})
1556
- db[:items].prepare(:select, :select_all)
1557
- db.call(:select_all).must_equal [{:id => 1, :x => 1}]
1558
- db[:items].filter(:n=>:$n).prepare(:select, :select_n)
1559
- db.call(:select_n, :n=>1).must_equal [{:id => 1, :x => 1}]
1560
- db.sqls.must_equal ['SELECT * FROM items', 'SELECT * FROM items WHERE (n = 1)']
1561
- end
1562
- end
1563
-
1564
- describe "Database#server_opts" do
1565
- it "should return the general opts if no :servers option is used" do
1566
- opts = {:host=>1, :database=>2}
1567
- Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 1
1568
- end
1569
-
1570
- it "should return the general opts if entry for the server is present in the :servers option" do
1571
- opts = {:host=>1, :database=>2, :servers=>{}}
1572
- Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 1
1573
- end
1574
-
1575
- it "should return the general opts merged with the specific opts if given as a hash" do
1576
- opts = {:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}}}
1577
- Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 3
1578
- end
1579
-
1580
- it "should return the sgeneral opts merged with the specific opts if given as a proc" do
1581
- opts = {:host=>1, :database=>2, :servers=>{:server1=>proc{|db| {:host=>4}}}}
1582
- Sequel::Database.new(opts).send(:server_opts, :server1)[:host].must_equal 4
1583
- end
1584
-
1585
- it "should raise an error if the specific opts is not a proc or hash" do
1586
- opts = {:host=>1, :database=>2, :servers=>{:server1=>2}}
1587
- proc{Sequel::Database.new(opts).send(:server_opts, :server1)}.must_raise(Sequel::Error)
1588
- end
1589
-
1590
- it "should return the general opts merged with given opts if given opts is a Hash" do
1591
- opts = {:host=>1, :database=>2}
1592
- Sequel::Database.new(opts).send(:server_opts, :host=>2)[:host].must_equal 2
1593
- end
1594
- end
1595
-
1596
- describe "Database#add_servers" do
1597
- before do
1598
- @db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
1599
- end
1600
-
1601
- it "should add new servers to the connection pool" do
1602
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1603
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1604
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
1605
-
1606
- @db.add_servers(:server2=>{:host=>6})
1607
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1608
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1609
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 6}
1610
-
1611
- @db.disconnect
1612
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1613
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1614
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 6}
1615
- end
1616
-
1617
- it "should replace options for future connections to existing servers" do
1618
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1619
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1620
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
1621
-
1622
- @db.add_servers(:default=>proc{{:host=>4}}, :server1=>{:host=>8})
1623
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1624
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1625
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
1626
-
1627
- @db.disconnect
1628
- @db.synchronize{|c| c.opts[:host].must_equal 4}
1629
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 8}
1630
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 4}
1631
- end
1632
- end
1633
-
1634
- describe "Database#remove_servers" do
1635
- before do
1636
- @db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
1637
- end
1638
-
1639
- it "should remove servers from the connection pool" do
1640
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1641
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 3}
1642
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 4}
1643
-
1644
- @db.remove_servers(:server1, :server2)
1645
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1646
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 1}
1647
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
1648
- end
1649
-
1650
- it "should accept arrays of symbols" do
1651
- @db.remove_servers([:server1, :server2])
1652
- @db.synchronize{|c| c.opts[:host].must_equal 1}
1653
- @db.synchronize(:server1){|c| c.opts[:host].must_equal 1}
1654
- @db.synchronize(:server2){|c| c.opts[:host].must_equal 1}
1655
- end
1656
-
1657
- it "should allow removal while connections are still open" do
1658
- @db.synchronize do |c1|
1659
- c1.opts[:host].must_equal 1
1660
- @db.synchronize(:server1) do |c2|
1661
- c2.opts[:host].must_equal 3
1662
- @db.synchronize(:server2) do |c3|
1663
- c3.opts[:host].must_equal 4
1664
- @db.remove_servers(:server1, :server2)
1665
- @db.synchronize(:server1) do |c4|
1666
- c4.wont_equal c2
1667
- c4.must_equal c1
1668
- c4.opts[:host].must_equal 1
1669
- @db.synchronize(:server2) do |c5|
1670
- c5.wont_equal c3
1671
- c5.must_equal c1
1672
- c5.opts[:host].must_equal 1
1673
- end
1674
- end
1675
- c3.opts[:host].must_equal 4
1676
- end
1677
- c2.opts[:host].must_equal 3
1678
- end
1679
- c1.opts[:host].must_equal 1
1680
- end
1681
- end
1682
- end
1683
-
1684
- describe "Database#each_server with do/jdbc adapter connection string without :adapter option" do
1685
- it "should yield a separate database object for each server" do
1686
- require 'sequel/adapters/mock'
1687
- klass = Class.new(Sequel::Database)
1688
- def klass.adapter_class(v)
1689
- raise unless v == :jdbc
1690
- Sequel::Mock::Database
1691
- end
1692
- @db = klass.connect('jdbc:blah:', :host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
1693
-
1694
- hosts = []
1695
- @db.each_server do |db|
1696
- db.must_be_kind_of(Sequel::Database)
1697
- db.wont_equal @db
1698
- db.opts[:adapter_class].must_equal Sequel::Mock::Database
1699
- db.opts[:database].must_equal 2
1700
- hosts << db.opts[:host]
1701
- end
1702
- hosts.sort.must_equal [1, 3]
1703
- end
1704
-
1705
- it "should raise if not given a block" do
1706
- proc{Sequel.mock.each_server}.must_raise(Sequel::Error)
1707
- end
1708
- end
1709
-
1710
- describe "Database#each_server" do
1711
- before do
1712
- @db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
1713
- end
1714
-
1715
- it "should yield a separate database object for each server" do
1716
- hosts = []
1717
- @db.each_server do |db|
1718
- db.must_be_kind_of(Sequel::Database)
1719
- db.wont_equal @db
1720
- db.opts[:adapter].must_equal :mock
1721
- db.opts[:database].must_equal 2
1722
- hosts << db.opts[:host]
1723
- end
1724
- hosts.sort.must_equal [1, 3, 4]
1725
- end
1726
-
1727
- it "should disconnect and remove entry from Sequel::DATABASES after use" do
1728
- dbs = []
1729
- dcs = []
1730
- @db.each_server do |db|
1731
- dbs << db
1732
- Sequel::DATABASES.must_include(db)
1733
- meta_def(db, :disconnect){dcs << db}
1734
- end
1735
- dbs.each do |db|
1736
- Sequel::DATABASES.wont_include(db)
1737
- end
1738
- dbs.must_equal dcs
1739
- end
1740
- end
1741
-
1742
- describe "Database#raise_error" do
1743
- before do
1744
- @db = Sequel.mock
1745
- end
1746
-
1747
- it "should reraise if the exception class is not in opts[:classes]" do
1748
- e = Class.new(StandardError)
1749
- proc{@db.send(:raise_error, e.new(''), :classes=>[])}.must_raise(e)
1750
- end
1751
-
1752
- it "should convert the exception to a DatabaseError if the exception class is in opts[:classes]" do
1753
- proc{@db.send(:raise_error, Interrupt.new(''), :classes=>[Interrupt])}.must_raise(Sequel::DatabaseError)
1754
- end
1755
-
1756
- it "should convert the exception to a DatabaseError if opts[:classes] if not present" do
1757
- proc{@db.send(:raise_error, Interrupt.new(''))}.must_raise(Sequel::DatabaseError)
1758
- end
1759
-
1760
- it "should convert the exception to a DatabaseDisconnectError if opts[:disconnect] is true" do
1761
- proc{@db.send(:raise_error, Interrupt.new(''), :disconnect=>true)}.must_raise(Sequel::DatabaseDisconnectError)
1762
- end
1763
-
1764
- it "should convert the exception to an appropriate error if exception message matches regexp" do
1765
- def @db.database_error_regexps
1766
- {/foo/ => Sequel::DatabaseDisconnectError, /bar/ => Sequel::ConstraintViolation}
1767
- end
1768
- proc{@db.send(:raise_error, Interrupt.new('foo'))}.must_raise(Sequel::DatabaseDisconnectError)
1769
- proc{@db.send(:raise_error, Interrupt.new('bar'))}.must_raise(Sequel::ConstraintViolation)
1770
- end
1771
- end
1772
-
1773
- describe "Database#typecast_value" do
1774
- before do
1775
- @db = Sequel::Database.new
1776
- end
1777
-
1778
- it "should raise an InvalidValue when given an invalid value" do
1779
- proc{@db.typecast_value(:integer, "13a")}.must_raise(Sequel::InvalidValue)
1780
- proc{@db.typecast_value(:float, "4.e2")}.must_raise(Sequel::InvalidValue)
1781
- proc{@db.typecast_value(:decimal, :invalid_value)}.must_raise(Sequel::InvalidValue)
1782
- proc{@db.typecast_value(:date, Object.new)}.must_raise(Sequel::InvalidValue)
1783
- proc{@db.typecast_value(:date, 'a')}.must_raise(Sequel::InvalidValue)
1784
- proc{@db.typecast_value(:time, Date.new)}.must_raise(Sequel::InvalidValue)
1785
- proc{@db.typecast_value(:datetime, 4)}.must_raise(Sequel::InvalidValue)
1786
- end
1787
-
1788
- it "should handle integers with leading 0 as base 10" do
1789
- @db.typecast_value(:integer, "013").must_equal 13
1790
- @db.typecast_value(:integer, "08").must_equal 8
1791
- @db.typecast_value(:integer, "000013").must_equal 13
1792
- @db.typecast_value(:integer, "000008").must_equal 8
1793
- end
1794
-
1795
- it "should handle integers with leading 0x as base 16" do
1796
- @db.typecast_value(:integer, "0x013").must_equal 19
1797
- @db.typecast_value(:integer, "0x80").must_equal 128
1798
- end
1799
-
1800
- it "should typecast blobs as as Sequel::SQL::Blob" do
1801
- v = @db.typecast_value(:blob, "0x013")
1802
- v.must_be_kind_of(Sequel::SQL::Blob)
1803
- v.must_equal Sequel::SQL::Blob.new("0x013")
1804
- @db.typecast_value(:blob, v).object_id.must_equal v.object_id
1805
- end
1806
-
1807
- it "should typecast boolean values to true, false, or nil" do
1808
- @db.typecast_value(:boolean, false).must_equal false
1809
- @db.typecast_value(:boolean, 0).must_equal false
1810
- @db.typecast_value(:boolean, "0").must_equal false
1811
- @db.typecast_value(:boolean, 'f').must_equal false
1812
- @db.typecast_value(:boolean, 'false').must_equal false
1813
- @db.typecast_value(:boolean, true).must_equal true
1814
- @db.typecast_value(:boolean, 1).must_equal true
1815
- @db.typecast_value(:boolean, '1').must_equal true
1816
- @db.typecast_value(:boolean, 't').must_equal true
1817
- @db.typecast_value(:boolean, 'true').must_equal true
1818
- @db.typecast_value(:boolean, '').must_equal nil
1819
- end
1820
-
1821
- it "should typecast date values to Date" do
1822
- @db.typecast_value(:date, Date.today).must_equal Date.today
1823
- @db.typecast_value(:date, DateTime.now).must_equal Date.today
1824
- @db.typecast_value(:date, Time.now).must_equal Date.today
1825
- @db.typecast_value(:date, Date.today.to_s).must_equal Date.today
1826
- @db.typecast_value(:date, :year=>Date.today.year, :month=>Date.today.month, :day=>Date.today.day).must_equal Date.today
1827
- end
1828
-
1829
- it "should have Sequel.application_to_database_timestamp convert to Sequel.database_timezone" do
1830
- begin
1831
- t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
1832
- t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
1833
- t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
1834
- t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
1835
- Sequel.application_timezone = :utc
1836
- Sequel.database_timezone = :local
1837
- Sequel.application_to_database_timestamp(t).must_equal t4
1838
- Sequel.application_timezone = :local
1839
- Sequel.database_timezone = :utc
1840
- Sequel.application_to_database_timestamp(t2).must_equal t3
1841
- ensure
1842
- Sequel.default_timezone = nil
1843
- end
1844
- end
1845
-
1846
- it "should have Database#to_application_timestamp convert values using the database's timezone" do
1847
- begin
1848
- t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
1849
- t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
1850
- t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
1851
- t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
1852
- Sequel.default_timezone = :utc
1853
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t
1854
- Sequel.database_timezone = :local
1855
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t3
1856
- Sequel.default_timezone = :local
1857
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t2
1858
- Sequel.database_timezone = :utc
1859
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t4
1860
-
1861
- Sequel.default_timezone = :utc
1862
- @db.timezone = :local
1863
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t3
1864
- Sequel.default_timezone = :local
1865
- @db.timezone = :utc
1866
- @db.to_application_timestamp('2011-01-02 03:04:05').must_equal t4
1867
- ensure
1868
- Sequel.default_timezone = nil
1869
- end
1870
- end
1871
-
1872
- it "should typecast datetime values to Sequel.datetime_class with correct timezone handling" do
1873
- t = Time.utc(2011, 1, 2, 3, 4, 5, 500000) # UTC Time
1874
- t2 = Time.mktime(2011, 1, 2, 3, 4, 5, 500000) # Local Time
1875
- t3 = Time.utc(2011, 1, 2, 3, 4, 5, 500000) - (t - t2) # Local Time in UTC Time
1876
- t4 = Time.mktime(2011, 1, 2, 3, 4, 5, 500000) + (t - t2) # UTC Time in Local Time
1877
- secs = defined?(Rational) ? Rational(11, 2) : 5.5
1878
- r1 = defined?(Rational) ? Rational(t2.utc_offset, 86400) : t2.utc_offset/86400.0
1879
- r2 = defined?(Rational) ? Rational((t - t2).to_i, 86400) : (t - t2).to_i/86400.0
1880
- dt = DateTime.civil(2011, 1, 2, 3, 4, secs)
1881
- dt2 = DateTime.civil(2011, 1, 2, 3, 4, secs, r1)
1882
- dt3 = DateTime.civil(2011, 1, 2, 3, 4, secs) - r2
1883
- dt4 = DateTime.civil(2011, 1, 2, 3, 4, secs, r1) + r2
1884
-
1885
- t.must_equal t4
1886
- t2.must_equal t3
1887
- dt.must_equal dt4
1888
- dt2.must_equal dt3
1889
-
1890
- check = proc do |i, o|
1891
- v = @db.typecast_value(:datetime, i)
1892
- v.must_equal o
1893
- if o.is_a?(Time)
1894
- v.utc_offset.must_equal o.utc_offset
1895
- else
1896
- v.offset.must_equal o.offset
1897
- end
1898
- end
1899
- @db.extend_datasets(Module.new{def supports_timestamp_timezones?; true; end})
1900
- begin
1901
- @db.typecast_value(:datetime, dt).must_equal t
1902
- @db.typecast_value(:datetime, dt2).must_equal t2
1903
- @db.typecast_value(:datetime, t).must_equal t
1904
- @db.typecast_value(:datetime, t2).must_equal t2
1905
- @db.typecast_value(:datetime, @db.literal(dt)[1...-1]).must_equal t
1906
- @db.typecast_value(:datetime, dt.strftime('%F %T.%N')).must_equal t2
1907
- @db.typecast_value(:datetime, Date.civil(2011, 1, 2)).must_equal Time.mktime(2011, 1, 2, 0, 0, 0)
1908
- @db.typecast_value(:datetime, :year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000).must_equal t2
1909
-
1910
- Sequel.datetime_class = DateTime
1911
- @db.typecast_value(:datetime, dt).must_equal dt
1912
- @db.typecast_value(:datetime, dt2).must_equal dt2
1913
- @db.typecast_value(:datetime, t).must_equal dt
1914
- @db.typecast_value(:datetime, t2).must_equal dt2
1915
- @db.typecast_value(:datetime, @db.literal(dt)[1...-1]).must_equal dt
1916
- @db.typecast_value(:datetime, dt.strftime('%F %T.%N')).must_equal dt
1917
- @db.typecast_value(:datetime, Date.civil(2011, 1, 2)).must_equal DateTime.civil(2011, 1, 2, 0, 0, 0)
1918
- @db.typecast_value(:datetime, :year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000).must_equal dt
1919
-
1920
- Sequel.application_timezone = :utc
1921
- Sequel.typecast_timezone = :local
1922
- Sequel.datetime_class = Time
1923
- check[dt, t]
1924
- check[dt2, t3]
1925
- check[t, t]
1926
- check[t2, t3]
1927
- check[@db.literal(dt)[1...-1], t]
1928
- check[dt.strftime('%F %T.%N'), t3]
1929
- check[Date.civil(2011, 1, 2), Time.utc(2011, 1, 2, 0, 0, 0)]
1930
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t3]
1931
-
1932
- Sequel.datetime_class = DateTime
1933
- check[dt, dt]
1934
- check[dt2, dt3]
1935
- check[t, dt]
1936
- check[t2, dt3]
1937
- check[@db.literal(dt)[1...-1], dt]
1938
- check[dt.strftime('%F %T.%N'), dt3]
1939
- check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0)]
1940
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt3]
1941
-
1942
- Sequel.typecast_timezone = :utc
1943
- Sequel.datetime_class = Time
1944
- check[dt, t]
1945
- check[dt2, t3]
1946
- check[t, t]
1947
- check[t2, t3]
1948
- check[@db.literal(dt)[1...-1], t]
1949
- check[dt.strftime('%F %T.%N'), t]
1950
- check[Date.civil(2011, 1, 2), Time.utc(2011, 1, 2, 0, 0, 0)]
1951
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t]
1952
-
1953
- Sequel.datetime_class = DateTime
1954
- check[dt, dt]
1955
- check[dt2, dt3]
1956
- check[t, dt]
1957
- check[t2, dt3]
1958
- check[@db.literal(dt)[1...-1], dt]
1959
- check[dt.strftime('%F %T.%N'), dt]
1960
- check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0)]
1961
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt]
1962
-
1963
- Sequel.application_timezone = :local
1964
- Sequel.datetime_class = Time
1965
- check[dt, t4]
1966
- check[dt2, t2]
1967
- check[t, t4]
1968
- check[t2, t2]
1969
- check[@db.literal(dt)[1...-1], t4]
1970
- check[dt.strftime('%F %T.%N'), t4]
1971
- check[Date.civil(2011, 1, 2), Time.local(2011, 1, 2, 0, 0, 0)]
1972
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t4]
1973
-
1974
- Sequel.datetime_class = DateTime
1975
- check[dt, dt4]
1976
- check[dt2, dt2]
1977
- check[t, dt4]
1978
- check[t2, dt2]
1979
- check[@db.literal(dt)[1...-1], dt4]
1980
- check[dt.strftime('%F %T.%N'), dt4]
1981
- check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0, r1)]
1982
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt4]
1983
-
1984
- Sequel.typecast_timezone = :local
1985
- Sequel.datetime_class = Time
1986
- check[dt, t4]
1987
- check[dt2, t2]
1988
- check[t, t4]
1989
- check[t2, t2]
1990
- check[@db.literal(dt)[1...-1], t4]
1991
- check[dt.strftime('%F %T.%N'), t2]
1992
- check[Date.civil(2011, 1, 2), Time.local(2011, 1, 2, 0, 0, 0)]
1993
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, t2]
1994
-
1995
- Sequel.datetime_class = DateTime
1996
- check[dt, dt4]
1997
- check[dt2, dt2]
1998
- check[t, dt4]
1999
- check[t2, dt2]
2000
- check[@db.literal(dt)[1...-1], dt4]
2001
- check[dt.strftime('%F %T.%N'), dt2]
2002
- check[Date.civil(2011, 1, 2), DateTime.civil(2011, 1, 2, 0, 0, 0, r1)]
2003
- check[{:year=>dt.year, :month=>dt.month, :day=>dt.day, :hour=>dt.hour, :minute=>dt.min, :second=>dt.sec, :nanos=>500000000}, dt2]
2004
-
2005
- ensure
2006
- Sequel.default_timezone = nil
2007
- Sequel.datetime_class = Time
2008
- end
2009
- end
2010
-
2011
- it "should handle arrays when typecasting timestamps" do
2012
- begin
2013
- @db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14]).must_equal Time.local(2011, 10, 11, 12, 13, 14)
2014
- @db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000]).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
2015
-
2016
- Sequel.datetime_class = DateTime
2017
- @db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14]).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
2018
- @db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000]).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
2019
- @db.typecast_value(:datetime, [2011, 10, 11, 12, 13, 14, 500000000, (defined?(Rational) ? Rational(1, 2) : 0.5)]).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
2020
- ensure
2021
- Sequel.datetime_class = Time
2022
- end
2023
- end
2024
-
2025
- it "should handle hashes when typecasting timestamps" do
2026
- begin
2027
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14).must_equal Time.local(2011, 10, 11, 12, 13, 14)
2028
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
2029
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14).must_equal Time.local(2011, 10, 11, 12, 13, 14)
2030
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000).must_equal Time.local(2011, 10, 11, 12, 13, 14, 500000)
2031
-
2032
- Sequel.datetime_class = DateTime
2033
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
2034
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
2035
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14)
2036
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5))
2037
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :offset=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14, (defined?(Rational) ? Rational(1, 2) : 0.5))
2038
- @db.typecast_value(:datetime, :year=>2011, :month=>10, :day=>11, :hour=>12, :minute=>13, :second=>14, :nanos=>500000000, :offset=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
2039
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'offset'=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, 14, (defined?(Rational) ? Rational(1, 2) : 0.5))
2040
- @db.typecast_value(:datetime, 'year'=>2011, 'month'=>10, 'day'=>11, 'hour'=>12, 'minute'=>13, 'second'=>14, 'nanos'=>500000000, 'offset'=>(defined?(Rational) ? Rational(1, 2) : 0.5)).must_equal DateTime.civil(2011, 10, 11, 12, 13, (defined?(Rational) ? Rational(29, 2) : 14.5), (defined?(Rational) ? Rational(1, 2) : 0.5))
2041
- ensure
2042
- Sequel.datetime_class = Time
2043
- end
2044
- end
2045
-
2046
- it "should typecast decimal values to BigDecimal" do
2047
- [1.0, 1, '1.0', BigDecimal('1.0')].each do |i|
2048
- v = @db.typecast_value(:decimal, i)
2049
- v.must_be_kind_of(BigDecimal)
2050
- v.must_equal BigDecimal.new('1.0')
2051
- end
2052
- end
2053
-
2054
- it "should typecast float values to Float" do
2055
- [1.0, 1, '1.0', BigDecimal('1.0')].each do |i|
2056
- v = @db.typecast_value(:float, i)
2057
- v.must_be_kind_of(Float)
2058
- v.must_equal 1.0
2059
- end
2060
- end
2061
-
2062
- it "should typecast string values to String" do
2063
- [1.0, '1.0', Sequel.blob('1.0')].each do |i|
2064
- v = @db.typecast_value(:string, i)
2065
- v.must_be_instance_of(String)
2066
- v.must_equal "1.0"
2067
- end
2068
- end
2069
-
2070
- it "should raise errors when typecasting hash and array values to String" do
2071
- [[], {}].each do |i|
2072
- proc{@db.typecast_value(:string, i)}.must_raise(Sequel::InvalidValue)
2073
- end
2074
- end
2075
-
2076
- it "should typecast time values to SQLTime" do
2077
- t = Time.now
2078
- st = Sequel::SQLTime.local(t.year, t.month, t.day, 1, 2, 3)
2079
- [st, Time.utc(t.year, t.month, t.day, 1, 2, 3), Time.local(t.year, t.month, t.day, 1, 2, 3), '01:02:03', {:hour=>1, :minute=>2, :second=>3}].each do |i|
2080
- v = @db.typecast_value(:time, i)
2081
- v.must_be_instance_of(Sequel::SQLTime)
2082
- v.must_equal st
2083
- end
2084
- end
2085
-
2086
- it "should correctly handle time value conversion to SQLTime with fractional seconds" do
2087
- t = Time.now
2088
- st = Sequel::SQLTime.local(t.year, t.month, t.day, 1, 2, 3, 500000)
2089
- t = Time.local(t.year, t.month, t.day, 1, 2, 3, 500000)
2090
- @db.typecast_value(:time, t).must_equal st
2091
- end
2092
-
2093
- it "should have an underlying exception class available at wrapped_exception" do
2094
- begin
2095
- @db.typecast_value(:date, 'a')
2096
- true.must_equal false
2097
- rescue Sequel::InvalidValue => e
2098
- e.wrapped_exception.must_be_kind_of(ArgumentError)
2099
- end
2100
- end
2101
-
2102
- it "should include underlying exception class in #inspect" do
2103
- begin
2104
- @db.typecast_value(:date, 'a')
2105
- true.must_equal false
2106
- rescue Sequel::InvalidValue => e
2107
- e.inspect.must_match(/\A#<Sequel::InvalidValue: ArgumentError: .*>\z/)
2108
- end
2109
- end
2110
- end
2111
-
2112
- describe "Database#blank_object?" do
2113
- it "should return whether the object is considered blank" do
2114
- db = Sequel::Database.new
2115
- c = lambda{|meth, value| Class.new{define_method(meth){value}}.new}
2116
-
2117
- db.send(:blank_object?, "").must_equal true
2118
- db.send(:blank_object?, " ").must_equal true
2119
- db.send(:blank_object?, nil).must_equal true
2120
- db.send(:blank_object?, false).must_equal true
2121
- db.send(:blank_object?, []).must_equal true
2122
- db.send(:blank_object?, {}).must_equal true
2123
- db.send(:blank_object?, c[:empty?, true]).must_equal true
2124
- db.send(:blank_object?, c[:blank?, true]).must_equal true
2125
-
2126
- db.send(:blank_object?, " a ").must_equal false
2127
- db.send(:blank_object?, 1).must_equal false
2128
- db.send(:blank_object?, 1.0).must_equal false
2129
- db.send(:blank_object?, true).must_equal false
2130
- db.send(:blank_object?, [1]).must_equal false
2131
- db.send(:blank_object?, {1.0=>2.0}).must_equal false
2132
- db.send(:blank_object?, c[:empty?, false]).must_equal false
2133
- db.send(:blank_object?, c[:blank?, false]).must_equal false
2134
- end
2135
- end
2136
-
2137
- describe "Database#schema_autoincrementing_primary_key?" do
2138
- it "should indicate whether the parsed schema row indicates a primary key" do
2139
- m = Sequel::Database.new.method(:schema_autoincrementing_primary_key?)
2140
- m.call(:primary_key=>true, :auto_increment=>true).must_equal true
2141
- m.call(:primary_key=>true, :auto_increment=>false).must_equal false
2142
- m.call(:primary_key=>false).must_equal false
2143
- end
2144
- end
2145
-
2146
- describe "Database#supports_schema_parsing?" do
2147
- it "should be false by default" do
2148
- Sequel::Database.new.supports_schema_parsing?.must_equal false
2149
- end
2150
-
2151
- it "should be true if the database implements schema_parse_table" do
2152
- db = Sequel::Database.new
2153
- def db.schema_parse_table(*) end
2154
- db.supports_schema_parsing?.must_equal true
2155
- end
2156
- end
2157
-
2158
- describe "Database#supports_foreign_key_parsing?" do
2159
- it "should be false by default" do
2160
- Sequel::Database.new.supports_foreign_key_parsing?.must_equal false
2161
- end
2162
-
2163
- it "should be true if the database implements foreign_key_list" do
2164
- db = Sequel::Database.new
2165
- def db.foreign_key_list(*) end
2166
- db.supports_foreign_key_parsing?.must_equal true
2167
- end
2168
- end
2169
-
2170
- describe "Database#supports_index_parsing?" do
2171
- it "should be false by default" do
2172
- Sequel::Database.new.supports_index_parsing?.must_equal false
2173
- end
2174
-
2175
- it "should be true if the database implements indexes" do
2176
- db = Sequel::Database.new
2177
- def db.indexes(*) end
2178
- db.supports_index_parsing?.must_equal true
2179
- end
2180
- end
2181
-
2182
- describe "Database#supports_table_listing?" do
2183
- it "should be false by default" do
2184
- Sequel::Database.new.supports_table_listing?.must_equal false
2185
- end
2186
-
2187
- it "should be true if the database implements tables" do
2188
- db = Sequel::Database.new
2189
- def db.tables(*) end
2190
- db.supports_table_listing?.must_equal true
2191
- end
2192
- end
2193
-
2194
- describe "Database#supports_view_listing?" do
2195
- it "should be false by default" do
2196
- Sequel::Database.new.supports_view_listing?.must_equal false
2197
- end
2198
-
2199
- it "should be true if the database implements views" do
2200
- db = Sequel::Database.new
2201
- def db.views(*) end
2202
- db.supports_view_listing?.must_equal true
2203
- end
2204
- end
2205
-
2206
- describe "Database#supports_deferrable_constraints?" do
2207
- it "should be false by default" do
2208
- Sequel::Database.new.supports_deferrable_constraints?.must_equal false
2209
- end
2210
- end
2211
-
2212
- describe "Database#supports_deferrable_foreign_key_constraints?" do
2213
- it "should be false by default" do
2214
- Sequel::Database.new.supports_deferrable_foreign_key_constraints?.must_equal false
2215
- end
2216
- end
2217
-
2218
- describe "Database#supports_transactional_ddl?" do
2219
- it "should be false by default" do
2220
- Sequel::Database.new.supports_transactional_ddl?.must_equal false
2221
- end
2222
- end
2223
-
2224
- describe "Database#global_index_namespace?" do
2225
- it "should be true by default" do
2226
- Sequel::Database.new.global_index_namespace?.must_equal true
2227
- end
2228
- end
2229
-
2230
- describe "Database#supports_savepoints?" do
2231
- it "should be false by default" do
2232
- Sequel::Database.new.supports_savepoints?.must_equal false
2233
- end
2234
- end
2235
-
2236
- describe "Database#supports_views_with_check_option?" do
2237
- it "should be false by default" do
2238
- Sequel::Database.new.supports_views_with_check_option?.must_equal false
2239
- end
2240
- end
2241
-
2242
- describe "Database#supports_views_with_local_check_option?" do
2243
- it "should be false by default" do
2244
- Sequel::Database.new.supports_views_with_local_check_option?.must_equal false
2245
- end
2246
- end
2247
-
2248
- describe "Database#supports_savepoints_in_prepared_transactions?" do
2249
- it "should be false by default" do
2250
- Sequel::Database.new.supports_savepoints_in_prepared_transactions?.must_equal false
2251
- end
2252
-
2253
- it "should be true if both savepoints and prepared transactions are supported" do
2254
- db = Sequel::Database.new
2255
- meta_def(db, :supports_savepoints?){true}
2256
- meta_def(db, :supports_prepared_transactions?){true}
2257
- db.supports_savepoints_in_prepared_transactions?.must_equal true
2258
- end
2259
- end
2260
-
2261
- describe "Database#supports_prepared_transactions?" do
2262
- it "should be false by default" do
2263
- Sequel::Database.new.supports_prepared_transactions?.must_equal false
2264
- end
2265
- end
2266
-
2267
- describe "Database#supports_transaction_isolation_levels?" do
2268
- it "should be false by default" do
2269
- Sequel::Database.new.supports_transaction_isolation_levels?.must_equal false
2270
- end
2271
- end
2272
-
2273
- describe "Database#input_identifier_meth" do
2274
- it "should be the input_identifer method of a default dataset for this database" do
2275
- db = Sequel::Database.new
2276
- db.send(:input_identifier_meth).call(:a).must_equal 'a'
2277
- db.identifier_input_method = :upcase
2278
- db.send(:input_identifier_meth).call(:a).must_equal 'A'
2279
- end
2280
- end
2281
-
2282
- describe "Database#output_identifier_meth" do
2283
- it "should be the output_identifer method of a default dataset for this database" do
2284
- db = Sequel::Database.new
2285
- db.send(:output_identifier_meth).call('A').must_equal :A
2286
- db.identifier_output_method = :downcase
2287
- db.send(:output_identifier_meth).call('A').must_equal :a
2288
- end
2289
- end
2290
-
2291
- describe "Database#metadata_dataset" do
2292
- it "should be a dataset with the default settings for identifier_input_method and identifier_output_method" do
2293
- ds = Sequel::Database.new.send(:metadata_dataset)
2294
- ds.literal(:a).must_equal 'A'
2295
- ds.send(:output_identifier, 'A').must_equal :a
2296
- end
2297
- end
2298
-
2299
- describe "Database#column_schema_to_ruby_default" do
2300
- it "should handle converting many default formats" do
2301
- db = Sequel::Database.new
2302
- p = lambda{|d,t| db.send(:column_schema_to_ruby_default, d, t)}
2303
- p[nil, :integer].must_equal nil
2304
- p[1, :integer].must_equal 1
2305
- p['1', :integer].must_equal 1
2306
- p['-1', :integer].must_equal(-1)
2307
- p[1.0, :float].must_equal 1.0
2308
- p['1.0', :float].must_equal 1.0
2309
- p['-1.0', :float].must_equal(-1.0)
2310
- p['1.0', :decimal].must_equal BigDecimal.new('1.0')
2311
- p['-1.0', :decimal].must_equal BigDecimal.new('-1.0')
2312
- p[true, :boolean].must_equal true
2313
- p[false, :boolean].must_equal false
2314
- p['1', :boolean].must_equal true
2315
- p['0', :boolean].must_equal false
2316
- p['true', :boolean].must_equal true
2317
- p['false', :boolean].must_equal false
2318
- p["'t'", :boolean].must_equal true
2319
- p["'f'", :boolean].must_equal false
2320
- p["'a'", :string].must_equal 'a'
2321
- p["'a'", :blob].must_equal Sequel.blob('a')
2322
- p["'a'", :blob].must_be_kind_of(Sequel::SQL::Blob)
2323
- p["''", :string].must_equal ''
2324
- p["'\\a''b'", :string].must_equal "\\a'b"
2325
- p["'NULL'", :string].must_equal "NULL"
2326
- p[Date.today, :date].must_equal Date.today
2327
- p["'2009-10-29'", :date].must_equal Date.new(2009,10,29)
2328
- p["CURRENT_TIMESTAMP", :date].must_equal Sequel::CURRENT_DATE
2329
- p["CURRENT_DATE", :date].must_equal Sequel::CURRENT_DATE
2330
- p["now()", :date].must_equal Sequel::CURRENT_DATE
2331
- p["getdate()", :date].must_equal Sequel::CURRENT_DATE
2332
- p["CURRENT_TIMESTAMP", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
2333
- p["CURRENT_DATE", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
2334
- p["now()", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
2335
- p["getdate()", :datetime].must_equal Sequel::CURRENT_TIMESTAMP
2336
- p["'2009-10-29T10:20:30-07:00'", :datetime].must_equal DateTime.parse('2009-10-29T10:20:30-07:00')
2337
- p["'2009-10-29 10:20:30'", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30')
2338
- p["'10:20:30'", :time].must_equal Time.parse('10:20:30')
2339
- p["NaN", :float].must_equal nil
2340
-
2341
- db = Sequel.mock(:host=>'postgres')
2342
- p["''::text", :string].must_equal ""
2343
- p["'\\a''b'::character varying", :string].must_equal "\\a'b"
2344
- p["'a'::bpchar", :string].must_equal "a"
2345
- p["(-1)", :integer].must_equal(-1)
2346
- p["(-1.0)", :float].must_equal(-1.0)
2347
- p['(-1.0)', :decimal].must_equal BigDecimal.new('-1.0')
2348
- p["'a'::bytea", :blob].must_equal Sequel.blob('a')
2349
- p["'a'::bytea", :blob].must_be_kind_of(Sequel::SQL::Blob)
2350
- p["'2009-10-29'::date", :date].must_equal Date.new(2009,10,29)
2351
- p["'2009-10-29 10:20:30.241343'::timestamp without time zone", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30.241343')
2352
- p["'10:20:30'::time without time zone", :time].must_equal Time.parse('10:20:30')
2353
-
2354
- db = Sequel.mock(:host=>'mysql')
2355
- p["\\a'b", :string].must_equal "\\a'b"
2356
- p["a", :string].must_equal "a"
2357
- p["NULL", :string].must_equal "NULL"
2358
- p["-1", :float].must_equal(-1.0)
2359
- p['-1', :decimal].must_equal BigDecimal.new('-1.0')
2360
- p["2009-10-29", :date].must_equal Date.new(2009,10,29)
2361
- p["2009-10-29 10:20:30", :datetime].must_equal DateTime.parse('2009-10-29 10:20:30')
2362
- p["10:20:30", :time].must_equal Time.parse('10:20:30')
2363
- p["a", :enum].must_equal "a"
2364
- p["a,b", :set].must_equal "a,b"
2365
-
2366
- db = Sequel.mock(:host=>'mssql')
2367
- p["(N'a')", :string].must_equal "a"
2368
- p["((-12))", :integer].must_equal(-12)
2369
- p["((12.1))", :float].must_equal 12.1
2370
- p["((-12.1))", :decimal].must_equal BigDecimal.new('-12.1')
2371
- end
2372
- end
2373
-
2374
- describe "Database extensions" do
2375
- before(:all) do
2376
- class << Sequel
2377
- alias _extension extension
2378
- remove_method :extension
2379
- def extension(*)
2380
- end
2381
- end
2382
- end
2383
- after(:all) do
2384
- class << Sequel
2385
- remove_method :extension
2386
- alias extension _extension
2387
- remove_method :_extension
2388
- end
2389
- end
2390
- before do
2391
- @db = Sequel.mock
2392
- end
2393
- after do
2394
- Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
2395
- end
2396
-
2397
- it "should be able to register an extension with a module have Database#extension extend the module" do
2398
- Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
2399
- @db.extension(:foo).a.must_equal 1
2400
- end
2401
-
2402
- it "should be able to register an extension with a block and have Database#extension call the block" do
2403
- @db.quote_identifiers = false
2404
- Sequel::Database.register_extension(:foo){|db| db.quote_identifiers = true}
2405
- @db.extension(:foo).quote_identifiers?.must_equal true
2406
- end
2407
-
2408
- it "should be able to register an extension with a callable and Database#extension call the callable" do
2409
- @db.quote_identifiers = false
2410
- Sequel::Database.register_extension(:foo, proc{|db| db.quote_identifiers = true})
2411
- @db.extension(:foo).quote_identifiers?.must_equal true
2412
- end
2413
-
2414
- it "should be able to load multiple extensions in the same call" do
2415
- @db.quote_identifiers = false
2416
- @db.identifier_input_method = :downcase
2417
- Sequel::Database.register_extension(:foo, proc{|db| db.quote_identifiers = true})
2418
- Sequel::Database.register_extension(:bar, proc{|db| db.identifier_input_method = nil})
2419
- @db.extension(:foo, :bar)
2420
- @db.quote_identifiers?.must_equal true
2421
- @db.identifier_input_method.must_equal nil
2422
- end
2423
-
2424
- it "should return the receiver" do
2425
- Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
2426
- @db.extension(:foo).must_be_same_as(@db)
2427
- end
2428
-
2429
- it "should raise an Error if registering with both a module and a block" do
2430
- proc{Sequel::Database.register_extension(:foo, Module.new){}}.must_raise(Sequel::Error)
2431
- end
2432
-
2433
- it "should raise an Error if attempting to load an incompatible extension" do
2434
- proc{@db.extension(:foo2)}.must_raise(Sequel::Error)
2435
- end
2436
-
2437
- it "should be able to load an extension into all future Databases with Database.extension" do
2438
- Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
2439
- Sequel::Database.register_extension(:bar, Module.new{def b; 2; end})
2440
- Sequel::Database.extension(:foo, :bar)
2441
- @db.wont_respond_to(:a)
2442
- @db.wont_respond_to(:b)
2443
- Sequel.mock.a.must_equal 1
2444
- Sequel.mock.b.must_equal 2
2445
- end
2446
- end
2447
-
2448
- describe "Database specific exception classes" do
2449
- before do
2450
- @db = Sequel.mock
2451
- class << @db
2452
- attr_accessor :sql_state
2453
-
2454
- def database_exception_sqlstate(exception, opts={})
2455
- @sql_state
2456
- end
2457
- end
2458
- end
2459
-
2460
- it "should use appropriate exception classes for given SQL states" do
2461
- @db.fetch = ArgumentError
2462
- @db.sql_state = '23502'
2463
- proc{@db.get(:a)}.must_raise(Sequel::NotNullConstraintViolation)
2464
- @db.sql_state = '23503'
2465
- proc{@db.get(:a)}.must_raise(Sequel::ForeignKeyConstraintViolation)
2466
- @db.sql_state = '23505'
2467
- proc{@db.get(:a)}.must_raise(Sequel::UniqueConstraintViolation)
2468
- @db.sql_state = '23513'
2469
- proc{@db.get(:a)}.must_raise(Sequel::CheckConstraintViolation)
2470
- @db.sql_state = '40001'
2471
- proc{@db.get(:a)}.must_raise(Sequel::SerializationFailure)
2472
- end
2473
- end
2474
-
2475
- describe "Database.after_initialize" do
2476
- after do
2477
- Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
2478
- end
2479
-
2480
- it "should allow a block to be run after each new instance is created" do
2481
- Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
2482
- db = Sequel.mock
2483
- db.sql_log_level.must_equal :debug
2484
- end
2485
-
2486
- it "should allow multiple hooks to be registered" do
2487
- Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
2488
- Sequel::Database.after_initialize{|db| db.loggers << 11 }
2489
-
2490
- db = Sequel.mock
2491
-
2492
- db.sql_log_level.must_equal :debug
2493
- db.loggers.must_include(11)
2494
- end
2495
-
2496
- it "should raise an error if registration is called without a block" do
2497
- proc {
2498
- Sequel::Database.after_initialize
2499
- }.must_raise(Sequel::Error, /must provide block/i)
2500
- end
2501
- end
2502
-
2503
- describe "Database#schema_type_class" do
2504
- it "should return the class or array of classes for the given type symbol" do
2505
- db = Sequel.mock
2506
- {:string=>String, :integer=>Integer, :date=>Date, :datetime=>[Time, DateTime],
2507
- :time=>Sequel::SQLTime, :boolean=>[TrueClass, FalseClass], :float=>Float, :decimal=>BigDecimal,
2508
- :blob=>Sequel::SQL::Blob}.each do |sym, klass|
2509
- db.schema_type_class(sym).must_equal klass
2510
- end
2511
- end
2512
- end
2513
-
2514
- describe "Database#execute_{dui,ddl,insert}" do
2515
- before do
2516
- @db = Sequel::Database.new
2517
- def @db.execute(sql, opts={})
2518
- (@sqls ||= []) << sql
2519
- end
2520
- def @db.sqls
2521
- @sqls
2522
- end
2523
- end
2524
-
2525
- it "should execute the SQL" do
2526
- @db.execute_dui "DELETE FROM table"
2527
- @db.execute_ddl "SET foo"
2528
- @db.execute_insert "INSERT INTO table DEFAULT VALUES"
2529
- @db.sqls.must_equal ["DELETE FROM table", "SET foo", "INSERT INTO table DEFAULT VALUES"]
2530
- end
2531
- end