NAME

ORM - Object relational mapper for Perl.

SYNOPSIS

  use Music::Song;
  use Music::Artist;

  # Show number of songs performed by 'Gorillaz'
  $M = Music::Song->M;
  print Music::Song->count( filter=>( $M->artist->name eq 'Gorillaz' ) );

  # Find all artists matching like expression 'G%'
  $M = Music::Artist->M;
  @artist = Music::Artist->find( filter=>$M->name->_like( 'G%' ) );

  # Add new song to database
  $error = ORM::Error->new;
  $song  = Music::Song->new
  (
      error => $error,
      prop  =>
      {
          artist    => $artist,
          year      => 2005,
          title     => "September's Gone",
          content   => "/home/user/music/Gorillaz/September's Gone.mp3",
      },
  );
  print $error->text;
  print $song->title,"\n" if( $song );

DESCRIPTION

ORM is Perl library that implements object-relational mapping. Its features are much similar to those of Java's Hibernate library, but interface is much different and easier to use.

Please start reading with ORM::Tutorial.

General features

  • Inheritance support

  • Nested transactions support

  • No SQL queries needed

  • Full-featured objects search using native Perl-expressions

  • One-to-many and many-to-many relations

  • Foreign keys emulation

  • Objects changes history

  • Lazy loaded objects

  • Objects statistics (using GROUP BY)

  • Third party classes support

  • Autogenerated acessors/mutators

  • Objects caching

  • Separate RDBMS layer

Information about planned features available in 'TODO.txt' file in package distribution.

Basic definitions

Initial class

direct descendant of 'ORM' class. Initial class is base class for all persistent classes. It's purpose is to:

  • initialize object's storage engine

  • set site-wide global options

  • define default classes behaviour by redefining special ORM's methods

  • define methods common to all its descendants

Primary class

direct descendant of initial class

Intermediate class

class, that can not have its own instances and can be used only as base to other classes.

Lazy-loaded state

State of the object when its data from database is loaded into memory partially or not at all.

Fully-loaded state

State of the object opposite to lazy-loaded. That means that all object's data are loaded from database into memory.

Meta-object and meta-properties

Meta-object is an object-oriented abstraction of the data stored in relational database. Depending on context it means:

  • particular object of the class

  • some object of the class

  • any object of the class

All properties of meta-object (even non-object properties). are meta-objects too. Meta-objects are used to construct meta-expressions.

Meta-expression

Meta-expression is object of class ORM::Expr or descendant. Meta-expressions are constructed in the way the plain Perl expressions are constructed.

Meta-expressions are constructed on client side in object-oriented fashion and executed on RDBMS server previously converted to SQL expression.

Common notes

Almost all methods and constructors accepts arguments in hash form. There is a brief usage description for each method titled 'Use'. It shows all arguments that particular method accepts and types of every argument. Types are: class name or usual data types as 'string', 'integer', 'boolean' etc. Special case is 'undef' means that value for this argument can be undefined.

Every constructor, method or property that accepts 'error' argument implies it to be object of class ORM::Error or undef. After call is completed this object contains all errors occured during method execution. When 'error' argument is undef or not specified, all errors are silently ignored. In future releases ommitted 'error' argument will be the reason to throw exception in case of error. Cases when 'error' is processed in different way are documented particularly.

Not documented parts of the ORM interface are subject to further changes.

CONSTRUCTORS

new

Use:

  $obj = $class->new
  (
      prop      => { prop => [string|OBJECT] ... },
      error     => ORM::Error,
      history   => boolean,
      temporary => boolean,
      suspended => boolean,
  )

Construct new object and store it in database.

prop

Hash reference containing values of properties of the object being constructed. It is possible to pass string values to properties those are expected to be objects, in that case constructor tries to convert string values into objects by calling __ORM_db_value method of the $class.

history

Specifies whether to store the operation in history table (see ORM::History). If ommitted then default value for this class is used (see history_is_enabled).

temporary

if set to true, then created object will not be stored in database. You can store that kind of objects later using $obj->make_permanent (to be implemented).

suspended

(This option is about to be implemented in future releases.)

if set to true, then constructor's behavior is similar to those with 'temporary'=1 but after creation object appended to the internal list of suspended objects.

Later you can flush all suspended objects into database at one time by calling $class->flush_suspended. This allows to optimize write of objects into database by means of database server, e.g. ORM::Db::DBI::MySQL storage engine will use multiple-rows form of INSERT statement:

  INSERT INTO table (a,b,c) VALUES (1,1,1),(2,2,2),(3,3,3)...

find

Use:

  @obj = $class->find
  (
      filter     => ORM::Expr || undef,
      order      => ORM::Order || undef,
      lazy_load  => boolean,
      page       => integer || undef,
      pagesize   => integer || undef,
      error      => ORM::Error,
      return_ref => boolean,
      return_res => boolean,
  )

