Class: Activr::Storage

Inherits:
Object
  • Object
show all
Defined in:
lib/activr/storage.rb

Overview

The storage is the component that uses the database driver to serialize/unserialize activities and timeline entries.

The storage singleton is accessible with storage

Defined Under Namespace

Classes: MongoDriver

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStorage

Returns a new instance of Storage.



15
16
17
18
19
# File 'lib/activr/storage.rb', line 15

def initialize
  @driver = Activr::Storage::MongoDriver.new

  @hooks = { }
end

Instance Attribute Details

#driverMongoDriver (readonly)

Returns database driver.

Returns:



13
14
15
# File 'lib/activr/storage.rb', line 13

def driver
  @driver
end

Instance Method Details

#clear_hooks!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Reset all hooks



398
399
400
# File 'lib/activr/storage.rb', line 398

def clear_hooks!
  @hooks = { }
end

#count_activities(options = { }) ⇒ Integer

Note:

If you use one of options selectors then you have to setup corresponding indexes in database.

Count number of activities

Parameters:

  • options (Hash) (defaults to: { })

    Options hash

Options Hash (options):

  • :before (Time)

    Find activities generated before that datetime (excluding)

  • :after (Time)

    Find activities generated after that datetime (excluding)

  • :entities (Hash{Sym=>String})

    Filter by entities values (empty means ‘all values’)

  • :only (Array<Class>)

    Find only these activities

  • :except (Array<Class>)

    Skip these activities

Returns:

  • (Integer)

    Number of activities



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/activr/storage.rb', line 138

def count_activities(options = { })
  # default options
  options = {
    :before   => nil,
    :after    => nil,
    :entities => { },
    :only     => [ ],
    :except   => [ ],
  }.merge(options)

  options[:only] = [ options[:only] ] if (options[:only] && !options[:only].is_a?(Array))

  # count
  self.driver.count_activities(options)
end

#count_duplicate_activities(activity, after) ⇒ Integer

Find number of duplicate activities

Parameters:

  • activity (Activity)

    Activity to search

  • after (Time)

    Search after that datetime

Returns:

  • (Integer)

    Number of activity duplicates



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/activr/storage.rb', line 159

def count_duplicate_activities(activity, after)
  entities = { }

  activity.entities.each do |entity_name, entity|
    entities[entity_name.to_sym] = entity.model_id
  end

  self.count_activities({
    :only     => activity.class,
    :entities => entities,
    :after    => after,
  })
end

#count_timeline(timeline, options = { }) ⇒ Integer

Count number of timeline entries

Parameters:

  • timeline (Timeline)

    Timeline instance

  • options (Hash) (defaults to: { })

    Options hash

Options Hash (options):

Returns:

  • (Integer)

    Number of timeline entries in given timeline



253
254
255
256
257
258
259
260
261
# File 'lib/activr/storage.rb', line 253

def count_timeline(timeline, options = { })
  options = {
    :only => [ ],
  }.merge(options)

  options[:only] = [ options[:only] ] if (options[:only] && !options[:only].is_a?(Array))

  self.driver.count_timeline_entries(timeline.kind, timeline.recipient_id, options)
end

#create_indexes {|String| ... } ⇒ Object

Ensure all necessary indexes

Yields:

  • (String)

    Created index name



298
299
300
# File 'lib/activr/storage.rb', line 298

def create_indexes
  self.driver.create_indexes
end

#delete_activities_for_entity_model(model) ⇒ Object

Delete activities referring to given entity model instance

Parameters:

  • model (Object)

    Model instance



176
177
178
179
180
# File 'lib/activr/storage.rb', line 176

def delete_activities_for_entity_model(model)
  Activr.registry.activity_entities_for_model(model.class).each do |entity_name|
    self.driver.delete_activities(:entities => { entity_name => model.id })
  end
end

#delete_timeline(timeline, options = { }) ⇒ Object

Delete timeline entries

Parameters:

  • timeline (Timeline)

    Timeline instance

  • options (Hash) (defaults to: { })

    Options hash

Options Hash (options):

  • :before (Time)

    Delete only timeline entries which timestamp is before that datetime (excluding)

  • :entity (Hash{Sym=>String})

    Delete only timeline entries with these entities values



269
270
271
272
273
274
275
276
277
# File 'lib/activr/storage.rb', line 269

def delete_timeline(timeline, options = { })
  # default options
  options = {
    :before   => nil,
    :entities => { },
  }.merge(options)

  self.driver.delete_timeline_entries(timeline.kind, timeline.recipient_id, options)
end

#delete_timeline_entries_for_entity_model(model) ⇒ Object

Delete timeline entries referring to given entity model instance

Parameters:

  • model (Object)

    Model instance



282
283
284
285
286
287
288
# File 'lib/activr/storage.rb', line 282

