activesupport 3.0.pre → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (351) hide show
  1. data/CHANGELOG +121 -1
  2. data/README.rdoc +33 -0
  3. data/lib/active_support.rb +42 -4
  4. data/lib/active_support/backtrace_cleaner.rb +31 -9
  5. data/lib/active_support/benchmarkable.rb +1 -0
  6. data/lib/active_support/buffered_logger.rb +5 -2
  7. data/lib/active_support/builder.rb +6 -0
  8. data/lib/active_support/cache.rb +454 -84
  9. data/lib/active_support/cache/compressed_mem_cache_store.rb +6 -13
  10. data/lib/active_support/cache/file_store.rb +140 -41
  11. data/lib/active_support/cache/mem_cache_store.rb +121 -76
  12. data/lib/active_support/cache/memory_store.rb +127 -27
  13. data/lib/active_support/cache/strategy/local_cache.rb +111 -58
  14. data/lib/active_support/cache/synchronized_memory_store.rb +2 -38
  15. data/lib/active_support/callbacks.rb +105 -76
  16. data/lib/active_support/configurable.rb +19 -18
  17. data/lib/active_support/core_ext/array.rb +1 -0
  18. data/lib/active_support/core_ext/array/access.rb +1 -1
  19. data/lib/active_support/core_ext/array/conversions.rb +29 -54
  20. data/lib/active_support/core_ext/array/extract_options.rb +16 -1
  21. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  22. data/lib/active_support/core_ext/array/random_access.rb +26 -5
  23. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +13 -9
  25. data/lib/active_support/core_ext/benchmark.rb +0 -12
  26. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +2 -0
  27. data/lib/active_support/core_ext/class.rb +2 -1
  28. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  29. data/lib/active_support/core_ext/class/attribute_accessors.rb +33 -27
  30. data/lib/active_support/core_ext/class/delegating_attributes.rb +35 -41
  31. data/lib/active_support/core_ext/class/inheritable_attributes.rb +23 -14
  32. data/lib/active_support/core_ext/class/subclasses.rb +50 -0
  33. data/lib/active_support/core_ext/date/calculations.rb +35 -12
  34. data/lib/active_support/core_ext/date/conversions.rb +5 -5
  35. data/lib/active_support/core_ext/date/zones.rb +14 -0
  36. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +24 -5
  38. data/lib/active_support/core_ext/date_time/zones.rb +4 -0
  39. data/lib/active_support/core_ext/enumerable.rb +5 -9
  40. data/lib/active_support/core_ext/exception.rb +0 -47
  41. data/lib/active_support/core_ext/file.rb +1 -0
  42. data/lib/active_support/core_ext/file/atomic.rb +3 -2
  43. data/lib/active_support/core_ext/file/path.rb +5 -0
  44. data/lib/active_support/core_ext/float/rounding.rb +3 -2
  45. data/lib/active_support/core_ext/hash/conversions.rb +65 -145
  46. data/lib/active_support/core_ext/hash/deep_merge.rb +6 -7
  47. data/lib/active_support/core_ext/hash/except.rb +8 -1
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -0
  49. data/lib/active_support/core_ext/hash/keys.rb +10 -11
  50. data/lib/active_support/core_ext/hash/slice.rb +6 -0
  51. data/lib/active_support/core_ext/integer.rb +1 -1
  52. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  53. data/lib/active_support/core_ext/kernel.rb +1 -1
  54. data/lib/active_support/core_ext/kernel/debugger.rb +3 -2
  55. data/lib/active_support/core_ext/kernel/reporting.rb +2 -1
  56. data/lib/active_support/core_ext/kernel/requires.rb +2 -2
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  58. data/lib/active_support/core_ext/load_error.rb +17 -30
  59. data/lib/active_support/core_ext/logger.rb +2 -40
  60. data/lib/active_support/core_ext/module.rb +5 -3
  61. data/lib/active_support/core_ext/module/aliasing.rb +1 -1
  62. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  63. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
  64. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  65. data/lib/active_support/core_ext/module/attribute_accessors.rb +20 -22
  66. data/lib/active_support/core_ext/module/delegation.rb +21 -10
  67. data/lib/active_support/core_ext/module/introspection.rb +8 -8
  68. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  69. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  70. data/lib/active_support/core_ext/module/remove_method.rb +11 -0
  71. data/lib/active_support/core_ext/module/synchronization.rb +2 -1
  72. data/lib/active_support/core_ext/name_error.rb +3 -1
  73. data/lib/active_support/core_ext/object.rb +5 -3
  74. data/lib/active_support/core_ext/object/blank.rb +20 -2
  75. data/lib/active_support/core_ext/object/conversions.rb +2 -16
  76. data/lib/active_support/core_ext/object/duplicable.rb +23 -1
  77. data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
  78. data/lib/active_support/core_ext/object/to_json.rb +19 -0
  79. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  80. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  81. data/lib/active_support/core_ext/object/with_options.rb +2 -0
  82. data/lib/active_support/core_ext/proc.rb +4 -4
  83. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  84. data/lib/active_support/core_ext/regexp.rb +0 -22
  85. data/lib/active_support/core_ext/rexml.rb +4 -1
  86. data/lib/active_support/core_ext/string.rb +3 -2
  87. data/lib/active_support/core_ext/string/access.rb +4 -2
  88. data/lib/active_support/core_ext/string/conversions.rb +28 -1
  89. data/lib/active_support/core_ext/string/encoding.rb +11 -0
  90. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  91. data/lib/active_support/core_ext/string/filters.rb +29 -0
  92. data/lib/active_support/core_ext/string/inflections.rb +12 -12
  93. data/lib/active_support/core_ext/string/interpolation.rb +2 -92
  94. data/lib/active_support/core_ext/string/multibyte.rb +16 -19
  95. data/lib/active_support/core_ext/string/output_safety.rb +101 -35
  96. data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -14
  97. data/lib/active_support/core_ext/string/xchar.rb +1 -1
  98. data/lib/active_support/core_ext/time/calculations.rb +14 -7
  99. data/lib/active_support/core_ext/time/conversions.rb +1 -0
  100. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  101. data/lib/active_support/core_ext/time/zones.rb +2 -5
  102. data/lib/active_support/core_ext/uri.rb +10 -4
  103. data/lib/active_support/dependencies.rb +200 -197
  104. data/lib/active_support/dependencies/autoload.rb +50 -0
  105. data/lib/active_support/deprecation/behaviors.rb +13 -9
  106. data/lib/active_support/deprecation/method_wrappers.rb +10 -9
  107. data/lib/active_support/deprecation/proxy_wrappers.rb +7 -0
  108. data/lib/active_support/deprecation/reporting.rb +5 -3
  109. data/lib/active_support/descendants_tracker.rb +43 -0
  110. data/lib/active_support/duration.rb +8 -4
  111. data/lib/active_support/file_update_checker.rb +36 -0
  112. data/lib/active_support/hash_with_indifferent_access.rb +9 -1
  113. data/lib/active_support/i18n.rb +9 -0
  114. data/lib/active_support/i18n_railtie.rb +81 -0
  115. data/lib/active_support/inflections.rb +1 -1
  116. data/lib/active_support/inflector.rb +4 -407
  117. data/lib/active_support/inflector/inflections.rb +211 -0
  118. data/lib/active_support/inflector/methods.rb +151 -0
  119. data/lib/active_support/inflector/transliterate.rb +97 -0
  120. data/lib/active_support/json/backends/jsongem.rb +12 -9
  121. data/lib/active_support/json/backends/yajl.rb +40 -0
  122. data/lib/active_support/json/backends/yaml.rb +1 -1
  123. data/lib/active_support/json/decoding.rb +17 -2
  124. data/lib/active_support/json/encoding.rb +48 -31
  125. data/lib/active_support/json/variable.rb +2 -4
  126. data/lib/active_support/lazy_load_hooks.rb +27 -0
  127. data/lib/active_support/locale/en.yml +5 -2
  128. data/lib/active_support/log_subscriber.rb +123 -0
  129. data/lib/active_support/log_subscriber/test_helper.rb +99 -0
  130. data/lib/active_support/memoizable.rb +1 -1
  131. data/lib/active_support/message_encryptor.rb +1 -0
  132. data/lib/active_support/message_verifier.rb +2 -1
  133. data/lib/active_support/multibyte.rb +8 -23
  134. data/lib/active_support/multibyte/chars.rb +213 -446
  135. data/lib/active_support/multibyte/unicode.rb +392 -0
  136. data/lib/active_support/multibyte/utils.rb +6 -7
  137. data/lib/active_support/notifications.rb +29 -122
  138. data/lib/active_support/notifications/fanout.rb +61 -0
  139. data/lib/active_support/notifications/instrumenter.rb +54 -0
  140. data/lib/active_support/ordered_hash.rb +59 -14
  141. data/lib/active_support/ordered_options.rb +6 -0
  142. data/lib/active_support/railtie.rb +60 -0
  143. data/lib/active_support/rescuable.rb +7 -4
  144. data/lib/active_support/ruby/shim.rb +4 -6
  145. data/lib/active_support/test_case.rb +2 -7
  146. data/lib/active_support/testing/assertions.rb +15 -0
  147. data/lib/active_support/testing/declarative.rb +1 -1
  148. data/lib/active_support/testing/isolation.rb +64 -17
  149. data/lib/active_support/testing/performance.rb +306 -335
  150. data/lib/active_support/testing/setup_and_teardown.rb +51 -29
  151. data/lib/active_support/time.rb +24 -3
  152. data/lib/active_support/time_with_zone.rb +10 -14
  153. data/lib/active_support/values/time_zone.rb +192 -234
  154. data/lib/active_support/values/unicode_tables.dat +0 -0
  155. data/lib/active_support/version.rb +3 -2
  156. data/lib/active_support/whiny_nil.rb +9 -7
  157. data/lib/active_support/xml_mini.rb +130 -1
  158. data/lib/active_support/xml_mini/jdom.rb +2 -0
  159. data/lib/active_support/xml_mini/libxml.rb +23 -86
  160. data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
  161. data/lib/active_support/xml_mini/nokogiri.rb +27 -24
  162. data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
  163. data/lib/active_support/xml_mini/rexml.rb +8 -2
  164. metadata +62 -195
  165. data/README +0 -43
  166. data/lib/active_support/autoload.rb +0 -28
  167. data/lib/active_support/core_ext/boolean.rb +0 -1
  168. data/lib/active_support/core_ext/boolean/conversions.rb +0 -11
  169. data/lib/active_support/core_ext/class/removal.rb +0 -53
  170. data/lib/active_support/core_ext/date.rb +0 -7
  171. data/lib/active_support/core_ext/date_time.rb +0 -5
  172. data/lib/active_support/core_ext/integer/even_odd.rb +0 -16
  173. data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
  174. data/lib/active_support/core_ext/module/inclusion.rb +0 -30
  175. data/lib/active_support/core_ext/module/loading.rb +0 -23
  176. data/lib/active_support/core_ext/nil.rb +0 -1
  177. data/lib/active_support/core_ext/nil/conversions.rb +0 -5
  178. data/lib/active_support/core_ext/object/extending.rb +0 -80
  179. data/lib/active_support/core_ext/object/metaclass.rb +0 -13
  180. data/lib/active_support/core_ext/object/misc.rb +0 -3
  181. data/lib/active_support/core_ext/object/returning.rb +0 -42
  182. data/lib/active_support/core_ext/object/tap.rb +0 -16
  183. data/lib/active_support/core_ext/string/bytesize.rb +0 -5
  184. data/lib/active_support/core_ext/string/iterators.rb +0 -13
  185. data/lib/active_support/core_ext/symbol.rb +0 -1
  186. data/lib/active_support/core_ext/symbol/to_proc.rb +0 -14
  187. data/lib/active_support/core_ext/time.rb +0 -10
  188. data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +0 -22
  189. data/lib/active_support/deprecated_callbacks.rb +0 -283
  190. data/lib/active_support/multibyte/unicode_database.rb +0 -71
  191. data/lib/active_support/vendor.rb +0 -16
  192. data/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb +0 -113
  193. data/lib/active_support/vendor/builder-2.1.2/lib/builder.rb +0 -13
  194. data/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb +0 -20
  195. data/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb +0 -250
  196. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb +0 -115
  197. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb +0 -139
  198. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb +0 -63
  199. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb +0 -328
  200. data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +0 -20
  201. data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
  202. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
  203. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
  204. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +0 -204
  205. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -215
  206. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +0 -53
  207. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
  208. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -99
  209. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
  210. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
  211. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
  212. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
  213. data/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb +0 -1133
  214. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo.rb +0 -33
  215. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone.rb +0 -47
  216. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone_info.rb +0 -228
  217. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Algiers.rb +0 -55
  218. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Cairo.rb +0 -219
  219. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Casablanca.rb +0 -42
  220. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Harare.rb +0 -18
  221. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
  222. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Monrovia.rb +0 -22
  223. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Nairobi.rb +0 -23
  224. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
  225. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
  226. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Bogota.rb +0 -23
  227. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Caracas.rb +0 -23
  228. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chicago.rb +0 -283
  229. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chihuahua.rb +0 -136
  230. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Denver.rb +0 -204
  231. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Godthab.rb +0 -161
  232. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Guatemala.rb +0 -27
  233. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Halifax.rb +0 -274
  234. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
  235. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Juneau.rb +0 -194
  236. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/La_Paz.rb +0 -22
  237. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Lima.rb +0 -35
  238. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Los_Angeles.rb +0 -232
  239. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mazatlan.rb +0 -139
  240. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mexico_City.rb +0 -144
  241. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Monterrey.rb +0 -131
  242. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/New_York.rb +0 -282
  243. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Phoenix.rb +0 -30
  244. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Regina.rb +0 -74
  245. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Santiago.rb +0 -205
  246. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
  247. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/St_Johns.rb +0 -288
  248. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Tijuana.rb +0 -196
  249. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Almaty.rb +0 -67
  250. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baghdad.rb +0 -73
  251. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baku.rb +0 -161
  252. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Bangkok.rb +0 -20
  253. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Chongqing.rb +0 -33
  254. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Colombo.rb +0 -30
  255. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Dhaka.rb +0 -27
  256. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
  257. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
  258. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jakarta.rb +0 -30
  259. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
  260. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kabul.rb +0 -20
  261. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
  262. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Karachi.rb +0 -32
  263. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kathmandu.rb +0 -20
  264. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kolkata.rb +0 -25
  265. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
  266. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
  267. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuwait.rb +0 -18
  268. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Magadan.rb +0 -163
  269. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Muscat.rb +0 -18
  270. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
  271. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Rangoon.rb +0 -24
  272. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Riyadh.rb +0 -18
  273. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Seoul.rb +0 -34
  274. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Shanghai.rb +0 -35
  275. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Singapore.rb +0 -33
  276. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Taipei.rb +0 -59
  277. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tashkent.rb +0 -47
  278. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
  279. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tehran.rb +0 -121
  280. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tokyo.rb +0 -30
  281. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
  282. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Urumqi.rb +0 -33
  283. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
  284. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
  285. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
  286. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yerevan.rb +0 -165
  287. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Azores.rb +0 -270
  288. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
  289. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
  290. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Adelaide.rb +0 -187
  291. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Brisbane.rb +0 -35
  292. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Darwin.rb +0 -29
  293. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Hobart.rb +0 -193
  294. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Melbourne.rb +0 -185
  295. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Perth.rb +0 -37
  296. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Sydney.rb +0 -185
  297. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Etc/UTC.rb +0 -16
  298. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
  299. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Athens.rb +0 -185
  300. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Belgrade.rb +0 -163
  301. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Berlin.rb +0 -188
  302. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bratislava.rb +0 -13
  303. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Brussels.rb +0 -232
  304. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bucharest.rb +0 -181
  305. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Budapest.rb +0 -197
  306. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
  307. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Dublin.rb +0 -276
  308. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Helsinki.rb +0 -163
  309. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Istanbul.rb +0 -218
  310. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Kiev.rb +0 -168
  311. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Lisbon.rb +0 -268
  312. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
  313. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/London.rb +0 -288
  314. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Madrid.rb +0 -211
  315. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Minsk.rb +0 -170
  316. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Moscow.rb +0 -181
  317. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Paris.rb +0 -232
  318. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Prague.rb +0 -187
  319. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Riga.rb +0 -176
  320. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Rome.rb +0 -215
  321. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
  322. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Skopje.rb +0 -13
  323. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sofia.rb +0 -173
  324. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Stockholm.rb +0 -165
  325. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Tallinn.rb +0 -172
  326. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vienna.rb +0 -183
  327. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vilnius.rb +0 -170
  328. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Warsaw.rb +0 -212
  329. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Zagreb.rb +0 -13
  330. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Auckland.rb +0 -202
  331. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Fiji.rb +0 -23
  332. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Guam.rb +0 -22
  333. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
  334. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Majuro.rb +0 -20
  335. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Midway.rb +0 -25
  336. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Noumea.rb +0 -25
  337. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
  338. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
  339. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
  340. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/info_timezone.rb +0 -52
  341. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone.rb +0 -51
  342. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone_info.rb +0 -44
  343. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/offset_rationals.rb +0 -98
  344. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/ruby_core_support.rb +0 -56
  345. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/time_or_datetime.rb +0 -292
  346. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone.rb +0 -508
  347. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_definition.rb +0 -56
  348. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_info.rb +0 -40
  349. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_offset_info.rb +0 -94
  350. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_period.rb +0 -198
  351. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_transition_info.rb +0 -129
