NAME

Podius::Persistence::ComponentCache - persistent component manager and read/write cache


SYNOPSIS

  use Podius::Persistence::ComponentCache;
  $cache = new Podius::Persistence::ComponentCache(
    new Podius::Persistence::Media::RDBMS('Oracle', 'mag', 'user', 'pass'),
    new Podius::Persistence::Media::RawData('../../rawdata'),
    new Podius::Persistence::ComponentPropertyMap,
    new Podius::Component::Root(new Parse::PerlConf("my.cfg"), ['Edition', [1]])
  );


DESCRIPTION

Components are stored in managed database using serialization. The ComponentCache object provides the persistent component storage and manages component memory (stores components only once, loads properties on demand, swaps components if the component limit is reached etc.).

The ComponentCache object uses: * Podius::Component::Root object (the only transient component in the component tree; it is created in constractor) * Persistence::Media (main and optionally secondary, also there is a posibility of two primary medias, one for load and one for save) * Persistence::ComponentPropertyMap object to ask about component property mapping to a persistence medias.

To write.

The module provides debug info via the Debug manpage module and throws exceptions via the Exception manpage module.


REQUIREMENTS

the Exception manpage, the Debug manpage, the Data::NeatFormat manpage. the Podius::Component manpage, the Podius::Component::Root manpage, the Podius::Persistence::ComponentIterator manpage.


CONSTRUCTORS

new

description
Class constructor.

parameters
  * class name (as in any constructor)
  * primary persistence-media ref of Podius::Persistence::Media
  * secondary persistence-media ref of Podius::Persistence::Media
  * component-property-man ref of Podius::Persistence::ComponentPropertyMap
  * optionally root ref of Podius::Component::Root.

If the persistence-media argument is array ref, it is treated as list of two persistence medias (load and save). Normally loading and saving done using the same persistence-media.

returns
New formed cache reference.


METHODS

get_root

description
Cache root component is set in constructor. Root is the only component, which is set (non-persistent) and not initialized from database.

returns
Reference to the spacial root component of the cache (or undef, if not defined such).

set_sizes

description
Sets cache sizes: limit for a number of components stored in the internal storage (size) and limit for a number of components participating in a single cache operation, like [get/delete]_components (bunch_max).

Cache swaps out latest components if needed, to ensure there are always bunch_max free places in the component storage before any operatrion.

Normally, the expression (size/bunch_max - 1) gives the number of cache operations after them the loaded component is still in the memory. After this number of operations it is unsafe to suppose a component reference is still valid, use $component->lock to suppose this.

This method may only be called at the beginning or after free method call.

parameters
  * size of the component storage
  * limit of components to request from persistence media at once.

set_preload_depth

description
Sets depth of the internal preloads structure. It is a number of last component groups (given by get_components) to optimize by preloading properties in a entire component group when one component from the matched group requests to load properties. This normally optimizes the number of calls to persistence media methods, because there are big chances that rest components in the group will shortly request the same properties and they are already preloaded and cached.

Use parameter 0 to disable preloading optimizations.

This method may only be called at the beginning or after free method call.

parameters
Positive number or zero (default 3).

set_component_property_merge_callback

description
Sets a component property merge callback, which is called when component properties (local and stored) can't be merged automatically. The callback must receive 2 components (local and stored) and 2 conflicting properties (local and stored) inside these components. It should return 1 if it did merging and 0 if it failed to merge, see Podius::Component::merge and Podius::Property::merge methods for more details.

parameters
CODE reference

set_component_delete_callback

description
Sets a component delete callback, which is called when component, which was previously used in the cache, does not exist anymore in the persistent storage. The callback must receive one local component. It should return 0 if the local component should be destroyed (persistent storage wins) or 1 if the local component should be left (local storage wins).

parameters
CODE reference

set_read_only

description
Sets the read-only cache mode. In the read-only mode, all changes done to component properties are lost. There are also some optimizations in this mode, say, transactions are not really started and stopped, everything is done outside of transactions.

