Class: Perpetuity::Mapper
- Inherits:
-
Object
- Object
- Perpetuity::Mapper
show all
- Includes:
- DataInjectable
- Defined in:
- lib/perpetuity/mapper.rb
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#give_id_to, #inject_attribute, #inject_data
Constructor Details
#initialize(registry = Perpetuity.mapper_registry, id_map = IdentityMap.new) ⇒ Mapper
Returns a new instance of Mapper.
16
17
18
19
20
|
# File 'lib/perpetuity/mapper.rb', line 16
def initialize registry=Perpetuity.mapper_registry, id_map=IdentityMap.new
@mapper_registry = registry
@identity_map = id_map
@dirty_tracker = DirtyTracker.new
end
|
Class Attribute Details
.collection_name ⇒ Object
Returns the value of attribute collection_name.
13
14
15
|
# File 'lib/perpetuity/mapper.rb', line 13
def collection_name
@collection_name
end
|
Instance Attribute Details
#dirty_tracker ⇒ Object
Returns the value of attribute dirty_tracker.
11
12
13
|
# File 'lib/perpetuity/mapper.rb', line 11
def dirty_tracker
@dirty_tracker
end
|
#identity_map ⇒ Object
Returns the value of attribute identity_map.
11
12
13
|
# File 'lib/perpetuity/mapper.rb', line 11
def identity_map
@identity_map
end
|
#mapper_registry ⇒ Object
Returns the value of attribute mapper_registry.
11
12
13
|
# File 'lib/perpetuity/mapper.rb', line 11
def mapper_registry
@mapper_registry
end
|
Class Method Details
.attribute(name, options = {}) ⇒ Object
32
33
34
35
|
# File 'lib/perpetuity/mapper.rb', line 32
def self.attribute name, options = {}
type = options.fetch(:type) { nil }
attribute_set << Attribute.new(name, type, options)
end
|
.attribute_set ⇒ Object
28
29
30
|
# File 'lib/perpetuity/mapper.rb', line 28
def self.attribute_set
@attribute_set ||= AttributeSet.new
end
|
.attributes ⇒ Object
37
38
39
|
# File 'lib/perpetuity/mapper.rb', line 37
def self.attributes
attribute_set.map(&:name)
end
|
.collection(name) ⇒ Object
274
275
276
|
# File 'lib/perpetuity/mapper.rb', line 274
def self.collection name
@collection_name = name.to_s
end
|
.data_source(configuration = Perpetuity.configuration) ⇒ Object
103
104
105
|
# File 'lib/perpetuity/mapper.rb', line 103
def self.data_source(configuration=Perpetuity.configuration)
configuration.data_source
end
|
.id(type = nil, &block) ⇒ Object
202
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/perpetuity/mapper.rb', line 202
def self.id type=nil, &block
if block_given?
@id = block
if type
attribute :id, type: type
end
nil
else
@id ||= -> { nil }
end
end
|
.index(attribute_names, options = {}) ⇒ Object
41
42
43
44
45
46
47
48
|
# File 'lib/perpetuity/mapper.rb', line 41
def self.index attribute_names, options={}
attributes = Array(attribute_names).map { |name| attribute_set[name] }
if attributes.one?
data_source.index collection_name, attributes.first, options
else
data_source.index collection_name, attributes, options
end
end
|
.map(klass, registry = Perpetuity.mapper_registry) ⇒ Object
22
23
24
25
26
|
# File 'lib/perpetuity/mapper.rb', line 22
def self.map klass, registry=Perpetuity.mapper_registry
registry[klass] = self
@mapped_class = klass
collection klass.name
end
|
.mapped_class ⇒ Object
270
271
272
|
# File 'lib/perpetuity/mapper.rb', line 270
def self.mapped_class
@mapped_class
end
|
Instance Method Details
#all ⇒ Object
131
132
133
|
# File 'lib/perpetuity/mapper.rb', line 131
def all
retrieve
end
|
#all?(&block) ⇒ Boolean
115
116
117
|
# File 'lib/perpetuity/mapper.rb', line 115
def all? &block
count(&block) == count
end
|
#any?(&block) ⇒ Boolean
111
112
113
|
# File 'lib/perpetuity/mapper.rb', line 111
def any? &block
count(&block) > 0
end
|
#attribute_set ⇒ Object
75
76
77
|
# File 'lib/perpetuity/mapper.rb', line 75
def attribute_set
self.class.attribute_set
end
|
#attributes ⇒ Object
71
72
73
|
# File 'lib/perpetuity/mapper.rb', line 71
def attributes
self.class.attributes
end
|
#collection_name ⇒ Object
282
283
284
|
# File 'lib/perpetuity/mapper.rb', line 282
def collection_name
self.class.collection_name
end
|
#count(&block) ⇒ Object
107
108
109
|
# File 'lib/perpetuity/mapper.rb', line 107
def count &block
data_source.count collection_name, &block
end
|
#data_source ⇒ Object
250
251
252
|
# File 'lib/perpetuity/mapper.rb', line 250
def data_source
self.class.data_source
end
|
#decrement(object, attribute, count = 1) ⇒ Object
233
234
235
236
|
# File 'lib/perpetuity/mapper.rb', line 233
def decrement object, attribute, count=1
id = id_for(object) || object
data_source.increment collection_name, id, attribute, -count
end
|
#delete(object_or_array) ⇒ Object
178
179
180
181
182
183
|
# File 'lib/perpetuity/mapper.rb', line 178
def delete object_or_array
ids = Array(object_or_array).map { |object|
persisted?(object) ? id_for(object) : object
}
data_source.delete ids, collection_name
end
|
#delete_all ⇒ Object
79
80
81
|
# File 'lib/perpetuity/mapper.rb', line 79
def delete_all
data_source.delete_all collection_name
end
|
#find(id = nil, &block) ⇒ Object
Also known as:
detect
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/perpetuity/mapper.rb', line 141
def find id=nil, &block
return select(&block).first if block_given?
result = if id.is_a? Array
find_all_by_ids id
else
identity_map[mapped_class, id] ||
select { |object| object.id == id }.first
end
Array(result).each do |r|
identity_map << r
dirty_tracker << r
end
result
end
|
#find_all_by_ids(ids) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
|
# File 'lib/perpetuity/mapper.rb', line 161
def find_all_by_ids ids
ids_in_map = ids & identity_map.ids_for(mapped_class)
ids_to_select = ids - ids_in_map
retrieved = if ids_to_select.any?
select { |object| object.id.in ids_to_select }.to_a
else
[]
end
from_map = ids_in_map.map { |id| identity_map[mapped_class, id] }
retrieved.concat from_map
end
|
#first ⇒ Object
127
128
129
|
# File 'lib/perpetuity/mapper.rb', line 127
def first
retrieve.limit(1).first
end
|
#generate_id_for(object) ⇒ Object
99
100
101
|
# File 'lib/perpetuity/mapper.rb', line 99
def generate_id_for object
object.instance_exec(&self.class.id)
end
|
#id_for(object) ⇒ Object
246
247
248
|
# File 'lib/perpetuity/mapper.rb', line 246
def id_for object
object.instance_variable_get(:@id)
end
|
#increment(object, attribute, count = 1) ⇒ Object
228
229
230
231
|
# File 'lib/perpetuity/mapper.rb', line 228
def increment object, attribute, count=1
id = id_for(object) || object
data_source.increment collection_name, id, attribute, count
end
|
#indexes ⇒ Object
54
55
56
|
# File 'lib/perpetuity/mapper.rb', line 54
def indexes
data_source.indexes(collection_name)
end
|
#insert(object) ⇒ Object
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/perpetuity/mapper.rb', line 83
def insert object
objects = Array(object)
serialized_objects = objects.map { |obj| serialize(obj) }
new_ids = data_source.insert(collection_name, serialized_objects, attribute_set)
objects.each_with_index do |obj, index|
give_id_to obj, new_ids[index]
end
if object.is_a? Array
new_ids
else
new_ids.first
end
end
|
#load_association!(object, attribute) ⇒ Object
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
# File 'lib/perpetuity/mapper.rb', line 185
def load_association! object, attribute
objects = Array(object)
dereferencer = Dereferencer.new(mapper_registry, identity_map)
dereferencer.load objects.map { |obj| obj.instance_variable_get("@#{attribute}") }
objects.each do |obj|
reference = obj.instance_variable_get("@#{attribute}")
if reference.is_a? Array
refs = reference
real_objects = refs.map { |ref| dereferencer[ref] }
inject_attribute obj, attribute, real_objects
else
inject_attribute obj, attribute, dereferencer[reference]
end
end
end
|
#mapped_class ⇒ Object
278
279
280
|
# File 'lib/perpetuity/mapper.rb', line 278
def mapped_class
self.class.mapped_class
end
|
#none?(&block) ⇒ Boolean
123
124
125
|
# File 'lib/perpetuity/mapper.rb', line 123
def none? &block
!any?(&block)
end
|
#one?(&block) ⇒ Boolean
119
120
121
|
# File 'lib/perpetuity/mapper.rb', line 119
def one? &block
count(&block) == 1
end
|
#persisted?(object) ⇒ Boolean
242
243
244
|
# File 'lib/perpetuity/mapper.rb', line 242
def persisted? object
!!id_for(object)
end
|
#reindex! ⇒ Object
58
59
60
61
62
63
|
# File 'lib/perpetuity/mapper.rb', line 58
def reindex!
indexes.each { |index| data_source.activate_index! index }
unspecified_indexes.each do |index|
data_source.remove_index index
end
end
|
#reject(&block) ⇒ Object
174
175
176
|
# File 'lib/perpetuity/mapper.rb', line 174
def reject &block
retrieve data_source.negate_query(&block)
end
|
#remove_index!(index) ⇒ Object
50
51
52
|
# File 'lib/perpetuity/mapper.rb', line 50
def remove_index! index
data_source.remove_index index
end
|
#sample ⇒ Object
238
239
240
|
# File 'lib/perpetuity/mapper.rb', line 238
def sample
all.sample
end
|
#save(object) ⇒ Object
219
220
221
222
223
224
225
226
|
# File 'lib/perpetuity/mapper.rb', line 219
def save object
changed_attributes = serialize_changed_attributes(object)
if changed_attributes && changed_attributes.any?
update object, changed_attributes
else
update object, serialize(object)
end
end
|
#select(&block) ⇒ Object
Also known as:
find_all
135
136
137
|
# File 'lib/perpetuity/mapper.rb', line 135
def select &block
retrieve data_source.query(&block)
end
|
#serialize(object) ⇒ Object
254
255
256
257
258
259
260
261
|
# File 'lib/perpetuity/mapper.rb', line 254
def serialize object
attributes = data_source.serialize(object, self)
if o_id = generate_id_for(object)
attributes['id'] = o_id
end
attributes
end
|
#serialize_changed_attributes(object) ⇒ Object
263
264
265
266
267
268
|
# File 'lib/perpetuity/mapper.rb', line 263
def serialize_changed_attributes object
cached = dirty_tracker[object.class, id_for(object)]
if cached
data_source.serialize_changed_attributes(object, cached, self)
end
end
|
#unspecified_indexes ⇒ Object
65
66
67
68
69
|
# File 'lib/perpetuity/mapper.rb', line 65
def unspecified_indexes
active_indexes = data_source.active_indexes(collection_name)
active_but_unspecified_indexes = (active_indexes - indexes)
active_but_unspecified_indexes.reject { |index| index.attribute =~ /id/ }
end
|
#update(object, new_data) ⇒ Object
214
215
216
217
|
# File 'lib/perpetuity/mapper.rb', line 214
def update object, new_data
id = object.is_a?(mapped_class) ? id_for(object) : object
data_source.update collection_name, id, new_data
end
|