switchman 0.0.1 → 1.0.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 (642) hide show
  1. checksums.yaml +13 -5
  2. data/app/models/switchman/shard.rb +64 -19
  3. data/lib/switchman/action_controller/caching.rb +26 -0
  4. data/lib/switchman/active_record/abstract_adapter.rb +11 -0
  5. data/lib/switchman/active_record/association.rb +37 -3
  6. data/lib/switchman/active_record/attribute_methods.rb +3 -2
  7. data/lib/switchman/active_record/base.rb +44 -15
  8. data/lib/switchman/active_record/calculations.rb +145 -3
  9. data/lib/switchman/active_record/connection_handler.rb +11 -0
  10. data/lib/switchman/active_record/connection_pool.rb +5 -3
  11. data/lib/switchman/active_record/finder_methods.rb +25 -0
  12. data/lib/switchman/active_record/log_subscriber.rb +3 -2
  13. data/lib/switchman/active_record/query_cache.rb +71 -0
  14. data/lib/switchman/active_record/query_methods.rb +64 -29
  15. data/lib/switchman/active_record/relation.rb +44 -15
  16. data/lib/switchman/active_record/spawn_methods.rb +74 -0
  17. data/lib/switchman/active_support/cache.rb +17 -0
  18. data/lib/switchman/connection_pool_proxy.rb +47 -5
  19. data/lib/switchman/database_server.rb +131 -63
  20. data/lib/switchman/default_shard.rb +38 -23
  21. data/lib/switchman/engine.rb +71 -8
  22. data/lib/switchman/r_spec_helper.rb +41 -34
  23. data/lib/switchman/rails.rb +21 -0
  24. data/lib/switchman/shackles.rb +20 -20
  25. data/lib/switchman/sharded_instrumenter.rb +19 -0
  26. data/lib/switchman/test_helper.rb +3 -3
  27. data/lib/switchman/version.rb +1 -1
  28. data/lib/switchman.rb +1 -1
  29. data/spec/dummy/app/models/root.rb +5 -0
  30. data/spec/dummy/app/models/user.rb +6 -0
  31. data/spec/dummy/db/migrate/20140123154135_add_parent_id_to_users.rb +5 -0
  32. data/spec/dummy/db/migrate/20140219183820_create_roots.rb +9 -0
  33. data/spec/dummy/db/schema.rb +8 -1
  34. data/spec/dummy/log/development.log +135 -0
  35. data/spec/dummy/log/test.log +86777 -29398
  36. data/spec/dummy/tmp/cache/{317/9C0/shard%2F43 → 14A/870/key} +1 -1
  37. data/spec/dummy/tmp/cache/{319/A10/shard%2F72 → 2E9/8A0/shard%2F9} +1 -1
  38. data/spec/dummy/tmp/cache/317/9E0/shard%2F61 +0 -0
  39. data/spec/dummy/tmp/cache/318/9F0/shard%2F62 +0 -0
  40. data/spec/dummy/tmp/cache/{319/9F0/shard%2F54 → 318/A00/shard%2F71} +1 -1
  41. data/spec/dummy/tmp/cache/31A/A10/shard%2F64 +0 -0
  42. data/spec/dummy/tmp/cache/31A/A20/shard%2F73 +0 -0
  43. data/spec/dummy/tmp/cache/31B/A20/shard%2F65 +0 -0
  44. data/spec/dummy/tmp/cache/31B/A30/shard%2F74 +0 -0
  45. data/spec/dummy/tmp/cache/{31B/9E0/shard%2F29 → 31C/A40/shard%2F75} +1 -1
  46. data/spec/dummy/tmp/cache/31D/A30/shard%2F58 +0 -0
  47. data/spec/dummy/tmp/cache/31D/A40/shard%2F67 +0 -0
  48. data/spec/dummy/tmp/cache/31E/A40/shard%2F59 +0 -0
  49. data/spec/dummy/tmp/cache/31E/A50/shard%2F68 +0 -0
  50. data/spec/dummy/tmp/cache/320/A80/shard%2F79 +0 -0
  51. data/spec/dummy/tmp/cache/343/D90/shard%2F210 +0 -0
  52. data/spec/dummy/tmp/cache/344/D70/shard%2F103 +0 -0
  53. data/spec/dummy/tmp/cache/345/D80/shard%2F104 +0 -0
  54. data/spec/dummy/tmp/cache/345/DB0/shard%2F212 +0 -0
  55. data/spec/dummy/tmp/cache/345/DC0/shard%2F140 +0 -0
  56. data/spec/dummy/tmp/cache/345/DC0/shard%2F302 +0 -0
  57. data/spec/dummy/tmp/cache/346/D90/shard%2F105 +0 -0
  58. data/spec/dummy/tmp/cache/346/DD0/shard%2F303 +0 -0
  59. data/spec/dummy/tmp/cache/346/DF0/shard%2F321 +0 -0
  60. data/spec/dummy/tmp/cache/347/E00/shard%2F322 +0 -0
  61. data/spec/dummy/tmp/cache/347/E50/shard%2F610 +0 -0
  62. data/spec/dummy/tmp/cache/348/DD0/shard%2F206 +0 -0
  63. data/spec/dummy/tmp/cache/348/DE0/shard%2F215 +0 -0
  64. data/spec/dummy/tmp/cache/{316/980/shard%2F15 → 348/E10/shard%2F323} +1 -1
  65. data/spec/dummy/tmp/cache/348/E30/shard%2F422 +0 -0
  66. data/spec/dummy/tmp/cache/348/E40/shard%2F350 +0 -0
  67. data/spec/dummy/tmp/cache/348/E50/shard%2F602 +0 -0
  68. data/spec/dummy/tmp/cache/348/E80/shard%2F710 +0 -0
  69. data/spec/dummy/tmp/cache/348/E90/shard%2F800 +0 -0
  70. data/spec/dummy/tmp/cache/349/DE0/shard%2F126 +0 -0
  71. data/spec/dummy/tmp/cache/349/DF0/shard%2F216 +0 -0
  72. data/spec/dummy/tmp/cache/349/E00/shard%2F225 +0 -0
  73. data/spec/dummy/tmp/cache/349/E20/shard%2F243 +0 -0
  74. data/spec/dummy/tmp/cache/349/E20/shard%2F405 +0 -0
  75. data/spec/dummy/tmp/cache/349/E30/shard%2F333 +0 -0
  76. data/spec/dummy/tmp/cache/349/E40/shard%2F423 +0 -0
  77. data/spec/dummy/tmp/cache/349/E60/shard%2F603 +0 -0
  78. data/spec/dummy/tmp/cache/34A/DF0/shard%2F127 +0 -0
  79. data/spec/dummy/tmp/cache/34A/E10/shard%2F226 +0 -0
  80. data/spec/dummy/tmp/cache/34A/E30/shard%2F244 +0 -0
  81. data/spec/dummy/tmp/cache/34A/E50/shard%2F505 +0 -0
  82. data/spec/dummy/tmp/cache/34A/E60/shard%2F433 +0 -0
  83. data/spec/dummy/tmp/cache/34A/E70/shard%2F523 +0 -0
  84. data/spec/dummy/tmp/cache/34A/E80/shard%2F613 +0 -0
  85. data/spec/dummy/tmp/cache/34A/EA0/shard%2F712 +0 -0
  86. data/spec/dummy/tmp/cache/34A/EC0/shard%2F730 +0 -0
  87. data/spec/dummy/tmp/cache/34B/E00/shard%2F128 +1 -0
  88. data/spec/dummy/tmp/cache/34B/E00/shard%2F209 +0 -0
  89. data/spec/dummy/tmp/cache/34B/E10/shard%2F137 +0 -0
  90. data/spec/dummy/tmp/cache/34B/E30/shard%2F236 +0 -0
  91. data/spec/dummy/tmp/cache/34B/E50/shard%2F254 +0 -0
  92. data/spec/dummy/tmp/cache/34B/E60/shard%2F344 +0 -0
  93. data/spec/dummy/tmp/cache/34B/E60/shard%2F506 +0 -0
  94. data/spec/dummy/tmp/cache/34B/E80/shard%2F605 +0 -0
  95. data/spec/dummy/tmp/cache/34B/E90/shard%2F290 +0 -0
  96. data/spec/dummy/tmp/cache/34B/EC0/shard%2F560 +0 -0
  97. data/spec/dummy/tmp/cache/34B/ED0/shard%2F731 +0 -0
  98. data/spec/dummy/tmp/cache/34B/ED0/shard%2F812 +0 -0
  99. data/spec/dummy/tmp/cache/34C/E20/shard%2F138 +0 -0
  100. data/spec/dummy/tmp/cache/34C/E20/shard%2F219 +1 -0
  101. data/spec/dummy/tmp/cache/34C/E30/shard%2F228 +0 -0
  102. data/spec/dummy/tmp/cache/34C/E40/shard%2F237 +0 -0
  103. data/spec/dummy/tmp/cache/34C/E40/shard%2F318 +0 -0
  104. data/spec/dummy/tmp/cache/34C/E50/shard%2F246 +1 -0
  105. data/spec/dummy/tmp/cache/34C/E60/shard%2F255 +0 -0
  106. data/spec/dummy/tmp/cache/34C/E80/shard%2F192 +0 -0
  107. data/spec/dummy/tmp/cache/34C/EA0/shard%2F372 +0 -0
  108. data/spec/dummy/tmp/cache/34C/EA0/shard%2F453 +0 -0
  109. data/spec/dummy/tmp/cache/34C/EB0/shard%2F462 +0 -0
  110. data/spec/dummy/tmp/cache/34C/ED0/shard%2F480 +0 -0
  111. data/spec/dummy/tmp/cache/34C/ED0/shard%2F561 +0 -0
  112. data/spec/dummy/tmp/cache/34C/EF0/shard%2F822 +0 -0
  113. data/spec/dummy/tmp/cache/34C/EF0/shard%2F903 +0 -0
  114. data/spec/dummy/tmp/cache/34C/F00/shard%2F912 +0 -0
  115. data/spec/dummy/tmp/cache/34D/E50/shard%2F319 +0 -0
  116. data/spec/dummy/tmp/cache/34D/E80/shard%2F508 +0 -0
  117. data/spec/dummy/tmp/cache/34D/E90/shard%2F355 +0 -0
  118. data/spec/dummy/tmp/cache/34D/EA0/shard%2F364 +0 -0
  119. data/spec/dummy/tmp/cache/34D/EB0/shard%2F373 +0 -0
  120. data/spec/dummy/tmp/cache/34D/EB0/shard%2F454 +0 -0
  121. data/spec/dummy/tmp/cache/34D/EB0/shard%2F616 +0 -0
  122. data/spec/dummy/tmp/cache/34D/EC0/shard%2F544 +0 -0
  123. data/spec/dummy/tmp/cache/34D/ED0/shard%2F391 +0 -0
  124. data/spec/dummy/tmp/cache/34D/ED0/shard%2F715 +0 -0
  125. data/spec/dummy/tmp/cache/34D/F00/shard%2F661 +0 -0
  126. data/spec/dummy/tmp/cache/34D/F10/shard%2F913 +0 -0
  127. data/spec/dummy/tmp/cache/34E/E80/shard%2F257 +0 -0
  128. data/spec/dummy/tmp/cache/34E/EA0/shard%2F275 +0 -0
  129. data/spec/dummy/tmp/cache/34E/EB0/shard%2F365 +0 -0
  130. data/spec/dummy/tmp/cache/34E/EC0/shard%2F617 +0 -0
  131. data/spec/dummy/tmp/cache/34E/ED0/shard%2F545 +0 -0
  132. data/spec/dummy/tmp/cache/34E/EE0/shard%2F635 +0 -0
  133. data/spec/dummy/tmp/cache/34E/EF0/shard%2F482 +1 -0
  134. data/spec/dummy/tmp/cache/34E/EF0/shard%2F644 +0 -0
  135. data/spec/dummy/tmp/cache/34E/F00/shard%2F491 +0 -0
  136. data/spec/dummy/tmp/cache/34E/F00/shard%2F734 +1 -0
  137. data/spec/dummy/tmp/cache/34E/F40/shard%2F932 +0 -0
  138. data/spec/dummy/tmp/cache/34E/F50/shard%2F941 +0 -0
  139. data/spec/dummy/tmp/cache/34F/E80/shard%2F249 +0 -0
  140. data/spec/dummy/tmp/cache/34F/EA0/shard%2F267 +0 -0
  141. data/spec/dummy/tmp/cache/34F/EB0/shard%2F276 +0 -0
  142. data/spec/dummy/tmp/cache/34F/ED0/shard%2F375 +0 -0
  143. data/spec/dummy/tmp/cache/34F/ED0/shard%2F456 +0 -0
  144. data/spec/dummy/tmp/cache/34F/EE0/shard%2F465 +0 -0
  145. data/spec/dummy/tmp/cache/34F/EF0/shard%2F636 +0 -0
  146. data/spec/dummy/tmp/cache/34F/F00/shard%2F645 +0 -0
  147. data/spec/dummy/tmp/cache/34F/F10/shard%2F573 +0 -0
  148. data/spec/dummy/tmp/cache/34F/F20/shard%2F906 +0 -0
  149. data/spec/dummy/tmp/cache/34F/F40/shard%2F681 +0 -0
  150. data/spec/dummy/tmp/cache/34F/F50/shard%2F771 +0 -0
  151. data/spec/dummy/tmp/cache/34F/F60/shard%2F780 +0 -0
  152. data/spec/dummy/tmp/cache/34F/F60/shard%2F861 +0 -0
  153. data/spec/dummy/tmp/cache/34F/F60/shard%2F942 +0 -0
  154. data/spec/dummy/tmp/cache/350/EC0/shard%2F358 +0 -0
  155. data/spec/dummy/tmp/cache/350/EE0/shard%2F376 +0 -0
  156. data/spec/dummy/tmp/cache/350/EE0/shard%2F457 +0 -0
  157. data/spec/dummy/tmp/cache/350/EE0/shard%2F538 +0 -0
  158. data/spec/dummy/tmp/cache/350/EE0/shard%2F619 +0 -0
  159. data/spec/dummy/tmp/cache/350/EF0/shard%2F385 +0 -0
  160. data/spec/dummy/tmp/cache/350/EF0/shard%2F466 +0 -0
  161. data/spec/dummy/tmp/cache/350/EF0/shard%2F709 +0 -0
  162. data/spec/dummy/tmp/cache/350/F00/shard%2F394 +0 -0
  163. data/spec/dummy/tmp/cache/350/F20/shard%2F574 +0 -0
  164. data/spec/dummy/tmp/cache/350/F20/shard%2F736 +0 -0
  165. data/spec/dummy/tmp/cache/350/F30/shard%2F664 +0 -0
  166. data/spec/dummy/tmp/cache/350/F30/shard%2F745 +0 -0
  167. data/spec/dummy/tmp/cache/350/F50/shard%2F763 +0 -0
  168. data/spec/dummy/tmp/cache/350/F60/shard%2F772 +0 -0
  169. data/spec/dummy/tmp/cache/350/F70/shard%2F781 +0 -0
  170. data/spec/dummy/tmp/cache/350/F70/shard%2F862 +0 -0
  171. data/spec/dummy/tmp/cache/351/ED0/shard%2F359 +0 -0
  172. data/spec/dummy/tmp/cache/351/EF0/shard%2F296 +0 -0
  173. data/spec/dummy/tmp/cache/351/F00/shard%2F386 +0 -0
  174. data/spec/dummy/tmp/cache/351/F10/shard%2F476 +0 -0
  175. data/spec/dummy/tmp/cache/351/F10/shard%2F557 +0 -0
  176. data/spec/dummy/tmp/cache/351/F20/shard%2F485 +0 -0
  177. data/spec/dummy/tmp/cache/351/F30/shard%2F494 +0 -0
  178. data/spec/dummy/tmp/cache/351/F30/shard%2F737 +0 -0
  179. data/spec/dummy/tmp/cache/351/F40/shard%2F665 +0 -0
  180. data/spec/dummy/tmp/cache/351/F40/shard%2F746 +0 -0
  181. data/spec/dummy/tmp/cache/351/F70/shard%2F935 +0 -0
  182. data/spec/dummy/tmp/cache/352/F00/shard%2F297 +0 -0
  183. data/spec/dummy/tmp/cache/352/F00/shard%2F378 +0 -0
  184. data/spec/dummy/tmp/cache/352/F00/shard%2F459 +0 -0
  185. data/spec/dummy/tmp/cache/352/F10/shard%2F468 +1 -0
  186. data/spec/dummy/tmp/cache/352/F20/shard%2F639 +1 -0
  187. data/spec/dummy/tmp/cache/352/F30/shard%2F486 +0 -0
  188. data/spec/dummy/tmp/cache/352/F50/shard%2F585 +0 -0
  189. data/spec/dummy/tmp/cache/352/F50/shard%2F909 +0 -0
  190. data/spec/dummy/tmp/cache/352/F60/shard%2F594 +0 -0
  191. data/spec/dummy/tmp/cache/352/F70/shard%2F684 +0 -0
  192. data/spec/dummy/tmp/cache/352/F80/shard%2F774 +0 -0
  193. data/spec/dummy/tmp/cache/352/F80/shard%2F936 +0 -0
  194. data/spec/dummy/tmp/cache/352/F90/shard%2F783 +0 -0
  195. data/spec/dummy/tmp/cache/352/F90/shard%2F864 +0 -0
  196. data/spec/dummy/tmp/cache/352/F90/shard%2F945 +1 -0
  197. data/spec/dummy/tmp/cache/352/FA0/shard%2F873 +0 -0
  198. data/spec/dummy/tmp/cache/352/FC0/shard%2F972 +0 -0
  199. data/spec/dummy/tmp/cache/353/F50/shard%2F577 +1 -0
  200. data/spec/dummy/tmp/cache/353/F50/shard%2F739 +0 -0
  201. data/spec/dummy/tmp/cache/353/F60/shard%2F748 +0 -0
  202. data/spec/dummy/tmp/cache/353/F70/shard%2F595 +0 -0
  203. data/spec/dummy/tmp/cache/353/F90/shard%2F775 +0 -0
  204. data/spec/dummy/tmp/cache/353/FA0/shard%2F784 +0 -0
  205. data/spec/dummy/tmp/cache/353/FD0/shard%2F892 +0 -0
  206. data/spec/dummy/tmp/cache/354/000/shard%2F992 +0 -0
  207. data/spec/dummy/tmp/cache/354/F30/shard%2F389 +1 -0
  208. data/spec/dummy/tmp/cache/354/F40/shard%2F479 +0 -0
  209. data/spec/dummy/tmp/cache/354/F50/shard%2F488 +0 -0
  210. data/spec/dummy/tmp/cache/354/F90/shard%2F929 +0 -0
  211. data/spec/dummy/tmp/cache/354/FA0/shard%2F938 +0 -0
  212. data/spec/dummy/tmp/cache/354/FD0/shard%2F965 +0 -0
  213. data/spec/dummy/tmp/cache/354/FE0/shard%2F893 +0 -0
  214. data/spec/dummy/tmp/cache/354/FF0/shard%2F983 +0 -0
  215. data/spec/dummy/tmp/cache/355/010/shard%2F993 +0 -0
  216. data/spec/dummy/tmp/cache/355/F60/shard%2F489 +0 -0
  217. data/spec/dummy/tmp/cache/355/F80/shard%2F588 +0 -0
  218. data/spec/dummy/tmp/cache/355/F90/shard%2F678 +0 -0
  219. data/spec/dummy/tmp/cache/355/FA0/shard%2F687 +0 -0
  220. data/spec/dummy/tmp/cache/355/FB0/shard%2F777 +1 -0
  221. data/spec/dummy/tmp/cache/355/FB0/shard%2F858 +0 -0
  222. data/spec/dummy/tmp/cache/355/FB0/shard%2F939 +0 -0
  223. data/spec/dummy/tmp/cache/355/FD0/shard%2F795 +0 -0
  224. data/spec/dummy/tmp/cache/355/FD0/shard%2F876 +0 -0
  225. data/spec/dummy/tmp/cache/355/FE0/shard%2F966 +0 -0
  226. data/spec/dummy/tmp/cache/356/000/shard%2F895 +1 -0
  227. data/spec/dummy/tmp/cache/356/FA0/shard%2F679 +0 -0
  228. data/spec/dummy/tmp/cache/356/FB0/shard%2F688 +0 -0
  229. data/spec/dummy/tmp/cache/356/FC0/shard%2F859 +0 -0
  230. data/spec/dummy/tmp/cache/356/FE0/shard%2F796 +0 -0
  231. data/spec/dummy/tmp/cache/356/FE0/shard%2F877 +0 -0
  232. data/spec/dummy/tmp/cache/357/020/shard%2F986 +0 -0
  233. data/spec/dummy/tmp/cache/357/FC0/shard%2F689 +1 -0
  234. data/spec/dummy/tmp/cache/358/000/shard%2F879 +0 -0
  235. data/spec/dummy/tmp/cache/358/FF0/shard%2F789 +0 -0
  236. data/spec/dummy/tmp/cache/372/470/shard%2F1010 +0 -0
  237. data/spec/dummy/tmp/cache/373/4A0/shard%2F1110 +0 -0
  238. data/spec/dummy/tmp/cache/374/490/shard%2F1012 +1 -0
  239. data/spec/dummy/tmp/cache/375/4C0/shard%2F2003 +1 -0
  240. data/spec/dummy/tmp/cache/375/510/shard%2F1400 +0 -0
  241. data/spec/dummy/tmp/cache/376/4E0/shard%2F1041 +0 -0
  242. data/spec/dummy/tmp/cache/376/4E0/shard%2F1203 +0 -0
  243. data/spec/dummy/tmp/cache/376/4F0/shard%2F1212 +0 -0
  244. data/spec/dummy/tmp/cache/376/500/shard%2F1221 +0 -0
  245. data/spec/dummy/tmp/cache/377/4C0/shard%2F1015 +0 -0
  246. data/spec/dummy/tmp/cache/377/500/shard%2F1213 +0 -0
  247. data/spec/dummy/tmp/cache/377/530/shard%2F1240 +0 -0
  248. data/spec/dummy/tmp/cache/377/530/shard%2F1321 +0 -0
  249. data/spec/dummy/tmp/cache/377/530/shard%2F1402 +0 -0
  250. data/spec/dummy/tmp/cache/378/4E0/shard%2F1106 +0 -0
  251. data/spec/dummy/tmp/cache/378/510/shard%2F1133 +0 -0
  252. data/spec/dummy/tmp/cache/378/520/shard%2F1142 +0 -0
  253. data/spec/dummy/tmp/cache/378/530/shard%2F1313 +0 -0
  254. data/spec/dummy/tmp/cache/378/540/shard%2F1241 +0 -0
  255. data/spec/dummy/tmp/cache/378/540/shard%2F1403 +0 -0
  256. data/spec/dummy/tmp/cache/378/550/shard%2F1331 +0 -0
  257. data/spec/dummy/tmp/cache/378/560/shard%2F1340 +0 -0
  258. data/spec/dummy/tmp/cache/379/4F0/shard%2F1026 +0 -0
  259. data/spec/dummy/tmp/cache/379/500/shard%2F1035 +0 -0
  260. data/spec/dummy/tmp/cache/379/510/shard%2F1044 +0 -0
  261. data/spec/dummy/tmp/cache/379/520/shard%2F1134 +0 -0
  262. data/spec/dummy/tmp/cache/379/530/shard%2F1224 +0 -0
  263. data/spec/dummy/tmp/cache/379/550/shard%2F1080 +0 -0
  264. data/spec/dummy/tmp/cache/379/550/shard%2F1161 +0 -0
  265. data/spec/dummy/tmp/cache/379/550/shard%2F1404 +1 -0
  266. data/spec/dummy/tmp/cache/379/560/shard%2F1332 +0 -0
  267. data/spec/dummy/tmp/cache/379/570/shard%2F1260 +0 -0
  268. data/spec/dummy/tmp/cache/379/570/shard%2F1341 +0 -0
  269. data/spec/dummy/tmp/cache/379/5A0/shard%2F1611 +1 -0
  270. data/spec/dummy/tmp/cache/37A/4E0/shard%2F1009 +0 -0
  271. data/spec/dummy/tmp/cache/37A/4F0/shard%2F1018 +0 -0
  272. data/spec/dummy/tmp/cache/37A/500/shard%2F1027 +0 -0
  273. data/spec/dummy/tmp/cache/37A/510/shard%2F1117 +0 -0
  274. data/spec/dummy/tmp/cache/37A/520/shard%2F1045 +0 -0
  275. data/spec/dummy/tmp/cache/37A/570/shard%2F1252 +0 -0
  276. data/spec/dummy/tmp/cache/37A/580/shard%2F1261 +0 -0
  277. data/spec/dummy/tmp/cache/37A/5C0/shard%2F1702 +0 -0
  278. data/spec/dummy/tmp/cache/37A/5D0/shard%2F1711 +1 -0
  279. data/spec/dummy/tmp/cache/37B/500/shard%2F1019 +0 -0
  280. data/spec/dummy/tmp/cache/37B/510/shard%2F1028 +1 -0
  281. data/spec/dummy/tmp/cache/37B/510/shard%2F1109 +0 -0
  282. data/spec/dummy/tmp/cache/37B/540/shard%2F1136 +0 -0
  283. data/spec/dummy/tmp/cache/37B/580/shard%2F1253 +0 -0
  284. data/spec/dummy/tmp/cache/37B/590/shard%2F1181 +0 -0
  285. data/spec/dummy/tmp/cache/37B/5A0/shard%2F1190 +0 -0
  286. data/spec/dummy/tmp/cache/37B/5B0/shard%2F1523 +0 -0
  287. data/spec/dummy/tmp/cache/37B/5C0/shard%2F1370 +0 -0
  288. data/spec/dummy/tmp/cache/37B/600/shard%2F1811 +1 -0
  289. data/spec/dummy/tmp/cache/37C/530/shard%2F1038 +0 -0
  290. data/spec/dummy/tmp/cache/37C/550/shard%2F1137 +0 -0
  291. data/spec/dummy/tmp/cache/37C/560/shard%2F1065 +0 -0
  292. data/spec/dummy/tmp/cache/37C/580/shard%2F1164 +0 -0
  293. data/spec/dummy/tmp/cache/37C/590/shard%2F1092 +0 -0
  294. data/spec/dummy/tmp/cache/37C/590/shard%2F1335 +1 -0
  295. data/spec/dummy/tmp/cache/37C/5A0/shard%2F1182 +0 -0
  296. data/spec/dummy/tmp/cache/37C/5A0/shard%2F1263 +0 -0
  297. data/spec/dummy/tmp/cache/37C/5B0/shard%2F1191 +1 -0
  298. data/spec/dummy/tmp/cache/37C/5B0/shard%2F1434 +0 -0
  299. data/spec/dummy/tmp/cache/37C/5C0/shard%2F1605 +1 -0
  300. data/spec/dummy/tmp/cache/37C/5F0/shard%2F1470 +0 -0
  301. data/spec/dummy/tmp/cache/37C/620/shard%2F1821 +0 -0
  302. data/spec/dummy/tmp/cache/37C/620/shard%2F1902 +1 -0
  303. data/spec/dummy/tmp/cache/37C/640/shard%2F1920 +1 -0
  304. data/spec/dummy/tmp/cache/37D/540/shard%2F1039 +0 -0
  305. data/spec/dummy/tmp/cache/37D/560/shard%2F1057 +0 -0
  306. data/spec/dummy/tmp/cache/37D/590/shard%2F1246 +0 -0
  307. data/spec/dummy/tmp/cache/37D/590/shard%2F1408 +0 -0
  308. data/spec/dummy/tmp/cache/37D/5A0/shard%2F1093 +0 -0
  309. data/spec/dummy/tmp/cache/37D/5E0/shard%2F1372 +0 -0
  310. data/spec/dummy/tmp/cache/37D/5F0/shard%2F1381 +0 -0
  311. data/spec/dummy/tmp/cache/37D/610/shard%2F1642 +0 -0
  312. data/spec/dummy/tmp/cache/37D/610/shard%2F1804 +0 -0
  313. data/spec/dummy/tmp/cache/37E/570/shard%2F1058 +0 -0
  314. data/spec/dummy/tmp/cache/37E/570/shard%2F1139 +0 -0
  315. data/spec/dummy/tmp/cache/37E/580/shard%2F1229 +0 -0
  316. data/spec/dummy/tmp/cache/37E/5A0/shard%2F1247 +0 -0
  317. data/spec/dummy/tmp/cache/37E/5A0/shard%2F1409 +0 -0
  318. data/spec/dummy/tmp/cache/37E/5C0/shard%2F1346 +0 -0
  319. data/spec/dummy/tmp/cache/37E/5F0/shard%2F1292 +0 -0
  320. data/spec/dummy/tmp/cache/37E/5F0/shard%2F1373 +0 -0
  321. data/spec/dummy/tmp/cache/37E/5F0/shard%2F1535 +0 -0
  322. data/spec/dummy/tmp/cache/37E/600/shard%2F1382 +0 -0
  323. data/spec/dummy/tmp/cache/37E/620/shard%2F1805 +0 -0
  324. data/spec/dummy/tmp/cache/37E/640/shard%2F1661 +1 -0
  325. data/spec/dummy/tmp/cache/37F/5A0/shard%2F1158 +0 -0
  326. data/spec/dummy/tmp/cache/37F/5B0/shard%2F1167 +0 -0
  327. data/spec/dummy/tmp/cache/37F/5B0/shard%2F1248 +1 -0
  328. data/spec/dummy/tmp/cache/37F/5C0/shard%2F1095 +1 -0
  329. data/spec/dummy/tmp/cache/37F/5E0/shard%2F1275 +0 -0
  330. data/spec/dummy/tmp/cache/37F/5E0/shard%2F1437 +0 -0
  331. data/spec/dummy/tmp/cache/37F/600/shard%2F1455 +0 -0
  332. data/spec/dummy/tmp/cache/37F/600/shard%2F1536 +0 -0
  333. data/spec/dummy/tmp/cache/37F/610/shard%2F1464 +0 -0
  334. data/spec/dummy/tmp/cache/37F/620/shard%2F1473 +1 -0
  335. data/spec/dummy/tmp/cache/37F/630/shard%2F1482 +0 -0
  336. data/spec/dummy/tmp/cache/37F/640/shard%2F1491 +0 -0
  337. data/spec/dummy/tmp/cache/37F/640/shard%2F1653 +0 -0
  338. data/spec/dummy/tmp/cache/380/5C0/shard%2F1168 +0 -0
  339. data/spec/dummy/tmp/cache/380/5E0/shard%2F1429 +0 -0
  340. data/spec/dummy/tmp/cache/380/5F0/shard%2F1195 +0 -0
  341. data/spec/dummy/tmp/cache/380/5F0/shard%2F1276 +0 -0
  342. data/spec/dummy/tmp/cache/380/610/shard%2F1375 +0 -0
  343. data/spec/dummy/tmp/cache/380/620/shard%2F1384 +0 -0
  344. data/spec/dummy/tmp/cache/380/620/shard%2F1465 +0 -0
  345. data/spec/dummy/tmp/cache/380/640/shard%2F1645 +1 -0
  346. data/spec/dummy/tmp/cache/380/640/shard%2F1726 +1 -0
  347. data/spec/dummy/tmp/cache/380/650/shard%2F1492 +0 -0
  348. data/spec/dummy/tmp/cache/380/650/shard%2F1654 +0 -0
  349. data/spec/dummy/tmp/cache/380/660/shard%2F1906 +0 -0
  350. data/spec/dummy/tmp/cache/380/670/shard%2F1591 +0 -0
  351. data/spec/dummy/tmp/cache/380/670/shard%2F1753 +0 -0
  352. data/spec/dummy/tmp/cache/381/5F0/shard%2F1349 +0 -0
  353. data/spec/dummy/tmp/cache/381/600/shard%2F1196 +0 -0
  354. data/spec/dummy/tmp/cache/381/610/shard%2F1286 +0 -0
  355. data/spec/dummy/tmp/cache/381/620/shard%2F1295 +0 -0
  356. data/spec/dummy/tmp/cache/381/630/shard%2F1547 +1 -0
  357. data/spec/dummy/tmp/cache/381/650/shard%2F1565 +1 -0
  358. data/spec/dummy/tmp/cache/381/660/shard%2F1493 +1 -0
  359. data/spec/dummy/tmp/cache/381/670/shard%2F1745 +1 -0
  360. data/spec/dummy/tmp/cache/381/670/shard%2F1907 +0 -0
  361. data/spec/dummy/tmp/cache/381/680/shard%2F1592 +0 -0
  362. data/spec/dummy/tmp/cache/381/680/shard%2F1754 +0 -0
  363. data/spec/dummy/tmp/cache/381/6C0/shard%2F1790 +1 -0
  364. data/spec/dummy/tmp/cache/382/5F0/shard%2F1098 +0 -0
  365. data/spec/dummy/tmp/cache/382/600/shard%2F1269 +0 -0
  366. data/spec/dummy/tmp/cache/382/610/shard%2F1278 +1 -0
  367. data/spec/dummy/tmp/cache/382/620/shard%2F1287 +0 -0
  368. data/spec/dummy/tmp/cache/382/630/shard%2F1296 +0 -0
  369. data/spec/dummy/tmp/cache/382/640/shard%2F1467 +1 -0
  370. data/spec/dummy/tmp/cache/382/650/shard%2F1557 +0 -0
  371. data/spec/dummy/tmp/cache/382/690/shard%2F1674 +1 -0
  372. data/spec/dummy/tmp/cache/382/6A0/shard%2F1845 +1 -0
  373. data/spec/dummy/tmp/cache/382/6D0/shard%2F1953 +1 -0
  374. data/spec/dummy/tmp/cache/382/700/shard%2F1980 +0 -0
  375. data/spec/dummy/tmp/cache/383/610/shard%2F1189 +0 -0
  376. data/spec/dummy/tmp/cache/383/630/shard%2F1369 +0 -0
  377. data/spec/dummy/tmp/cache/383/640/shard%2F1378 +0 -0
  378. data/spec/dummy/tmp/cache/383/660/shard%2F1639 +1 -0
  379. data/spec/dummy/tmp/cache/383/680/shard%2F1576 +1 -0
  380. data/spec/dummy/tmp/cache/383/690/shard%2F1828 +1 -0
  381. data/spec/dummy/tmp/cache/383/6C0/shard%2F1774 +1 -0
  382. data/spec/dummy/tmp/cache/383/700/shard%2F1891 +0 -0
  383. data/spec/dummy/tmp/cache/383/700/shard%2F1972 +1 -0
  384. data/spec/dummy/tmp/cache/384/6B0/shard%2F1838 +0 -0
  385. data/spec/dummy/tmp/cache/384/700/shard%2F1883 +1 -0
  386. data/spec/dummy/tmp/cache/384/710/shard%2F1892 +0 -0
  387. data/spec/dummy/tmp/cache/386/690/shard%2F1399 +0 -0
  388. data/spec/dummy/tmp/cache/386/6D0/shard%2F1759 +1 -0
  389. data/spec/dummy/tmp/cache/386/6F0/shard%2F1858 +1 -0
  390. data/spec/dummy/tmp/cache/386/750/shard%2F1993 +1 -0
  391. data/spec/dummy/tmp/cache/388/710/shard%2F1698 +1 -0
  392. data/spec/dummy/tmp/cache/3A3/EA0/shard%2F10101 +1 -0
  393. data/spec/dummy/tmp/cache/3A3/EC0/shard%2F11010 +1 -0
  394. data/spec/dummy/tmp/cache/3A6/EB0/shard%2F10005 +1 -0
  395. data/spec/dummy/tmp/cache/3A6/ED0/shard%2F10104 +1 -0
  396. data/spec/dummy/tmp/cache/3A7/EC0/shard%2F10006 +1 -0
  397. data/spec/dummy/tmp/cache/3A7/F10/shard%2F10051 +1 -0
  398. data/spec/dummy/tmp/cache/3A8/F50/shard%2F10322 +1 -0
  399. data/spec/dummy/tmp/cache/3A9/F10/shard%2F10035 +1 -0
  400. data/spec/dummy/tmp/cache/3A9/F90/shard%2F11403 +1 -0
  401. data/spec/dummy/tmp/cache/3AA/F40/shard%2F10216 +1 -0
  402. data/spec/dummy/tmp/cache/3AA/FB0/shard%2F11332 +1 -0
  403. data/spec/dummy/tmp/cache/3AB/030/shard%2F11720 +1 -0
  404. data/spec/dummy/tmp/cache/3AB/F10/shard%2F10019 +1 -0
  405. data/spec/dummy/tmp/cache/3AB/F40/shard%2F10127 +1 -0
  406. data/spec/dummy/tmp/cache/3AB/F50/shard%2F11027 +1 -0
  407. data/spec/dummy/tmp/cache/3AB/F80/shard%2F10244 +1 -0
  408. data/spec/dummy/tmp/cache/3AC/020/shard%2F10731 +1 -0
  409. data/spec/dummy/tmp/cache/3AC/020/shard%2F11541 +1 -0
  410. data/spec/dummy/tmp/cache/3AC/020/shard%2F11703 +1 -0
  411. data/spec/dummy/tmp/cache/3AC/F80/shard%2F10074 +1 -0
  412. data/spec/dummy/tmp/cache/3AC/F90/shard%2F10083 +1 -0
  413. data/spec/dummy/tmp/cache/3AC/FA0/shard%2F10173 +1 -0
  414. data/spec/dummy/tmp/cache/3AC/FF0/shard%2F11190 +1 -0
  415. data/spec/dummy/tmp/cache/3AD/020/shard%2F10480 +1 -0
  416. data/spec/dummy/tmp/cache/3AD/F70/shard%2F10138 +1 -0
  417. data/spec/dummy/tmp/cache/3AE/050/shard%2F11471 +1 -0
  418. data/spec/dummy/tmp/cache/3AE/080/shard%2F11822 +1 -0
  419. data/spec/dummy/tmp/cache/3AE/F90/shard%2F10067 +1 -0
  420. data/spec/dummy/tmp/cache/3AE/FF0/shard%2F11093 +1 -0
  421. data/spec/dummy/tmp/cache/3AF/070/shard%2F11643 +1 -0
  422. data/spec/dummy/tmp/cache/3AF/070/shard%2F11805 +1 -0
  423. data/spec/dummy/tmp/cache/3AF/FA0/shard%2F10068 +1 -0
  424. data/spec/dummy/tmp/cache/3AF/FF0/shard%2F11247 +1 -0
  425. data/spec/dummy/tmp/cache/3B0/040/shard%2F10636 +1 -0
  426. data/spec/dummy/tmp/cache/3B0/060/shard%2F11626 +1 -0
  427. data/spec/dummy/tmp/cache/3B0/0B0/shard%2F10942 +1 -0
  428. data/spec/dummy/tmp/cache/3B0/FC0/shard%2F10159 +1 -0
  429. data/spec/dummy/tmp/cache/3B1/040/shard%2F10466 +1 -0
  430. data/spec/dummy/tmp/cache/3B1/040/shard%2F11276 +1 -0
  431. data/spec/dummy/tmp/cache/3B1/050/shard%2F11609 +1 -0
  432. data/spec/dummy/tmp/cache/3B1/070/shard%2F10574 +1 -0
  433. data/spec/dummy/tmp/cache/3B1/070/shard%2F11465 +1 -0
  434. data/spec/dummy/tmp/cache/3B1/0A0/shard%2F11492 +1 -0
  435. data/spec/dummy/tmp/cache/3B1/0A0/shard%2F11654 +1 -0
  436. data/spec/dummy/tmp/cache/3B1/0E0/shard%2F11771 +1 -0
  437. data/spec/dummy/tmp/cache/3B2/050/shard%2F10386 +1 -0
  438. data/spec/dummy/tmp/cache/3B2/0C0/shard%2F11907 +1 -0
  439. data/spec/dummy/tmp/cache/3B2/0D0/shard%2F11592 +1 -0
  440. data/spec/dummy/tmp/cache/3B2/0D0/shard%2F11754 +1 -0
  441. data/spec/dummy/tmp/cache/3B2/110/shard%2F11952 +1 -0
  442. data/spec/dummy/tmp/cache/3B3/0C0/shard%2F11575 +1 -0
  443. data/spec/dummy/tmp/cache/3B3/0C0/shard%2F11737 +1 -0
  444. data/spec/dummy/tmp/cache/3B4/0B0/shard%2F11558 +1 -0
  445. data/spec/dummy/tmp/cache/3B4/0E0/shard%2F10775 +1 -0
  446. data/spec/dummy/tmp/cache/3B4/130/shard%2F11873 +1 -0
  447. data/spec/dummy/tmp/cache/3B4/160/shard%2F11981 +1 -0
  448. data/spec/dummy/tmp/cache/3B5/120/shard%2F11856 +1 -0
  449. data/spec/dummy/tmp/cache/3B5/130/shard%2F10893 +1 -0
  450. data/spec/dummy/tmp/cache/3B5/150/shard%2F11964 +1 -0
  451. data/spec/dummy/tmp/cache/3B5/160/shard%2F11892 +1 -0
  452. data/spec/dummy/tmp/cache/3B6/110/shard%2F11839 +1 -0
  453. data/spec/dummy/tmp/cache/3B6/120/shard%2F11686 +1 -0
  454. data/spec/dummy/tmp/cache/3B7/100/shard%2F10688 +1 -0
  455. data/spec/dummy/tmp/cache/3B7/110/shard%2F11669 +1 -0
  456. data/spec/dummy/tmp/cache/3B9/170/shard%2F11788 +1 -0
  457. data/spec/dummy/tmp/cache/3BC/1F0/shard%2F11998 +1 -0
  458. data/spec/dummy/tmp/cache/4B7/9C0/shard_12%3Akey +1 -0
  459. data/spec/dummy/tmp/cache/4B8/A30/shard_13%3Akey +1 -0
  460. data/spec/dummy/tmp/cache/4B9/AA0/shard_14%3Akey +1 -0
  461. data/spec/dummy/tmp/cache/4BA/B50/shard_51%3Akey +1 -0
  462. data/spec/dummy/tmp/cache/4BB/B90/shard_25%3Akey +1 -0
  463. data/spec/dummy/tmp/cache/4BB/BC0/shard_52%3Akey +1 -0
  464. data/spec/dummy/tmp/cache/4BC/C00/shard_26%3Akey +1 -0
  465. data/spec/dummy/tmp/cache/4BC/C50/shard_71%3Akey +1 -0
  466. data/spec/dummy/tmp/cache/4BD/CC0/shard_72%3Akey +1 -0
  467. data/spec/dummy/tmp/cache/4BD/CE0/shard_90%3Akey +1 -0
  468. data/spec/dummy/tmp/cache/4BE/D00/shard_46%3Akey +1 -0
  469. data/spec/dummy/tmp/cache/4BF/D70/shard_47%3Akey +1 -0
  470. data/spec/dummy/tmp/cache/4C0/DF0/shard_57%3Akey +1 -0
  471. data/spec/dummy/tmp/cache/4C0/E20/shard_84%3Akey +1 -0
  472. data/spec/dummy/tmp/cache/4C1/E60/shard_58%3Akey +1 -0
  473. data/spec/dummy/tmp/cache/4C1/E90/shard_85%3Akey +1 -0
  474. data/spec/dummy/tmp/cache/4C5/050/shard_89%3Akey +1 -0
  475. data/spec/dummy/tmp/cache/4E5/B10/shard_100%3Akey +1 -0
  476. data/spec/dummy/tmp/cache/4E6/B80/shard_101%3Akey +1 -0
  477. data/spec/dummy/tmp/cache/4E8/CA0/shard_220%3Akey +1 -0
  478. data/spec/dummy/tmp/cache/4E9/D10/shard_221%3Akey +1 -0
  479. data/spec/dummy/tmp/cache/4EA/D90/shard_150%3Akey +1 -0
  480. data/spec/dummy/tmp/cache/4EA/DC0/shard_420%3Akey +1 -0
  481. data/spec/dummy/tmp/cache/4EB/E00/shard_151%3Akey +1 -0
  482. data/spec/dummy/tmp/cache/4ED/EE0/shard_153%3Akey +1 -0
  483. data/spec/dummy/tmp/cache/4EE/F50/shard_154%3Akey +1 -0
  484. data/spec/dummy/tmp/cache/4EE/F80/shard_181%3Akey +1 -0
  485. data/spec/dummy/tmp/cache/4EE/F90/shard_352%3Akey +1 -0
  486. data/spec/dummy/tmp/cache/4EF/000/shard_272%3Akey +1 -0
  487. data/spec/dummy/tmp/cache/4EF/000/shard_353%3Akey +1 -0
  488. data/spec/dummy/tmp/cache/4EF/000/shard_515%3Akey +1 -0
  489. data/spec/dummy/tmp/cache/4EF/030/shard_380%3Akey +1 -0
  490. data/spec/dummy/tmp/cache/4EF/040/shard_632%3Akey +1 -0
  491. data/spec/dummy/tmp/cache/4EF/FF0/shard_182%3Akey +1 -0
  492. data/spec/dummy/tmp/cache/4F0/010/shard_138%3Akey +1 -0
  493. data/spec/dummy/tmp/cache/4F0/070/shard_273%3Akey +1 -0
  494. data/spec/dummy/tmp/cache/4F0/070/shard_516%3Akey +1 -0
  495. data/spec/dummy/tmp/cache/4F0/0A0/shard_381%3Akey +1 -0
  496. data/spec/dummy/tmp/cache/4F0/0B0/shard_633%3Akey +1 -0
  497. data/spec/dummy/tmp/cache/4F1/080/shard_139%3Akey +1 -0
  498. data/spec/dummy/tmp/cache/4F1/140/shard_814%3Akey +1 -0
  499. data/spec/dummy/tmp/cache/4F2/120/shard_167%3Akey +1 -0
  500. data/spec/dummy/tmp/cache/4F2/130/shard_419%3Akey +1 -0
  501. data/spec/dummy/tmp/cache/4F2/1B0/shard_815%3Akey +1 -0
  502. data/spec/dummy/tmp/cache/4F2/1E0/shard_923%3Akey +1 -0
  503. data/spec/dummy/tmp/cache/4F3/190/shard_168%3Akey +1 -0
  504. data/spec/dummy/tmp/cache/4F3/250/shard_924%3Akey +1 -0
  505. data/spec/dummy/tmp/cache/4F5/320/shard_755%3Akey +1 -0
  506. data/spec/dummy/tmp/cache/4F6/360/shard_567%3Akey +1 -0
  507. data/spec/dummy/tmp/cache/4F6/390/shard_756%3Akey +1 -0
  508. data/spec/dummy/tmp/cache/4F7/3D0/shard_568%3Akey +1 -0
  509. data/spec/dummy/tmp/cache/4F7/3E0/shard_658%3Akey +1 -0
  510. data/spec/dummy/tmp/cache/4F8/450/shard_659%3Akey +1 -0
  511. data/spec/dummy/tmp/cache/4F8/4C0/shard_884%3Akey +1 -0
  512. data/spec/dummy/tmp/cache/4F9/530/shard_885%3Akey +1 -0
  513. data/spec/dummy/tmp/cache/4FA/5A0/shard_967%3Akey +1 -0
  514. data/spec/dummy/tmp/cache/4FB/610/shard_968%3Akey +1 -0
  515. data/spec/dummy/tmp/cache/518/1C0/shard_1111%3Akey +1 -0
  516. data/spec/dummy/tmp/cache/519/230/shard_1112%3Akey +1 -0
  517. data/spec/dummy/tmp/cache/51A/2C0/shard_1050%3Akey +1 -0
  518. data/spec/dummy/tmp/cache/51B/3A0/shard_1600%3Akey +1 -0
  519. data/spec/dummy/tmp/cache/51C/410/shard_1601%3Akey +1 -0
  520. data/spec/dummy/tmp/cache/51D/4B0/shard_1710%3Akey +1 -0
  521. data/spec/dummy/tmp/cache/51E/4E0/shard_1351%3Akey +1 -0
  522. data/spec/dummy/tmp/cache/51F/550/shard_1352%3Akey +1 -0
  523. data/spec/dummy/tmp/cache/51F/570/shard_1532%3Akey +1 -0
  524. data/spec/dummy/tmp/cache/520/580/shard_1155%3Akey +1 -0
  525. data/spec/dummy/tmp/cache/520/5A0/shard_1416%3Akey +1 -0
  526. data/spec/dummy/tmp/cache/520/5D0/shard_1443%3Akey +1 -0
  527. data/spec/dummy/tmp/cache/520/5E0/shard_1452%3Akey +1 -0
  528. data/spec/dummy/tmp/cache/520/5E0/shard_1533%3Akey +1 -0
  529. data/spec/dummy/tmp/cache/520/5F0/shard_1461%3Akey +1 -0
  530. data/spec/dummy/tmp/cache/520/600/shard_1551%3Akey +1 -0
  531. data/spec/dummy/tmp/cache/521/5F0/shard_1156%3Akey +1 -0
  532. data/spec/dummy/tmp/cache/521/610/shard_1417%3Akey +1 -0
  533. data/spec/dummy/tmp/cache/521/620/shard_1507%3Akey +1 -0
  534. data/spec/dummy/tmp/cache/521/630/shard_1516%3Akey +1 -0
  535. data/spec/dummy/tmp/cache/521/640/shard_1444%3Akey +1 -0
  536. data/spec/dummy/tmp/cache/521/650/shard_1453%3Akey +1 -0
  537. data/spec/dummy/tmp/cache/521/660/shard_1462%3Akey +1 -0
  538. data/spec/dummy/tmp/cache/521/670/shard_1552%3Akey +1 -0
  539. data/spec/dummy/tmp/cache/521/680/shard_1480%3Akey +1 -0
  540. data/spec/dummy/tmp/cache/521/690/shard_1813%3Akey +1 -0
  541. data/spec/dummy/tmp/cache/522/630/shard_1049%3Akey +1 -0
  542. data/spec/dummy/tmp/cache/522/690/shard_1508%3Akey +1 -0
  543. data/spec/dummy/tmp/cache/522/6A0/shard_1517%3Akey +1 -0
  544. data/spec/dummy/tmp/cache/522/700/shard_1571%3Akey +1 -0
  545. data/spec/dummy/tmp/cache/522/700/shard_1733%3Akey +1 -0
  546. data/spec/dummy/tmp/cache/522/700/shard_1814%3Akey +1 -0
  547. data/spec/dummy/tmp/cache/522/740/shard_1850%3Akey +1 -0
  548. data/spec/dummy/tmp/cache/523/6F0/shard_1257%3Akey +1 -0
  549. data/spec/dummy/tmp/cache/523/730/shard_1617%3Akey +1 -0
  550. data/spec/dummy/tmp/cache/523/770/shard_1572%3Akey +1 -0
  551. data/spec/dummy/tmp/cache/523/770/shard_1734%3Akey +1 -0
  552. data/spec/dummy/tmp/cache/523/7B0/shard_1851%3Akey +1 -0
  553. data/spec/dummy/tmp/cache/524/760/shard_1258%3Akey +1 -0
  554. data/spec/dummy/tmp/cache/524/7A0/shard_1537%3Akey +1 -0
  555. data/spec/dummy/tmp/cache/524/7A0/shard_1618%3Akey +1 -0
  556. data/spec/dummy/tmp/cache/524/7C0/shard_1636%3Akey +1 -0
  557. data/spec/dummy/tmp/cache/524/820/shard_1690%3Akey +1 -0
  558. data/spec/dummy/tmp/cache/525/810/shard_1538%3Akey +1 -0
  559. data/spec/dummy/tmp/cache/525/820/shard_1709%3Akey +1 -0
  560. data/spec/dummy/tmp/cache/525/830/shard_1637%3Akey +1 -0
  561. data/spec/dummy/tmp/cache/525/870/shard_1835%3Akey +1 -0
  562. data/spec/dummy/tmp/cache/525/8A0/shard_1862%3Akey +1 -0
  563. data/spec/dummy/tmp/cache/526/8D0/shard_1665%3Akey +1 -0
  564. data/spec/dummy/tmp/cache/526/8E0/shard_1755%3Akey +1 -0
  565. data/spec/dummy/tmp/cache/526/8E0/shard_1836%3Akey +1 -0
  566. data/spec/dummy/tmp/cache/526/910/shard_1863%3Akey +1 -0
  567. data/spec/dummy/tmp/cache/527/8F0/shard_1297%3Akey +1 -0
  568. data/spec/dummy/tmp/cache/527/920/shard_1486%3Akey +1 -0
  569. data/spec/dummy/tmp/cache/527/930/shard_1738%3Akey +1 -0
  570. data/spec/dummy/tmp/cache/527/940/shard_1585%3Akey +1 -0
  571. data/spec/dummy/tmp/cache/527/940/shard_1666%3Akey +1 -0
  572. data/spec/dummy/tmp/cache/527/950/shard_1756%3Akey +1 -0
  573. data/spec/dummy/tmp/cache/527/990/shard_1792%3Akey +1 -0
  574. data/spec/dummy/tmp/cache/528/960/shard_1298%3Akey +1 -0
  575. data/spec/dummy/tmp/cache/528/990/shard_1487%3Akey +1 -0
  576. data/spec/dummy/tmp/cache/528/9A0/shard_1739%3Akey +1 -0
  577. data/spec/dummy/tmp/cache/528/9B0/shard_1586%3Akey +1 -0
  578. data/spec/dummy/tmp/cache/528/9E0/shard_1775%3Akey +1 -0
  579. data/spec/dummy/tmp/cache/528/A00/shard_1793%3Akey +1 -0
  580. data/spec/dummy/tmp/cache/529/9F0/shard_1479%3Akey +1 -0
  581. data/spec/dummy/tmp/cache/529/A30/shard_1677%3Akey +1 -0
  582. data/spec/dummy/tmp/cache/529/A50/shard_1776%3Akey +1 -0
  583. data/spec/dummy/tmp/cache/529/A80/shard_1884%3Akey +1 -0
  584. data/spec/dummy/tmp/cache/52A/A80/shard_1498%3Akey +1 -0
  585. data/spec/dummy/tmp/cache/52A/AA0/shard_1678%3Akey +1 -0
  586. data/spec/dummy/tmp/cache/52A/AF0/shard_1885%3Akey +1 -0
  587. data/spec/dummy/tmp/cache/52B/AF0/shard_1499%3Akey +1 -0
  588. data/spec/dummy/tmp/cache/52C/B90/shard_1689%3Akey +1 -0
  589. data/spec/dummy/tmp/cache/52E/CC0/shard_1898%3Akey +1 -0
  590. data/spec/dummy/tmp/cache/52F/D30/shard_1899%3Akey +1 -0
  591. data/spec/lib/action_controller/caching_spec.rb +49 -0
  592. data/spec/lib/active_record/association_spec.rb +41 -0
  593. data/spec/lib/active_record/attribute_methods_spec.rb +6 -0
  594. data/spec/lib/active_record/base_spec.rb +20 -4
  595. data/spec/lib/active_record/calculations_spec.rb +117 -0
  596. data/spec/lib/active_record/finder_methods_spec.rb +22 -0
  597. data/spec/lib/active_record/query_cache_spec.rb +288 -0
  598. data/spec/lib/active_record/query_methods_spec.rb +33 -0
  599. data/spec/lib/active_record/relation_spec.rb +9 -0
  600. data/spec/lib/active_record/spawn_methods_spec.rb +43 -0
  601. data/spec/lib/database_server_spec.rb +73 -14
  602. data/spec/lib/default_shard_spec.rb +24 -0
  603. data/spec/lib/r_spec_helper_spec.rb +20 -0
  604. data/spec/lib/rails_spec.rb +31 -0
  605. data/spec/lib/shackles_spec.rb +68 -14
  606. data/spec/models/shard_spec.rb +30 -9
  607. metadata +1132 -94
  608. data/lib/switchman/cache_extensions.rb +0 -12
  609. data/spec/dummy/tmp/cache/2E2/830/shard%2F2 +0 -0
  610. data/spec/dummy/tmp/cache/2E3/840/shard%2F3 +0 -0
  611. data/spec/dummy/tmp/cache/313/970/shard%2F30 +0 -0
  612. data/spec/dummy/tmp/cache/314/980/shard%2F31 +0 -0
  613. data/spec/dummy/tmp/cache/316/9D0/shard%2F60 +0 -0
  614. data/spec/dummy/tmp/cache/317/990/shard%2F16 +0 -0
  615. data/spec/dummy/tmp/cache/318/9A0/shard%2F17 +0 -0
  616. data/spec/dummy/tmp/cache/318/9D0/shard%2F44 +0 -0
  617. data/spec/dummy/tmp/cache/319/9E0/shard%2F45 +0 -0
  618. data/spec/dummy/tmp/cache/319/A30/shard%2F90 +0 -0
  619. data/spec/dummy/tmp/cache/321/AA0/shard%2F89 +0 -0
  620. data/spec/dummy/tmp/cache/322/AC0/shard%2F99 +0 -1
  621. data/spec/dummy/tmp/cache/345/DB0/shard%2F131 +0 -1
  622. data/spec/dummy/tmp/cache/346/DB0/shard%2F123 +0 -0
  623. data/spec/dummy/tmp/cache/346/DD0/shard%2F222 +0 -1
  624. data/spec/dummy/tmp/cache/346/DE0/shard%2F150 +0 -0
  625. data/spec/dummy/tmp/cache/346/DF0/shard%2F240 +0 -1
  626. data/spec/dummy/tmp/cache/347/DA0/shard%2F106 +0 -1
  627. data/spec/dummy/tmp/cache/347/DC0/shard%2F124 +0 -0
  628. data/spec/dummy/tmp/cache/347/DC0/shard%2F205 +0 -1
  629. data/spec/dummy/tmp/cache/347/E10/shard%2F250 +0 -1
  630. data/spec/dummy/tmp/cache/348/DF0/shard%2F143 +0 -1
  631. data/spec/dummy/tmp/cache/348/DF0/shard%2F224 +0 -1
  632. data/spec/dummy/tmp/cache/348/E10/shard%2F161 +0 -1
  633. data/spec/dummy/tmp/cache/349/DD0/shard%2F117 +0 -1
  634. data/spec/dummy/tmp/cache/349/E40/shard%2F180 +0 -1
  635. data/spec/dummy/tmp/cache/34A/DF0/shard%2F208 +0 -1
  636. data/spec/dummy/tmp/cache/34A/E10/shard%2F145 +0 -1
  637. data/spec/dummy/tmp/cache/34A/E60/shard%2F190 +0 -1
  638. data/spec/dummy/tmp/cache/34B/E30/shard%2F155 +0 -1
  639. data/spec/dummy/tmp/cache/34D/E30/shard%2F139 +0 -0
  640. data/spec/dummy/tmp/cache/34E/E50/shard%2F149 +0 -0
  641. data/spec/dummy/tmp/cache/353/EF0/shard%2F199 +0 -1
  642. data/spec/lib/cache_extensions_spec.rb +0 -27