@@ -1,19 +1,12 @@
1
1
  module ActiveSupport
2
2
  module Cache
3
3
  class CompressedMemCacheStore < MemCacheStore
4
- def read(name, options = nil)
5
- if value = super(name, (options || {}).merge(:raw => true))
6
- if raw?(options)
7
- value
8
- else
9
- Marshal.load(ActiveSupport::Gzip.decompress(value))
10
- end
11
- end
12
- end
13
-
14
- def write(name, value, options = nil)
15
- value = ActiveSupport::Gzip.compress(Marshal.dump(value)) unless raw?(options)
16
- super(name, value, (options || {}).merge(:raw => true))
4
+ def initialize(*args)
5
+ ActiveSupport::Deprecation.warn('ActiveSupport::Cache::CompressedMemCacheStore has been deprecated in favor of ActiveSupport::Cache::MemCacheStore(:compress => true).', caller)
6
+ addresses = args.dup
7
+ options = addresses.extract_options!
8
+ args = addresses + [options.merge(:compress => true)]
9
+ super(*args)
17
10
  end
18
11
  end
19
12
  end
@@ -1,75 +1,174 @@
1
1
  require 'active_support/core_ext/file/atomic'
2
+ require 'active_support/core_ext/string/conversions'
2
3
 
3
4
  module ActiveSupport
4
5
  module Cache
5
6
  # A cache store implementation which stores everything on the filesystem.
7
+ #
8
+ # FileStore implements the Strategy::LocalCache strategy which implements
9
+ # an in memory cache inside of a block.
6
10
  class FileStore < Store
7
11
  attr_reader :cache_path
8
12
 
9
- def initialize(cache_path)
13
+ DIR_FORMATTER = "%03X"
14
+ ESCAPE_FILENAME_CHARS = /[^a-z0-9_.-]/i
15
+ UNESCAPE_FILENAME_CHARS = /%[0-9A-F]{2}/
16
+
17
+ def initialize(cache_path, options = nil)
18
+ super(options)
10
19
  @cache_path = cache_path
20
+ extend Strategy::LocalCache
11
21
  end
12
22
 
13
- # Reads a value from the cache.
14
- #
15
- # Possible options:
16
- # - +:expires_in+ - the number of seconds that this value may stay in
17
- # the cache.
18
- def read(name, options = nil)
19
- super do
20
- file_name = real_file_path(name)
21
- expires = expires_in(options)
22
-
23
- if File.exist?(file_name) && (expires <= 0 || Time.now - File.mtime(file_name) < expires)
24
- File.open(file_name, 'rb') { |f| Marshal.load(f) }
25
- end
23
+ def clear(options = nil)
24
+ root_dirs = Dir.entries(cache_path).reject{|f| ['.', '..'].include?(f)}
25
+ FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
26
+ end
27
+
28
+ def cleanup(options = nil)
29
+ options = merged_options(options)
30
+ each_key(options) do |key|
31
+ entry = read_entry(key, options)
32
+ delete_entry(key, options) if entry && entry.expired?
26
33
  end
