sequel 3.21.0 → 3.41.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 (363) hide show
  1. data/CHANGELOG +1131 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +106 -65
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +68 -52
  7. data/doc/advanced_associations.rdoc +201 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/bin_sequel.rdoc +144 -0
  10. data/doc/cheat_sheet.rdoc +21 -21
  11. data/doc/core_extensions.rdoc +374 -0
  12. data/doc/dataset_basics.rdoc +10 -10
  13. data/doc/dataset_filtering.rdoc +54 -42
  14. data/doc/mass_assignment.rdoc +56 -0
  15. data/doc/migration.rdoc +89 -557
  16. data/doc/model_hooks.rdoc +80 -29
  17. data/doc/object_model.rdoc +576 -0
  18. data/doc/opening_databases.rdoc +121 -53
  19. data/doc/prepared_statements.rdoc +41 -15
  20. data/doc/querying.rdoc +137 -56
  21. data/doc/reflection.rdoc +36 -10
  22. data/doc/release_notes/3.22.0.txt +39 -0
  23. data/doc/release_notes/3.23.0.txt +172 -0
  24. data/doc/release_notes/3.24.0.txt +420 -0
  25. data/doc/release_notes/3.25.0.txt +88 -0
  26. data/doc/release_notes/3.26.0.txt +88 -0
  27. data/doc/release_notes/3.27.0.txt +82 -0
  28. data/doc/release_notes/3.28.0.txt +304 -0
  29. data/doc/release_notes/3.29.0.txt +459 -0
  30. data/doc/release_notes/3.30.0.txt +135 -0
  31. data/doc/release_notes/3.31.0.txt +146 -0
  32. data/doc/release_notes/3.32.0.txt +202 -0
  33. data/doc/release_notes/3.33.0.txt +157 -0
  34. data/doc/release_notes/3.34.0.txt +671 -0
  35. data/doc/release_notes/3.35.0.txt +144 -0
  36. data/doc/release_notes/3.36.0.txt +245 -0
  37. data/doc/release_notes/3.37.0.txt +338 -0
  38. data/doc/release_notes/3.38.0.txt +234 -0
  39. data/doc/release_notes/3.39.0.txt +237 -0
  40. data/doc/release_notes/3.40.0.txt +73 -0
  41. data/doc/release_notes/3.41.0.txt +155 -0
  42. data/doc/schema_modification.rdoc +585 -0
  43. data/doc/sharding.rdoc +99 -8
  44. data/doc/sql.rdoc +154 -112
  45. data/doc/testing.rdoc +169 -0
  46. data/doc/thread_safety.rdoc +17 -0
  47. data/doc/transactions.rdoc +137 -0
  48. data/doc/validations.rdoc +1 -1
  49. data/doc/virtual_rows.rdoc +78 -43
  50. data/lib/sequel/adapters/ado/access.rb +334 -0
  51. data/lib/sequel/adapters/ado/mssql.rb +18 -12
  52. data/lib/sequel/adapters/ado.rb +69 -21
  53. data/lib/sequel/adapters/amalgalite.rb +17 -14
  54. data/lib/sequel/adapters/cubrid.rb +143 -0
  55. data/lib/sequel/adapters/db2.rb +178 -85
  56. data/lib/sequel/adapters/dbi.rb +19 -21
  57. data/lib/sequel/adapters/do/mysql.rb +17 -11
  58. data/lib/sequel/adapters/do/postgres.rb +2 -61
  59. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  60. data/lib/sequel/adapters/do.rb +20 -39
  61. data/lib/sequel/adapters/firebird.rb +33 -210
  62. data/lib/sequel/adapters/ibmdb.rb +452 -0
  63. data/lib/sequel/adapters/informix.rb +6 -29
  64. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  65. data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
  66. data/lib/sequel/adapters/jdbc/db2.rb +78 -0
  67. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  68. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  69. data/lib/sequel/adapters/jdbc/h2.rb +68 -31
  70. data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
  71. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  73. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  74. data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
  75. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  76. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  77. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  78. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  79. data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
  80. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  81. data/lib/sequel/adapters/jdbc.rb +308 -114
  82. data/lib/sequel/adapters/mock.rb +372 -0
  83. data/lib/sequel/adapters/mysql.rb +130 -230
  84. data/lib/sequel/adapters/mysql2.rb +64 -63
  85. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  86. data/lib/sequel/adapters/odbc.rb +29 -10
  87. data/lib/sequel/adapters/openbase.rb +7 -11
  88. data/lib/sequel/adapters/oracle.rb +364 -57
  89. data/lib/sequel/adapters/postgres.rb +379 -145
  90. data/lib/sequel/adapters/shared/access.rb +236 -11
  91. data/lib/sequel/adapters/shared/cubrid.rb +216 -0
  92. data/lib/sequel/adapters/shared/db2.rb +353 -0
  93. data/lib/sequel/adapters/shared/firebird.rb +231 -0
  94. data/lib/sequel/adapters/shared/informix.rb +53 -0
  95. data/lib/sequel/adapters/shared/mssql.rb +412 -116
  96. data/lib/sequel/adapters/shared/mysql.rb +396 -89
  97. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
  98. data/lib/sequel/adapters/shared/oracle.rb +262 -45
  99. data/lib/sequel/adapters/shared/postgres.rb +688 -279
  100. data/lib/sequel/adapters/shared/progress.rb +5 -8
  101. data/lib/sequel/adapters/shared/sqlite.rb +317 -96
  102. data/lib/sequel/adapters/sqlite.rb +109 -46
  103. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  104. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  105. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  106. data/lib/sequel/adapters/swift.rb +31 -27
  107. data/lib/sequel/adapters/tinytds.rb +177 -25
  108. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  109. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  110. data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
  111. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  112. data/lib/sequel/ast_transformer.rb +194 -0
  113. data/lib/sequel/connection_pool/sharded_single.rb +23 -13
  114. data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
  115. data/lib/sequel/connection_pool/single.rb +11 -3
  116. data/lib/sequel/connection_pool/threaded.rb +69 -20
  117. data/lib/sequel/connection_pool.rb +20 -18
  118. data/lib/sequel/core.rb +143 -11
  119. data/lib/sequel/database/connecting.rb +66 -29
  120. data/lib/sequel/database/dataset.rb +4 -4
  121. data/lib/sequel/database/dataset_defaults.rb +63 -2
  122. data/lib/sequel/database/logging.rb +7 -2
  123. data/lib/sequel/database/misc.rb +192 -51
  124. data/lib/sequel/database/query.rb +299 -114
  125. data/lib/sequel/database/schema_generator.rb +103 -36
  126. data/lib/sequel/database/schema_methods.rb +310 -69
  127. data/lib/sequel/dataset/actions.rb +344 -90
  128. data/lib/sequel/dataset/features.rb +101 -8
  129. data/lib/sequel/dataset/graph.rb +42 -15
  130. data/lib/sequel/dataset/misc.rb +52 -25
  131. data/lib/sequel/dataset/mutation.rb +12 -7
  132. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  133. data/lib/sequel/dataset/query.rb +322 -68
  134. data/lib/sequel/dataset/sql.rb +716 -293
  135. data/lib/sequel/dataset.rb +8 -0
  136. data/lib/sequel/exceptions.rb +4 -0
  137. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  138. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  139. data/lib/sequel/extensions/blank.rb +4 -0
  140. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  141. data/lib/sequel/extensions/connection_validator.rb +109 -0
  142. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  143. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  144. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  145. data/lib/sequel/extensions/inflector.rb +4 -0
  146. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  147. data/lib/sequel/extensions/migration.rb +100 -11
  148. data/lib/sequel/extensions/named_timezones.rb +9 -0
  149. data/lib/sequel/extensions/null_dataset.rb +94 -0
  150. data/lib/sequel/extensions/pagination.rb +4 -0
  151. data/lib/sequel/extensions/pg_array.rb +539 -0
  152. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  153. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  154. data/lib/sequel/extensions/pg_hstore.rb +334 -0
  155. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  156. data/lib/sequel/extensions/pg_inet.rb +113 -0
  157. data/lib/sequel/extensions/pg_interval.rb +191 -0
  158. data/lib/sequel/extensions/pg_json.rb +212 -0
  159. data/lib/sequel/extensions/pg_range.rb +513 -0
  160. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  161. data/lib/sequel/extensions/pg_row.rb +576 -0
  162. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  163. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  164. data/lib/sequel/extensions/pretty_table.rb +17 -72
  165. data/lib/sequel/extensions/query.rb +8 -4
  166. data/lib/sequel/extensions/query_literals.rb +79 -0
  167. data/lib/sequel/extensions/schema_caching.rb +76 -0
  168. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  169. data/lib/sequel/extensions/select_remove.rb +39 -0
  170. data/lib/sequel/extensions/server_block.rb +140 -0
  171. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  172. data/lib/sequel/extensions/sql_expr.rb +8 -110
  173. data/lib/sequel/extensions/string_date_time.rb +4 -0
  174. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  175. data/lib/sequel/extensions/to_dot.rb +99 -83
  176. data/lib/sequel/model/associations.rb +1263 -409
  177. data/lib/sequel/model/base.rb +624 -171
  178. data/lib/sequel/model/errors.rb +1 -1
  179. data/lib/sequel/model/exceptions.rb +24 -2
  180. data/lib/sequel/model/inflections.rb +1 -1
  181. data/lib/sequel/model.rb +30 -11
  182. data/lib/sequel/no_core_ext.rb +2 -0
  183. data/lib/sequel/plugins/active_model.rb +13 -1
  184. data/lib/sequel/plugins/association_pks.rb +137 -16
  185. data/lib/sequel/plugins/caching.rb +25 -18
  186. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  187. data/lib/sequel/plugins/composition.rb +44 -12
  188. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  189. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  190. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  191. data/lib/sequel/plugins/dirty.rb +214 -0
  192. data/lib/sequel/plugins/eager_each.rb +59 -0
  193. data/lib/sequel/plugins/force_encoding.rb +6 -6
  194. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  195. data/lib/sequel/plugins/identity_map.rb +134 -15
  196. data/lib/sequel/plugins/instance_filters.rb +10 -0
  197. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  198. data/lib/sequel/plugins/json_serializer.rb +77 -6
  199. data/lib/sequel/plugins/list.rb +13 -2
  200. data/lib/sequel/plugins/many_through_many.rb +103 -51
  201. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  202. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  203. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  204. data/lib/sequel/plugins/pg_row.rb +121 -0
  205. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  206. data/lib/sequel/plugins/prepared_statements.rb +168 -0
  207. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  208. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  209. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  210. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  211. data/lib/sequel/plugins/schema.rb +8 -3
  212. data/lib/sequel/plugins/serialization.rb +98 -49
  213. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  214. data/lib/sequel/plugins/sharding.rb +21 -54
  215. data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
  216. data/lib/sequel/plugins/static_cache.rb +99 -0
  217. data/lib/sequel/plugins/subclasses.rb +29 -3
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  219. data/lib/sequel/plugins/timestamps.rb +1 -1
  220. data/lib/sequel/plugins/touch.rb +18 -6
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  223. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  224. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  225. data/lib/sequel/plugins/validation_helpers.rb +57 -4
  226. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  227. data/lib/sequel/sql.rb +721 -141
  228. data/lib/sequel/timezones.rb +67 -40
  229. data/lib/sequel/version.rb +1 -1
  230. data/spec/adapters/db2_spec.rb +146 -0
  231. data/spec/adapters/firebird_spec.rb +53 -39
  232. data/spec/adapters/mssql_spec.rb +261 -66
  233. data/spec/adapters/mysql_spec.rb +597 -352
  234. data/spec/adapters/oracle_spec.rb +92 -117
  235. data/spec/adapters/postgres_spec.rb +2103 -341
  236. data/spec/adapters/spec_helper.rb +16 -6
  237. data/spec/adapters/sqlite_spec.rb +237 -76
  238. data/spec/core/connection_pool_spec.rb +270 -141
  239. data/spec/core/database_spec.rb +980 -524
  240. data/spec/core/dataset_spec.rb +1658 -1243
  241. data/spec/core/expression_filters_spec.rb +741 -334
  242. data/spec/core/mock_adapter_spec.rb +453 -0
  243. data/spec/core/object_graph_spec.rb +88 -129
  244. data/spec/core/schema_generator_spec.rb +4 -4
  245. data/spec/core/schema_spec.rb +556 -53
  246. data/spec/core/spec_helper.rb +7 -48
  247. data/spec/core_extensions_spec.rb +626 -0
  248. data/spec/extensions/active_model_spec.rb +13 -0
  249. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  250. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  251. data/spec/extensions/association_dependencies_spec.rb +15 -25
  252. data/spec/extensions/association_pks_spec.rb +227 -33
  253. data/spec/extensions/association_proxies_spec.rb +4 -4
  254. data/spec/extensions/boolean_readers_spec.rb +25 -25
  255. data/spec/extensions/caching_spec.rb +47 -51
  256. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  257. data/spec/extensions/columns_introspection_spec.rb +91 -0
  258. data/spec/extensions/composition_spec.rb +18 -13
  259. data/spec/extensions/connection_validator_spec.rb +118 -0
  260. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  261. data/spec/extensions/constraint_validations_spec.rb +316 -0
  262. data/spec/extensions/dataset_associations_spec.rb +199 -0
  263. data/spec/extensions/defaults_setter_spec.rb +88 -0
  264. data/spec/extensions/dirty_spec.rb +155 -0
  265. data/spec/extensions/eager_each_spec.rb +34 -0
  266. data/spec/extensions/eval_inspect_spec.rb +67 -0
  267. data/spec/extensions/force_encoding_spec.rb +4 -2
  268. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  269. data/spec/extensions/identity_map_spec.rb +142 -24
  270. data/spec/extensions/inflector_spec.rb +0 -4
  271. data/spec/extensions/instance_filters_spec.rb +11 -21
  272. data/spec/extensions/instance_hooks_spec.rb +72 -0
  273. data/spec/extensions/json_serializer_spec.rb +49 -12
  274. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  275. data/spec/extensions/list_spec.rb +49 -40
  276. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  277. data/spec/extensions/many_through_many_spec.rb +368 -254
  278. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  279. data/spec/extensions/migration_spec.rb +140 -35
  280. data/spec/extensions/named_timezones_spec.rb +29 -11
  281. data/spec/extensions/nested_attributes_spec.rb +268 -89
  282. data/spec/extensions/null_dataset_spec.rb +85 -0
  283. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  284. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  285. data/spec/extensions/pg_array_spec.rb +324 -0
  286. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  287. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  288. data/spec/extensions/pg_hstore_spec.rb +200 -0
  289. data/spec/extensions/pg_inet_spec.rb +47 -0
  290. data/spec/extensions/pg_interval_spec.rb +72 -0
  291. data/spec/extensions/pg_json_spec.rb +99 -0
  292. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  293. data/spec/extensions/pg_range_spec.rb +395 -0
  294. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  295. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  296. data/spec/extensions/pg_row_spec.rb +340 -0
  297. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  298. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  299. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  300. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  301. data/spec/extensions/prepared_statements_spec.rb +87 -0
  302. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  303. data/spec/extensions/pretty_table_spec.rb +7 -6
  304. data/spec/extensions/query_literals_spec.rb +167 -0
  305. data/spec/extensions/query_spec.rb +9 -3
  306. data/spec/extensions/rcte_tree_spec.rb +50 -43
  307. data/spec/extensions/schema_caching_spec.rb +41 -0
  308. data/spec/extensions/schema_dumper_spec.rb +434 -49
  309. data/spec/extensions/schema_spec.rb +30 -49
  310. data/spec/extensions/select_remove_spec.rb +38 -0
  311. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  312. data/spec/extensions/serialization_spec.rb +86 -48
  313. data/spec/extensions/server_block_spec.rb +90 -0
  314. data/spec/extensions/sharding_spec.rb +69 -143
  315. data/spec/extensions/single_table_inheritance_spec.rb +65 -29
  316. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  317. data/spec/extensions/spec_helper.rb +34 -67
  318. data/spec/extensions/split_array_nil_spec.rb +24 -0
  319. data/spec/extensions/sql_expr_spec.rb +29 -60
  320. data/spec/extensions/static_cache_spec.rb +145 -0
  321. data/spec/extensions/subclasses_spec.rb +14 -0
  322. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  323. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  324. data/spec/extensions/timestamps_spec.rb +6 -6
  325. data/spec/extensions/to_dot_spec.rb +8 -11
  326. data/spec/extensions/touch_spec.rb +53 -14
  327. data/spec/extensions/tree_spec.rb +11 -26
  328. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  329. data/spec/extensions/update_primary_key_spec.rb +30 -24
  330. data/spec/extensions/validation_class_methods_spec.rb +77 -68
  331. data/spec/extensions/validation_helpers_spec.rb +48 -37
  332. data/spec/extensions/xml_serializer_spec.rb +29 -4
  333. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  334. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  335. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  336. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  337. data/spec/integration/associations_test.rb +659 -21
  338. data/spec/integration/database_test.rb +25 -5
  339. data/spec/integration/dataset_test.rb +729 -141
  340. data/spec/integration/eager_loader_test.rb +38 -54
  341. data/spec/integration/migrator_test.rb +2 -3
  342. data/spec/integration/model_test.rb +81 -2
  343. data/spec/integration/plugin_test.rb +871 -160
  344. data/spec/integration/prepared_statement_test.rb +272 -128
  345. data/spec/integration/schema_test.rb +377 -57
  346. data/spec/integration/spec_helper.rb +49 -32
  347. data/spec/integration/timezone_test.rb +38 -12
  348. data/spec/integration/transaction_test.rb +183 -8
  349. data/spec/integration/type_test.rb +40 -8
  350. data/spec/model/association_reflection_spec.rb +207 -8
  351. data/spec/model/associations_spec.rb +1206 -693
  352. data/spec/model/base_spec.rb +334 -100
  353. data/spec/model/dataset_methods_spec.rb +45 -27
  354. data/spec/model/eager_loading_spec.rb +828 -692
  355. data/spec/model/hooks_spec.rb +355 -67
  356. data/spec/model/model_spec.rb +251 -179
  357. data/spec/model/plugins_spec.rb +24 -13
  358. data/spec/model/record_spec.rb +506 -232
  359. data/spec/model/spec_helper.rb +16 -77
  360. data/spec/model/validations_spec.rb +38 -2
  361. data/spec/rcov.opts +2 -0
  362. metadata +223 -81
  363. data/spec/core/core_sql_spec.rb +0 -451