Find objects stored in database.

filter

Specifies condition that found objects should satisfy to. If undefined then all objects are returned.

order

Specifies the way that found objects should be ordered in (see ORM::Order). If this option is an array reference then it is passed to ORM::Order constructor like this:

  $order = ORM::Order->new( @$order );
lazy_load

If 'lazy_load' specified then only data from tables corresponding to base class $class will be loaded initially.

For example suppose you have class A (table 'A') and class B descendant of A (tables 'A','B'), and there are instances of both classes. When you call A->find( lazy_load=>0 ), then ORM loads data by two queries, first is for select required rows from table 'A', second is for select rows from 'B' with proprietary data of instances of B. When you call A->find( lazy_load=>1 ), then ORM uses only first query, and therefore all instances of B are lazy-loaded (miss data from table 'B').

page

If pagesize is specified then result set is divided to pages with 'pagesize' objects per page and page numbered 'page' is returned. Pages are numbered starting with 1. If pagesize is specified and page is omitted then page number is implied to be 1.

pagesize

Size of the page to be returned.

Returned value depends on the following:

  • If called in scalar context returns first object from result set

  • If called in array context returns array of found objects

  • If return_ref option is true then return value is reference to the array of found objects with no respect to context.

  • If return_res option is true then return value is object of class ORM::ResultSet, found objects can be accesed one by one via $result->next. It is useful to retrieve large amount of objects. Pays no respect to context and 'return_ref'.

find_id

Use:

  $obj = $class->find_id
  (
      id        => integer,
      lazy_load => boolean,
      error     => ORM::Error,
  );

Find object stored in database by its ID. This is a shorthand for find when you know ID of the object to find.

id

ID of the object to find.

lazy_load

In this context 'lazy_load' means that object will not be loaded at all. Loading of object data will be delayed until its properties will be demanded.

find_id() with 'lazy_load' is mostly useful when utilized by ORM->stat().

If lazy_load option is undef then by default all fields of the object are loaded irrespective of prefer_lazy_load option to _init.

When using find_id with lazy_load option remember that there is no way to detect actual object's class during construction, therefore constructed object is instance of class $class for which find_id method is called. When an object's property is first accessed finish_loading is called to completely load fields of the object, after that class of the object is being changed to actual object's class as recorded in database. finish_loading is also being implicitly called in update method.

find_or_new

Use:

  $obj = $class->find_or_new
  (
      prop      => { prop_name => [string|OBJECT] ... },
      lazy_load => boolean,
      history   => boolean,
      error     => ORM::Error,
  )

Find object with properties specified by prop.

If there is no object with that properties then create it.

If there is more than one object with that properties then error message returned and return value is undef.

stat

Use:

  $class->stat
  (
      data        => { alias=>ORM::Expr, ... },
      preload     => { alias=>boolean, ... } || undef,
      filter      => ORM::Expr || undef,
      group_by    => [ ORM::Ident|ORM::Metaprop, ... ] || undef,
      post_filter => ORM::Expr || undef,
      order       => ORM::Order || undef,
      lazy_load   => boolean,
      page        => integer || undef,
      pagesize    => integer || undef,
      count       => boolean,
      error       => ORM::Error,
      return_res  => boolean,
  )

Return custom information about objects of the $class and related objects. You can find some exmples of stat usage in ORM::Tutorial.

data

Defines the data to be fetched. Data is set of properties of objects of $class and related classes.

Each key of 'data' option is alias for property to be fetched, each value is meta-expression that correspond to the property.

preload

By default every property specified in 'data' that is an ORM-object is fetched as its ID and then depending on 'lazy_load' option constructed using find_id as fully-loaded object (with separate SQL-query for each object) or as lazy-loaded (without any SQL-query).

You can use 'preload' option to force load of objects in single SQL-query. To do so just add record to 'preload' hash where key is an alias from 'data' hash and value is true perl expression.

You can examine how exactly it works using ORM::DbLog.

filter

Specifies condition that fetched data should satisfy to. This is analogue to SQL 'WHERE' clause.

group_by

This is analogue to SQL 'GROUP BY' clause.

post_filter

This is analogue to SQL 'HAVING' clause.

order

Specifies the way that fetched data should be ordered in (see ORM::Order). If this option is an array reference then it is passed to ORM::Order constructor like this:

  $order = ORM::Order->new( @$order );
lazy_load

Fetched objects are initialized by find_id. Value of 'lazy_load' option to stat is passed to find_id directly.

page

If pagesize is specified then result set is divided to pages with 'pagesize' items per page and page numbered 'page' is returned. Pages are numbered starting with 1. If pagesize is specified and page is omitted then page number is implied to be 1.

