Class: Poro::Context

Inherits:
Object
  • Object
show all
Includes:
CallbackMethods, FindMethods
Defined in:
lib/poro/context.rb,
lib/poro/context.rb,
lib/poro/context.rb,
lib/poro/context.rb

Overview

This is the abstract superclass of all Contexts.

For find methods, see FindMethods.

The Context is the responsible delegate for directly interfacing with the persistence layer. Each program class that needs persistence must have its own context instance that knows how to store/retrive only instances of that class.

All instances respond to the methods declared here, and must conform to the rules described with each method.

One normally uses a subclass of Context, and that subclass may have extra methods for setting options and configuring behavior.

Defined Under Namespace

Modules: CallbackMethods, FindMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CallbackMethods

#callbacks, #clear_callbacks, #register_callback

Methods included from FindMethods

#data_store_find, #find, included

Constructor Details

#initialize(klass) {|_self| ... } ⇒ Context

Initizialize this context for the given class. Yields self if a block is given, so that instances can be easily configured at instantiation.

Subclasses are expected to use this method (through calls to super).

Yields:

  • (_self)

Yield Parameters:

  • _self (Poro::Context)

    the object that the method was called on



65
66
67
68
69
70
# File 'lib/poro/context.rb', line 65

def initialize(klass)
  @klass = klass
  self.data_store = nil unless defined?(@data_store)
  self.primary_key = :id
  yield(self) if block_given?
end

Instance Attribute Details

#data_storeObject

The raw data store backing this context. This is useful for advanced usage, such as special queries. Be aware that whenever you use this, there is tight coupling with the underlying persistence store!



78
79
80
# File 'lib/poro/context.rb', line 78

def data_store
  @data_store
end

#klassObject (readonly)

The class that this context instance services.



73
74
75
# File 'lib/poro/context.rb', line 73

def klass
  @klass
end

#primary_keyObject

Returns the a symbol for the method that returns the Context assigned primary key for the managed object. This defaults to :id



86
87
88
# File 'lib/poro/context.rb', line 86

def primary_key
  @primary_key
end

Class Method Details

.configure_for_class(klass) {|context| ... } ⇒ Object

A convenience method for further configuration of a context over what the factory does, via the passed block.

This really just fetches (and creates, if necessary) the Context for the class, and then yields it to the block. Returns the context.

Yields:

  • (context)


40
41
42
43
44
# File 'lib/poro/context.rb', line 40

def self.configure_for_class(klass)
  context = self.fetch(klass)
  yield(context) if block_given?
  return context
end

.factoryObject

Returns the application’s ContextFactory instance.



47
48
49
# File 'lib/poro/context.rb', line 47

def self.factory
  return ContextFactory.instance
end

.factory=(context_factory) ⇒ Object

Sets the application’s ContextFactory instance.



52
53
54
# File 'lib/poro/context.rb', line 52

def self.factory=(context_factory)
  ContextFactory.instance = context_factory
end

.factory?Boolean

Returns true if there is a factory assigned to the application.

Returns:

  • (Boolean)


57
58
59
# File 'lib/poro/context.rb', line 57

def self.factory?
  ContextFactory.has_instance?
end

.fetch(obj) ⇒ Object

Fetches the context for the given object or class from ContextFactory.instance. Returns nil if no context is found.



21
22
23
24
25
26
27
# File 'lib/poro/context.rb', line 21

def self.fetch(obj)
  if( obj.kind_of?(Class) )
    return self.factory.fetch(obj)
  else
    return self.factory.fetch(obj.class)
  end
end

.managed_class?(klass) ⇒ Boolean

Returns true if the given class is configured to be represented by a context. This is done by including Poro::Persistify into the module.

Returns:

  • (Boolean)


31
32
33
# File 'lib/poro/context.rb', line 31

def self.managed_class?(klass)
  return self.factory.context_managed_class?(klass)
end

Instance Method Details

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

Convert a plain ol’ ruby object into the data store data format this context represents.

For non-embedded persistent stores, only records of the type for this context must be handled. However, for embedded stores–or more complex embedded handling on non-embedded stores–more compex rules may be necessary, handling all sorts of data types.

The second argument is reserved for state information that the method may need to pass around, say if it is recursively converting elements. Any root object returned from a “find” in the data store needs to be able to be converted



184
185
186
187
188
189
# File 'lib/poro/context.rb', line 184

def convert_to_data(obj, state_info={})
  transformed_obj = callback_transform(:before_convert_to_data, obj)
  data = transformed_obj
  callback_event(:after_convert_to_data, data)
  return data
end

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

Convert the data from the data store into the correct plain ol’ ruby object for the class this context represents.

For non-embedded persistent stores, only records of the type for this context must be handled. However, for embedded stores–or more complex embedded handling on non-embedded stores–more compex rules may be necessary, handling all sorts of data types.

The second argument is reserved for state information that the method may need to pass around, say if it is recursively converting elements. Any root object returned from a “find” in the data store needs to be able to be converted



165
166
167
168
169
170
# File 'lib/poro/context.rb', line 165

def convert_to_plain_object(data, state_info={})
  transformed_data = callback_transform(:before_convert_to_plain_object, data)
  obj = transformed_data
  callback_event(:after_convert_to_plain_object, obj)
  return obj
end

#fetch(id) ⇒ Object

Fetches the object from the store with the given id, or returns nil if there are none matching.



113
114
115
116
117
# File 'lib/poro/context.rb', line 113

def fetch(id)
  obj = convert_to_plain_object( clean_id(nil) )
  callback_event(:after_fetch, obj)
  return obj
end

#primary_key_value(obj) ⇒ Object

Returns the primary key value from the given object, using the primary key set for this context.



100
101
102
# File 'lib/poro/context.rb', line 100

def primary_key_value(obj)
  return obj.send( primary_key() )
end

#remove(obj) ⇒ Object

Remove the given object from the persisten store using this context.

Subclasses do not need to call super, but should follow the given rules:

Returns the removed object.

If the object is successfully removed, the id is set to nil.

Raises an Error is the remove fails.



146
147
148
149
150
151
# File 'lib/poro/context.rb', line 146

def remove(obj)
  callback_event(:before_remove, obj)
  obj.id = nil if obj.respond_to?(:id=)
  callback_event(:after_remove, obj)
  return obj
end

#save(obj) ⇒ Object

Saves the given object to the persistent store using this context.

Subclasses do not need to call super, but should follow the given rules:

Returns the saved object.

If the object has never been saved, it should be inserted and given an id. If the object has been added before, the id is used to update the existing record.

Raises an Error if save fails.



130
131
132
133
134
135
# File 'lib/poro/context.rb', line 130

def save(obj)
  callback_event(:before_save, obj)
  obj.id = obj.object_id if obj.respond_to?(:id) && obj.id.nil? && obj.respond_to?(:id=)
  callback_event(:after_save, obj)
  return obj
end

#set_primary_key_value(obj, id) ⇒ Object

Sets the primary key value on the managed object, using the primary key set for this context.



106
107
108
109
# File 'lib/poro/context.rb', line 106

def set_primary_key_value(obj, id)
  method = (primary_key().to_s + '=').to_sym
  obj.send(method, id)
end