27
34
  end
28
35
 
29
- # Writes a value to the cache.
30
- def write(name, value, options = nil)
31
- super do
32
- ensure_cache_path(File.dirname(real_file_path(name)))
33
- File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) }
34
- value
36
+ def increment(name, amount = 1, options = nil)
37
+ file_name = key_file_path(namespaced_key(name, options))
38
+ lock_file(file_name) do
39
+ options = merged_options(options)
40
+ if num = read(name, options)
41
+ num = num.to_i + amount
42
+ write(name, num, options)
43
+ num
44
+ else
45
+ nil
46
+ end
35
47
  end
36
- rescue => e
37
- logger.error "Couldn't create cache directory: #{name} (#{e.message})" if logger
38
48
  end
39
49
 
40
- def delete(name, options = nil)
41
- super do
42
- File.delete(real_file_path(name))
50
+ def decrement(name, amount = 1, options = nil)
51
+ file_name = key_file_path(namespaced_key(name, options))
52
+ lock_file(file_name) do
53
+ options = merged_options(options)
54
+ if num = read(name, options)
55
+ num = num.to_i - amount
56
+ write(name, num, options)
57
+ num
58
+ else
59
+ nil
60
+ end
43
61
  end
44
- rescue SystemCallError => e
45
- # If there's no cache, then there's nothing to complain about
46
62
  end
47
63
 
48
64
  def delete_matched(matcher, options = nil)
49
- super do
50
- search_dir(@cache_path) do |f|
51
- if f =~ matcher
52
- begin
53
- File.delete(f)
54
- rescue SystemCallError => e
55
- # If there's no cache, then there's nothing to complain about
65
+ options = merged_options(options)
66
+ instrument(:delete_matched, matcher.inspect) do
67
+ matcher = key_matcher(matcher, options)
68
+ search_dir(cache_path) do |path|
69
+ key = file_path_key(path)
70
+ delete_entry(key, options) if key.match(matcher)
71
+ end
72
+ end
73
+ end
74
+
75
+ protected
76
+
77
+ def read_entry(key, options)
78
+ file_name = key_file_path(key)
79
+ if File.exist?(file_name)
80
+ entry = File.open(file_name) { |f| Marshal.load(f) }
81
+ if entry && !entry.expired? && !entry.expires_in && !self.options[:expires_in]
82
+ # Check for deprecated use of +:expires_in+ option from versions < 3.0
83
+ deprecated_expires_in = options[:expires_in]
84
+ if deprecated_expires_in
85
+ ActiveSupport::Deprecation.warn('Setting :expires_in on read has been deprecated in favor of setting it on write.', caller)
86
+ if entry.created_at + deprecated_expires_in.to_f <= Time.now.to_f
87
+ delete_entry(key, options)
88
+ entry = nil
89
+ end
56
90
  end
