Froze rails gems
[depot.git] / vendor / rails / activerecord / lib / active_record / connection_adapters / abstract / query_cache.rb
1 module ActiveRecord
2 module ConnectionAdapters # :nodoc:
3 module QueryCache
4 class << self
5 def included(base)
6 base.class_eval do
7 alias_method_chain :columns, :query_cache
8 alias_method_chain :select_all, :query_cache
9 end
10
11 dirties_query_cache base, :insert, :update, :delete
12 end
13
14 def dirties_query_cache(base, *method_names)
15 method_names.each do |method_name|
16 base.class_eval <<-end_code, __FILE__, __LINE__
17 def #{method_name}_with_query_dirty(*args)
18 clear_query_cache if @query_cache_enabled
19 #{method_name}_without_query_dirty(*args)
20 end
21
22 alias_method_chain :#{method_name}, :query_dirty
23 end_code
24 end
25 end
26 end
27
28 attr_reader :query_cache, :query_cache_enabled
29
30 # Enable the query cache within the block.
31 def cache
32 old, @query_cache_enabled = @query_cache_enabled, true
33 @query_cache ||= {}
34 yield
35 ensure
36 clear_query_cache
37 @query_cache_enabled = old
38 end
39
40 # Disable the query cache within the block.
41 def uncached
42 old, @query_cache_enabled = @query_cache_enabled, false
43 yield
44 ensure
45 @query_cache_enabled = old
46 end
47
48 # Clears the query cache.
49 #
50 # One reason you may wish to call this method explicitly is between queries
51 # that ask the database to randomize results. Otherwise the cache would see
52 # the same SQL query and repeatedly return the same result each time, silently
53 # undermining the randomness you were expecting.
54 def clear_query_cache
55 @query_cache.clear if @query_cache
56 end
57
58 def select_all_with_query_cache(*args)
59 if @query_cache_enabled
60 cache_sql(args.first) { select_all_without_query_cache(*args) }
61 else
62 select_all_without_query_cache(*args)
63 end
64 end
65
66 def columns_with_query_cache(*args)
67 if @query_cache_enabled
68 @query_cache["SHOW FIELDS FROM #{args.first}"] ||= columns_without_query_cache(*args)
69 else
70 columns_without_query_cache(*args)
71 end
72 end
73
74 private
75 def cache_sql(sql)
76 result =
77 if @query_cache.has_key?(sql)
78 log_info(sql, "CACHE", 0.0)
79 @query_cache[sql]
80 else
81 @query_cache[sql] = yield
82 end
83
84 if Array === result
85 result.collect { |row| row.dup }
86 else
87 result.duplicable? ? result.dup : result
88 end
89 rescue TypeError
90 result
91 end
92 end
93 end
94 end