@@ -3,6 +3,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe Sequel::Model, "dataset & schema" do
4
4
  before do
5
5
  @model = Class.new(Sequel::Model(:items))
6
+ @model.plugin :schema
6
7
  end
7
8
 
8
9
  specify "sets schema with implicit table name" do
@@ -22,30 +23,17 @@ describe Sequel::Model, "dataset & schema" do
22
23
  end
23
24
  end
24
25
 
25
- describe Sequel::Model, "table_exists?" do
26
-
27
- before(:each) do
28
- MODEL_DB.reset
29
- @model = Class.new(Sequel::Model(:items))
30
- end
31
-
32
- it "should get the table name and question the model's db if table_exists?" do
33
- @model.should_receive(:table_name).and_return(:items)
34
- @model.db.should_receive(:table_exists?)
35
- @model.table_exists?
36
- end
37
- end
38
-
39
26
  describe Sequel::Model, "create_table and schema" do
40
-
41
- before(:each) do
42
- MODEL_DB.reset
43
- @model = Class.new(Sequel::Model) do
27
+ before do
28
+ @model = Class.new(Sequel::Model)
29
+ @model.class_eval do
30
+ plugin :schema
44
31
  set_schema(:items) do
45
32
  text :name
46
33
  float :price, :null => false
47
34
  end