57
91
  end
92
+ entry
58
93
  end
94
+ rescue
95
+ nil
59
96
  end
60
- end
61
97
 
62
- def exist?(name, options = nil)
63
- super do
64
- File.exist?(real_file_path(name))
98
+ def write_entry(key, entry, options)
99
+ file_name = key_file_path(key)
100
+ ensure_cache_path(File.dirname(file_name))
101
+ File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)}
102
+ true
103
+ end
104
+
105
+ def delete_entry(key, options)
106
+ file_name = key_file_path(key)
107
+ if File.exist?(file_name)
108
+ begin
109
+ File.delete(file_name)
110
+ delete_empty_directories(File.dirname(file_name))
111
+ true
112
+ rescue => e
113
+ # Just in case the error was caused by another process deleting the file first.
114
+ raise e if File.exist?(file_name)
115
+ false
116
+ end
117
+ end
65
118
  end
66
- end
67
119
 
68
120
  private
69
- def real_file_path(name)
70
- '%s/%s.cache' % [@cache_path, name.gsub('?', '.').gsub(':', '.')]
121
+ # Lock a file for a block so only one process can modify it at a time.
122
+ def lock_file(file_name, &block) # :nodoc:
123
+ if File.exist?(file_name)
124
+ File.open(file_name, 'r') do |f|
125
+ begin
126
+ f.flock File::LOCK_EX
127
+ yield
128
+ ensure
129
+ f.flock File::LOCK_UN
130
+ end
131
+ end
132
+ else
133
+ yield
134
+ end
135
+ end
136
+
137
+ # Translate a key into a file path.
138
+ def key_file_path(key)
139
+ fname = key.to_s.gsub(ESCAPE_FILENAME_CHARS){|match| "%#{match.ord.to_s(16).upcase}"}
140
+ hash = Zlib.adler32(fname)
141
+ hash, dir_1 = hash.divmod(0x1000)
142
+ dir_2 = hash.modulo(0x1000)
143
+ fname_paths = []
144
+ # Make sure file name is < 255 characters so it doesn't exceed file system limits.
145
+ if fname.size <= 255
146
+ fname_paths << fname
147
+ else
148
+ while fname.size <= 255
149
+ fname_path << fname[0, 255]
150
+ fname = fname[255, -1]
151
+ end
152
+ end
153
+ File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths)
154
+ end
155
+
156
+ # Translate a file path into a key.
157
+ def file_path_key(path)
158
+ fname = path[cache_path.size, path.size].split(File::SEPARATOR, 4).last
159
+ fname.gsub(UNESCAPE_FILENAME_CHARS){|match| $1.ord.to_s(16)}
160
+ end
161
+
162
+ # Delete empty directories in the cache.
163
+ def delete_empty_directories(dir)
164
+ return if dir == cache_path
165
+ if Dir.entries(dir).reject{|f| ['.', '..'].include?(f)}.empty?
166
+ File.delete(dir) rescue nil
167
+ delete_empty_directories(File.dirname(dir))
168
+ end
71
169
  end
72
170
 
171
+ # Make sure a file path's directories exist.
73
172
  def ensure_cache_path(path)
74
173
  FileUtils.makedirs(path) unless File.exist?(path)
75
174
  end
@@ -1,4 +1,10 @@
1
- require 'memcache'
1
+ begin
2
+ require 'memcache'
3
+ rescue LoadError => e
4
+ $stderr.puts "You don't have memcache installed in your application. Please add it to your Gemfile and run bundle install"
5
+ raise e
6
+ end
7
+ require 'digest/md5'
2
8
 
3
9
  module ActiveSupport
4
10
  module Cache
@@ -12,8 +18,9 @@ module ActiveSupport
12
18
  # and MemCacheStore will load balance between all available servers. If a
13
19
  # server goes down, then MemCacheStore will ignore it until it goes back
14
20
  # online.
15
- # - Time-based expiry support. See #write and the <tt>:expires_in</tt> option.
16
- # - Per-request in memory cache for all communication with the MemCache server(s).
21
+ #
22
+ # MemCacheStore implements the Strategy::LocalCache strategy which implements
23
+ # an in memory cache inside of a block.
17
24
  class MemCacheStore < Store
