Class: Poro::Contexts::MongoContext
- Inherits:
-
Poro::Context
- Object
- Poro::Context
- Poro::Contexts::MongoContext
- 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:
-
If the object can be saved as a primitive, save it that way.
-
If the object is managed by a Mongo context, save and encode it as a DBRef.
-
If the object is managed by another context, save and store the class and id in a hash.
-
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.
{}
Instance Attribute Summary collapse
-
#attempt_id_conversion ⇒ Object
Normally, one uses BSON::ObjectId instances for the IDs on a stored Mongo object.
-
#encode_symbols ⇒ Object
If true, it encodes Symbol as a hash with a class name property, and then decodes them back into Symbol.
-
#persistent_attributes_blacklist ⇒ Object
Returns the value of attribute persistent_attributes_blacklist.
-
#persistent_attributes_whitelist ⇒ Object
Returns the value of attribute persistent_attributes_whitelist.
Attributes inherited from Poro::Context
#data_store, #klass, #primary_key
Instance Method Summary collapse
- #convert_to_data(obj, state_info = {}) ⇒ Object
- #convert_to_plain_object(data, state_info = {}) ⇒ Object
-
#data_store=(collection) ⇒ Object
Set the data store to the given collection.
- #fetch(id) ⇒ Object
-
#initialize(klass) ⇒ MongoContext
constructor
Takes the class for the context, and optionally the collection object up front.
- #remove(obj) ⇒ Object
- #save(obj) ⇒ Object
Methods included from FinderMethods
Methods inherited from Poro::Context
configure_for_class, factory, factory=, factory?, fetch, managed_class?, #primary_key_value, #set_primary_key_value
Methods included from Poro::Context::CallbackMethods
#callbacks, #clear_callbacks, #register_callback
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.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/poro/contexts/mongo_context.rb', line 38 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 # Some configuration variables @encode_symbols = false @attempt_id_conversion = true @set_encoding_method = :embedded_array # Initialize super(klass) end |
Instance Attribute Details
#attempt_id_conversion ⇒ Object
Normally, one uses BSON::ObjectId instances for the IDs on a stored Mongo object. However, one can design a database to use many different values as sthe primary key.
When this is set to true, fetch tries to convert the given ID into a BSON::ObjectId before doing a fetch. If the conversion fails, it tries using the raw value given. If this is set to false, then it always passes along the raw value, skipping the conversion step.
88 89 90 |
# File 'lib/poro/contexts/mongo_context.rb', line 88 def attempt_id_conversion @attempt_id_conversion end |
#encode_symbols ⇒ Object
If true, it encodes Symbol as a hash with a class name property, and then decodes them back into Symbol. If false, it converts them to String for storage. Defaults to false.
While one would think they want to preserve the type of the saved element, the change in storage method makes it harder to write Mongo queries on the data. Thus it is normally best to save symbols as strings for storage.
77 78 79 |
# File 'lib/poro/contexts/mongo_context.rb', line 77 def encode_symbols @encode_symbols end |
#persistent_attributes_blacklist ⇒ Object
Returns the value of attribute persistent_attributes_blacklist.
67 68 69 |
# File 'lib/poro/contexts/mongo_context.rb', line 67 def persistent_attributes_blacklist @persistent_attributes_blacklist end |
#persistent_attributes_whitelist ⇒ Object
Returns the value of attribute persistent_attributes_whitelist.
64 65 66 |
# File 'lib/poro/contexts/mongo_context.rb', line 64 def persistent_attributes_whitelist @persistent_attributes_whitelist end |
Instance Method Details
#convert_to_data(obj, state_info = {}) ⇒ Object
125 126 127 128 129 130 131 132 |
# File 'lib/poro/contexts/mongo_context.rb', line 125 def convert_to_data(obj, state_info={}) transformed_obj = callback_transform(:before_convert_to_data, obj) data = route_encode(transformed_obj, state_info) callback_event(:after_convert_to_data, data) return data end |
#convert_to_plain_object(data, state_info = {}) ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/poro/contexts/mongo_context.rb', line 114 def convert_to_plain_object(data, state_info={}) transformed_data = callback_transform(:before_convert_to_plain_object, data) # If it is a root record, and it has no class name, assume this context's class name. transformed_data['_class_name'] = self.klass if( transformed_data && transformed_data.kind_of?(Hash) && !state_info[:embedded] ) obj = route_decode(transformed_data, state_info) callback_event(:after_convert_to_plain_object, obj) return obj end |
#data_store=(collection) ⇒ Object
Set the data store to the given collection.
58 59 60 61 62 |
# File 'lib/poro/contexts/mongo_context.rb', line 58 def data_store=(collection) @@collection_map.delete(self.data_store && self.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
91 92 93 94 95 96 |
# File 'lib/poro/contexts/mongo_context.rb', line 91 def fetch(id) data = data_store.find_one( clean_id(id) ) obj = convert_to_plain_object(data) callback_event(:after_fetch, obj) return obj end |
#remove(obj) ⇒ Object
107 108 109 110 111 112 |
# File 'lib/poro/contexts/mongo_context.rb', line 107 def remove(obj) callback_event(:before_remove, obj) data_store.remove( {'_id' => primary_key_value(obj)} ) callback_event(:after_remove, obj) return obj end |
#save(obj) ⇒ Object
98 99 100 101 102 103 104 105 |
# File 'lib/poro/contexts/mongo_context.rb', line 98 def save(obj) callback_event(:before_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! callback_event(:after_save, obj) return obj end |