Eric Wolf
and 1 contributors

NAME

Data::ObjectStore - store and lazy load perl objects, hashes and arrays in a rooted tree on-disc.

SYNOPSIS

 use Data::ObjectStore;

 my $store = Data::ObjectStore::open_store( '/path/to/data-directory' );

 # each store has a root to hang all other data structures from
 my $root = $store->load_root_container;

 # fetches the apps data from the root. If none exists, it uses the
 # default given {} as the app data structure
 my $apps = $root->get_apps({});

 my $newApp = $store->create_container( { name => "CoolNewApp" } );

 $apps->{CoolNewApp} = $newApp;

 my $users = $newApp->set_users_by_name( {} );
 my $admin = $store->create_container( { name => "Admin", isAdmin => 1 } );
 $users->{admin} = $admin;
 $newApp->add_to_users( $admin );

 $store->save; #new app with its admin user saved to store

 ... lots more users added

 #
 # big hashes and lists are chunked and not loaded all into RAM at once.
 #
 my $zillion_users = $newApp->get_users;
 my $zillion_users_by_name = $newApp->get_user_by_name;

 my $fred = $zillion_users_by_name->{fred};

DESCRIPTION

Data::ObjectStore preserves data structures on disc and provides them on an add needed basis. Large hashes and arrays are not loaded in memory all at once while still adhering to the normal perl hash and array API. The data structures can contain any arraingment of hashes, arrays and Data::ObjectStore::Container objects which may be subclassed. Subclassing is described below.

The object database self vacuums; any entry that cannot trace back to the root node is deleted and the storage space reclaimed.

Data::ObjectStore operates directly and instantly on the file system. It is not a daemon or server and is not thread safe. It can be used in a thread safe manner if its controlling program uses locking mechanisms.

METHODS

open_store( %options )

Starts up a persistance engine that stores data in the given directory and returns it. Currently supported options :

group

permissions group id for the data store on disc.

data_store

Returns the Data::RecordStore implementaion.

empty_cache

Empties the cache, if any.

fetch( id, force )

Returns the object indexed by that id. Dies if the saved object's package cannot be found. If force is given, it will not die if the object's package can't be found, but the object will be instantiated as a simple Data::ObjectStore::Container.

load_root_container()

Fetches the root node of the store, a Data::ObjectStore::Container object.

create_container( optionalClass, { data } )

Returns a new Data::ObjectStore::Container container object or a subclass, depending if the optional class parameter is supplied. If provided with data, the object is initialized with the data.

If the object is attached to the root or a container that is ultimately attached to the root, it will be saved when save is called.

save(optional_obj)

When called, this stores the optional_obj or all objects that have been changed since the last time save was called. Note that this deletes the objects that are not connected to root.

existing_id( obj )

If the object already has an id in the store, this returns that id. If it does not, it returns undef.

quick_purge

This is a memory intensive version of vaccuuming the store. It maintains a hash of all the items to not purge in memory as it runs. This shouldn't be run if the store is really really big.

upgrade_store( '/path/to/directory' )

This updagrades the object store to the current version. Back up the store before applying.

info()

Returns a hash of info about this opened data store. Updating the hash has no effect.

 * db_version
 * ObjectStore_version
 * created_time
 * last_update_time

get_db_version

Returns the version of Data::RecordStore that this was created under.

get_store_version

Returns the version of Data::ObjectStore that this was created under.

get_created_time

Returns when the store was created.

get_last_update_time

last_updated( obj )

Returns the timestamp the given object was last updated

created( obj )

Returns the timestamp the given object was created.

Returns the last time this store was updated.

lock( @names )

Adds an advisory (flock) lock for each of the unique names given.

unlock()

Unlocks all names locked by this thread

sync()

Asks the data provider to sync to persistance.

SUBCLASSING

Blessed objects must be a subclass of Data::ObjectStore::Container in order to be able to be stored in the object store. _init and _load can be useful to override.

 package Mad::Science::User;
 use Data::ObjectStore;
 use base 'Data::ObjectStore::Container';

 # called when an object is newly created
 sub _init {
   my $self = shift;
   $self->set_status( "NEWLY CREATED" );
   $self->set_experiments([]);
 }

 # called when the object is loaded from the store
 sub _load {
   my $self = shift;
   print "Loaded " . $self->get_name . " from store";
   if( @{$self->get_experiments} > 0 ) {
     $self->set_status( "DOING EXPERIMENTS" );
   }
 }

 sub evacuate {
   my $self = shift;
   $self->set_status( "HEADING FOR THE HILLS" );
 }

Data::ObjectStore::Container

 Persistant Perl container object.

SYNOPSIS

 $obj_A = $store->create_container;

 $obj_B = $store->create_container( {
                          myfoo  => "This foo is mine",
                          mylist => [ "A", "B", "C" ],
                          myhash => { peanut => "Butter" }
                                  } );

 $obj_C = $store->create_container( 'My::Subclass' );

 $obj_D = $store->create_container( 'My::Othersubclass', { initial => "DATA" } );

 #
 # get operations
 #
 print $obj_B->get_myfoo; # prints "this foo is mine"

 print $obj_B->get( "myfoo" ); # prints "this foo is mine"

 print $obj_B->get_myhash->{peanut}; # prints 'butter'

 $val = $obj_A->get_val; # $val is now undef

 $val = $obj_A->get_val("default"); # $val is now 'default'

 $val = $obj_A->get_Val("otherdefault"); # $val is still 'default'

 $val = $obj_A->set_arbitraryfield( "SOMEVALUE" ); # $val is 'SOMEVALUE'

 #
 # set operations
 #
 $obj_C->set( "MYSET", "MYVAL" );
 $val = $obj_C->get_MYSET; # $val is 'MYVAL'

 $obj_B->set_A( $obj_A );

 $root = $store->load_root_container;

 $root->set_B( $obj_B );

 #
 # list operations
 #
 $mylist = $obj_B->add_to_mylist( "D" ); #mylist now 'A','B','C','D'

 $newlist = $obj_B->add_to_newlist( 1, 2, 3, 3, 3 );
 print join(",", $newlist);  # prints 1,2,3,3,3

 $obj_B->remove_from_newlist( 3 );
 print join(",", $newlist);  # prints 1,2,3,3
 $obj_B->remove_all_from_newlist( 3 );
 print join(",", $newlist);  # prints 1,2

 # yes, the $newlist reference is changed when the object is operated on with list operations

DESCRIPTION

This is a container object that can be used to store key value data where the keys are strings and the values can be hashes, arrays or Data::ObjectStore::Container objects. Any instances that can trace a reference path to the store's root node are reachable upon reload.

This class is designed to be overridden. Two methods are provided for convenience. _init is run the first time the object is created. _load is run each time the object is loaded from the data store. These methods are no-ops in the base class.

METHODS

set( field, value )

Sets the field to the given value and returns the value. The value may be a Data::ObjectStore::Container or subclass, or a hash or array reference.

get( field, default_value )

Returns the value associated with the given field. If the value is not defined and a default value is given, this sets the value to the given default value and returns it.

The value may be a Data::ObjectStore::Container or subclass, or a hash or array reference.

fields

Returns a list reference of all the field names of the object.

remove_field( field )

Removes the field from the object.

vol( key, value )

This sets or gets a temporary (volatile) value attached to the object.

clearvol( key )

This unsets a temporary (volatile) value attached to the object.

store

Returns the Data::ObjectStore that created this object.

lock( @names )

Adds an advisory (flock) lock for each of the unique names given. This may not be called twice in a row without an unlock in between.

unlock

Unlocks all names locked by this thread

_init

    This is called the first time an object is created. It is not
    called when the object is loaded from storage. This can be used
    to set up defaults. This is meant to be overridden.

_load

    This is called each time the object is loaded from the data store.
    This is meant to be overridden.

AUTHOR Eric Wolf coyocanid@gmail.com

COPYRIGHT AND LICENSE

       Copyright (c) 2012 - 2019 Eric Wolf. All rights reserved.  This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

VERSION Version 2.10 (Aug, 2019))