def delete_timeline_entries_for_entity_model(model)
  Activr.registry.timeline_entities_for_model(model.class).each do |timeline_class, entities|
    entities.each do |entity_name|
      self.driver.delete_timeline_entries(timeline_class.kind, nil, :entities => { entity_name => model.id })
    end
  end
end

#did_find_activity(&block) ⇒ Object

Hook: run just after fetching an activity document from the database

Examples:

Ignore the ‘foo’ meta


Activr.storage.did_find_activity do |activity_hash|
  if activity_hash['meta']
    activity_hash['meta'].delete('foo')
  end
end


330
331
332
# File 'lib/activr/storage.rb', line 330

def did_find_activity(&block)
  register_hook(:did_find_activity, block)
end

#did_find_timeline_entry(&block) ⇒ Object

Hook: run just after fetching a timeline entry document from the database

Examples:

Ignore the ‘bar’ field


Activr.storage.did_find_timeline_entry do |timeline_entry_hash, timeline_class|
  timeline_entry_hash.delete('bar')
end


354
355
356
# File 'lib/activr/storage.rb', line 354

def did_find_timeline_entry(&block)
  register_hook(:did_find_timeline_entry, block)
end

#find_activities(limit, options = { }) ⇒ Array<Activity>

Note:

If you use others selectors then ‘limit’ argument and ‘skip’ option then you have to setup corresponding indexes in database.

Find latest activities

Parameters:

  • limit (Integer)

    Max number of activities to find

  • options (Hash) (defaults to: { })

    Options hash

Options Hash (options):

  • :skip (Integer)

    Number of activities to skip (default: 0)

  • :before (Time)

    Find activities generated before that datetime (excluding)

  • :after (Time)

    Find activities generated after that datetime (excluding)

  • :entities (Hash{Sym=>String})

    Filter by entities values (empty means ‘all values’)

  • :only (Array<Class>)

    Find only these activities

  • :except (Array<Class>)

    Skip these activities

Returns:

  • (Array<Activity>)

    An array of activities



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/activr/storage.rb', line 102

def find_activities(limit, options = { })
  # default options
  options = {
    :skip     => 0,
    :before   => nil,
    :after    => nil,
    :entities => { },
    :only     => [ ],
    :except   => [ ],
  }.merge(options)

  options[:only] = [ options[:only] ] if (options[:only] && !options[:only].is_a?(Array))

  # find
  result = self.driver.find_activities(limit, options).map do |activity_hash|
    # run hook
    self.run_hook(:did_find_activity, activity_hash)

    # unserialize
    Activr::Activity.from_hash(activity_hash)
  end

  result
end

#find_activity(activity_id) ⇒ Activity, Nil

Find an activity

Parameters:

  • activity_id (Object)

    Activity id to find

Returns:

  • (Activity, Nil)

    An activity instance or ‘nil` if not found



76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/activr/storage.rb', line 76

def find_activity(activity_id)
  activity_hash = self.driver.find_activity(activity_id)
  if activity_hash
    # run hook
    self.run_hook(:did_find_activity, activity_hash)

    # unserialize
    Activr::Activity.from_hash(activity_hash)
  else
    nil
  end
end

#find_timeline(timeline, limit, options = { }) ⇒ Array<Timeline::Entry>

Find timeline entries by descending timestamp

Parameters:

  • timeline (Timeline)

    Timeline instance

  • limit (Integer)

    Max number of entries to find

  • options (Hash) (defaults to: { })

    Options hash

Options Hash (options):

  • :skip (Integer)

    Number of entries to skip (default: 0)

  • :only (Array<Timeline::Route>)

    An array of routes to fetch

Returns:



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/activr/storage.rb', line 228

def find_timeline(timeline, limit, options = { })
  options = {
    :skip => 0,
    :only => [ ],
  }.merge(options)

  options[:only] = [ options[:only] ] if (options[:only] && !options[:only].is_a?(Array))

  result = self.driver.find_timeline_entries(timeline.kind, timeline.recipient_id, limit, options).map do |timeline_entry_hash|
    # run hook
    self.run_hook(:did_find_timeline_entry, timeline_entry_hash, timeline.class)

    # unserialize
    Activr::Timeline::Entry.from_hash(timeline_entry_hash, timeline)
  end

  result
end

#find_timeline_entry(timeline, tl_entry_id) ⇒ Timeline::Entry, Nil

Find a timeline entry

Parameters:

  • timeline (Timeline)

    Timeline instance

  • tl_entry_id (Object)

    Timeline entry id

Returns:



207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/activr/storage.rb', line 207

def find_timeline_entry(timeline, tl_entry_id)
  timeline_entry_hash = self.driver.find_timeline_entry(timeline.kind, tl_entry_id)
  if timeline_entry_hash
    # run hook
    self.run_hook(:did_find_timeline_entry, timeline_entry_hash, timeline.class)

    # unserialize
    Activr::Timeline::Entry.from_hash(timeline_entry_hash, timeline)
  else
    nil
  end
end

#hooks(name = nil) ⇒ Array<Proc>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Returns all hooks if ‘name` is `nil`

