sequel 5.8.0 → 5.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -1,269 +0,0 @@
1
- require 'rbconfig'
2
- require 'yaml'
3
-
4
- RUBY = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['RUBY_INSTALL_NAME'])
5
- OUTPUT = "spec/bin-sequel-spec-output-#{$$}.log"
6
- TMP_FILE = "spec/bin-sequel-tmp-#{$$}.rb"
7
- BIN_SPEC_DB = "spec/bin-sequel-spec-db-#{$$}.sqlite3"
8
- BIN_SPEC_DB2 = "spec/bin-sequel-spec-db2-#{$$}.sqlite3"
9
-
10
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
11
- CONN_PREFIX = 'jdbc:sqlite:'
12
- CONN_HASH = {:adapter=>'jdbc', :uri=>"#{CONN_PREFIX}#{BIN_SPEC_DB}"}
13
- else
14
- CONN_PREFIX = 'sqlite://'
15
- CONN_HASH = {:adapter=>'sqlite', :database=>BIN_SPEC_DB}
16
- end
17
-
18
- require_relative '../lib/sequel'
19
-
20
- Sequel::DB = nil
21
- File.delete(BIN_SPEC_DB) if File.file?(BIN_SPEC_DB)
22
- File.delete(BIN_SPEC_DB2) if File.file?(BIN_SPEC_DB2)
23
- DB = Sequel.connect("#{CONN_PREFIX}#{BIN_SPEC_DB}", :test=>false)
24
- DB2 = Sequel.connect("#{CONN_PREFIX}#{BIN_SPEC_DB2}", :test=>false)
25
-
26
- require 'minitest/autorun'
27
-
28
- describe "bin/sequel" do
29
- def bin(opts={})
30
- cmd = "#{opts[:pre]}\"#{RUBY}\" -I lib bin/sequel #{opts[:args]} #{"#{CONN_PREFIX}#{BIN_SPEC_DB}" unless opts[:no_conn]} #{opts[:post]}> #{OUTPUT}#{" 2>&1" if opts[:stderr]}"
31
- system(cmd)
32
- File.read(OUTPUT)
33
- end
34
-
35
- after do
36
- DB.disconnect
37
- DB2.disconnect
38
- [BIN_SPEC_DB, BIN_SPEC_DB2, TMP_FILE, OUTPUT].each do |file|
39
- if File.file?(file)
40
- begin
41
- File.delete(file)
42
- rescue Errno::ENOENT
43
- nil
44
- end
45
- end
46
- end
47
- end
48
-
49
- it "-h should print the help" do
50
- help = bin(:args=>"-h", :no_conn=>true)
51
- help.must_match(/\ASequel: The Database Toolkit for Ruby/)
52
- help.must_match(/^Usage: sequel /)
53
- end
54
-
55
- it "-c should run code" do
56
- bin(:args=>'-c "print DB.tables.inspect"').must_equal '[]'
57
- DB.create_table(:a){Integer :a}
58
- bin(:args=>'-c "print DB.tables.inspect"').must_equal '[:a]'
59
- bin(:args=>'-v -c "print DB.tables.inspect"').strip.must_equal "sequel #{Sequel.version}\n[:a]"
60
- end
61
-
62
- it "-C should copy databases" do
63
- DB.create_table(:a) do
64
- primary_key :a
65
- String :name
66
- end
67
- DB.create_table(:b) do
68
- foreign_key :a, :a
69
- index :a
70
- end
71
- DB[:a].insert(1, 'foo')
72
- DB[:b].insert(1)
73
- bin(:args=>'-C', :post=>"#{CONN_PREFIX}#{BIN_SPEC_DB2}").must_match Regexp.new(<<END)
74
- Databases connections successful
75
- Migrations dumped successfully
76
- Tables created
77
- Begin copying data
78
- Begin copying records for table: a
79
- Finished copying 1 records for table: a
80
- Begin copying records for table: b
81
- Finished copying 1 records for table: b
82
- Finished copying data
83
- Begin creating indexes
84
- Finished creating indexes
85
- Begin adding foreign key constraints
86
- Finished adding foreign key constraints
87
- Database copy finished in \\d\\.\\d+ seconds
88
- END
89
- DB2.tables.sort_by{|t| t.to_s}.must_equal [:a, :b]
90
- DB[:a].all.must_equal [{:a=>1, :name=>'foo'}]
91
- DB[:b].all.must_equal [{:a=>1}]
92
- DB2.schema(:a).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.must_equal [[:a, false, nil, true, "integer", :integer, nil], [:name, true, nil, false, "varchar(255)", :string, nil]]
93
- DB2.schema(:b).map{|col, sch| [col, *sch.values_at(:allow_null, :default, :primary_key, :db_type, :type, :ruby_default)]}.must_equal [[:a, true, nil, false, "integer", :integer, nil]]
94
- DB2.indexes(:a).must_equal({})
95
- DB2.indexes(:b).must_equal(:b_a_index=>{:unique=>false, :columns=>[:a]})
96
- DB2.foreign_key_list(:a).must_equal []
97
- DB2.foreign_key_list(:b).must_equal [{:columns=>[:a], :table=>:a, :key=>nil, :on_update=>:no_action, :on_delete=>:no_action}]
98
- end
99
-
100
- it "-d and -D should dump generic and specific migrations" do
101
- DB.create_table(:a) do
102
- primary_key :a
103
- String :name
104
- end
105
- DB.create_table(:b) do
106
- foreign_key :a, :a
107
- index :a
108
- end
109
- bin(:args=>'-d').must_equal <<END
110
- Sequel.migration do
111
- change do
112
- create_table(:a) do
113
- primary_key :a
114
- String :name, :size=>255
115
- end
116
-
117
- create_table(:b, :ignore_index_errors=>true) do
118
- foreign_key :a, :a
119
-
120
- index [:a]
121
- end
122
- end
123
- end
124
- END
125
- bin(:args=>'-D').must_equal <<END
126
- Sequel.migration do
127
- change do
128
- create_table(:a) do
129
- primary_key :a
130
- column :name, "varchar(255)"
131
- end
132
-
133
- create_table(:b) do
134
- foreign_key :a, :a
135
-
136
- index [:a]
137
- end
138
- end
139
- end
140
- END
141
- end
142
-
143
- it "-E should echo SQL statements to stdout" do
144
- bin(:args=>'-E -c DB.tables').must_include "SELECT * FROM `sqlite_master` WHERE ((`name` != 'sqlite_sequence') AND (`type` = 'table'))"
145
- end
146
-
147
- it "-I should include directory in load path" do
148
- bin(:args=>'-Ifoo -c "p 1 if $:.include?(\'foo\')"').must_equal "1\n"
149
- end
150
-
151
- it "-l should log SQL statements to file" do
152
- bin(:args=>"-l #{TMP_FILE} -c DB.tables").must_equal ''
153
- File.read(TMP_FILE).must_include "SELECT * FROM `sqlite_master` WHERE ((`name` != 'sqlite_sequence') AND (`type` = 'table'))"
154
- end
155
-
156
- it "-L should load all *.rb files in given directory" do
157
- bin(:args=>'-r ./lib/sequel/extensions/migration -L ./spec/files/integer_migrations -c "p Sequel::Migration.descendants.length"').must_equal "3\n"
158
- end
159
-
160
- it "-m should migrate database up" do
161
- bin(:args=>"-m spec/files/integer_migrations").must_equal ''
162
- DB.tables.sort_by{|t| t.to_s}.must_equal [:schema_info, :sm1111, :sm2222, :sm3333]
163
- end
164
-
165
- it "-M should specify version to migrate to" do
166
- bin(:args=>"-m spec/files/integer_migrations -M 2").must_equal ''
167
- DB.tables.sort_by{|t| t.to_s}.must_equal [:schema_info, :sm1111, :sm2222]
168
- end
169
-
170
- it "-N should not test for a valid connection" do
171
- bin(:no_conn=>true, :args=>"-c '' -N #{CONN_PREFIX}spec/nonexistent/foo").must_equal ''
172
- bin(:no_conn=>true, :args=>"-c '' #{CONN_PREFIX}spec/nonexistent/foo", :stderr=>true).must_match(/\AError: Sequel::DatabaseConnectionError: /)
173
- end
174
-
175
- it "-r should require a given library" do
176
- bin(:args=>'-rsequel/extensions/sql_expr -c "print DB.literal(1.sql_expr)"').must_equal "1"
177
- end
178
-
179
- it "-S should dump the schema cache" do
180
- bin(:args=>"-S #{TMP_FILE}").must_equal ''
181
- Marshal.load(File.read(TMP_FILE)).must_equal({})
182
- DB.create_table(:a){Integer :a}
183
- bin(:args=>"-S #{TMP_FILE}").must_equal ''
184
- Marshal.load(File.read(TMP_FILE)).must_equal("`a`"=>[[:a, {:type=>:integer, :db_type=>"integer", :ruby_default=>nil, :allow_null=>true, :default=>nil, :primary_key=>false}]])
185
- end
186
-
187
- it "-X should dump the index cache" do
188
- bin(:args=>"-X #{TMP_FILE}").must_equal ''
189
- Marshal.load(File.read(TMP_FILE)).must_equal({})
190
- DB.create_table(:a){Integer :id}
191
- DB.create_table(:b){Integer :b, index: {name: "idx_test", unique: true}}
192
- bin(:args=>"-X #{TMP_FILE}").must_equal ''
193
- Marshal.load(File.read(TMP_FILE)).must_equal("`a`"=>{}, "`b`"=>{:idx_test=>{:unique=>true, :columns=>[:b]}})
194
- end
195
-
196
- it "-t should output full backtraces on error" do
197
- bin(:args=>'-c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").must_be :<, 3
198
- bin(:args=>'-t -c "lambda{lambda{lambda{raise \'foo\'}.call}.call}.call"', :stderr=>true).count("\n").must_be :>, 3
199
- end
200
-
201
- it "-v should output the Sequel version and exit if database is not given" do
202
- bin(:args=>"-v", :no_conn=>true).strip.must_equal "sequel #{Sequel.version}"
203
- end
204
-
205
- it "should error if using -M without -m" do
206
- bin(:args=>'-M 2', :stderr=>true).must_equal "Error: Must specify -m if using -M\n"
207
- end
208
-
209
- it "should error if using mutually exclusive options together" do
210
- bin(:args=>'-c foo -d', :stderr=>true).must_equal "Error: Cannot specify -c and -d together\n"
211
- bin(:args=>'-D -d', :stderr=>true).must_equal "Error: Cannot specify -D and -d together\n"
212
- bin(:args=>'-m foo -d', :stderr=>true).must_equal "Error: Cannot specify -m and -d together\n"
213
- bin(:args=>'-S foo -d', :stderr=>true).must_equal "Error: Cannot specify -S and -d together\n"
214
- bin(:args=>'-S foo -C', :stderr=>true).must_equal "Error: Cannot specify -S and -C together\n"
215
- end
216
-
217
- it "should warn if providing too many arguments" do
218
- bin(:args=>'-c "" "" 1 2 3 4', :stderr=>true).must_equal "Warning: last 5 arguments ignored\n"
219
- end
220
-
221
- it "should use a mock database if no database is given" do
222
- bin(:args=>'-c "print DB.adapter_scheme"', :no_conn=>true).must_equal "mock"
223
- end
224
-
225
- it "should work with a yaml config file" do
226
- File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(CONN_HASH))}
227
- bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[]"
228
- DB.create_table(:a){Integer :a}
229
- bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
230
- end
231
-
232
- it "should work with a yaml config file with string keys" do
233
- h = {}
234
- CONN_HASH.each{|k,v| h[k.to_s] = v}
235
- File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(h))}
236
- DB.create_table(:a){Integer :a}
237
- bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
238
- end
239
-
240
- it "should work with a yaml config file with environments" do
241
- File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(:development=>CONN_HASH))}
242
- bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[]"
243
- DB.create_table(:a){Integer :a}
244
- bin(:args=>"-c \"print DB.tables.inspect\" #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
245
- end
246
-
247
- it "-e should set environment for yaml config file" do
248
- File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump(:foo=>CONN_HASH))}
249
- bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[]"
250
- DB.create_table(:a){Integer :a}
251
- bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
252
- File.open(TMP_FILE, 'wb'){|f| f.write(YAML.dump('foo'=>CONN_HASH))}
253
- bin(:args=>"-c \"print DB.tables.inspect\" -e foo #{TMP_FILE}", :no_conn=>true).must_equal "[:a]"
254
- end
255
-
256
- it "should run code in given filenames" do
257
- File.open(TMP_FILE, 'wb'){|f| f.write('print DB.tables.inspect')}
258
- bin(:post=>TMP_FILE).must_equal '[]'
259
- DB.create_table(:a){Integer :a}
260
- bin(:post=>TMP_FILE).must_equal '[:a]'
261
- bin(:post=>TMP_FILE, :args=>'-v').strip.must_equal "sequel #{Sequel.version}\n[:a]"
262
- end
263
-
264
- it "should run code provided on stdin" do
265
- bin(:pre=>'echo print DB.tables.inspect | ').must_equal '[]'
266
- DB.create_table(:a){Integer :a}
267
- bin(:pre=>'echo print DB.tables.inspect | ').must_equal '[:a]'
268
- end
269
- end
@@ -1,1228 +0,0 @@
1
- require_relative "spec_helper"
2
- require_relative '../../lib/sequel/connection_pool/sharded_threaded'
3
-
4
- connection_pool_defaults = {:pool_timeout=>5, :max_connections=>4}
5
- st_connection_pool_defaults = connection_pool_defaults.merge(:single_threaded=>true)
6
-
7
- mock_db = lambda do |*a, &b|
8
- db = Sequel.mock
9
- db.define_singleton_method(:connect){|c| b.arity == 1 ? b.call(c) : b.call} if b
10
- if b2 = a.shift
11
- db.define_singleton_method(:disconnect_connection){|c| b2.arity == 1 ? b2.call(c) : b2.call}
12
- end
13
- # Work around JRuby Issue #3854
14
- db.singleton_class.send(:public, :connect, :disconnect_connection)
15
- db
16
- end
17
-
18
- describe "An empty ConnectionPool" do
19
- before do
20
- @cpool = Sequel::ConnectionPool.get_pool(mock_db.call, connection_pool_defaults)
21
- end
22
-
23
- it "should have no available connections" do
24
- @cpool.available_connections.must_equal []
25
- end
26
-
27
- it "should have no allocated connections" do
28
- @cpool.allocated.must_equal({})
29
- end
30
-
31
- it "should have a size of zero" do
32
- @cpool.size.must_equal 0
33
- end
34
-
35
- it "should raise Error for bad pool class" do
36
- proc{Sequel::ConnectionPool.get_pool(mock_db.call, :pool_class=>:foo)}.must_raise Sequel::Error
37
- end
38
- end
39
-
40
- describe "ConnectionPool options" do
41
- it "should support string option values" do
42
- cpool = Sequel::ConnectionPool.get_pool(mock_db.call, {:max_connections=>'5', :pool_timeout=>'3'})
43
- cpool.max_size.must_equal 5
44
- cpool.instance_variable_get(:@timeout).must_equal 3
45
- end
46
-
47
- it "should raise an error unless size is positive" do
48
- lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>0)}.must_raise(Sequel::Error)
49
- lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>-10)}.must_raise(Sequel::Error)
50
- lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'-10')}.must_raise(Sequel::Error)
51
- lambda{Sequel::ConnectionPool.get_pool(mock_db.call{1}, :max_connections=>'0')}.must_raise(Sequel::Error)
52
- end
53
- end
54
-
55
- describe "A connection pool handling connections" do
56
- before do
57
- @max_size = 2
58
- msp = proc{@max_size=3}
59
- @cpool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){:got_connection}, connection_pool_defaults.merge(:max_connections=>@max_size))
60
- end
61
-
62
- it "#hold should increment #size" do
63
- @cpool.hold do
64
- @cpool.size.must_equal 1
65
- @cpool.hold {@cpool.hold {@cpool.size.must_equal 1}}
66
- Thread.new{@cpool.hold {_(@cpool.size).must_equal 2}}.join
67
- end
68
- end
69
-
70
- it "#hold should add the connection to the #allocated array" do
71
- @cpool.hold do
72
- @cpool.allocated.size.must_equal 1
73
-
74
- @cpool.allocated.must_equal(Thread.current=>:got_connection)
75
- end
76
- end
77
-
78
- it "#hold should yield a new connection" do
79
- @cpool.hold {|conn| conn.must_equal :got_connection}
80
- end
81
-
82
- it "a connection should be de-allocated after it has been used in #hold" do
83
- @cpool.hold {}
84
- @cpool.allocated.size.must_equal 0
85
- end
86
-
87
- it "#hold should return the value of its block" do
88
- @cpool.hold {:block_return}.must_equal :block_return
89
- end
90
-
91
- it "#make_new should not make more than max_size connections" do
92
- q = Queue.new
93
- 50.times{Thread.new{@cpool.hold{q.pop}}}
94
- 50.times{q.push nil}
95
- @cpool.size.must_be :<=, @max_size
96
- end
97
-
98
- it "database's disconnect connection method should be called when a disconnect is detected" do
99
- @max_size.must_equal 2
100
- proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
101
- @max_size.must_equal 3
102
- end
103
-
104
- it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
105
- @cpool.size.must_equal 0
106
- q, q1 = Queue.new, Queue.new
107
- @cpool.hold{Thread.new{@cpool.hold{q1.pop; q.push nil}; q1.pop; q.push nil}; q1.push nil; q.pop; q1.push nil; q.pop}
108
- @cpool.size.must_equal 2
109
- proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
110
- @cpool.size.must_equal 1
111
- proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
112
- @cpool.size.must_equal 0
113
- proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
114
- @cpool.size.must_equal 0
115
- end
116
- end
117
-
118
- describe "A connection pool handling connection errors" do
119
- it "#hold should raise a Sequel::DatabaseConnectionError if an exception is raised by the connection_proc" do
120
- cpool = Sequel::ConnectionPool.get_pool(mock_db.call{raise Interrupt}, connection_pool_defaults)
121
- proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
122
- cpool.size.must_equal 0
123
- end
124
-
125
- it "#hold should raise a Sequel::DatabaseConnectionError if nil is returned by the connection_proc" do
126
- cpool = Sequel::ConnectionPool.get_pool(mock_db.call{nil}, connection_pool_defaults)
127
- proc{cpool.hold{:block_return}}.must_raise(Sequel::DatabaseConnectionError)
128
- cpool.size.must_equal 0
129
- end
130
- end
131
-
132
- describe "ConnectionPool#hold" do
133
- before do
134
- value = 0
135
- c = @c = Class.new do
136
- define_method(:initialize){value += 1}
137
- define_method(:value){value}
138
- end
139
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{c.new}, connection_pool_defaults)
140
- end
141
-
142
- it "shoulda use the database's connect method to get new connections" do
143
- res = nil
144
- @pool.hold {|c| res = c}
145
- res.must_be_kind_of(@c)
146
- res.value.must_equal 1
147
- @pool.hold {|c| res = c}
148
- res.must_be_kind_of(@c)
149
- res.value.must_equal 1 # the connection maker is invoked only once
150
- end
151
-
152
- it "should be re-entrant by the same thread" do
153
- cc = nil
154
- @pool.hold {|c| @pool.hold {|c1| @pool.hold {|c2| cc = c2}}}
155
- cc.must_be_kind_of(@c)
156
- end
157
-
158
- it "should catch exceptions and reraise them" do
159
- proc {@pool.hold {|c| c.foobar}}.must_raise(NoMethodError)
160
- end
161
- end
162
-
163
- describe "A connection pool with a max size of 1" do
164
- before do
165
- @invoked_count = 0
166
- icp = proc{@invoked_count += 1}
167
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{icp.call; 'herro'.dup}, connection_pool_defaults.merge(:max_connections=>1))
168
- end
169
-
170
- it "should let only one thread access the connection at any time" do
171
- cc,c1, c2 = nil
172
- q, q1 = Queue.new, Queue.new
173
-
174
- t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; q1.push nil; q.pop}}
175
- q1.pop
176
- cc.must_equal 'herro'
177
- c1.must_equal 'herro'
178
-
179
- t2 = Thread.new {@pool.hold {|c| c2 = c.dup; q1.push nil; q.pop;}}
180
-
181
- # connection held by t1
182
- t1.must_be :alive?
183
- t2.must_be :alive?
184
-
185
- cc.must_equal 'herro'
186
- c1.must_equal 'herro'
187
- c2.must_be_nil
188
-
189
- @pool.available_connections.must_be :empty?
190
- @pool.allocated.must_equal(t1=>cc)
191
-
192
- cc.gsub!('rr', 'll')
193
- q.push nil
194
- q1.pop
195
-
196
- t1.join
197
- t2.must_be :alive?
198
-
199
- c2.must_equal 'hello'
200
-
201
- @pool.available_connections.must_be :empty?
202
- @pool.allocated.must_equal(t2=>cc)
203
-
204
- #connection released
205
- q.push nil
206
- t2.join
207
-
208
- @invoked_count.must_equal 1
209
- @pool.size.must_equal 1
210
- @pool.available_connections.must_equal [cc]
211
- @pool.allocated.must_be :empty?
212
- end
213
-
214
- it "should let the same thread reenter #hold" do
215
- c1, c2, c3 = nil
216
- @pool.hold do |c|
217
- c1 = c
218
- @pool.hold do |cc2|
219
- c2 = cc2
220
- @pool.hold do |cc3|
221
- c3 = cc3
222
- end
223
- end
224
- end
225
- c1.must_equal 'herro'
226
- c2.must_equal 'herro'
227
- c3.must_equal 'herro'
228
-
229
- @invoked_count.must_equal 1
230
- @pool.size.must_equal 1
231
- @pool.available_connections.size.must_equal 1
232
- @pool.allocated.must_be :empty?
233
- end
234
- end
235
-
236
- ThreadedConnectionPoolSpecs = shared_description do
237
- it "should not have all_connections yield connections allocated to other threads" do
238
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
239
- q, q1 = Queue.new, Queue.new
240
- t = Thread.new do
241
- pool.hold do |c1|
242
- q1.push nil
243
- q.pop
244
- end
245
- end
246
- pool.hold do |c1|
247
- q1.pop
248
- pool.all_connections{|c| c.must_equal c1}
249
- q.push nil
250
- end
251
- t.join
252
- end
253
-
254
- it "should work when acquire fails and then succeeds" do
255
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
256
- def pool._acquire(*)
257
- if @called
258
- super
259
- else
260
- @called = true
261
- nil
262
- end
263
- end
264
- c = nil
265
- pool.hold do |c1|
266
- c = c1
267
- end
268
- c.wont_be_nil
269
- end
270
-
271
- it "should wait until a connection is available if all are checked out" do
272
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0.1))
273
- q, q1 = Queue.new, Queue.new
274
- t = Thread.new do
275
- pool.hold do |c|
276
- q1.push nil
277
- 3.times{Thread.pass}
278
- q.pop
279
- end
280
- end
281
- q1.pop
282
- proc{pool.hold{}}.must_raise(Sequel::PoolTimeout)
283
- q.push nil
284
- t.join
285
- end
286
-
287
- it "should not have all_connections yield all available connections" do
288
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>2, :pool_timeout=>0))
289
- q, q1 = Queue.new, Queue.new
290
- b = []
291
- t = Thread.new do
292
- pool.hold do |c1|
293
- @m.synchronize{b << c1}
294
- q1.push nil
295
- q.pop
296
- end
297
- end
298
- pool.hold do |c1|
299
- q1.pop
300
- @m.synchronize{b << c1}
301
- q.push nil
302
- end
303
- t.join
304
- a = []
305
- pool.all_connections{|c| a << c}
306
- a.sort.must_equal b.sort
307
- end
308
-
309
- it "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
310
- q, q1 = Queue.new, Queue.new
311
- db = mock_db.call(&@icpp)
312
- db.opts[:name] = 'testing'
313
- pool = Sequel::ConnectionPool.get_pool(db, @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
314
- t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
315
- q1.pop
316
- e = proc{pool.hold{|c|}}.must_raise(Sequel::PoolTimeout)
317
- e.message.must_include "name: testing"
318
- e.message.must_include "server: default" if pool.is_a?(Sequel::ShardedThreadedConnectionPool)
319
- q.push nil
320
- t.join
321
- end
322
-
323
- it "should not add a disconnected connection back to the pool if the disconnection_proc raises an error" do
324
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| raise Sequel::Error}, &@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
325
- proc{pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::Error)
326
- pool.available_connections.length.must_equal 0
327
- end
328
-
329
- it "should let five threads simultaneously access separate connections" do
330
- cc = {}
331
- threads = []
332
- q, q1, q2 = Queue.new, Queue.new, Queue.new
333
-
334
- 5.times{|i| threads << Thread.new{@pool.hold{|c| q.pop; @m.synchronize{cc[i] = c}; q1.push nil; q2.pop}}; q.push nil; q1.pop}
335
- threads.each {|t| t.must_be :alive?}
336
- cc.size.must_equal 5
337
- @invoked_count.must_equal 5
338
- @pool.size.must_equal 5
339
- @pool.available_connections.must_be :empty?
340
-
341
- h = {}
342
- i = 0
343
- threads.each{|t| h[t] = (i+=1)}
344
- @pool.allocated.must_equal h
345
- @pool.available_connections.must_equal []
346
- 5.times{q2.push nil}
347
- threads.each{|t| t.join}
348
-
349
- @pool.available_connections.size.must_equal 5
350
- @pool.allocated.must_be :empty?
351
- end
352
-
353
- it "should allow simultaneous connections without preconnecting" do
354
- @pool.disconnect
355
- b = @icpp
356
-
357
- time = Time.now
358
- cc = {}
359
- threads = []
360
- results = []
361
- j = 0
362
- q, q1, q2, q3, q4 = Queue.new, Queue.new, Queue.new, Queue.new, Queue.new
363
- m = @m
364
- @pool.db.define_singleton_method(:connect) do |server|
365
- q1.pop
366
- m.synchronize{q3.push(j += 1)}
367
- q4.pop
368
- b.call
369
- end
370
- 5.times{|i| threads << Thread.new{@pool.hold{|c| m.synchronize{i -= 1; cc[i] = c}; q2.pop; q.push nil}}}
371
- 5.times{|i| q1.push nil}
372
- 5.times{|i| results << q3.pop}
373
- 5.times{|i| q4.push nil}
374
- 5.times{|i| q2.push nil}
375
- 5.times{|i| q.pop}
376
- results.sort.must_equal (1..5).to_a
377
- threads.each(&:join)
378
- (Time.now - time).must_be :<, 0.75
379
-
380
- threads.each{|t| t.wont_be :alive?}
381
- cc.size.must_equal 5
382
- @invoked_count.must_equal 5
383
- @pool.size.must_equal 5
384
- @pool.available_connections.sort.must_equal (1..5).to_a
385
- end
386
-
387
- it "should block threads until a connection becomes available" do
388
- cc = {}
389
- threads = []
390
- q, q1 = Queue.new, Queue.new
391
-
392
- 5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop}}}
393
- 5.times{q1.pop}
394
- threads.each {|t| t.must_be :alive?}
395
- @pool.available_connections.must_be :empty?
396
-
397
- 3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil}}}
398
-
399
- threads[5].must_be :alive?
400
- threads[6].must_be :alive?
401
- threads[7].must_be :alive?
402
- cc.size.must_equal 5
403
- cc[5].must_be_nil
404
- cc[6].must_be_nil
405
- cc[7].must_be_nil
406
-
407
- 5.times{q.push nil}
408
- 5.times{|i| threads[i].join}
409
- 3.times{q1.pop}
410
- 3.times{|i| threads[i+5].join}
411
-
412
- threads.each {|t| t.wont_be :alive?}
413
- cc.values.uniq.length.must_equal 5
414
-
415
- @pool.size.must_equal 5
416
- @invoked_count.must_equal 5
417
- @pool.available_connections.size.must_equal 5
418
- @pool.allocated.must_be :empty?
419
- end
420
-
421
- it "should block threads until a connection becomes available, when assign connection returns nil" do
422
- # Shorten pool timeout, as making assign_connection return nil when there are
423
- # connections in the pool can make the pool later block until the timeout expires,
424
- # since then the pool will not be signalled correctly.
425
- # This spec is only added for coverage purposes, to ensure that fallback code is tested.
426
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:pool_timeout=>0.25))
427
-
428
- cc = {}
429
- threads = []
430
- q, q1 = Queue.new, Queue.new
431
-
432
- 5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop}}}
433
- 5.times{q1.pop}
434
- threads.each {|t| t.must_be :alive?}
435
- @pool.available_connections.must_be :empty?
436
-
437
- def @pool.assign_connection(*) nil end
438
- 3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil}}}
439
-
440
- threads[5].must_be :alive?
441
- threads[6].must_be :alive?
442
- threads[7].must_be :alive?
443
- cc.size.must_equal 5
444
- cc[5].must_be_nil
445
- cc[6].must_be_nil
446
- cc[7].must_be_nil
447
-
448
- 5.times{q.push nil}
449
- 5.times{|i| threads[i].join}
450
- 3.times{q1.pop}
451
- 3.times{|i| threads[i+5].join}
452
-
453
- threads.each {|t| t.wont_be :alive?}
454
- cc.values.uniq.length.must_equal 5
455
-
456
- @pool.size.must_equal 5
457
- @invoked_count.must_equal 5
458
- @pool.available_connections.size.must_equal 5
459
- @pool.allocated.must_be :empty?
460
- end
461
-
462
- it "should block threads until a connection becomes available, and reconnect on disconnection" do
463
- cc = {}
464
- threads = []
465
- exceptions = []
466
- q, q1, q2, q3 = Queue.new, Queue.new, Queue.new, Queue.new
467
- b = @icpp
468
- @pool.db.define_singleton_method(:connect) do |server|
469
- b.call
470
- Object.new
471
- end
472
- 5.times{|i| threads << Thread.new{@pool.hold{|c| @m.synchronize{cc[i] = c}; q1.push nil; q.pop; raise Sequel::DatabaseDisconnectError} rescue q2.push($!)}}
473
- 5.times{q1.pop}
474
- threads.each {|t| t.must_be :alive?}
475
- @pool.available_connections.must_be :empty?
476
-
477
- 3.times {|i| threads << Thread.new {@pool.hold {|c| @m.synchronize{cc[i + 5] = c}; q1.push nil; q3.pop}}}
478
-
479
- threads[5].must_be :alive?
480
- threads[6].must_be :alive?
481
- threads[7].must_be :alive?
482
- cc.size.must_equal 5
483
- cc[5].must_be_nil
484
- cc[6].must_be_nil
485
- cc[7].must_be_nil
486
-
487
- 5.times{q.push nil}
488
- 5.times{|i| threads[i].join}
489
- 5.times{exceptions << q2.pop}
490
- 3.times{q1.pop}
491
- 3.times{q3.push nil}
492
- 3.times{|i| threads[i+5].join}
493
-
494
- threads.each {|t| t.wont_be :alive?}
495
- exceptions.length.must_equal 5
496
- cc.values.uniq.length.must_equal 8
497
-
498
- @pool.size.must_equal 3
499
- @invoked_count.must_equal 8
500
- @pool.available_connections.size.must_equal 3
501
- @pool.allocated.must_be :empty?
502
- end
503
-
504
- it "should store connections in a stack if :connection_handling=>:stack" do
505
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:stack))
506
- c2 = nil
507
- c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
508
- @pool.size.must_equal 2
509
- @pool.hold{|cc| cc.must_equal c}
510
- @pool.hold{|cc| cc.must_equal c}
511
- @pool.hold do |cc|
512
- cc.must_equal c
513
- Thread.new{@pool.hold{|cc2| _(cc2).must_equal c2}}.join
514
- end
515
- end
516
-
517
- it "should store connections in a queue if :connection_handling=>:queue" do
518
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:queue))
519
- c2 = nil
520
- c = @pool.hold{|cc| Thread.new{@pool.hold{|cc2| c2 = cc2}}.join; cc}
521
- @pool.size.must_equal 2
522
- @pool.hold{|cc| cc.must_equal c2}
523
- @pool.hold{|cc| cc.must_equal c}
524
- @pool.hold do |cc|
525
- cc.must_equal c2
526
- Thread.new{@pool.hold{|cc2| _(cc2).must_equal c}}.join
527
- end
528
- end
529
-
530
- it "should not store connections if :connection_handling=>:disconnect" do
531
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:disconnect))
532
- d = []
533
- m = @m
534
- @pool.db.define_singleton_method(:disconnect_connection){|c| m.synchronize{d << c}}
535
- @pool.hold do |cc|
536
- cc.must_equal 1
537
- Thread.new{@pool.hold{|cc2| _(cc2).must_equal 2}}.join
538
- d.must_equal [2]
539
- @pool.hold{|cc3| cc3.must_equal 1}
540
- end
541
- @pool.size.must_equal 0
542
- d.must_equal [2, 1]
543
-
544
- @pool.hold{|cc| cc.must_equal 3}
545
- @pool.size.must_equal 0
546
- d.must_equal [2, 1, 3]
547
-
548
- @pool.hold{|cc| cc.must_equal 4}
549
- @pool.size.must_equal 0
550
- d.must_equal [2, 1, 3, 4]
551
- end
552
- end
553
-
554
- describe "Threaded Unsharded Connection Pool" do
555
- before do
556
- @m = Mutex.new
557
- @invoked_count = 0
558
- @icpp = proc{@m.synchronize{@invoked_count += 1}}
559
- @cp_opts = connection_pool_defaults.merge(:max_connections=>5)
560
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
561
- end
562
-
563
- include ThreadedConnectionPoolSpecs
564
- end
565
-
566
- describe "Threaded Sharded Connection Pool" do
567
- before do
568
- @m = Mutex.new
569
- @invoked_count = 0
570
- @icpp = proc{@m.synchronize{@invoked_count += 1}}
571
- @cp_opts = connection_pool_defaults.merge(:max_connections=>5, :servers=>{})
572
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts)
573
- end
574
-
575
- include ThreadedConnectionPoolSpecs
576
- end
577
-
578
- describe "ConnectionPool#disconnect" do
579
- before do
580
- @count = 0
581
- cp = proc{@count += 1}
582
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{{:id => cp.call}}, connection_pool_defaults.merge(:max_connections=>5, :servers=>{}))
583
- threads = []
584
- q, q1 = Queue.new, Queue.new
585
- 5.times {|i| threads << Thread.new {@pool.hold {|c| q1.push nil; q.pop}}}
586
- 5.times{q1.pop}
587
- 5.times{q.push nil}
588
- threads.each {|t| t.join}
589
- end
590
-
591
- it "should invoke the given block for each available connection" do
592
- @pool.size.must_equal 5
593
- @pool.available_connections.size.must_equal 5
594
- @pool.available_connections.each {|c| c[:id].wont_equal nil}
595
- conns = []
596
- @pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
597
- @pool.disconnect
598
- conns.size.must_equal 5
599
- end
600
-
601
- it "should remove all available connections" do
602
- @pool.size.must_equal 5
603
- @pool.disconnect
604
- @pool.size.must_equal 0
605
- end
606
-
607
- it "should disconnect connections in use as soon as they are no longer in use" do
608
- @pool.size.must_equal 5
609
- @pool.hold do |conn|
610
- @pool.available_connections.size.must_equal 4
611
- @pool.available_connections.each {|c| c.wont_be_same_as(conn)}
612
- conns = []
613
- @pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
614
- @pool.disconnect
615
- conns.size.must_equal 4
616
- @pool.size.must_equal 1
617
- end
618
- @pool.size.must_equal 0
619
- end
620
- end
621
-
622
- describe "A connection pool with multiple servers" do
623
- before do
624
- ic = @invoked_counts = Hash.new(0)
625
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, connection_pool_defaults.merge(:servers=>{:read_only=>{}}))
626
- end
627
-
628
- it "should support preconnect method that immediately creates the maximum number of connections" do
629
- @pool.send(:preconnect)
630
- i = 0
631
- @pool.all_connections{|c1| i+=1}
632
- i.must_equal(@pool.max_size * 2)
633
- end
634
-
635
- it "should support preconnect method that immediately creates the maximum number of connections concurrently" do
636
- @pool.send(:preconnect, true)
637
- i = 0
638
- @pool.all_connections{|c1| i+=1}
639
- i.must_equal(@pool.max_size * 2)
640
- end
641
-
642
- it "#all_connections should return connections for all servers" do
643
- @pool.hold{}
644
- @pool.all_connections{|c1| c1.must_equal "default1"}
645
- a = []
646
- @pool.hold(:read_only) do |c|
647
- @pool.all_connections{|c1| a << c1}
648
- end
649
- a.sort_by{|c| c.to_s}.must_equal ["default1", "read_only1"]
650
- end
651
-
652
- it "#servers should return symbols for all servers" do
653
- @pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
654
- end
655
-
656
- it "should use the :default server by default" do
657
- @pool.size.must_equal 0
658
- @pool.hold do |c|
659
- c.must_equal "default1"
660
- @pool.allocated.must_equal(Thread.current=>"default1")
661
- end
662
- @pool.available_connections.must_equal ["default1"]
663
- @pool.size.must_equal 1
664
- @invoked_counts.must_equal(:default=>1)
665
- end
666
-
667
- it "should use the :default server an invalid server is used" do
668
- @pool.hold do |c1|
669
- c1.must_equal "default1"
670
- @pool.hold(:blah) do |c2|
671
- c2.must_equal c1
672
- @pool.hold(:blah2) do |c3|
673
- c2.must_equal c3
674
- end
675
- end
676
- end
677
- end
678
-
679
- it "should support a :servers_hash option used for converting the server argument" do
680
- ic = @invoked_counts
681
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, connection_pool_defaults.merge(:servers_hash=>Hash.new(:read_only), :servers=>{:read_only=>{}}))
682
- @pool.hold(:blah) do |c1|
683
- c1.must_equal "read_only1"
684
- @pool.hold(:blah) do |c2|
685
- c2.must_equal c1
686
- @pool.hold(:blah2) do |c3|
687
- c2.must_equal c3
688
- end
689
- end
690
- end
691
-
692
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{|server| "#{server}#{ic[server] += 1}"}, connection_pool_defaults.merge(:servers_hash=>Hash.new{|h,k| raise Sequel::Error}, :servers=>{:read_only=>{}}))
693
- proc{@pool.hold(:blah){|c1|}}.must_raise(Sequel::Error)
694
- end
695
-
696
- it "should use the requested server if server is given" do
697
- @pool.size(:read_only).must_equal 0
698
- @pool.hold(:read_only) do |c|
699
- c.must_equal "read_only1"
700
- @pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
701
- end
702
- @pool.available_connections(:read_only).must_equal ["read_only1"]
703
- @pool.size(:read_only).must_equal 1
704
- @invoked_counts.must_equal(:read_only=>1)
705
- end
706
-
707
- it "#hold should only yield connections for the server requested" do
708
- @pool.hold(:read_only) do |c|
709
- c.must_equal "read_only1"
710
- @pool.allocated(:read_only).must_equal(Thread.current=>"read_only1")
711
- @pool.hold do |d|
712
- d.must_equal "default1"
713
- @pool.hold do |e|
714
- e.must_equal d
715
- @pool.hold(:read_only){|b| b.must_equal c}
716
- end
717
- @pool.allocated.must_equal(Thread.current=>"default1")
718
- end
719
- end
720
- @invoked_counts.must_equal(:read_only=>1, :default=>1)
721
- end
722
-
723
- it "#disconnect should disconnect from all servers" do
724
- @pool.hold(:read_only){}
725
- @pool.hold{}
726
- conns = []
727
- @pool.size.must_equal 1
728
- @pool.size(:read_only).must_equal 1
729
- @pool.db.define_singleton_method(:disconnect_connection){|c| conns << c}
730
- @pool.disconnect
731
- conns.sort.must_equal %w'default1 read_only1'
732
- @pool.size.must_equal 0
733
- @pool.size(:read_only).must_equal 0
734
- @pool.hold(:read_only){|c| c.must_equal 'read_only2'}
735
- @pool.hold{|c| c.must_equal 'default2'}
736
- end
737
-
738
- it "#add_servers should add new servers to the pool" do
739
- pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
740
-
741
- pool.hold{}
742
- pool.hold(:server2){}
743
- pool.hold(:server3){}
744
- pool.hold(:server1) do
745
- pool.allocated.length.must_equal 0
746
- pool.allocated(:server1).length.must_equal 1
747
- pool.allocated(:server2).must_be_nil
748
- pool.allocated(:server3).must_be_nil
749
- pool.available_connections.length.must_equal 1
750
- pool.available_connections(:server1).length.must_equal 0
751
- pool.available_connections(:server2).must_be_nil
752
- pool.available_connections(:server3).must_be_nil
753
-
754
- pool.add_servers([:server2, :server3])
755
- pool.hold(:server2){}
756
- pool.hold(:server3) do
757
- pool.allocated.length.must_equal 0
758
- pool.allocated(:server1).length.must_equal 1
759
- pool.allocated(:server2).length.must_equal 0
760
- pool.allocated(:server3).length.must_equal 1
761
- pool.available_connections.length.must_equal 1
762
- pool.available_connections(:server1).length.must_equal 0
763
- pool.available_connections(:server2).length.must_equal 1
764
- pool.available_connections(:server3).length.must_equal 0
765
- end
766
- end
767
- end
768
-
769
- it "#add_servers should ignore existing keys" do
770
- pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
771
-
772
- pool.allocated.length.must_equal 0
773
- pool.allocated(:server1).length.must_equal 0
774
- pool.available_connections.length.must_equal 0
775
- pool.available_connections(:server1).length.must_equal 0
776
- pool.hold do |c1|
777
- c1.must_equal :default
778
- pool.allocated.length.must_equal 1
779
- pool.allocated(:server1).length.must_equal 0
780
- pool.available_connections.length.must_equal 0
781
- pool.available_connections(:server1).length.must_equal 0
782
- pool.hold(:server1) do |c2|
783
- c2.must_equal :server1
784
- pool.allocated.length.must_equal 1
785
- pool.allocated(:server1).length.must_equal 1
786
- pool.available_connections.length.must_equal 0
787
- pool.available_connections(:server1).length.must_equal 0
788
- pool.add_servers([:default, :server1])
789
- pool.allocated.length.must_equal 1
790
- pool.allocated(:server1).length.must_equal 1
791
- pool.available_connections.length.must_equal 0
792
- pool.available_connections(:server1).length.must_equal 0
793
- end
794
- pool.allocated.length.must_equal 1
795
- pool.allocated(:server1).length.must_equal 0
796
- pool.available_connections.length.must_equal 0
797
- pool.available_connections(:server1).length.must_equal 1
798
- pool.add_servers([:default, :server1])
799
- pool.allocated.length.must_equal 1
800
- pool.allocated(:server1).length.must_equal 0
801
- pool.available_connections.length.must_equal 0
802
- pool.available_connections(:server1).length.must_equal 1
803
- end
804
- pool.allocated.length.must_equal 0
805
- pool.allocated(:server1).length.must_equal 0
806
- pool.available_connections.length.must_equal 1
807
- pool.available_connections(:server1).length.must_equal 1
808
- pool.add_servers([:default, :server1])
809
- pool.allocated.length.must_equal 0
810
- pool.allocated(:server1).length.must_equal 0
811
- pool.available_connections.length.must_equal 1
812
- pool.available_connections(:server1).length.must_equal 1
813
- end
814
-
815
- it "#remove_servers should disconnect available connections immediately" do
816
- pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :max_connections=>5, :servers=>{:server1=>{}})
817
- threads = []
818
- q, q1 = Queue.new, Queue.new
819
- 5.times {|i| threads << Thread.new {pool.hold(:server1){|c| q1.push nil; q.pop}}}
820
- 5.times{q1.pop}
821
- 5.times{q.push nil}
822
- threads.each {|t| t.join}
823
-
824
- pool.size(:server1).must_equal 5
825
- pool.remove_servers([:server1])
826
- pool.size(:server1).must_equal 0
827
- end
828
-
829
- it "#remove_servers should disconnect connections in use as soon as they are returned to the pool" do
830
- dc = []
831
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
832
- c1 = nil
833
- pool.hold(:server1) do |c|
834
- pool.size(:server1).must_equal 1
835
- dc.must_equal []
836
- pool.remove_servers([:server1])
837
- pool.size(:server1).must_equal 0
838
- dc.must_equal []
839
- c1 = c
840
- end
841
- pool.size(:server1).must_equal 0
842
- dc.must_equal [c1]
843
- end
844
-
845
- it "#remove_servers should remove server related data structures immediately" do
846
- pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
847
- pool.available_connections(:server1).must_equal []
848
- pool.allocated(:server1).must_equal({})
849
- pool.remove_servers([:server1])
850
- pool.available_connections(:server1).must_be_nil
851
- pool.allocated(:server1).must_be_nil
852
- end
853
-
854
- it "#remove_servers should not allow the removal of the default server" do
855
- pool = Sequel::ConnectionPool.get_pool(mock_db.call{|s| s}, :servers=>{:server1=>{}})
856
- pool.remove_servers([:server1])
857
- proc{pool.remove_servers([:default])}.must_raise(Sequel::Error)
858
- end
859
-
860
- it "#remove_servers should ignore servers that have already been removed" do
861
- dc = []
862
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| dc << c}){|c| c}, :servers=>{:server1=>{}})
863
- c1 = nil
864
- pool.hold(:server1) do |c|
865
- pool.size(:server1).must_equal 1
866
- dc.must_equal []
867
- pool.remove_servers([:server1])
868
- pool.remove_servers([:server1])
869
- pool.size(:server1).must_equal 0
870
- dc.must_equal []
871
- c1 = c
872
- end
873
- pool.size(:server1).must_equal 0
874
- dc.must_equal [c1]
875
- end
876
- end
877
-
878
- describe "SingleConnectionPool" do
879
- before do
880
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call{1234}, st_connection_pool_defaults)
881
- end
882
-
883
- it "should provide a #hold method" do
884
- conn = nil
885
- @pool.hold{|c| conn = c}
886
- conn.must_equal 1234
887
- end
888
-
889
- it "should provide a #disconnect method" do
890
- conn = nil
891
- x = nil
892
- pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| conn = c; c.must_be_kind_of(Integer)}){1234}, st_connection_pool_defaults)
893
- pool.hold{|c| x = c}
894
- x.must_equal 1234
895
- pool.disconnect
896
- conn.must_equal 1234
897
- pool.disconnect
898
- end
899
- end
900
-
901
- describe "A single threaded pool with multiple servers" do
902
- before do
903
- @max_size=2
904
- msp = proc{@max_size += 1}
905
- @pool = Sequel::ConnectionPool.get_pool(mock_db.call(proc{|c| msp.call}){|c| c}, st_connection_pool_defaults.merge(:servers=>{:read_only=>{}}))
906
- end
907
-
908
- it "should support preconnect method that immediately creates the maximum number of connections" do
909
- @pool.send(:preconnect)
910
- i = 0
911
- @pool.all_connections{|c1| i+=1}
912
- i.must_equal 2
913
- end
914
-
915
- it "should support preconnect method that immediately creates the maximum number of connections, ignoring concurrent param" do
916
- @pool.send(:preconnect, true)
917
- i = 0
918
- @pool.all_connections{|c1| i+=1}
919
- i.must_equal 2
920
- end
921
-
922
- it "#all_connections should return connections for all servers" do
923
- @pool.hold{}
924
- @pool.all_connections{|c1| c1.must_equal :default}
925
- a = []
926
- @pool.hold(:read_only) do
927
- @pool.all_connections{|c1| a << c1}
928
- end
929
- a.sort_by{|c| c.to_s}.must_equal [:default, :read_only]
930
- end
931
-
932
- it "#servers should return symbols for all servers" do
933
- @pool.servers.sort_by{|s| s.to_s}.must_equal [:default, :read_only]
934
- end
935
-
936
- it "#add_servers should add new servers to the pool" do
937
- @pool.hold(:blah){|c| c.must_equal :default}
938
- @pool.add_servers([:blah])
939
- @pool.hold(:blah){|c| c.must_equal :blah}
940
- end
941
-
942
- it "#add_servers should ignore keys already existing" do
943
- @pool.hold{|c| c.must_equal :default}
944
- @pool.hold(:read_only){|c| c.must_equal :read_only}
945
- @pool.add_servers([:default, :read_only])
946
- @pool.conn.must_equal :default
947
- @pool.conn(:read_only).must_equal :read_only
948
- end
949
-
950
- it "#remove_servers should remove servers from the pool" do
951
- @pool.hold(:read_only){|c| c.must_equal :read_only}
952
- @pool.remove_servers([:read_only])
953
- @pool.hold(:read_only){|c| c.must_equal :default}
954
- end
955
-
956
- it "#remove_servers should not allow the removal of the default server" do
957
- proc{@pool.remove_servers([:default])}.must_raise(Sequel::Error)
958
- end
959
-
960
- it "#remove_servers should disconnect connection immediately" do
961
- @pool.hold(:read_only){|c| c.must_equal :read_only}
962
- @pool.conn(:read_only).must_equal :read_only
963
- @pool.remove_servers([:read_only])
964
- @pool.conn(:read_only).must_be_nil
965
- @pool.hold{}
966
- @pool.conn(:read_only).must_equal :default
967
- end
968
-
969
- it "#remove_servers should ignore keys that do not exist" do
970
- @pool.remove_servers([:blah])
971
- end
972
-
973
- it "should use the :default server by default" do
974
- @pool.hold{|c| c.must_equal :default}
975
- @pool.conn.must_equal :default
976
- end
977
-
978
- it "should use the :default server an invalid server is used" do
979
- @pool.hold do |c1|
980
- c1.must_equal :default
981
- @pool.hold(:blah) do |c2|
982
- c2.must_equal c1
983
- @pool.hold(:blah2) do |c3|
984
- c2.must_equal c3
985
- end
986
- end
987
- end
988
- end
989
-
990
- it "should use the requested server if server is given" do
991
- @pool.hold(:read_only){|c| c.must_equal :read_only}
992
- @pool.conn(:read_only).must_equal :read_only
993
- end
994
-
995
- it "#hold should only yield connections for the server requested" do
996
- @pool.hold(:read_only) do |c|
997
- c.must_equal :read_only
998
- @pool.hold do |d|
999
- d.must_equal :default
1000
- @pool.hold do |e|
1001
- e.must_equal d
1002
- @pool.hold(:read_only){|b| b.must_equal c}
1003
- end
1004
- end
1005
- end
1006
- @pool.conn.must_equal :default
1007
- @pool.conn(:read_only).must_equal :read_only
1008
- end
1009
-
1010
- it "#disconnect should disconnect from all servers" do
1011
- @pool.hold(:read_only){}
1012
- @pool.hold{}
1013
- @pool.conn.must_equal :default
1014
- @pool.conn(:read_only).must_equal :read_only
1015
- @pool.disconnect
1016
- @max_size.must_equal 4
1017
- @pool.conn.must_be_nil
1018
- @pool.conn(:read_only).must_be_nil
1019
- end
1020
-
1021
- it ":disconnection_proc option should set the disconnection proc to use" do
1022
- @max_size.must_equal 2
1023
- proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
1024
- @max_size.must_equal 3
1025
- end
1026
-
1027
- it "#hold should remove the connection if a DatabaseDisconnectError is raised" do
1028
- @pool.instance_variable_get(:@conns).length.must_equal 0
1029
- @pool.hold{}
1030
- @pool.instance_variable_get(:@conns).length.must_equal 1
1031
- proc{@pool.hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
1032
- @pool.instance_variable_get(:@conns).length.must_equal 0
1033
- end
1034
- end
1035
-
1036
- AllConnectionPoolClassesSpecs = shared_description do
1037
- it "should work correctly after being frozen" do
1038
- o = Object.new
1039
- db = mock_db.call{o}
1040
- cp = @class.new(db, {})
1041
- db.instance_variable_set(:@pool, cp)
1042
- db.freeze
1043
- cp.frozen?.must_equal true
1044
- db.synchronize{|c| c.must_be_same_as o}
1045
- end
1046
-
1047
- it "should have pool correctly handle disconnect errors not raised as DatabaseDisconnectError" do
1048
- db = mock_db.call{Object.new}
1049
- def db.dec; @dec ||= Class.new(StandardError) end
1050
- def db.database_error_classes; super + [dec] end
1051
- def db.disconnect_error?(e, opts); e.message =~ /foo/ end
1052
- cp = @class.new(db, {})
1053
-
1054
- conn = nil
1055
- cp.hold do |c|
1056
- conn = c
1057
- end
1058
-
1059
- proc do
1060
- cp.hold do |c|
1061
- c.must_equal conn
1062
- raise db.dec, "bar"
1063
- end
1064
- end.must_raise db.dec
1065
-
1066
- proc do
1067
- cp.hold do |c|
1068
- c.must_equal conn
1069
- raise StandardError
1070
- end
1071
- end.must_raise StandardError
1072
-
1073
- cp.hold do |c|
1074
- c.must_equal conn
1075
- end
1076
-
1077
- proc do
1078
- cp.hold do |c|
1079
- c.must_equal conn
1080
- raise db.dec, "foo"
1081
- end
1082
- end.must_raise db.dec
1083
-
1084
- cp.hold do |c|
1085
- c.wont_equal conn
1086
- end
1087
- end
1088
-
1089
- it "should have pool_type return a symbol" do
1090
- @class.new(mock_db.call{123}, {}).pool_type.must_be_kind_of(Symbol)
1091
- end
1092
-
1093
- it "should have all_connections yield current and available connections" do
1094
- p = @class.new(mock_db.call{123}, {})
1095
- p.hold{|c| p.all_connections{|c1| c.must_equal c1}}
1096
- end
1097
-
1098
- it "should have a size method that gives the current size of the pool" do
1099
- p = @class.new(mock_db.call{123}, {})
1100
- p.size.must_equal 0
1101
- p.hold{}
1102
- p.size.must_equal 1
1103
- end
1104
-
1105
- it "should have a max_size method that gives the maximum size of the pool" do
1106
- @class.new(mock_db.call{123}, {}).max_size.must_be :>=, 1
1107
- end
1108
-
1109
- it "should support preconnect method that immediately creates the maximum number of connections" do
1110
- p = @class.new(mock_db.call{123}, {})
1111
- p.send(:preconnect)
1112
- i = 0
1113
- p.all_connections{|c1| i+=1}
1114
- i.must_equal p.max_size
1115
- end
1116
-
1117
- it "should support preconnect method that immediately creates the maximum number of connections concurrently" do
1118
- p = @class.new(mock_db.call{123}, {})
1119
- p.send(:preconnect, true)
1120
- i = 0
1121
- p.all_connections{|c1| i+=1}
1122
- i.must_equal p.max_size
1123
- end
1124
-
1125
- it "should be able to modify after_connect proc after the pool is created" do
1126
- a = []
1127
- p = @class.new(mock_db.call{123}, {})
1128
- p.after_connect = pr = proc{|c| a << c}
1129
- p.after_connect.must_equal pr
1130
- a.must_equal []
1131
- p.hold{}
1132
- a.must_equal [123]
1133
- end
1134
-
1135
- it "should not raise an error when disconnecting twice" do
1136
- c = @class.new(mock_db.call{123}, {})
1137
- c.disconnect
1138
- c.disconnect
1139
- end
1140
-
1141
- it "should yield a connection created by the initialize block to hold" do
1142
- x = nil
1143
- @class.new(mock_db.call{123}, {}).hold{|c| x = c}
1144
- x.must_equal 123
1145
- end
1146
-
1147
- it "should have the initialize block accept a shard/server argument" do
1148
- x = nil
1149
- @class.new(mock_db.call{|c| [c, c]}, {}).hold{|c| x = c}
1150
- x.must_equal [:default, :default]
1151
- end
1152
-
1153
- it "should have respect an :after_connect proc that is called with each newly created connection" do
1154
- x = nil
1155
- @class.new(mock_db.call{123}, :after_connect=>proc{|c| x = [c, c]}).hold{}
1156
- x.must_equal [123, 123]
1157
- @class.new(mock_db.call{123}, :after_connect=>lambda{|c| x = [c, c]}).hold{}
1158
- x.must_equal [123, 123]
1159
- @class.new(mock_db.call{123}, :after_connect=>proc{|c, s| x = [c, s]}).hold{}
1160
- x.must_equal [123, :default]
1161
- @class.new(mock_db.call{123}, :after_connect=>lambda{|c, s| x = [c, s]}).hold{}
1162
- x.must_equal [123, :default]
1163
- end
1164
-
1165
- it "should raise a DatabaseConnectionError if the connection raises an exception" do
1166
- proc{@class.new(mock_db.call{|c| raise Exception}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
1167
- end
1168
-
1169
- it "should raise a DatabaseConnectionError if the initialize block returns nil" do
1170
- proc{@class.new(mock_db.call{}, {}).hold{}}.must_raise(Sequel::DatabaseConnectionError)
1171
- end
1172
-
1173
- it "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
1174
- x = nil
1175
- proc{@class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.must_raise(Sequel::DatabaseDisconnectError)
1176
- x.must_equal 123
1177
- end
1178
-
1179
- it "should have a disconnect method that disconnects the connection" do
1180
- x = nil
1181
- c = @class.new(mock_db.call(proc{|c1| x = c1}){123})
1182
- c.hold{}
1183
- x.must_be_nil
1184
- c.disconnect
1185
- x.must_equal 123
1186
- end
1187
-
1188
- it "should have a reentrent hold method" do
1189
- o = Object.new
1190
- c = @class.new(mock_db.call{o}, {})
1191
- c.hold do |x|
1192
- x.must_equal o
1193
- c.hold do |x1|
1194
- x1.must_equal o
1195
- c.hold do |x2|
1196
- x2.must_equal o
1197
- end
1198
- end
1199
- end
1200
- end
1201
-
1202
- it "should have a servers method that returns an array of shard/server symbols" do
1203
- @class.new(mock_db.call{123}, {}).servers.must_equal [:default]
1204
- end
1205
-
1206
- it "should have a servers method that returns an array of shard/server symbols" do
1207
- c = @class.new(mock_db.call{123}, {})
1208
- c.size.must_equal 0
1209
- c.hold{}
1210
- c.size.must_equal 1
1211
- end
1212
- end
1213
-
1214
- [true, false].each do |k|
1215
- [true, false].each do |v|
1216
- opts = {:single_threaded=>k, :servers=>(v ? {} : nil)}
1217
- describe "Connection pool with #{opts.inspect}" do
1218
- before(:all) do
1219
- Sequel::ConnectionPool.send(:get_pool, mock_db.call, opts)
1220
- end
1221
- before do
1222
- @class = Sequel::ConnectionPool.send(:connection_pool_class, opts)
1223
- end
1224
-
1225
- include AllConnectionPoolClassesSpecs
1226
- end
1227
- end
1228
- end