48
35
  end
36
+ MODEL_DB.reset
49
37
  end
50
38
 
51
39
  it "should get the create table SQL list from the db and execute it line by line" do
@@ -60,7 +48,7 @@ describe Sequel::Model, "create_table and schema" do
60
48
 
61
49
  it "should reload the schema from the database" do
62
50
  schem = {:name=>{:type=>:string}, :price=>{:type=>:float}}
63
- @model.db.should_receive(:schema).with(:items, :reload=>true).and_return(schem.to_a.sort_by{|x| x[0].to_s})
51
+ @model.db.should_receive(:schema).with(@model.dataset, :reload=>true).and_return(schem.to_a.sort_by{|x| x[0].to_s})
64
52
  @model.create_table
65
53
  @model.db_schema.should == schem
66
54
  @model.instance_variable_get(:@columns).should == [:name, :price]
@@ -77,56 +65,49 @@ describe Sequel::Model, "create_table and schema" do
77
65
 
78
66
  it "should return nil if no schema is present" do
79
67
  @model = Class.new(Sequel::Model)
68
+ @model.plugin :schema
80
69
  @model.schema.should == nil
81
70
  @submodel = Class.new(@model)
82
71
  @submodel.schema.should == nil
83
72
  end
84
73
  end
85
74
 