@@ -96,6 +96,15 @@ module Switchman
96
96
  relation.where_values.detect{|v| v.left.name == "id"}.right.should == [a1.local_id, a2.global_id]
97
97
  end
98
98
 
99
+ it "should properly set up a cross-shard-category query" do
100
+ @shard1.activate(:mirror_universe) do
101
+ mirror_user = MirrorUser.create!
102
+ relation = mirror_user.association(:user).scoped
103
+ relation.shard_value.should == Shard.default
104
+ relation.where_values.first.right.should == mirror_user.global_id
105
+ end
106
+ end
107
+
99
108
  describe "multishard associations" do
100
109
  it "should group has_many associations over associated_shards" do
101
110
  @shard1.activate{ Appendage.create!(:user_id => @user1, :value => 1) }
@@ -181,6 +190,38 @@ module Switchman
181
190
  @user1.digits.has_no_value.shard(@shard2).to_a.count.should == 0
182
191
  end
183
192
 
193
+ describe "unsharded associations" do
194
+ it "should be able to create an unsharded new record through a collection" do
195
+ root = @user2.roots.create!
196
+ root.reload
197
+ root.shard.should == Shard.default
198
+ root.user_id.should == @user2.global_id
199
+ root.user.should == @user2
200
+ end
201
+ end
202
+
203
+ describe "belongs_to associations" do
204
+ it "should identify an implied shard value based on the foreign id" do
205
+ @shard1.activate do
206
+ @appendage = Appendage.create!(:user_id => @user2.global_id)
207
+ @appendage.reload.user.should == @user2
208
+ end
209
+ end
210
+
211
+ it "should translate foreign keys when replacing the record" do
212
+ a = @shard2.activate { Appendage.create! }
213
+ copy = a.dup
214
+ @shard1.activate do
215
+ copy.user = @user1
216
+ copy.shard = @user1.shard
217
+ copy.save!
218
+ copy.reload
219
+ copy.user.shard.should == @shard1
220
+ copy.user.should == @user1
221
+ end
222
+ end
223
+ end
224
+
184
225
  describe "preloading" do
185
226
  it "should preload belongs_to associations across shards" do
186
227
  a1 = Appendage.create!(:user => @user1)
@@ -102,6 +102,12 @@ module Switchman
102
102
  appendage.original_user_id.should == @shard2.global_id_for(6)
103
103
  end
104
104
  end
105
+
106
+ it "should not choke on polymorphic associations that are missing their type" do
107
+ f = Feature.create!(owner: User.create!)
108
+ f = Feature.select(:owner_id).where(id: f).first
109
+ f.owner_id
110
+ end
105
111
  end
106
112
  end
107
113
  end
@@ -6,17 +6,23 @@ module Switchman
6
6
  include RSpecHelper
7
7
 
8
8
  describe "to_param" do
9
- it "should return nil if not persisted" do
9
+ it "should return nil if no id" do
10
10
  user = User.new
11
11
  user.to_param.should be_nil
12
12
  end
13
13
 
14
+ it "should return the id even if not persisted" do
15
+ user = User.new
16
+ user.id = 1
17
+ user.to_param.should == '1'
18
+ end
19
+
14
20
  it "should return local id if in the current shard" do
15
21
  user = User.create!
16
- user.to_param.should == user.local_id
22
+ user.to_param.should == user.local_id.to_s
17
23
  @shard1.activate do
18
24
  user2 = User.create!
19
- user2.to_param.should == user2.local_id
25
+ user2.to_param.should == user2.local_id.to_s
20
26
  end
21
27
  end
22
28
 
@@ -31,7 +37,7 @@ module Switchman
31
37
  end
32
38
 
33
39
  it "should use to_param in url helpers" do
34
- helpers = Rails.application.routes.url_helpers
40
+ helpers = ::Rails.application.routes.url_helpers
35
41
  user = nil
36
42
  appendage = nil
37
43
 
@@ -61,6 +67,16 @@ module Switchman
61
67
  end
62
68
  end
63
69
  end
70
+
71
+ describe "shard=" do
72
+ it "should adjust foreign ids when shard is changed" do
73
+ user = User.create!
74
+ appendage = Appendage.new
75
+ appendage.user_id = user.id
76
+ appendage.shard = @shard1
77
+ appendage.attributes["user_id"].should == user.global_id
78
+ end
79
+ end
64
80
  end
65
81
  end
66
82
  end
@@ -114,6 +114,123 @@ module Switchman
114
114
  Appendage.where(:id => @appendages).sum(:value).should == 15
115
115
  end
116
116
  end
117
+
118
+ describe "#execute_grouped_calculation" do
119
+ before do
120
+ @appendages = []
121
+ @shard1.activate { @user1 = User.create!(:name => "user1") }
122
+ @shard2.activate { @user2 = User.create!(:name => "user2") }
123
+
124
+ @shard1.activate do
125
+ @appendages << Appendage.create!(:user_id => @user1.id, :value => 1)
126
+ @appendages << Appendage.create!(:user_id => @user2.id, :value => 3)
127
+ end
128
+ @shard2.activate do
129
+ @appendages << Appendage.create!(:user_id => @user1.id, :value => 2)
130
+ @appendages << Appendage.create!(:user_id => @user2.id, :value => 4)
131
+ @appendages << Appendage.create!(:user_id => @user2.id, :value => 5)
132
+ end
133
+ end
134
+
135
+ it "should calculate average across shards" do
136
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").average(:value).should ==
137
+ {@user1.global_id => 1.5, @user2.global_id => 4}
138
+
139
+ @shard1.activate do
140
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").average(:value).should ==
141
+ {@user1.local_id => 1.5, @user2.global_id => 4}
142
+ end
143
+
144
+ @shard2.activate do
145
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").average(:value).should ==
146
+ {@user1.global_id => 1.5, @user2.local_id => 4}
147
+ end
148
+
149
+ Appendage.shard([@shard1, @shard2]).group(:user).average(:value).should ==
150
+ {@user1 => 1.5, @user2 => 4}
151
+ end
152
+
153
+ it "should count across shards" do
154
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").count.should ==
155
+ {@user1.global_id => 2, @user2.global_id => 3}
156
+
157
+ @shard1.activate do
158
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").count.should ==
159
+ {@user1.local_id => 2, @user2.global_id => 3}
160
+ end
161
+
162
+ @shard2.activate do
163
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").count.should ==
164
+ {@user1.global_id => 2, @user2.local_id => 3}
165
+ end
166
+
167
+ Appendage.shard([@shard1, @shard2]).group(:user).count.should ==
168
+ {@user1 => 2, @user2 => 3}
169
+ end
170
+
171
+ it "should calculate minimum across shards" do
172
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").minimum(:value).should ==
173
+ {@user1.global_id => 1, @user2.global_id => 3}
174
+
175
+ @shard1.activate do
176
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").minimum(:value).should ==
177
+ {@user1.local_id => 1, @user2.global_id => 3}
178
+ end
179
+
180
+ @shard2.activate do
181
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").minimum(:value).should ==
182
+ {@user1.global_id => 1, @user2.local_id => 3}
183
+ end
184
+
185
+ Appendage.shard([@shard1, @shard2]).group(:user).minimum(:value).should ==
186
+ {@user1 => 1, @user2 => 3}
187
+ end
188
+
189
+ it "should calculate maximum across shards" do
190
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").maximum(:value).should ==
191
+ {@user1.global_id => 2, @user2.global_id => 5}
192
+
193
+ @shard1.activate do
194
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").maximum(:value).should ==
195
+ {@user1.local_id => 2, @user2.global_id => 5}
196
+ end
197
+
198
+ @shard2.activate do
199
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").maximum(:value).should ==
200
+ {@user1.global_id => 2, @user2.local_id => 5}
201
+ end
202
+
203
+ Appendage.shard([@shard1, @shard2]).group(:user).maximum(:value).should ==
204
+ {@user1 => 2, @user2 => 5}
205
+ end
206
+
207
+ it "should calculate sum across shards" do
208
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").sum(:value).should ==
209
+ {@user1.global_id => 3, @user2.global_id => 12}
210
+
211
+ @shard1.activate do
212
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").sum(:value).should ==
213
+ {@user1.local_id => 3, @user2.global_id => 12}
214
+ end
215
+
216
+ @shard2.activate do
217
+ Appendage.shard([@shard1, @shard2]).group("appendages.user_id").sum(:value).should ==
218
+ {@user1.global_id => 3, @user2.local_id => 12}
219
+ end
220
+
221
+ Appendage.shard([@shard1, @shard2]).group(:user).sum(:value).should ==
222
+ {@user1 => 3, @user2 => 12}
223
+ end
224
+
225
+ it "should respect order for a single shard" do
226
+ @shard1.activate do
227
+ @user1.appendages.create!
228
+ user2 = User.create!
229
+ user2.appendages.create!
230
+ Appendage.group(:user_id).order("COUNT(*) DESC").limit(1).count.should == { @user1.id => 2 }
231
+ end
232
+ end
233
+ end
117
234
  end
