=head1 NAME

ORM - Object relational mapper for Perl.

=head1 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 );

=head1 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 L<ORM::Tutorial>.

=head2 General features

=over

=item * Inheritance support

=item * Nested transactions support

=item * No SQL queries needed

=item * Full-featured objects search using native Perl-expressions

=item * One-to-many and many-to-many relations

=item * Foreign keys emulation

=item * Objects changes history

=item * Lazy loaded objects

=item * Objects statistics (using GROUP BY)

=item * Third party classes support

=item * Autogenerated acessors/mutators

=item * Objects caching

=item * Separate RDBMS layer

=back

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

=head2 Basic definitions

=over 

=item Initial class

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

=over

=item * initialize object's storage engine

=item * set site-wide global options

=item * define default classes behaviour by redefining special ORM's methods

=item * define methods common to all its descendants

=back

=item Primary class

direct descendant of B<initial class>

=item Intermediate class

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

=item Lazy-loaded state

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

=item Fully-loaded state

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

=item Meta-object and meta-properties

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

=over

=item * particular object of the class

=item * some object of the class

=item * any object of the class

=back

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

=item Meta-expression

Meta-expression is object of class C<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.

=back

=head2 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 C<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.

=head1 CONSTRUCTORS

=head2 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.

=over

=item 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 C<__ORM_db_value> method of the C<$class>.

=item history

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

=item temporary

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

=item 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)...

=back

=head2 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.

=over 

=item filter

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

=item order

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

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

=item lazy_load

If 'lazy_load' specified then only data from tables corresponding to base class
C<$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').

=item page

If C<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 C<pagesize> is specified and
C<page> is omitted then page number is implied to be 1.

=item pagesize

Size of the page to be returned.

=back

Returned value depends on the following:

=over 

=item * If called in scalar context returns first object from result set

=item * If called in array context returns array of found objects

=item * If C<return_ref> option is true then return value is reference
to the array of found objects with no respect to context.

=item * If C<return_res> option is true then return value is object of
class C<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'.

=back

=head2 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 C<find> when you know ID of the object to find.

=over

=item id

ID of the object to find.

=item 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 C<lazy_load> option is undef then by default all fields of the object
are loaded irrespective of C<prefer_lazy_load> option to C<_init>.

When using C<find_id> with C<lazy_load> option remember that there is
no way to detect actual object's class during construction, therefore
constructed object is instance of class C<$class> for which C<find_id>
method is called. When an object's property is first accessed
C<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. C<finish_loading> is also being implicitly
called in C<update> method.

=back

=head2 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 C<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.

=head2 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 C<$class> and related objects.
You can find some exmples of C<stat> usage in L<ORM::Tutorial>.

=over

=item data

Defines the data to be fetched. Data is set of properties 
of objects of C<$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.

=item 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 C<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 C<ORM::DbLog>.

=item filter

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

=item group_by

This is analogue to SQL 'GROUP BY' clause.

=item post_filter

This is analogue to SQL 'HAVING' clause.

=item order

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

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

=item lazy_load

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

=item page

If C<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 C<pagesize> is specified and
C<page> is omitted then page number is implied to be 1.

=item pagesize

Size of the page to be returned.

=item 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'.

=item return_res

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

=back

=head1 CLASS METHODS

=head2 count

Use:

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

Return number of objects satisfying the C<filter> condition.

=over

=item 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
C<$class> (and descendants) is returned.

=back

=head2 new_transaction

Use:

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

Begins transaction.
Transaction commits when object $ta is destroyed.
C<$class> is B<initial class>.

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

=head2 base_class

Use:

  $class_name = $class->base_class();

Return name of base class for C<$class>.

=head2 primary_class

Use:

  $class_name = $class->primary_class();

Return name of C<primary class> for C<$class>.

=head2 initial_class

Use:

  $class_name = $class->initial_class();

Return name of C<initial class> for C<$class>.

=head2 history_is_enabled

Use:

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

C<$class> is B<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.

=head2 prefer_lazy_load

Use:

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

C<$class> is B<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.

=head2 optimize_storage

Use:

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

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

=head2 M

  $M = $class->M;

Return B<meta-object> of class C<$class>.

=head2 _db

  $db = $class->_db();

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

=head2 _plain_prop

Use:

  $class->_plain_prop( $prop_name );

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

=head2 _prop_is_ref

Use:

  $class->_prop_is_ref( $prop_name );

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

=head2 _prop_class

Use:

  $class->_prop_is_ref( $prop_name );

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

=head2 _prop_default_value

Use:

  $class->_prop_default_value( $prop_name );

Return default value for the property named C<$prop_name>.

=head2 _has_prop

Use:

  $class->_has_prop( $prop_name );

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

=head2 _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.

=head2 _rev_refs

Use:

  $class->_rev_refs();

Return list of hash references describing B<reverse properties> of the class.

=head2 _has_rev_ref

Use:

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

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

=head1 OBJECT METHODS

=head2 update

Use:

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

Update object C<$obj> in database.

=over

=item prop

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

Values of C<prop> hash can be objects of class C<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.

=item 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.

=item history

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

=back

=head2 delete

Use:

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

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

=over

=item history

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

=back

=head2 refresh

Use:

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

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

=head2 finish_loading

Use:

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

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

=head1 OBJECT PROPERTIES

=head2 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.

=head2 class

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

=head2 is_temporary

Return true if object is temporary.

=head2 P

Use:

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

Return complex property by executing only one SQL-query.

=head2 _prop

=head2 _property

Use:

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

Return value of named property.

=over

=item name

'name' or C<$prop_name> is name of the property.

=back

=head2 _prop_id

=head2 _property_id

Use:

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

=over

=item name

'name' or C<$prop_name> is name of the property.

=back

Return value is:

=over

=item * the same as of C<_property> for plain (non-object) properties

=item * database value for object of non-ORM classes

=item * object's ID for ORM objects

=back

=head2 _rev

=head2 _rev_prop

Use:

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

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

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

=head2 _rev_count

=head2 _rev_prop_count

=head2 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 C<_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.

=head1 PROTECTED METHODS

=head2 _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 B<initial class> to make basic setup.

=over

=item history_class

Specify class to be used as changes history class. This
class must be initialized as described in C<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 C<ORM::Base> module
(see L<ORM::Base>). Also you can enable or disable changes history
individually for each particular method call using 'history'
option of method.

=item prefer_lazy_load

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

=item 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.

=item 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.

=item db

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

=back

=head2 _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 C<$obj_class>.

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

=head2 _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 C<ORM::Date> class to fields of type DATE,
and C<ORM::Datetime> class to fields of type DATETIME and TIMESTAMP.

=head2 _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 C<new> and C<update>
methods just before data is written to database. To correct
values of object's properties use C<_fix_prop> method.

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

=over

=item 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 C<$prop_name> is changed:

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

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

=item method

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

=item error

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

=back

=head2 _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 C<update>.

=head1 SEE ALSO

L<ORM::Tutorial>

L<ORM::Error>

L<ORM::ResultSet>

L<ORM::Broken>

L<ORM::Db>

L<ORM::Order>

L<ORM::Metaprop>

L<ORM::DbLog>

http://perlorm.sourceforge.net/

=head1 AUTHOR

Alexey V. Akimov

=head1 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

=cut