pagesize

Size of the page to be returned.

count

If 'count' is set to true then result of the call is amount of resulting rows. Also options 'page' and 'pagesize' have no sence together with 'count'.

return_res

If return_res option is true then return value is an iterator which is object of class ORM::ResultSet, found objects can be accesed one by one via $result->next. It is useful to retrieve large amount of objects.

CLASS METHODS

count

Use:

  $count = $class->count
  (
      filter   => ORM::Expr || undef,
      error    => ORM::Error,
  )

Return number of objects satisfying the filter condition.

filter

If 'filter' argument is specified then only objects that satisfy 'filter' condition are counted. If 'filter' is omitted then total number of objects of the class $class (and descendants) is returned.

new_transaction

Use:

  $ta = $class->new_transaction( error=>ORM::Error );

Begins transaction. Transaction commits when object $ta is destroyed. $class is initial class.

Note that transactions are assigned to the initial class. If $class is not an initial class then created transaction is assigned to the initial class of the $class. If $class is an instance of some class, then transaction is assigned to the initial class of the instance's class.

base_class

Use:

  $class_name = $class->base_class();

Return name of base class for $class.

primary_class

Use:

  $class_name = $class->primary_class();

Return name of primary class for $class.

initial_class

Use:

  $class_name = $class->initial_class();

Return name of initial class for $class.

history_is_enabled

Use:

  $state = $class->history_is_enabled;
  $state = $class->history_is_enabled( $new_state );

$class is initial class. If $new_state is specified then value of flag 'history_is_enabled' will be replaced to $new_state. $new_state can be undef, in that case global default value will be used instead.

prefer_lazy_load

Use:

  $state = $class->prefer_lazy_load;
  $state = $class->prefer_lazy_load( $new_state );

$class is initial class. If $new_state is specified then value of flag 'prefer_lazy_load' will be replaced to $new_state. $new_state can be undef, in that case global default value will be used instead.

optimize_storage

Use:

  $class->optimize_storage( error=>ORM::Error );

This method simply calls SQL 'OPTIMIZE TABLE ...' or similar.

M

  $M = $class->M;

Return meta-object of class $class.

_db

  $db = $class->_db();

Return object of class derived from ORM::Db that is used to operate with database storage.

_plain_prop

Use:

  $class->_plain_prop( $prop_name );

Return true if property named $prop_name is plain (non-object) value.

_prop_is_ref

Use:

  $class->_prop_is_ref( $prop_name );

Return class of the property named $prop_name if property value is an ORM-object.

_prop_class

Use:

  $class->_prop_is_ref( $prop_name );

Return class of the property named $prop_name if property value is an object.

_prop_default_value

Use:

  $class->_prop_default_value( $prop_name );

Return default value for the property named $prop_name.

_has_prop

Use:

  $class->_has_prop( $prop_name );

Return true if objects of the class have property named $prop_name.

_all_props

Use:

  $class->_all_props();

Return list of object property names. Order of properties in common case do not agree with order of fields in database table.

_rev_refs

Use:

  $class->_rev_refs();

Return list of hash references describing reverse properties of the class.

_has_rev_ref

Use:

  $class->_rev_refs( $ref_class, $ref_prop );

Return true if class $ref_class has property $ref_prop that is of type $class.

OBJECT METHODS

update

Use:

  $obj->update
  (
      prop     => HASH,
      old_prop => HASH || undef,
      history  => boolean,
      error    => ORM::Error,
  )

Update object $obj in database.

prop

Hash reference containing new values for properties that should be changed.

Values of prop hash can be objects of class ORM::Expr to do incremental server-side updates of properties. In this case the object being changed falls in lazy loaded state. More specifically it has no idea about new value of the property updated this way. Note also that if history is enabled for method (see 'history' option below) or for entire class then the object is being brought to fully loaded state to consider history changes.

old_prop

Hash reference containing assumed values for properties that should be changed. If assumed values are not equal to current values then object is not updated and error corresponding message is returned.

history

Specifies whether to store the operation in history table ("see ORM::History"). If ommitted then default value specified to _init is used.

delete

Use:

  $obj->delete( error=>ORM::Error, history=>boolean )

Delete object from database storage and make $obj scalar unusable by reblessing it to ORM::Broken.

history

Specifies whether to store the operation in history table ("see ORM::History"). If ommitted then default value specified to _init is used.

refresh

Use:

  $object->refresh( error=>ORM::Error );

Re-read object's data from database. Also put object in fully-loaded state.

finish_loading

Use:

  $object->finish_loading
  $object->finish_loading( error=>ORM::Error );

Put object in fully-loaded state. First form will rebless object to 'ORM::Broken' in case of error.

OBJECT PROPERTIES

id

Return ID of the objects. For now ID is value of 'id' database fiend. In future version ID can be an object in case of multi-field primary key.