118
235
  end
119
236
  end
@@ -24,6 +24,28 @@ module Switchman
24
24
  User.find_by_id([@user.global_id]).should == @user
25
25
  end
26
26
  end
27
+
28
+ describe "#find_or_initialize" do
29
+ it "should initialize with the shard from the scope" do
30
+ @user.destroy
31
+ u = User.shard(@shard1).where(id: @user).first_or_initialize
32
+ u.should be_new_record
33
+ u.shard.should == @shard1
34
+ end
35
+ end
36
+
37
+ describe "#exists?" do
38
+ it "should work for an out-of-shard scope" do
39
+ scope = @shard1.activate { User.where(id: @user) }
40
+ scope.shard_value.should == @shard1
41
+ scope.exists?.should be_true
42
+ end
43
+
44
+ it "should work for a multi-shard scope" do
45
+ user2 = @shard2.activate { User.create!(name: "multi-shard exists") }
46
+ User.where(name: "multi-shard exists").shard(Shard.scoped).exists?.should be_true
47
+ end
48
+ end
27
49
  end
28
50
  end
29
51
  end
@@ -5,6 +5,45 @@ module Switchman
5
5
  describe QueryCache do
6
6
  include RSpecHelper
7
7
 
8
+ # call with two blocks. the first will run on a new thread, pausing at
9
+ # the site of a "cc.call". the second will run on the original thread
10
+ # while the first is paused. the first will then finish.
11
+ def threaded(blk1, blk2)
12
+ mutex = Mutex.new
13
+ ready1 = ConditionVariable.new
14
+ ready2 = ConditionVariable.new
15
+
16
+ cc = lambda do
17
+ mutex.synchronize do
18
+ ready1.signal
19
+ ready2.wait(mutex)
20
+ end
21
+ end
22
+
23
+ thread = Thread.new do
24
+ blk1.call(cc)
25
+ ::ActiveRecord::Base.connection_pool.release_connection
26
+ end
27
+
28
+ mutex.synchronize do
29
+ ready1.wait(mutex)
30
+ blk2.call
31
+ ready2.signal
32
+ end
33
+
34
+ thread.join
35
+ end
36
+
37
+ before do
38
+ @orig_enabled = User.connection.query_cache_enabled
39
+ @orig_cache = User.connection.query_cache.dup
40
+ end
41
+
42
+ after do
43
+ User.connection.query_cache_enabled = @enabled
44
+ User.connection.instance_variable_set(:@query_cache, @orig_cache)
45
+ end
46
+
8
47
  it "should isolate queries to multiple shards on the same server" do
9
48
  @shard1.activate do
10
49
  User.create!
@@ -15,6 +54,255 @@ module Switchman
15
54
  end
16
55
  @shard1.activate { User.all }.should_not == @shard3.activate { User.all }
17
56
  end
57
+
58
+ describe "query_cache_enabled" do
59
+ it "should be shared across shards on the same server" do
60
+ @shard1.activate{ User.connection.query_cache_enabled = true }
61
+ @shard3.activate{ User.connection.query_cache_enabled = false }
62
+ @shard1.activate{ User.connection.query_cache_enabled.should == false }
63
+ end
64
+
65
+ it "should be shared across servers" do
66
+ @shard1.activate{ User.connection.query_cache_enabled = true }
67
+ @shard2.activate{ User.connection.query_cache_enabled = false }
68
+ @shard1.activate{ User.connection.query_cache_enabled.should == false }
69
+ end
70
+
71
+ it "should be distinct across threads" do
72
+ User.connection.query_cache_enabled = true
73
+ threaded(
74
+ lambda{ |cc| User.connection.query_cache_enabled = false; cc.call },
75
+ lambda{ User.connection.query_cache_enabled.should == true })
76
+ end
77
+ end
78
+
79
+ describe "enable_query_cache!" do
80
+ it "should only enable for the current thread" do
81
+ User.connection.query_cache_enabled = false
82
+ threaded(
83
+ lambda{ |cc|
84
+ User.connection.query_cache_enabled = false
85
+ User.connection.enable_query_cache!
86
+ User.connection.query_cache_enabled.should == true
87
+ cc.call
88
+ },
89
+ lambda{ User.connection.query_cache_enabled.should == false })
90
+ end
91
+ end
92
+
93
+ describe "disable_query_cache!" do
94
+ it "should only enable for the current thread" do
95
+ User.connection.query_cache_enabled = true
96
+ threaded(
97
+ lambda{ |cc|
98
+ User.connection.query_cache_enabled = true
99
+ User.connection.disable_query_cache!
100
+ User.connection.query_cache_enabled.should == false
101
+ cc.call
102
+ },
103
+ lambda{ User.connection.query_cache_enabled.should == true })
104
+ end
105
+ end
106
+
107
+ describe "cache" do
108
+ it "should only enable for the current thread" do
109
+ # check that query_cache_enabled stays false on this thread while
110
+ # another thread is in a cache{} block
111
+ User.connection.disable_query_cache!
112
+ threaded(
113
+ lambda{ |cc| User.connection.cache{ cc.call } },
114
+ lambda{ User.connection.query_cache_enabled.should == false })
115
+ end
116
+
117
+ it "should only enable for the duration of the block" do
118
+ User.connection.disable_query_cache!
119
+ User.connection.cache do
120
+ User.connection.query_cache_enabled.should == true
121
+ end
122
+ User.connection.query_cache_enabled.should == false
123
+ end
124
+
125
+ it "should clear query cache if disabling query cache after block" do
126
+ User.connection.disable_query_cache!
127
+ User.connection.cache do
128
+ User.connection.query_cache[:key][:binds] = :value
129
+ end
130
+ User.connection.query_cache[:key][:binds].should be_nil
131
+ end
132
+
133
+ it "should not clear query cache if the cache was already enabled" do
134
+ User.connection.enable_query_cache!
135
+ User.connection.cache do
136
+ User.connection.query_cache[:key][:binds] = :value
137
+ end
138
+ User.connection.query_cache[:key][:binds].should == :value
139
+ end
140
+ end
141
+
142
+ describe "uncached" do
143
+ it "should only disable for the current thread" do
144
+ # check that query_cache_enabled stays true on this thread while
145
+ # another thread is in an uncached{} block
146
+ User.connection.enable_query_cache!
147
+ threaded(
148
+ lambda{ |cc| User.connection.uncached{ cc.call } },
149
+ lambda{ User.connection.query_cache_enabled.should == true })
150
+ end
151
+
152
+ it "should only disable for the duration of the block" do
153
+ User.connection.enable_query_cache!
154
+ User.connection.uncached do
155
+ User.connection.query_cache_enabled.should == false
156
+ end
157
+ User.connection.query_cache_enabled.should == true
158
+ end
159
+
160
+ it "should not clear query cache" do
161
+ User.connection.query_cache[:key][:binds] = :value
162
+ User.connection.uncached{}
163
+ User.connection.query_cache[:key][:binds].should == :value
164
+ end
165
+ end
166
+
167
+ describe "select_all" do
168
+ it "should cache when query cache enabled" do
169
+ User.connection.enable_query_cache!
170
+ User.all
171
+ User.connection.query_cache.should_not be_empty
172
+ end
173
+
174
+ it "should not cache when query cache disabled" do
175
+ User.connection.disable_query_cache!
176
+ User.all
177
+ User.connection.query_cache.should be_empty
178
+ end
179
+
180
+ it "should not cache when query cache disabled but other thread's enabled" do
181
+ User.connection.disable_query_cache!
182
+ threaded(
183
+ lambda{ |cc| User.connection.cache{ cc.call } },
184
+ lambda{ User.all; User.connection.query_cache.should be_empty })
185
+ end
186
+
187
+ it "should not cache when query is locked" do
188
+ User.connection.enable_query_cache!
189
+ User.lock.all
190
+ User.connection.query_cache.should be_empty
191
+ end
192
+ end
193
+
194
+ describe "insert" do
195
+ it "should clear thread's query cache if enabled" do
196
+ User.connection.enable_query_cache!
197
+ User.all
198
+ User.create!
199
+ User.connection.query_cache.should be_empty
200
+ end
201
+
202
+ it "should not clear thread's query cache if disabled" do
203
+ User.connection.enable_query_cache!
204
+ User.all
205
+ User.connection.disable_query_cache!
206
+ User.create!
207
+ User.connection.query_cache.should_not be_empty
208
+ end
209
+
210
+ it "should not clear thread's query cache if disabled but other thread's enabled" do
211
+ User.connection.enable_query_cache!
212
+ User.all
213
+ User.connection.disable_query_cache!
214
+ threaded(
215
+ lambda{ |cc| User.create!; cc.call },
216
+ lambda{ User.connection.query_cache.should_not be_empty })
217
+ end
218
+
219
+ it "should not clear other thread's query cache" do
220
+ User.connection.enable_query_cache!
221
+ User.all
222
+ User.connection.disable_query_cache!
223
+ threaded(
224
+ lambda{ |cc| User.create!; cc.call },
225
+ lambda{ User.connection.query_cache.should_not be_empty })
226
+ end
227
+ end
228
+
229
+ describe "update" do
230
+ before do
231
+ User.create!
232
+ end
233
+
234
+ it "should clear thread's query cache if enabled" do
235
+ User.connection.enable_query_cache!
236
+ User.all
237
+ User.update_all(updated_at: Time.now)
238
+ User.connection.query_cache.should be_empty
239
+ end
240
+
241
+ it "should not clear thread's query cache if disabled" do
242
+ User.connection.enable_query_cache!
243
+ User.all
244
+ User.connection.disable_query_cache!
245
+ User.update_all(updated_at: Time.now)
246
+ User.connection.query_cache.should_not be_empty
247
+ end
248
+
249
+ it "should not clear thread's query cache if disabled but other thread's enabled" do
250
+ User.connection.enable_query_cache!
251
+ User.all
252
+ User.connection.disable_query_cache!
253
+ threaded(
254
+ lambda{ |cc| User.update_all(updated_at: Time.now); cc.call },
255
+ lambda{ User.connection.query_cache.should_not be_empty })
256
+ end
257
+
258
+ it "should not clear other thread's query cache" do
259
+ User.connection.enable_query_cache!
260
+ User.all
261
+ User.connection.disable_query_cache!
262
+ threaded(
263
+ lambda{ |cc| User.update_all(updated_at: Time.now); cc.call },
264
+ lambda{ User.connection.query_cache.should_not be_empty })
265
+ end
266
+ end
267
+
268
+ describe "delete" do
269
+ before do
270
+ User.create!
271
+ end
272
+
273
+ it "should clear thread's query cache if enabled" do
274
+ User.connection.enable_query_cache!
275
+ User.all
276
+ User.delete_all
277
+ User.connection.query_cache.should be_empty
278
+ end
279
+
280
+ it "should not clear thread's query cache if disabled" do
281
+ User.connection.enable_query_cache!
282
+ User.all
283
+ User.connection.disable_query_cache!
284
+ User.delete_all
285
+ User.connection.query_cache.should_not be_empty
286
+ end
287
+
288
+ it "should not clear thread's query cache if disabled but other thread's enabled" do
289
+ User.connection.enable_query_cache!
290
+ User.all
291
+ User.connection.disable_query_cache!
292
+ threaded(
293
+ lambda{ |cc| User.delete_all; cc.call },
294
+ lambda{ User.connection.query_cache.should_not be_empty })
295
+ end
296
+
297
+ it "should not clear other thread's query cache" do
298
+ User.connection.enable_query_cache!
299
+ User.all
300
+ User.connection.disable_query_cache!
301
+ threaded(
302
+ lambda{ |cc| User.delete_all; cc.call },
303
+ lambda{ User.connection.query_cache.should_not be_empty })
304
+ end
305
+ end
18
306
  end
19
307
  end
20
308
  end
@@ -124,6 +124,39 @@ module Switchman
124
124
  relation.where_values.first.right.should == [@user1.global_id, @user2.local_id]
125
125
  end
126
126
  end
127
+
128
+ it "should translate ids in joins" do
129
+ relation = User.joins(:appendage).where(appendages: { user_id: [@user1, @user2]})
130
+ relation.where_values.first.right.should == [@user1.local_id, @user2.global_id]
131
+ end
132
+
133
+ it "should translate ids according to the current shard of the foreign type" do
134
+ @shard1.activate(:mirror_universe) do
135
+ mirror_user = MirrorUser.create!
136
+ relation = User.where(mirror_user_id: mirror_user)
137
+ relation.where_values.first.right.should == mirror_user.global_id
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "with table aliases" do
143
+ it "should properly construct the query" do
144
+ child = @user1.children.create!
145
+ grandchild = child.children.create!
146
+ child.reload.parent.should == @user1
147
+
148
+ relation = @user1.association(:grandchildren).scoped
149
+
150
+ attribute = relation.where_values.first.left
151
+ attribute.name.to_s.should == 'parent_id'
152
+ attribute.relation.class.should == Arel::Nodes::TableAlias
153
+
154
+ rel, column = relation.send(:relation_and_column, attribute)
155
+ relation.send(:sharded_primary_key?, rel, column).should == false
156
+ relation.send(:sharded_foreign_key?, rel, column).should == true
157
+
158
+ @user1.grandchildren.should == [grandchild]
159
+ end
127
160
  end
128
161
  end
129
162
  end
@@ -33,6 +33,15 @@ module Switchman
33
33
  @user2.reload.name.should == 'a'
34
34
  end
35
35
  end
36
+
37
+ describe "#new" do
38
+ it "should infer the scope's shard" do
39
+ scope = @shard1.activate { User.where(id: 1) }
40
+ u = scope.new
41
+ u.shard.should == @shard1
42
+ u.local_id.should == 1
43
+ end
44
+ end
36
45
  end
37
46
  end
38
47
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module Switchman
4
+ module ActiveRecord
5
+ describe SpawnMethods do
6
+ include RSpecHelper
7
+
8
+ describe "#merge" do
9
+ it "should merge shard_value for multiple explicits" do
10
+ result = User.shard([@shard1, @shard2]).merge(User.shard([Shard.default, @shard1]))
11
+ result.shard_value.should == @shard1
12
+ result.shard_source_value.should == :explicit
13
+ end
14
+
15
+ it "should merge shard_value relations for multiple explicits" do
16
+ result = User.shard(Shard.where("id IN (?)", [@shard1, @shard2])).merge(User.shard(Shard.where(id: [Shard.default, @shard1])))
17
+ (::ActiveRecord::Relation === result.shard_value).should be_true
18
+ result.shard_value.to_a.should == [@shard1]
19
+ result.shard_source_value.should == :explicit
20
+ end
21
+
22
+ it "should ignore implicit shard value lhs" do
23
+ result = User.scoped.merge(User.shard(@shard1))
24
+ result.shard_value.should == @shard1
25
+ result.shard_source_value.should == :explicit
26
+ end
27
+
28
+ it "should ignore implicit shard value rhs" do
29
+ result = User.shard(@shard1).merge(User.scoped)
30
+ result.shard_value.should == @shard1
31
+ result.shard_source_value.should == :explicit
32
+ end
33
+
34
+ it "should take lhs shard_value for double implicit" do
35
+ scope1 = @shard2.activate { User.scoped }
36
+ result = scope1.merge(User.scoped)
37
+ result.shard_value.should == @shard2
38
+ result.shard_source_value.should == :implicit
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end