In the strict read-only mode (value is 2), calling create_component is forbidden; in the non strict read-only mode (value is 1), new components can be created, but they are not saved and when they are swapped out (without really creating/saving them), there will be errors in accessing them again. For this reason, it is not suggested to create new components in this mode, or they should be locked not to be swapped out.

This method may only be called at the beginning or after free method call. This method can't be called inside transaction.

parameters
  * optional boolean value (default is 1)

begin_tx

usage
  $cache->begin_tx();
description
Starts transaction. Most queries to the cache must be inside transaction. The caller of begin_tx will probably (good practice) close transaction after all queries using one of two methods: commit_tx or abort_tx (automatical default).

This acctually starts a native transaction in persistence media(s).

This call is now not needed for valid cache work. Changes to components, done outside the transaction are auto-commited by persistence media without rollback ability. But this method is better be called in most cases immideately after creating cache.

returns
Nothing. On error (transaction can't be started) throws exception.

commit_tx

usage
  $cache->commit_tx();
description
Finishes transaction and updates persistent storage. The operations are: * saving all modified components using persistence media * deleting clones * sending commit to persistence media

returns
Nothing. On error (transaction can't be finished) throws exception.

abort_tx

usage
  $cache->abort_tx();
description
Aborts transaction and restores cache (from persistent storage and internal structures). The operations are: * sending rollback to persistence media * reloading all modified component (### or freeing cache?) * deleting clones

returns
Nothing. On error (transaction can't be aborted) throws exception.

free

usage
  $cache->free();
description
Frees memory. All stored components are removed.

returns
Nothing. On error throws exception.

get_component

usage
  $component = $cache->get_component($type, $id);
description
Returns component from the cache. If the cache does not contain the component, it is updated using persistence media.

parameters
  * $type - component type
  * $id   - component id, unique in $type
returns
Reference to the component. If it does not exist - throws exception.

example
  $cache->get_component('Article', 10);

get_components

usage
  @components = @{$cache->get_components($type, $id_array_ref)};
description
Returns reference to array of components from the cache. If cache does not contain the component, the cache is updated from Persistence Media.

The method is optimized to retrieve all components of same type at once.

additions
If parameter $id_array_ref is not defined, returns ALL components of this class. If both parameters are not defined, returns ALL components in database. The additions must not be used in applications, but only in administrative scripts for full database managing.

parameters
  * $type - component type
  * $id_array_ref - reference to array of component ids, unique in $type
returns
Reference to array of components (or undefs).

example
  $cache->get_components('Edition', [1, 2]);  # use strict;

find_components

usage
  $components = $cache->find_components($type, "name =~ 'my cats'");
  $count = $cache->find_components($type, $cond, want_count => 1);
  $ids = $cache->find_components($type, $cond, want_ids => 1);
  $iterator = $cache->find_components($type, $cond, want_iterator => 1);
description
Finds all components of the given type matching the given condition. The search is done directly on the storage without traversing component trees.

parameters
  * $type - component type
  * $cond - condition, see Podius::Query for info
  * %params

Possible params keys (boolean, code or integer):

  want_count - return the number of found components instead
  want_ids - return the component ids instead
  want_iterator - return the component iterator instead of arrayref
  sort - sorting function (gets two components, returns -1, 0 or 1)
  grep - filtering function (gets component, returns boolean)
  limit - maximal number of components/ids to return
  start - skip the given number of components/ids
  caching - string with caching policy, default is usually 'rw'

If sort is not given the returned ids are sorted numerically.

Instead of passing sort function, you may pass a method name (usually a property name, like ``name'' or ``-last_modified'') with optional dash prefix meaning reverse sorting. In this case the numeric sorting is done for numeric values and the string sorting is done otherwise. If you wish to always force the string sorting or to apply multiple conditions, supply your own sorting function.

returns
Arrayref of found components (or other depending on params).

last_find_components_count

usage
  my $count = $cache->last_find_components_count;
description
Returns the component count in the last find_components method call, before any parameters like grep or limit or start are applied.

returns
Non-negative integer or undef (prior to any find_components method calls).

create_component

usage
  my $new_component = $cache->create_component($type);
  my $new_component = $cache->create_component($init_component);
description
Creates new component. It will be actually saved for sure on commit_tx only and will be deleted on abort_tx.

parameters
  * type - component type
  * id - optional id for a newly created component
  * init_component - optional component to copy properties from

Additionally, as a shortcut it is possible to pass init_component instead of type, in this case the type of init_component is used.

By default (if id is false) a new free id is assigned for the new component.

returns
Reference to the newly created component.

delete_component

usage
  delete_component($type, $id);
description
Deletes the specified component from the cache and persistent storage.

parameters
  * $type - component type
  * $id   - component id, unique in $type

or

  * $type - component class
  * $component - component itself to delete

or

  * reference to the component to be deleted
returns
1 on success, on error (the component is not deleted or not found) throws exception.

example
  $cache->delete_component('Article', 10);

verify_component

usage
  verify_component($type, $id);
description
Verifies that the specified component exists in the persistent storage.

If the component existance was changed from the time it was first gotten by the cache, i.e. it does not exist anymore in the persistent storage, the component-delete-callback is called and the component is deleted from (0) or kept in (1) the cache.

You probably only want to call this method from an interactive application, which uses many short transactions, so the state of components in the persistent storage could be changed between transactions and you want to verify that the specified component is still valid before modifying it.

It is optional, you will get the effect of calling this method automatically on save if something had happened with that component.

parameters
  * $type - component type
  * $id   - component id, unique in $type

or

  * $type - component class
  * $component - component itself to be verified

or

  * reference to the component to be verified
returns
In these 2 cases the component-delete-callback is not called:
  * undef - the component does not exist and unknown to cache
  *    -1 - the component exists in the persistent storage

In these 2 cases the component was deleted from the persistent storage and the component-delete-callback is called and its return value is returned:

  * 0 - returned 0, lose it
  * 1 - returned 1, keep it

example
  my $component = $cache->get_component('Publishable', 1);
  $cache->verify_component($component);

create_persistent_component_iterator

description
Component iterators is the way to work with component collections. Here component collection (for which iterator is created) is persistent, property of persistent component (container).

parameters
  * $type - container component type
  * $id   - container component id, unique in $type
  * $collection_name - name of collection to iterate

or

  * $type - container component type
  * $component - container component itself to work on
  * $collection_name - name of collection to iterate

or

  * $component - container component itself to work on
  * $collection_name - name of collection to iterate
returns
Reference to the new created component iterator.

create_component_iterator

description
Component iterators is the way to work with component collections. Here component collection (for which iterator is created) is non-persistent, however components themselves are persistent.

If you use the second variant with queries, query result must be one or more columns and ids are taken from the first column.

parameters
  * $type - stored component type
  * $ids  - stored component ids

or

  * $type - stored component type
  * $query - low level query for persistence media to get ids
returns
Reference to the new created component iterator.

create_component_clone

description
Clone is a temporary transient component copy, which can be modified instead of the source component and then replace it by replace_cloned_component method. Created clones are valid inside the current transaction only.

parameters
  * $type - component type
  * $id   - component id, unique in $type

or

  * $type - component type
  * $component - component itself to clone

or

  * reference to the component to be cloned
returns
Reference to the new created component clone.

replace_cloned_component

description
When the modification to the clone is done, this method enables replacing the source component by the clone.

parameters
Reference to the clone, which will replace the source component.

returns
1 on success, undef on error.

save_all_modified_components

usage
  $cache->save_all_modified_components();
description
Updates database from cache.

MUST BE OPTIMIZED to save data of all components of same class in one call.

returns
1 on success, undef on error.

reload_all_modified_components

usage
  reload_all_modified_components();
description
Reloads modified components from the persistent storage to cache storage.

returns
1 on success, undef on error.

delete_all_clones

description
Automatically called at end of transaction, but can be called at the middle too. Clones are temporary transient components, which are valid inside current transaction.

returns
1 on success, undef on error.

reset_high_id

description
If no parameter given, all component types are considered.

parameters
optional scalar (super component type) or array ref (super component types)

returns
1 on success. On error throws exception.