Class: Poro::Contexts::MongoContext

Inherits:
Poro::Context show all
Includes:
FinderMethods
Defined in:
lib/poro/contexts/mongo_context.rb,
lib/poro/contexts/mongo_context.rb,
lib/poro/contexts/mongo_context.rb

Overview

The MongoDB Context Adapter.

Manages an object in MongoDB.

WARNING: At this time, only objects that follow nice tree hierarchies can be encoded. Cyclical loops cannot be auto-encoded, and need embedded objects to be managed with the parent pointers blacklisted.

WARNING: Embedded objects of the same kind–which are referenced via a DBRef, are re-fetched and re-saved every time the managing object is fetched or saved.

This adapter recursively encodes the object according to the following rules for each instance variable’s value:

  1. If the object can be saved as a primitive, save it that way.

  2. If the object is managed by a Mongo context, save and encode it as a DBRef.

  3. If the object is managed by another context, save and store the class and id in a hash.

  4. Otherwise, encode all instance variables and the class, in a Hash.

For Mongo represented objects, the instance variables that are encoded can be controlled via any combination of the save_attributes and save_attributes_blacklist properties. The Context will start with the save attributes (which defaults to all the instance variables), and then subtract out the attributes in the blacklist. Thus the blacklist takes priority.

Defined Under Namespace

Modules: FinderMethods

Constant Summary collapse

@@collection_map =

A map of all the collection names registered for this kind of context. This is to facilitate DBRef dereferencing, even when your class doesn’t match the

{}

Instance Attribute Summary collapse

Attributes inherited from Poro::Context

#data_store, #klass, #primary_key

Instance Method Summary collapse

Methods included from FinderMethods

#data_store_cursor

Methods inherited from Poro::Context

configure_for_klass, factory, factory=, fetch, managed_class?, #primary_key_value, #set_primary_key_value

Methods included from Poro::Context::FindMethods

#data_store_find, #find, included

Constructor Details

#initialize(klass) ⇒ MongoContext

Takes the class for the context, and optionally the collection object up front. This can be changed at any time by setting the data store for the Context.



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/poro/contexts/mongo_context.rb', line 39

def initialize(klass)
  # Require mongo.  We do it here so that it is only required when
  # we use this.  (How does this affect speed?  It seems this takes 1/30000 of a second.)
  require 'mongo'
  
  # Set-up the lists.
  @persistent_attributes_whitelist = nil
  @persistent_attributes_blacklist = nil
  
  # Initialize
  super(klass)
end

Instance Attribute Details

#persistent_attributes_blacklistObject

Returns the value of attribute persistent_attributes_blacklist.



62
63
64
# File 'lib/poro/contexts/mongo_context.rb', line 62

def persistent_attributes_blacklist
  @persistent_attributes_blacklist
end

#persistent_attributes_whitelistObject

Returns the value of attribute persistent_attributes_whitelist.



59
60
61
# File 'lib/poro/contexts/mongo_context.rb', line 59

def persistent_attributes_whitelist
  @persistent_attributes_whitelist
end

Instance Method Details

#convert_to_data(obj, state_info = {}) ⇒ Object



88
89
90
91
# File 'lib/poro/contexts/mongo_context.rb', line 88

def convert_to_data(obj, state_info={})
  data = route_encode(obj, state_info)
  return data
end

#convert_to_plain_object(data, state_info = {}) ⇒ Object



81
82
83
84
85
86
# File 'lib/poro/contexts/mongo_context.rb', line 81

def convert_to_plain_object(data, state_info={})
  # If it is a root record, and it has no class name, assume this context's class name.
  data['_class_name'] = self.klass if( data && data.kind_of?(Hash) && !state_info[:embedded] )
  obj = route_decode(data, state_info)
  return obj
end

#data_store=(collection) ⇒ Object

Set the data store to the given collection.



53
54
55
56
57
# File 'lib/poro/contexts/mongo_context.rb', line 53

def data_store=(collection)
  @@collection_map.delete(self.data_store && data.store.name) # Clean-up the old record in case we change names.
  @@collection_map[collection.name] = self unless collection.nil? # Create the new record.
  super(collection)
end

#fetch(id) ⇒ Object



65
66
67
68
# File 'lib/poro/contexts/mongo_context.rb', line 65

def fetch(id)
  data = data_store.find_one( clean_id(id) )
  return convert_to_plain_object(data)
end

#remove(obj) ⇒ Object



77
78
79
# File 'lib/poro/contexts/mongo_context.rb', line 77

def remove(obj)
  return obj
end

#save(obj) ⇒ Object



70
71
72
73
74
75
# File 'lib/poro/contexts/mongo_context.rb', line 70

def save(obj)
  data = convert_to_data(obj)
  data_store.save(data)
  set_primary_key_value(obj, (data['_id'] || data[:_id])) # The pk generator uses a symbol, while everything else uses a string!
  return obj
end