sequel 4.26.0 → 5.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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