Get hooks

Parameters:

  • name (Symbol) (defaults to: nil)

    Hook name

Returns:

  • (Array<Proc>)

    List of hooks



377
378
379
# File 'lib/activr/storage.rb', line 377

def hooks(name = nil)
  name ? (@hooks[name] || [ ]) : @hooks
end

#insert_activity(activity) ⇒ Object

Insert a new activity

Parameters:

  • activity (Activity)

    Activity to insert

Returns:

  • (Object)

    The inserted activity id



61
62
63
64
65
66
67
68
69
70
# File 'lib/activr/storage.rb', line 61

def insert_activity(activity)
  # serialize
  activity_hash = activity.to_hash

  # run hook
  self.run_hook(:will_insert_activity, activity_hash)

  # insert
  self.driver.insert_activity(activity_hash)
end

#insert_timeline_entry(timeline_entry) ⇒ Object

Insert a new timeline entry

Parameters:

Returns:

  • (Object)

    Inserted timeline entry id



191
192
193
194
195
196
197
198
199
200
# File 'lib/activr/storage.rb', line 191

def insert_timeline_entry(timeline_entry)
  # serialize
  timeline_entry_hash = timeline_entry.to_hash

  # run hook
  self.run_hook(:will_insert_timeline_entry, timeline_entry_hash, timeline_entry.timeline.class)

  # insert
  self.driver.insert_timeline_entry(timeline_entry.timeline.kind, timeline_entry_hash)
end

#register_hook(name, block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Register a hook

Parameters:

  • name (Symbol)

    Hook name

  • block (Proc)

    Hook code



365
366
367
368
# File 'lib/activr/storage.rb', line 365

def register_hook(name, block)
  @hooks[name] ||= [ ]
  @hooks[name] << block
end

#run_hook(name, *args) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Run a hook

Parameters:

  • name (Symbol)

    Hook name

  • args (Array)

    Hook arguments



387
388
389
390
391
392
393
# File 'lib/activr/storage.rb', line 387

def run_hook(name, *args)
  return if @hooks[name].blank?

  @hooks[name].each do |hook|
    args.any? ? hook.call(*args) : hook.call
  end
end

#serialized_id?(doc_id) ⇒ true, false

Is it a serialized document id

Returns:

  • (true, false)


32
33
34
# File 'lib/activr/storage.rb', line 32

def serialized_id?(doc_id)
  self.driver.serialized_id?(doc_id)
end

#unserialize_id(doc_id) ⇒ Object

Unserialize a document id

Parameters:

  • doc_id (Object)

    Document id

Returns:

  • (Object)

    Unserialized document id



40
41
42
# File 'lib/activr/storage.rb', line 40

def unserialize_id(doc_id)
  self.driver.unserialize_id(doc_id)
end

#unserialize_id_if_necessary(doc_id) ⇒ Object

Unserialize given parameter only if it is a serialized document id

Parameters:

  • doc_id (Object)

    Document id

Returns:

  • (Object)

    Unserialized or unmodified document id



48
49
50
# File 'lib/activr/storage.rb', line 48

def unserialize_id_if_necessary(doc_id)
  self.serialized_id?(doc_id) ? self.unserialize_id(doc_id) : doc_id
end

#valid_id?(doc_id) ⇒ true, false

Is it a valid document id

Parameters:

  • doc_id (Object)

    Document id to check

Returns:

  • (true, false)


25
26
27
# File 'lib/activr/storage.rb', line 25

def valid_id?(doc_id)
  self.driver.valid_id?(doc_id)
end

#will_insert_activity(&block) ⇒ Object

Hook: run just before inserting an activity document in the database

Examples:

Insert the ‘foo’ meta into all activities


Activr.storage.will_insert_activity do |activity_hash|
  activity_hash['meta'] ||= { }
  activity_hash['meta']['foo'] = 'bar'
end


316
317
318
# File 'lib/activr/storage.rb', line 316

def will_insert_activity(&block)
  register_hook(:will_insert_activity, block)
end

#will_insert_timeline_entry(&block) ⇒ Object

Hook: run just before inserting a timeline entry document in the database

Examples:

Insert the ‘bar’ field into all timeline entries documents


Activr.storage.will_insert_timeline_entry do |timeline_entry_hash, timeline_class|
  timeline_entry_hash['bar'] = 'baz'
end


342
343
344
# File 'lib/activr/storage.rb', line 342

def will_insert_timeline_entry(&block)
  register_hook(:will_insert_timeline_entry, block)
end