NAME

Class::PObject::Driver::file - Default PObject driver

SYNOPSIS

pobject Person => {
    columns   => ['id', 'name', 'email']
    datasource=> 'data',
    serializer => 'xml'
};

DESCRIPTION

Class::PObject::Driver::file is a default driver used by Class::PObject. Class::PObject::Driver::file is a direct subclass of Class::PObject::Driver. Refer to its manual for more details.

The only required class property is columns. If driver is missing, Class::PObject will default to file automatically. If datasource is missing, the driver will default to your system's temporary directory, which is /tmp on most *nix systems, and C:\TEMP on Windows.

This data source is a folder in your operating system, inside which objects will be stored. Pobject will create a folder for each object type inside the datasource folder, and will store all the objects of the same type in their own folders.

Other supported property is serialiazer, which defaults to storable if the value is missing. This serializer defines the serializing and de-serializing method used by object driver. Possible values are xml, which requires XML::Dumper to have been installed, and dumper, which requires Data::Dumper and 'storable'.

SUPPORTED FEATURES

Class::PObject::Driver::file overrides following methods of Class::PObject::Driver

  • save()

  • load()

  • remove()

In addition to standard methods, it also defines following methods of its own. These methods are just private/utility methods that are not invoked by PObjects directly. But knowledge of these methods may prove useful if you want to subclass this driver to cater it to your needs.

  • load_by_id($self, $pobject_name, \%properties, $id) is called from within load() method when an object is to be loaded by id. This happens if the pobject invokes load() method with a single digit:

    $article = Article->load(443)

    This is the most efficient way of loading objects using file driver.

    Although the effect of saying

    $article = Article->load({id=>443})

    is the same as the previous example, the latter will bypass optimizer, thus will not invoke load_by_id() method.

  • generate_id($self, $pobject_name, \%properties) is called whenever a new object is to be stored and new, unique ID is to be generated.

  • _dir($self, $pobject_name, \%propertries) is called to get the path to a directory where objects of this type are to be stored. If the directory hierarchy doesn't exist, it will create necessary directories automatically, assuming it has necessary permissions.

  • _filename($self, $pobject_name, \%properties) is called to get a path to a file this particular object should be stored into. _filename() will call _dir() method to get the object directory, and builds a filename inside this directory.

OBJECT STORAGE

Each object is stored as a separate file. File name pattern for each object file is defined in $Class::PObject::Driver::file::f global variable, and is obj%05.cpo by default, where %05 will be replaced with the id of the object, zero-padded if necessary.

Note: extension '.cpo' stands for Class::PObject.

SERIALIZATION

Objects are serialized and de-serialized with the help of freeze() and thaw() methods provided by its base class, Class::PObject::Driver.

ID GENERATION

file driver keeps its own record counter for generating auto-incrementing values for subsequent records more efficiently. Record counter is stored inside the object directory (_dir() method returns the path to this folder) in a file called "counter.cpo".

WARNING

Removing counter.cpo from the directory will force PObject to reset object ids. This may be a problem if there already are objects in the directory, and they may be overridden by new ids. I realize this is a scary limitation, which will eventually be addressed.

In the meanwhile, just don't make habit of removing counter.cpo :-).

EFFICIENCY

Since the driver doesn't keep an index of any kind, the most efficient way of loading the data is by its id. A relatively simple load(undef, {limit=n})> syntax is also reasonably efficient.

$p       = Person->load(451);
@people  = Person->load();
@group   = Person->load(undef, {limit=>100});

as load() becomes complex, the performance gets degrading:

@people = Person->load( {name=>"Sherzod"}, 
                        {sort=>'age', direction=>'desc', limit=>10, offset=>4} );

To perform the above search, the driver walks through all the objects available in the datasource, pushes all the objects matching 'name="sherzod"' to the data-set, then, just before returning the data set, performs sort, limit and offset calculations.

As you imagine, as the number of objects in the datasource increases, this operation will become more costly.

SEE ALSO

Class::PObject, Class::PObject::Driver::mysql, Class::PObject::Driver::file

COPYRIGHT AND LICENSE

For author and copyright information refer to Class::PObject's online manual.