86
- describe Sequel::Model, "drop_table" do
87
-
88
- before(:each) do
89
- MODEL_DB.reset
75
+ describe Sequel::Model, "schema methods" do
76
+ before do
90
77
  @model = Class.new(Sequel::Model(:items))
78
+ @model.plugin :schema
79
+ MODEL_DB.reset
91
80
  end
92
81
 
93
- it "should get the drop table SQL for the associated table and then execute the SQL." do
94
- @model.should_receive(:table_name).and_return(:items)
95
- @model.db.should_receive(:drop_table_sql).with(:items)
96
- @model.db.should_receive(:execute).and_return(:true)
97
- @model.drop_table
82
+ it "table_exists? should get the table name and question the model's db if table_exists?" do
83
+ @model.db.should_receive(:table_exists?).and_return(false)
84
+ @model.table_exists?.should == false
98
85
  end
99
86
 
100
- end
87
+ it "drop_table should drop the related table" do
88
+ @model.drop_table
89
+ MODEL_DB.sqls.should == ['DROP TABLE items']
90
+ end
101
91
 
102
- describe Sequel::Model, "create_table!" do
103
- before do
104
- MODEL_DB.reset
105
- @model = Class.new(Sequel::Model(:items))
92
+ it "drop_table? should drop the table if it exists" do
93
+ @model.drop_table?
94
+ MODEL_DB.sqls.should == ["SELECT NULL FROM items LIMIT 1", 'DROP TABLE items']
106
95
  end
107
96
 
108
- it "should drop table if it exists and then create the table" do
109
- @model.should_receive(:drop_table).and_return(true)
110
- @model.should_receive(:create_table).and_return(true)
97
+ it "create_table! should drop table if it exists and then create the table" do
111
98
  @model.create_table!
112
- end
113
- end
114
-
115
- describe Sequel::Model, "create_table?" do
116
- before do
117
- MODEL_DB.reset
118
- @model = Class.new(Sequel::Model(:items))
99
+ MODEL_DB.sqls.should == ["SELECT NULL FROM items LIMIT 1", 'DROP TABLE items', 'CREATE TABLE items ()']
119
100
  end
120
101
 
121
- it "should not create the table if it already exists" do
102
+ it "create_table? should not create the table if it already exists" do
122
103
  @model.should_receive(:table_exists?).and_return(true)
123
- @model.should_not_receive(:create_table)
124
- @model.create_table?.should == nil
104
+ @model.create_table?
105
+ MODEL_DB.sqls.should == []
125
106
  end
126
107
 
127
- it "should create the table if it doesn't exist" do
108
+ it "create_table? should create the table if it doesn't exist" do
128
109
  @model.should_receive(:table_exists?).and_return(false)
129
- @model.should_receive(:create_table).and_return(3)
130
- @model.create_table?.should == 3
110
+ @model.create_table?
111
+ MODEL_DB.sqls.should == ['CREATE TABLE items ()']
131
112
  end
132
113
  end
@@ -0,0 +1,38 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Dataset#select_remove" do
4
+ before do
5
+ @d = Sequel.mock.from(:test)
6
+ @d.columns :a, :b, :c
7
+ end
8
+
9
+ specify "should remove columns from the selected columns" do
10
+ @d.sql.should == 'SELECT * FROM test'
11
+ @d.select_remove(:a).sql.should == 'SELECT b, c FROM test'
12
+ @d.select_remove(:b).sql.should == 'SELECT a, c FROM test'
13
+ @d.select_remove(:c).sql.should == 'SELECT a, b FROM test'
14
+ end
15
+
16
+ specify "should work correctly if there are already columns selected" do
17
+ d = @d.select(:a, :b, :c)
18
+ d.columns :a, :b, :c
19
+ d.select_remove(:c).sql.should == 'SELECT a, b FROM test'
20
+ end
21
+
22
+ specify "should have no effect if the columns given are not currently selected" do
23
+ @d.select_remove(:d).sql.should == 'SELECT a, b, c FROM test'
24
+ end
25
+
26
+ specify "should handle expressions where Sequel can't determine the alias by itself" do
27
+ d = @d.select(:a, Sequel.function(:b), Sequel.as(:c, :b))
28
+ d.columns :a, :"b()", :b
29
+ d.select_remove(:"b()").sql.should == 'SELECT a, c AS b FROM test'
30
+ end
31
+
32
+ specify "should remove expressions if given exact expressions" do
33
+ d = @d.select(:a, Sequel.function(:b), Sequel.as(:c, :b))
34
+ d.columns :a, :"b()", :b
35
+ d.select_remove(Sequel.function(:b)).sql.should == 'SELECT a, c AS b FROM test'
36
+ d.select_remove(Sequel.as(:c, :b)).sql.should == 'SELECT a, b() FROM test'
37
+ end
38
+ end
@@ -0,0 +1,72 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+ require 'yaml'
3
+
4
+ describe "serialization_modification_detection plugin" do
5
+ before do
6
+ @c = Class.new(Sequel::Model(:items))
7
+ @c.class_eval do
8
+ columns :id, :h
9
+ plugin :serialization, :yaml, :h
10
+ plugin :serialization_modification_detection
11
+ end
12
+ @o1 = @c.new(:h=>{})
13
+ @o2 = @c.load(:id=>1, :h=>"--- {}\n\n")
14
+ @o3 = @c.new
15
+ @o4 = @c.load(:id=>1, :h=>nil)
16
+ MODEL_DB.reset
17
+ end
18
+
19
+ it "should not detect columns that haven't been changed" do
20
+ @o1.changed_columns.should == []
21
+ @o1.h.should == {}
22
+ @o1.h[1] = 2
23
+ @o1.h.clear
24
+ @o1.changed_columns.should == []
25
+
26
+ @o2.changed_columns.should == []
27
+ @o2.h.should == {}
28
+ @o2.h[1] = 2
29
+ @o2.h.clear
30
+ @o2.changed_columns.should == []
31
+ end
32
+
33
+ it "should detect columns that have been changed" do
34
+ @o1.changed_columns.should == []
35
+ @o1.h.should == {}
36
+ @o1.h[1] = 2
37
+ @o1.changed_columns.should == [:h]
38
+
39
+ @o2.changed_columns.should == []
40
+ @o2.h.should == {}
41
+ @o2.h[1] = 2
42
+ @o2.changed_columns.should == [:h]
43
+
44
+ @o3.changed_columns.should == []
45
+ @o3.h.should == nil
46
+ @o3.h = {}
47
+ @o3.changed_columns.should == [:h]
48
+
49
+ @o4.changed_columns.should == []
50
+ @o4.h.should == nil
51
+ @o4.h = {}
52
+ @o4.changed_columns.should == [:h]
53
+ end
54
+
55
+ it "should report correct changed_columns after saving" do
56
+ @o1.h[1] = 2
57
+ @o1.save
58
+ @o1.changed_columns.should == []
59
+
60
+ @o2.h[1] = 2
61
+ @o2.save_changes
62
+ @o2.changed_columns.should == []
63
+
64
+ @o3.h = {1=>2}
65
+ @o3.save
66
+ @o3.changed_columns.should == []
67
+
68
+ @o4.h = {1=>2}
69
+ @o4.save
70
+ @o4.changed_columns.should == []
71
+ end
72
+ end
@@ -1,18 +1,11 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
- begin
4
3
  require 'yaml'