class

Return class of the object. The same as <ref $obj>. When this property is called as class method it returns class name itself.

is_temporary

Return true if object is temporary.

P

Use:

  $value = -$object->P( error=>$error )->prop1->prop2->prop3;

Return complex property by executing only one SQL-query.

_prop

_property

Use:

  $prop_value = $obj->_property( $prop_name );
  $prop_value = $obj->_property( name=>string, error=>ORM::Error );

Return value of named property.

name

'name' or $prop_name is name of the property.

_prop_id

_property_id

Use:

  $prop_value = $obj->_property_id( $prop_name );
  $prop_value = $obj->_property_id( name=>string, error=>ORM::Error );
name

'name' or $prop_name is name of the property.

Return value is:

  • the same as of _property for plain (non-object) properties

  • database value for object of non-ORM classes

  • object's ID for ORM objects

_rev

_rev_prop

Use:

  $obj->_rev_prop( $ref_class, $ref_prop, %args );

Return objects of class $ref_class those refer to $obj by its property $ref_prop.

%args and return value are the same as for find.

_rev_count

_rev_prop_count

AUTOLOAD

Use:

  $prop = $obj->prop( new_value=>SCALAR, error=>ORM::Error );

Autoload makes automatic acessors and mutators available for database stored properties of the same name.

When 'new_value' is not specified then _property method is called with appropriate arguments and returns the value of the property.

If 'new_value' is specified, then the method behaves like mutator, it means that the value of the property will be updated with new value specified. Return value is undef.

PROTECTED METHODS

_init

Use:

  $initial_class->_init
  (
      db                   => ORM::Db,
      history_class        => string||undef,
      prefer_lazy_load     => boolean,
      emulate_foreign_keys => boolean,
      default_cache_size   => integer,
  )

Must be called inside each initial class to make basic setup.

history_class

Specify class to be used as changes history class. This class must be initialized as described in ORM::History.

Changes history feature is disabled if the option is omitted.

You can enable or disable changes history individually for each class using 'history_is_enabled' option to ORM::Base module (see ORM::Base). Also you can enable or disable changes history individually for each particular method call using 'history' option of method.

prefer_lazy_load

Prefer lazy loading of objects by default. This option affects only find and stat methods.

emulate_foreign_keys

You can enable this option to force ORM to do additional checks before object's deletion. With 'emulate_foreign_keys' set to true object will not be deleted if another objects refer to it.

default_cache_size

Set default object cache size on per-primary class basis.

Per-primary class cache means that there is separate cache by one for every primary class and its descendants.

db

The ORM::Db object used to access objects storage. Please refer to ORM::Db(5).

_guess_table_name

Use:

  $table_name = $class->_guess_table_name( $obj_class );

This method is subject to user's redefinition.

Define mechanism to automatically assign tables to a classes. Should return name of the table for class $obj_class.

Default behaviour is to apply regexp s/::/_/g to class name.

_db_type_to_class

Use:

  $prop_class = $class->_db_type_to_class( $db_field_name, $db_type_name );

This method is subject to user's redefinition.

Define automatic detection of property class based on database field name and type.

Default is to assign ORM::Date class to fields of type DATE, and ORM::Datetime class to fields of type DATETIME and TIMESTAMP.

_validate_prop

Use:

  $self->_validate_prop( prop=>HASH, error=>ORM::Error )

This method is subject to user's redefinition.

Check validity of object's properties and correct when possible. You should never call this method explicitly.

This method is called implicitly from new and update methods just before data is written to database. To correct values of object's properties use _fix_prop method.

When redefining this method do not forget to call $self->SUPER::_validate_prop( %arg ).

prop

When the method is being called 'prop' argument is set to hash reference containing information about changed object's properties. See example of how to test whether particular property $prop_name is changed:

  sub _validate_prop
  {
      my $self = shift;
      my %arg  = @_;

      if( $arg{prop}{$prop_name} )
      {
          print "$prop_name is changed\n";
      }
  }
method

Contains name of the method from which the call was initiated. Possible values are 'new' and 'update'.

error

When redefining this method you can be sure that 'error' argument is always valid object of type ORM::Error.

_fix_prop

use: $self->_fix_prop( prop=>HASH, error=>ORM::Error )

May be called from _validate_prop to change values of properties before commiting them to database.

'prop' argument is the same as for update.

SEE ALSO

ORM::Tutorial

ORM::Error

ORM::ResultSet

ORM::Broken

ORM::Db

ORM::Order

ORM::Metaprop

ORM::DbLog

http://perlorm.sourceforge.net/

AUTHOR

Alexey V. Akimov

COPYRIGHT AND LICENSE

Copyright (C) 2005-2006 Alexey V. Akimov

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA