Class: RecordCache::Index
- Inherits:
-
Object
- Object
- RecordCache::Index
- Includes:
- Deferrable
- Defined in:
- lib/record_cache/index.rb
Constant Summary collapse
- NULL =
'NULL'
- @@disable_db =
false
Instance Attribute Summary collapse
-
#cache ⇒ Object
readonly
Returns the value of attribute cache.
-
#expiry ⇒ Object
readonly
Returns the value of attribute expiry.
-
#fields ⇒ Object
readonly
Returns the value of attribute fields.
-
#index_field ⇒ Object
readonly
Returns the value of attribute index_field.
-
#limit ⇒ Object
readonly
Returns the value of attribute limit.
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#order_by ⇒ Object
readonly
Returns the value of attribute order_by.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
Class Method Summary collapse
Instance Method Summary collapse
- #auto_name? ⇒ Boolean
- #cached_set(id) ⇒ Object
- #disallow_null? ⇒ Boolean
- #field_lookup(keys, model_class, field, flag = nil) ⇒ Object
- #fields_hash ⇒ Object
- #find_by_field(keys, model_class, type) ⇒ Object
- #find_by_ids(ids, model_class) ⇒ Object
- #find_method_name(type) ⇒ Object
- #full_record? ⇒ Boolean
- #includes_id? ⇒ Boolean
-
#initialize(opts) ⇒ Index
constructor
A new instance of Index.
- #invalidate(*keys) ⇒ Object
- #invalidate_from_conditions(conditions) ⇒ Object
- #invalidate_from_conditions_lambda(conditions) ⇒ Object
- #invalidate_model(model) ⇒ Object
- #namespace ⇒ Object
- #scope ⇒ Object
- #scope_query ⇒ Object
- #set_class ⇒ Object
- #write_ahead? ⇒ Boolean
Constructor Details
#initialize(opts) ⇒ Index
Returns a new instance of Index.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/record_cache/index.rb', line 9 def initialize(opts) raise ':by => index_field required for cache' if opts[:by].nil? raise 'explicit name or prefix required with scope' if opts[:scope] and opts[:name].nil? and opts[:prefix].nil? @auto_name = opts[:name].nil? @write_ahead = opts[:write_ahead] @cache = opts[:cache] || CACHE @expiry = opts[:expiry] @model_class = opts[:class] @set_class = opts[:set_class] || "#{@model_class}Set" @index_field = opts[:by].to_s @fields = opts[:fields].collect {|field| field.to_s} @prefix = opts[:prefix] @name = ( opts[:name] || [prefix, 'by', index_field].compact.join('_') ).to_s @order_by = opts[:order_by] @limit = opts[:limit] @disallow_null = opts[:null] == false @scope_query = opts[:scope] || {} end |
Instance Attribute Details
#cache ⇒ Object (readonly)
Returns the value of attribute cache.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def cache @cache end |
#expiry ⇒ Object (readonly)
Returns the value of attribute expiry.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def expiry @expiry end |
#fields ⇒ Object (readonly)
Returns the value of attribute fields.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def fields @fields end |
#index_field ⇒ Object (readonly)
Returns the value of attribute index_field.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def index_field @index_field end |
#limit ⇒ Object (readonly)
Returns the value of attribute limit.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def limit @limit end |
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def model_class @model_class end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def name @name end |
#order_by ⇒ Object (readonly)
Returns the value of attribute order_by.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def order_by @order_by end |
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
5 6 7 |
# File 'lib/record_cache/index.rb', line 5 def prefix @prefix end |
Class Method Details
.disable_db ⇒ Object
208 209 210 |
# File 'lib/record_cache/index.rb', line 208 def self.disable_db @@disable_db = true end |
.enable_db ⇒ Object
212 213 214 |
# File 'lib/record_cache/index.rb', line 212 def self.enable_db @@disable_db = false end |
Instance Method Details
#auto_name? ⇒ Boolean
29 |
# File 'lib/record_cache/index.rb', line 29 def auto_name?; @auto_name; end |
#cached_set(id) ⇒ Object
235 236 237 238 239 240 241 |
# File 'lib/record_cache/index.rb', line 235 def cached_set(id) # Used for debugging. Gives you the RecordCache::Set that is currently in the cache. id = stringify([id]).first cache.in_namespace(namespace) do cache.get(id) end end |
#disallow_null? ⇒ Boolean
31 |
# File 'lib/record_cache/index.rb', line 31 def disallow_null?; @disallow_null; end |
#field_lookup(keys, model_class, field, flag = nil) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/record_cache/index.rb', line 127 def field_lookup(keys, model_class, field, flag = nil) keys = [*keys] keys = stringify(keys) field = field.to_s if field records_by_key = get_records(keys) field_by_index = {} all_fields = [].to_ordered_set keys.each do |key| records = records_by_key[key] fields = field ? records.fields(field, model_class) : records.all_fields(model_class, :except => index_field) if flag == :all all_fields.concat(fields) elsif flag == :first next if fields.empty? field_by_index[index_column.type_cast(key)] = fields.first else field_by_index[index_column.type_cast(key)] = fields end end if flag == :all all_fields.to_a else field_by_index end end |
#fields_hash ⇒ Object
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/record_cache/index.rb', line 49 def fields_hash if @fields_hash.nil? if full_record? @fields_hash ||= model_class.column_names.hash else @fields_hash ||= fields.collect {|field| field.to_s}.hash end end @fields_hash end |
#find_by_field(keys, model_class, type) ⇒ Object
94 95 96 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 |
# File 'lib/record_cache/index.rb', line 94 def find_by_field(keys, model_class, type) keys = [keys] if not keys.kind_of?(Array) keys = stringify(keys) records_by_key = get_records(keys) case type when :first keys.each do |key| model = records_by_key[key].instantiate_first(model_class, full_record?) return model if model end return nil when :all models = [] keys.each do |key| models.concat( records_by_key[key].instantiate(model_class, full_record?) ) end models when :set, :ids ids = [] keys.each do |key| ids.concat( records_by_key[key].ids(model_class) ) end type == :set ? set_class.new(ids) : ids when :raw raw_records = [] keys.each do |key| raw_records.concat( records_by_key[key].records(model_class) ) end raw_records end end |
#find_by_ids(ids, model_class) ⇒ 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 84 85 86 87 88 89 90 91 92 |
# File 'lib/record_cache/index.rb', line 60 def find_by_ids(ids, model_class) expects_array = ids.first.kind_of?(Array) ids = ids.flatten.compact.collect {|id| id.to_i} ids = stringify(ids) if ids.empty? return [] if expects_array raise ActiveRecord::RecordNotFound, "Couldn't find #{model_class} without an ID" end records_by_id = get_records(ids) models = ids.collect do |id| records = records_by_id[id] model = records.instantiate_first(model_class, full_record?) if records # try to get record from db again before we throw an exception if model.nil? invalidate(id) records = get_records([id])[id] model = records.instantiate_first(model_class, full_record?) if records end raise ActiveRecord::RecordNotFound, "Couldn't find #{model_class} with ID #{id}" unless model model end if models.size == 1 and not expects_array models.first else models end end |
#find_method_name(type) ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/record_cache/index.rb', line 216 def find_method_name(type) if name =~ /(^|_)by_/ if type == :first "find_#{name}" else "find_#{type}_#{name}" end else case type when :all "find_#{name}" when :first "find_#{type}_#{name.singularize}" else "find_#{name.singularize}_#{type}" end end end |
#full_record? ⇒ Boolean
33 34 35 |
# File 'lib/record_cache/index.rb', line 33 def full_record? fields.empty? end |
#includes_id? ⇒ Boolean
37 38 39 |
# File 'lib/record_cache/index.rb', line 37 def includes_id? full_record? or fields.include?('id') end |
#invalidate(*keys) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/record_cache/index.rb', line 154 def invalidate(*keys) keys = stringify(keys) cache.in_namespace(namespace) do keys.each do |key| cache.delete(key) end end end |
#invalidate_from_conditions(conditions) ⇒ Object
170 171 172 |
# File 'lib/record_cache/index.rb', line 170 def invalidate_from_conditions(conditions) invalidate_from_conditions_lambda(conditions).call end |
#invalidate_from_conditions_lambda(conditions) ⇒ Object
163 164 165 166 167 168 |
# File 'lib/record_cache/index.rb', line 163 def invalidate_from_conditions_lambda(conditions) sql = "SELECT #{index_field} FROM #{table_name} " model_class.send(:add_conditions!, sql, conditions, model_class.send(:scope, :find)) ids = db.select_values(sql) lambda { invalidate(*ids) } end |
#invalidate_model(model) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/record_cache/index.rb', line 174 def invalidate_model(model) attribute = model.send(index_field) attribute_was = model.attr_was(index_field) if scope.match_previous?(model) if write_ahead? remove_from_cache(model) else now_and_later do invalidate(attribute_was) end end end if scope.match_current?(model) if write_ahead? add_to_cache(model) elsif not (scope.match_previous?(model) and attribute_was == attribute) now_and_later do invalidate(attribute) end end end end |
#namespace ⇒ Object
45 46 47 |
# File 'lib/record_cache/index.rb', line 45 def namespace "#{model_class.name}_#{model_class.version}_#{RecordCache.version}:#{name}" << ( full_record? ? '' : ":#{fields.join(',')}" ) end |
#scope ⇒ Object
203 204 205 |
# File 'lib/record_cache/index.rb', line 203 def scope @scope ||= Scope.new(model_class, scope_query) end |
#scope_query ⇒ Object
198 199 200 201 |
# File 'lib/record_cache/index.rb', line 198 def scope_query @scope_query[:type] ||= model_class.to_s if sub_class? @scope_query end |
#set_class ⇒ Object
41 42 43 |
# File 'lib/record_cache/index.rb', line 41 def set_class @set_class.constantize end |
#write_ahead? ⇒ Boolean
30 |
# File 'lib/record_cache/index.rb', line 30 def write_ahead?; @write_ahead; end |