5
4
  require 'json'
6
- rescue LoadError => e
7
- skip_warn "serialization plugin: can't load json (#{e.class}: #{e})"
8
- else
5
+
9
6
  describe "Serialization plugin" do
10
7
  before do
11
8
  @c = Class.new(Sequel::Model(:items)) do
12
- include(Module.new do
13
- def before_save
14
- end
15
- end)
16
9
  no_primary_key
17
10
  columns :id, :abc, :def, :ghi
18
11
  end
@@ -22,11 +15,11 @@ describe "Serialization plugin" do
22
15
  it "should allow setting additional serializable attributes via plugin :serialization call" do
23
16
  @c.plugin :serialization, :yaml, :abc
24
17
  @c.create(:abc => 1, :def=> 2)
25
- MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n', 2|2, '--- 1\n')\)/
18
+ MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n(\.\.\.\n)?', 2|2, '--- 1\n(\.\.\.\n)?')\)/
26
19
 
27
20
  @c.plugin :serialization, :marshal, :def
28
21
  @c.create(:abc => 1, :def=> 1)
29
- MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n', 'BAhpBg==\n'|'BAhpBg==\n', '--- 1\n')\)/
22
+ MODEL_DB.sqls.last.should =~ /INSERT INTO items \((abc, def|def, abc)\) VALUES \(('--- 1\n(\.\.\.\n)?', 'BAhpBg==\n'|'BAhpBg==\n', '--- 1\n(\.\.\.\n)?')\)/
30
23
 
31
24
  @c.plugin :serialization, :json, :ghi
32
25
  @c.create(:ghi => [123])
@@ -38,15 +31,7 @@ describe "Serialization plugin" do
38
31
  @c.create(:abc => 1)
39
32
  @c.create(:abc => "hello")
40
33
 
41
- MODEL_DB.sqls.should == [ \
42
- "INSERT INTO items (abc) VALUES ('--- 1\n')", \
43
- "INSERT INTO items (abc) VALUES ('--- hello\n')", \
44
- ]
45
- end
46
-
47
- it "serialization_format should be the serialization format used" do
48
- @c.plugin :serialization, :yaml, :abc
49
- @c.serialization_format.should == :yaml
34
+ MODEL_DB.sqls.map{|s| s.sub("...\n", '')}.should == ["INSERT INTO items (abc) VALUES ('--- 1\n')", "INSERT INTO items (abc) VALUES ('--- hello\n')"]
50
35
  end
51
36
 
52
37
  it "serialized_columns should be the columns serialized" do
@@ -78,15 +63,21 @@ describe "Serialization plugin" do
78
63
  ]
79
64
  end
80
65
 
66
+ it "should allow serializing attributes using arbitrary callable" do
67
+ @c.plugin :serialization, [proc{|s| s.reverse}, proc{}], :abc
68
+ @c.create(:abc => "hello")
69
+ MODEL_DB.sqls.should == ["INSERT INTO items (abc) VALUES ('olleh')"]
70
+ end
71
+
72
+ it "should raise an error if specificing serializer as an unregistered symbol" do
73
+ proc{@c.plugin :serialization, :foo, :abc}.should raise_error(Sequel::Error)
74
+ end
75
+
81
76
  it "should translate values to and from yaml serialization format using accessor methods" do
82
77
  @c.set_primary_key :id
83
78
  @c.plugin :serialization, :yaml, :abc, :def
84
79
  vals = nil
85
-
86
- ds = @c.dataset
87
- def ds.fetch_rows(sql, &block)
88
- block.call(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
89
- end
80
+ @c.dataset._fetch = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
90
81
 
91
82
  o = @c.first
92
83
  o.id.should == 1
@@ -97,18 +88,16 @@ describe "Serialization plugin" do
97
88
 
98
89
  o.update(:abc => 23)
99
90
  @c.create(:abc => [1, 2, 3])
100
- MODEL_DB.sqls.should == ["UPDATE items SET abc = '--- 23\n' WHERE (id = 1)",
101
- "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"]
91
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
92
+ "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)",
93
+ "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')",
94
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
102
95
  end
103
96
 
104
97
  it "should translate values to and from marshal serialization format using accessor methods" do
105
98
  @c.set_primary_key :id
106
99
  @c.plugin :serialization, :marshal, :abc, :def
107
-
108
- ds = @c.dataset
109
- def ds.fetch_rows(sql, &block)
110
- block.call(:id => 1, :abc =>[Marshal.dump(1)].pack('m'), :def =>[Marshal.dump('hello')].pack('m'))
111
- end
100
+ @c.dataset._fetch = [:id => 1, :abc =>[Marshal.dump(1)].pack('m'), :def =>[Marshal.dump('hello')].pack('m')]
112
101
 
113
102
  o = @c.first
114
103
  o.id.should == 1
@@ -119,18 +108,16 @@ describe "Serialization plugin" do
119
108
 
120
109
  o.update(:abc => 23)
121
110
  @c.create(:abc => [1, 2, 3])
122
- MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{[Marshal.dump(23)].pack('m')}' WHERE (id = 1)",
123
- "INSERT INTO items (abc) VALUES ('#{[Marshal.dump([1, 2, 3])].pack('m')}')"]
111
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
112
+ "UPDATE items SET abc = '#{[Marshal.dump(23)].pack('m')}' WHERE (id = 1)",
113
+ "INSERT INTO items (abc) VALUES ('#{[Marshal.dump([1, 2, 3])].pack('m')}')",
114
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
124
115
  end
125
116
 
126
117
  it "should translate values to and from json serialization format using accessor methods" do
127
118
  @c.set_primary_key :id
128
119
  @c.plugin :serialization, :json, :abc, :def
129
-
130
- ds = @c.dataset
131
- def ds.fetch_rows(sql, &block)
132
- block.call(:id => 1, :abc => [1].to_json, :def => ["hello"].to_json)
133
- end
120
+ @c.dataset._fetch = {:id => 1, :abc => [1].to_json, :def => ["hello"].to_json}
134
121
 
135
122
  o = @c.first
136
123
  o.id.should == 1
@@ -142,18 +129,59 @@ describe "Serialization plugin" do
142
129
  o.update(:abc => [23])
143
130
  @c.create(:abc => [1,2,3])
144
131
 
145
- MODEL_DB.sqls.should == ["UPDATE items SET abc = '#{[23].to_json}' WHERE (id = 1)",
146
- "INSERT INTO items (abc) VALUES ('#{[1,2,3].to_json}')"]
132
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
133
+ "UPDATE items SET abc = '#{[23].to_json}' WHERE (id = 1)",
134
+ "INSERT INTO items (abc) VALUES ('#{[1,2,3].to_json}')",
135
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
136
+ end
137
+
138
+ it "should translate values to and from arbitrary callables using accessor methods" do
139
+ @c.set_primary_key :id
140
+ @c.plugin :serialization, [proc{|s| s.reverse}, proc{|s| s.reverse}], :abc, :def
141
+ @c.dataset._fetch = {:id => 1, :abc => 'cba', :def => 'olleh'}
142
+
143
+ o = @c.first
144
+ o.id.should == 1
145
+ o.abc.should == 'abc'
146
+ o.abc.should == 'abc'
147
+ o.def.should == "hello"
148
+ o.def.should == "hello"
149
+
150
+ o.update(:abc => 'foo')
151
+ @c.create(:abc => 'bar')
152
+
153
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
154
+ "UPDATE items SET abc = 'oof' WHERE (id = 1)",
155
+ "INSERT INTO items (abc) VALUES ('rab')",
156
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
157
+ end
158
+
159
+ it "should handle registration of custom serializer/deserializer pairs" do
160
+ @c.set_primary_key :id
161
+ Sequel::Plugins::Serialization.register_format(:reverse, proc{|s| s.reverse}, proc{|s| s.reverse})
162
+ @c.plugin :serialization, :reverse, :abc, :def
163
+ @c.dataset._fetch = {:id => 1, :abc => 'cba', :def => 'olleh'}
164
+
165
+ o = @c.first
166
+ o.id.should == 1
167
+ o.abc.should == 'abc'
168
+ o.abc.should == 'abc'
169
+ o.def.should == "hello"
170
+ o.def.should == "hello"
171
+
172
+ o.update(:abc => 'foo')
173
+ @c.create(:abc => 'bar')
174
+
175
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
176
+ "UPDATE items SET abc = 'oof' WHERE (id = 1)",
177
+ "INSERT INTO items (abc) VALUES ('rab')",
178
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
147
179
  end
148
180
 
149
181
  it "should copy serialization formats and columns to subclasses" do
150
182
  @c.set_primary_key :id
151
183
  @c.plugin :serialization, :yaml, :abc, :def
152
-
153
- ds = @c.dataset
154
- def ds.fetch_rows(sql, &block)
155
- block.call(:id => 1, :abc => "--- 1\n", :def => "--- hello\n")
156
- end
184
+ @c.dataset._fetch = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
157
185
 
158
186
  o = Class.new(@c).first
159
187
  o.id.should == 1
@@ -164,8 +192,10 @@ describe "Serialization plugin" do
164
192
 
165
193
  o.update(:abc => 23)
166
194
  Class.new(@c).create(:abc => [1, 2, 3])
167
- MODEL_DB.sqls.should == ["UPDATE items SET abc = '--- 23\n' WHERE (id = 1)",
168
- "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"]
195
+ MODEL_DB.sqls.should == ["SELECT * FROM items LIMIT 1",
196
+ "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)",
197
+ "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')",
198
+ "SELECT * FROM items WHERE (id = 10) LIMIT 1"]
169
199
  end
170
200
 
171
201
  it "should clear the deserialized columns when refreshing" do
@@ -179,6 +209,15 @@ describe "Serialization plugin" do
179
209
  o.deserialized_values.length.should == 0
180
210
  end
181
211
 
212
+ it "should clear the deserialized columns when refreshing after saving a new object" do
213
+ @c.set_primary_key :id
214
+ @c.plugin :serialization, :yaml, :abc, :def
215
+ o = @c.new(:abc => "--- 1\n", :def => "--- hello\n")
216
+ o.deserialized_values.length.should == 2
217
+ o.save
218
+ o.deserialized_values.length.should == 0
219
+ end
220
+
182
221
  it "should raise an error if calling internal serialization methods with bad columns" do
183
222
  @c.set_primary_key :id
184
223
  @c.plugin :serialization
@@ -210,4 +249,3 @@ describe "Serialization plugin" do
210
249
  o.abc.should == 9
211
250
  end
212
251
  end
213
- end
@@ -0,0 +1,90 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ shared_examples_for "Database#with_server" do
4
+ specify "should set the default server to use in the block" do
5
+ @db.with_server(:a){@db[:t].all}
6
+ @db.sqls.should == ["SELECT * FROM t -- a"]
7
+ @db.with_server(:b){@db[:t].all}
8
+ @db.sqls.should == ["SELECT * FROM t -- b"]
9
+ end
10
+
11
+ specify "should have no affect after the block" do
12
+ @db.with_server(:a){@db[:t].all}
13
+ @db.sqls.should == ["SELECT * FROM t -- a"]
14
+ @db[:t].all
15
+ @db.sqls.should == ["SELECT * FROM t"]
16
+ end
17
+
18
+ specify "should not override specific server inside the block" do
19
+ @db.with_server(:a){@db[:t].server(:b).all}
20
+ @db.sqls.should == ["SELECT * FROM t -- b"]
21
+ end
22
+
23
+ specify "should work correctly when blocks are nested" do
24
+ @db[:t].all
25
+ @db.with_server(:a) do
26
+ @db[:t].all
27
+ @db.with_server(:b){@db[:t].all}
28
+ @db[:t].all
29
+ end
30
+ @db[:t].all
31
+ @db.sqls.should == ["SELECT * FROM t", "SELECT * FROM t -- a", "SELECT * FROM t -- b", "SELECT * FROM t -- a", "SELECT * FROM t"]
32
+ end
33
+
34
+ specify "should work correctly for inserts/updates/deletes" do
35
+ @db.with_server(:a) do
36
+ @db[:t].insert
37
+ @db[:t].update(:a=>1)
38
+ @db[:t].delete
39
+ end
40
+ @db.sqls.should == ["INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
41
+ end
42
+ end
43
+
44
+ describe "Database#with_server single threaded" do
45
+ before do
46
+ @db = Sequel.mock(:single_threaded=>true, :servers=>{:a=>{}, :b=>{}})
47
+ @db.extension :server_block
48
+ end
49
+
50
+ it_should_behave_like "Database#with_server"
51
+ end
52
+
53
+ describe "Database#with_server multi threaded" do
54
+ before do
55
+ @db = Sequel.mock(:servers=>{:a=>{}, :b=>{}, :c=>{}, :d=>{}})
56
+ @db.extension :server_block
57
+ end
58
+
59
+ it_should_behave_like "Database#with_server"
60
+
61
+ specify "should respect multithreaded access" do
62
+ q, q1 = Queue.new, Queue.new
63
+
64
+ t = nil
65
+ @db[:t].all
66
+ @db.with_server(:a) do
67
+ @db[:t].all
68
+ t = Thread.new do
69
+ @db[:t].all
70
+ @db.with_server(:c) do
71
+ @db[:t].all
72
+ @db.with_server(:d){@db[:t].all}
73
+ q.push nil
74
+ q1.pop
75
+ @db[:t].all
76
+ end
77
+ @db[:t].all
78
+ end
79
+ q.pop
80
+ @db.with_server(:b){@db[:t].all}
81
+ @db[:t].all
82
+ end
83
+ @db[:t].all
84
+ q1.push nil
85
+ t.join
86
+ @db.sqls.should == ["SELECT * FROM t", "SELECT * FROM t -- a", "SELECT * FROM t", "SELECT * FROM t -- c", "SELECT * FROM t -- d",
87
+ "SELECT * FROM t -- b", "SELECT * FROM t -- a", "SELECT * FROM t", "SELECT * FROM t -- c", "SELECT * FROM t"]
88
+ end
89
+ end
90
+