18
25
  module Response # :nodoc:
19
26
  STORED = "STORED\r\n"
@@ -23,10 +30,12 @@ module ActiveSupport
23
30
  DELETED = "DELETED\r\n"
24
31
  end
25
32
 
33
+ ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/
34
+
26
35
  def self.build_mem_cache(*addresses)
27
36
  addresses = addresses.flatten
28
37
  options = addresses.extract_options!
29
- addresses = ["localhost"] if addresses.empty?
38
+ addresses = ["localhost:11211"] if addresses.empty?
30
39
  MemCache.new(addresses, options)
31
40
  end
32
41
 
@@ -38,109 +47,145 @@ module ActiveSupport
38
47
  #
39
48
  # If no addresses are specified, then MemCacheStore will connect to
40
49
  # localhost port 11211 (the default memcached port).
50
+ #
51
+ # Instead of addresses one can pass in a MemCache-like object. For example:
52
+ #
53
+ # require 'memcached' # gem install memcached; uses C bindings to libmemcached
54
+ # ActiveSupport::Cache::MemCacheStore.new(Memcached::Rails.new("localhost:11211"))
41
55
  def initialize(*addresses)
56
+ addresses = addresses.flatten
57
+ options = addresses.extract_options!
58
+ super(options)
59
+
42
60
  if addresses.first.respond_to?(:get)
43
61
  @data = addresses.first
44
62
  else
45
- @data = self.class.build_mem_cache(*addresses)
63
+ mem_cache_options = options.dup
64
+ UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
65
+ @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
46
66
  end
47
67
 
48
68
  extend Strategy::LocalCache
69
+ extend LocalCacheWithRaw
49
70
  end
50
71
 
51
- # Reads multiple keys from the cache.
52
- def read_multi(*keys)
53
- @data.get_multi keys
54
- end
55
-
56
- def read(key, options = nil) # :nodoc:
57
- super do
58
- @data.get(key, raw?(options))
59
- end
60
- rescue MemCache::MemCacheError => e
61
- logger.error("MemCacheError (#{e}): #{e.message}")
62
- nil
63
- end
64
-
65
- # Writes a value to the cache.
66
- #
67
- # Possible options:
68
- # - <tt>:unless_exist</tt> - set to true if you don't want to update the cache
69
- # if the key is already set.
70
- # - <tt>:expires_in</tt> - the number of seconds that this value may stay in
71
- # the cache. See ActiveSupport::Cache::Store#write for an example.
72
- def write(key, value, options = nil)
73
- super do
74
- method = options && options[:unless_exist] ? :add : :set
75
- # memcache-client will break the connection if you send it an integer
76
- # in raw mode, so we convert it to a string to be sure it continues working.
77
- value = value.to_s if raw?(options)
78
- response = @data.send(method, key, value, expires_in(options), raw?(options))
79
- response == Response::STORED
80
- end
81
- rescue MemCache::MemCacheError => e
82
- logger.error("MemCacheError (#{e}): #{e.message}")
83
- false
84
- end
85
-
86
- def delete(key, options = nil) # :nodoc:
87
- super do
88
- response = @data.delete(key, expires_in(options))
89
- response == Response::DELETED
72
+ # Reads multiple keys from the cache using a single call to the
73
+ # servers for all keys. Options can be passed in the last argument.
74
+ def read_multi(*names)
75
+ options = names.extract_options!
76
+ options = merged_options(options)
77
+ keys_to_names = names.inject({}){|map, name| map[escape_key(namespaced_key(name, options))] = name; map}
78
+ raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
79
+ values = {}
80
+ raw_values.each do |key, value|
81
+ entry = deserialize_entry(value)
82
+ values[keys_to_names[key]] = entry.value unless entry.expired?
90
83
  end
91
- rescue MemCache::MemCacheError => e
92
- logger.error("MemCacheError (#{e}): #{e.message}")
93
- false
84
+ values
94
85
  end
95
86
 
96
- def exist?(key, options = nil) # :nodoc:
97
- # Doesn't call super, cause exist? in memcache is in fact a read
98
- # But who cares? Reading is very fast anyway
99
- # Local cache is checked first, if it doesn't know then memcache itself is read from
100
- super do
101
- !read(key, options).nil?
87
+ # Increment a cached value. This method uses the memcached incr atomic
88
+ # operator and can only be used on values written with the :raw option.
89
+ # Calling it on a value not stored with :raw will initialize that value
90
+ # to zero.
91
+ def increment(name, amount = 1, options = nil) # :nodoc:
92
+ options = merged_options(options)
93
+ response = instrument(:increment, name, :amount => amount) do
94
+ @data.incr(escape_key(namespaced_key(name, options)), amount)
102
95
  end
