Module: RecordCache::ClassMethods

Defined in:
lib/record_cache.rb

Instance Method Summary collapse

Instance Method Details

#add_cached_index(index) ⇒ Object



147
148
149
150
151
152
153
154
155
156
# File 'lib/record_cache.rb', line 147

def add_cached_index(index)
  name  = index.name
  count = nil
  # Make sure the key is unique.
  while cached_indexes["#{name}#{count}"]
    count ||= 0
    count += 1
  end
  cached_indexes["#{name}#{count}"] = index
end

#cached_index(name) ⇒ Object



140
141
142
143
144
145
# File 'lib/record_cache.rb', line 140

def cached_index(name)
  name = name.to_s
  index = cached_indexes[name]
  index ||= base_class.cached_index(name) if base_class != self and base_class.respond_to?(:cached_index)
  index
end

#cached_index_namesObject



164
165
166
167
168
# File 'lib/record_cache.rb', line 164

def cached_index_names
  names = cached_indexes.keys
  names.concat(base_class.cached_index_names) if base_class != self and base_class.respond_to?(:cached_index_names)
  names.uniq
end

#cached_indexesObject



136
137
138
# File 'lib/record_cache.rb', line 136

def cached_indexes
  @cached_indexes ||= {}
end

#delete_all_with_invalidate(conditions = nil) ⇒ Object



91
92
93
94
95
# File 'lib/record_cache.rb', line 91

def delete_all_with_invalidate(conditions = nil)
  invalidate_from_conditions(conditions) do |conditions|
    delete_all_without_invalidate(conditions)
  end
end

#each_cached_indexObject



158
159
160
161
162
# File 'lib/record_cache.rb', line 158

def each_cached_index
  cached_index_names.each do |index_name|
    yield cached_index(index_name)
  end      
end

#find_with_caching(*args, &block) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/record_cache.rb', line 60

def find_with_caching(*args, &block)
  if args.last.is_a?(Hash)
    args.last.delete_if {|k,v| v.nil?}
    args.pop if args.last.empty?
  end
  
  if [:all, :first, :last].include?(args.first)
    opts = args.last
    if opts.is_a?(Hash) and opts.keys == [:conditions]
      # Try to match the SQL.
      if opts[:conditions] =~ /^"?#{table_name}"?.(\w*) = (\d*)$/
        field, value = $1, $2
        index = cached_index("by_#{field}")
        return index.find_by_field([value], self, args.first) if index
      end
    end
  elsif not args.last.is_a?(Hash)
    # This is a find with just ids.
    index = cached_index('by_id')
    return index.find_by_ids(args, self) if index
  end

  find_without_caching(*args, &block)
end

#invalidate_from_conditions(conditions, flag = nil) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/record_cache.rb', line 97

def invalidate_from_conditions(conditions, flag = nil)
  if conditions.nil?
    # Just invalidate all indexes.
    result = yield(nil)
    self.increment_version
    return result
  end

  # Freeze ids to avoid race conditions.
  sql = "SELECT id FROM #{table_name} "
  self.send(:add_conditions!, sql, conditions, self.send(:scope, :find))
  ids = RecordCache.db(self).select_values(sql)

  return if ids.empty?
  conditions = "id IN (#{ids.join(',')})"

  if block_given?
    # Capture the ids to invalidate in lambdas.
    lambdas = []
    each_cached_index do |index|
      lambdas << index.invalidate_from_conditions_lambda(conditions)
    end

    result = yield(conditions)

    # Finish invalidating with prior attributes.
    lambdas.each {|l| l.call}      
  end

  # Invalidate again afterwards if we are updating (or for the first time if no block was given).
  if flag == :update or not block_given?
    each_cached_index do |index|
      index.invalidate_from_conditions(conditions)
    end
  end

  result
end

#record_cache_config(opts = nil) ⇒ Object



170
171
172
173
174
175
176
# File 'lib/record_cache.rb', line 170

def record_cache_config(opts = nil)
  if opts
    record_cache_config.merge!(opts)
  else
    @record_cache_config ||= RecordCache.config.clone
  end
end

#update_all_with_invalidate(updates, conditions = nil) ⇒ Object



85
86
87
88
89
# File 'lib/record_cache.rb', line 85

def update_all_with_invalidate(updates, conditions = nil)
  invalidate_from_conditions(conditions, :update) do |conditions|
    update_all_without_invalidate(updates, conditions)
  end
end