103
- end
104
-
105
- def increment(key, amount = 1) # :nodoc:
106
- response = instrument(:increment, key, :amount => amount) do
107
- @data.incr(key, amount)
108
- end
109
-
110
- response == Response::NOT_FOUND ? nil : response
96
+ response == Response::NOT_FOUND ? nil : response.to_i
111
97
  rescue MemCache::MemCacheError
112
98
  nil
113
99
  end
114
100
 
115
- def decrement(key, amount = 1) # :nodoc:
116
- response = instrument(:decrement, key, :amount => amount) do
117
- @data.decr(key, amount)
101
+ # Decrement a cached value. This method uses the memcached decr atomic
102
+ # operator and can only be used on values written with the :raw option.
103
+ # Calling it on a value not stored with :raw will initialize that value
104
+ # to zero.
105
+ def decrement(name, amount = 1, options = nil) # :nodoc:
106
+ options = merged_options(options)
107
+ response = instrument(:decrement, name, :amount => amount) do
108
+ @data.decr(escape_key(namespaced_key(name, options)), amount)
118
109
  end
119
-
120
- response == Response::NOT_FOUND ? nil : response
110
+ response == Response::NOT_FOUND ? nil : response.to_i
121
111
  rescue MemCache::MemCacheError
122
112
  nil
123
113
  end
124
114
 
125
- def delete_matched(matcher, options = nil) # :nodoc:
126
- # don't do any local caching at present, just pass
127
- # through and let the error happen
128
- super
129
- raise "Not supported by Memcache"
130
- end
131
-
132
- def clear
115
+ # Clear the entire cache on all memcached servers. This method should
116
+ # be used with care when using a shared cache.
117
+ def clear(options = nil)
133
118
  @data.flush_all
134
119
  end
135
120
 
121
+ # Get the statistics from the memcached servers.
136
122
  def stats
137
123
  @data.stats
138
124
  end
139
125
 
126
+ protected
127
+ # Read an entry from the cache.
128
+ def read_entry(key, options) # :nodoc:
129
+ deserialize_entry(@data.get(escape_key(key), true))
130
+ rescue MemCache::MemCacheError => e
131
+ logger.error("MemCacheError (#{e}): #{e.message}") if logger
132
+ nil
133
+ end
134
+
135
+ # Write an entry to the cache.
136
+ def write_entry(key, entry, options) # :nodoc:
137
+ method = options && options[:unless_exist] ? :add : :set
138
+ value = options[:raw] ? entry.value.to_s : entry
139
+ expires_in = options[:expires_in].to_i
140
+ if expires_in > 0 && !options[:raw]
141
+ # Set the memcache expire a few minutes in the future to support race condition ttls on read
142
+ expires_in += 5.minutes
143
+ end
144
+ response = @data.send(method, escape_key(key), value, expires_in, options[:raw])
145
+ response == Response::STORED
146
+ rescue MemCache::MemCacheError => e
147
+ logger.error("MemCacheError (#{e}): #{e.message}") if logger
148
+ false
149
+ end
150
+
151
+ # Delete an entry from the cache.
152
+ def delete_entry(key, options) # :nodoc:
153
+ response = @data.delete(escape_key(key))
154
+ response == Response::DELETED
155
+ rescue MemCache::MemCacheError => e
156
+ logger.error("MemCacheError (#{e}): #{e.message}") if logger
157
+ false
158
+ end
159
+
140
160
  private
141
- def raw?(options)
142
- options && options[:raw]
161
+ def escape_key(key)
162
+ key = key.to_s.gsub(ESCAPE_KEY_CHARS){|match| "%#{match.getbyte(0).to_s(16).upcase}"}
163
+ key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
164
+ key
165
+ end
166
+
167
+ def deserialize_entry(raw_value)
168
+ if raw_value
169
+ entry = Marshal.load(raw_value) rescue raw_value
170
+ entry.is_a?(Entry) ? entry : Entry.new(entry)
171
+ else
172
+ nil
173
+ end
143
174
  end
175
+
176
+ # Provide support for raw values in the local cache strategy.
177
+ module LocalCacheWithRaw # :nodoc:
178
+ protected
179
+ def write_entry(key, entry, options) # :nodoc:
180
+ retval = super
181
+ if options[:raw] && local_cache && retval
182
+ raw_entry = Entry.new(entry.value.to_s)
183
+ raw_entry.expires_at = entry.expires_at
184
+ local_cache.write_entry(key, raw_entry, options)
185
+ end
186
+ retval
187
+ end
188
+ end
144
189
  end
145
190
  end
146
191
  end