NAME
    Class::Persist - Persistency framework for objects

SYNOPSIS
      package My::Person;
      use base qw( Class::Persist );
      Class::Persist->dbh( $dbh );
      __PACKAGE__->simple_db_spec(
        first_name => 'CHAR(30)',
        last_name  => 'CHAR(30)',
        address => "My::Address",  # has_a relationship
        phones => [ "My::Phone" ], # has_many relationship
      );

      my $person = My::Person->new( first_name => "Dave" );
      $person->addesss( My::Address->new );
      $person->store;

DESCRIPTION
    Provides the framework to persist the objects in a DB in a Class::DBI
    style. The main difference between Class::Persist and Class::DBI is that
    Class::DBI provides an object wrapper around a row in a database,
    typically a database that already exists. The purpose of Class::Persist
    is to store an object, or a tree / collection of objects in a database,
    without worrying too much about what the database looks like. The other
    difference is that it's possible to have a Class::Persist object that
    does not come from a database - Class::DBI objects always represent an
    existing db row.

    Class::Persist is not Pixie or another 'magic' persistence layer - the
    properties of your object go into real database columns, and you need to
    know a bit about databases, with the attendant advantage that you can
    use SQL to search the database for objects.

USAGE
    In its simplest form, to make a package persistable, inherit from
    Class::Persist, and call simple_db_spec on your package name to tell
    Class::Persist what bits of your object you would like to store, and
    what sort of DB fields you would like to store them in. Use the
    setup_DB_infrastructure and create_table methods to create the database
    tables for your objects in the setup code for your application. Then,
    call dbh on the Class::Persist package to set the global database
    connection for all Class::Persist objects, and your objects are now
    persistable.

      package My::Foo;
      use base qw( Class::Persist );
      Class::Persist->dbh( $dbh );
      My::Foo->simple_db_spec( name => "CHAR(30)" );

    If you need to have more than one Class::Persist database, you can
    subclass Class::Persist through a middle class that defines your
    application-specific database connection, and have your persistable
    classes inherit from that:

      package My::Persistable;
      use base qw( Class::Persist );
      My::Persistable->dbh( $dbh );

      package My::Bar
      use base qw( My::Persistable );
      My::Bar->simple_db_spec( name => "CHAR(30)" );

    Objects will be assigned a table name automatically based on their class
    name - if you prefer to choose table names explicitly, use the db_table
    method.

      My::Bar->db_table( "table_bar" );

  Subclassing
    You can subclass other persistable objects to create new objects, which
    share the properties of their superclasses, and can add fields. They are
    stored in seperate database tables, but inherit the column types from
    their superclass.

      package My::Baz;
      use base qw( My::Bar );
      My::Baz->simple_db_spec( height => "INT" );

  Relationships
    You can trivially define relationships with other classes by putting a
    class name in the 'data type' part of the db spec.

      My::Wallace->simple_db_spec( bar => "My::Bar" );
      my $wallace = My::Wallace->new;
      my $bar = My::Bar->new;
      $wallace->bar( $bar );
      $wallace->store;

    An object can have a listref of other persistable objects stored in a
    property, by passing a listref with the property name as the data type.

      My::Grommit->simple_db_spec( bars => ["My::Bar"] );
      my $grommit = My::Grommit->new;
      my $bar = My::Bar->new;
      push @{ $grommit->bar }, $bar;

    or

      $grommit->bar->push( $bar );

    See the documentation for simple_db_spec for more details of how to
    define relationships.

  Setup
    To create the database tables for the objects you have defined, call
    create_table on each of them in turn.

      My::Foo->create_table;
      My::Bar->create_table;
      My::Baz->create_table;

    If you subsequently change the layout of the database by changing the
    object spec, you will have to either delete and re-create the tables,
    losing all the data, or change the table definition yourself manually.

  Storing and retrieving objects
    All objects inheriting from Class::Persist have an 'oid' method that
    returns the unique id of the object, this will be a UUID - a unique
    non-guessable 36 character string. The simplest way to retrieve an
    object is by its oid:

      my $bar = My::Bar->load( $oid );

    Alternatively, the two-parameter version of load is useful if you can
    rely on some other unique value in the object:

      my $bar = My::Bar->load( name => "The Founder's Arms" );

    You can search for objects using methods of varying sophistication

      # get all the bars.
      my @bars = My::Bar->get_all;

      # get bars where the 'color' property is equal to 'Green'
      my @green_bars = My::Bar->search( color => "Green" );

      # get bars where the color contains an 'e'
      my @some_bars = My::Bar->sql("color like ?", "%e%");

    See the search, sql and advanced_search methods for increasingly
    complicated ways of searching the database for objects.

OBJECT CREATION
    The standard way of creating an object is with the new() method. new()
    optionally takes a hash of key/value pairs to populate the initial state
    of the object.

PROPERTIES
    All Class::Persist subclasses inherit certain properties from the
    superclass.

  creation_date()
    A DateTime object for when this object was originally created. Should be
    considered read-only.

  timestamp()
    A DateTime object that represents the last time this object was stored
    into the database.

  owner()
    If the object is owned, ie it is the target of a has_a, has_many, etc
    relationship, the owner method will return the object's owner.

RETRIEVING OBJECTS
  load( id ), load( key => value )
    Loads an object from the database. Can be used in two different ways.

    My::Class->load( $id )
        Loads the unique item of the class My::Class with the oid $id.

    My::Classs->load( foo => "Bar" )
        Loads the first item of class My::Classs where the property 'foo' is
        equal to 'bar'.

  get_all()
    Returns a list of all the objects of this class in the database.

  search( column => "value" )
    Takes a hash of attribute=>value pairs. Values of undef become IS NULL
    tests. Returns a list of objects in the database of this class which
    match these criteria.

      my $pears = Fruit->search( shape => 'pear' );

    The special parameter 'order_by' will not be used as part of the search,
    but will order the results by that column.

      my $sorted_pears = Fruit->search( shape => 'pear', order_by => 'size' );

  sql( sql, [placeholder values] )
    Free-form search based on a SQL query. Returns a list of objects from
    the database for each row of the passed SQL 'WHERE' clause. You can use
    placeholders in this string, passing the values for the placeholders as
    the 2nd, etc, params

      Person->sql("name LIKE '%ob%' AND age > ? ORDER BY height", $min_age)

  advanced_search( ... )
    when search() isn't good enough, and even sql() isn't good enough, you
    want advanced_search. You pass a complete SQL statement that will return
    a number of rows. It is assumed that the left-most column will contain
    oids. These oids will be inflated from the database and returned in a
    list.

    As with the sql method, you can use placeholders and pass the values as
    the remaining parameters.

      People->advanced_sql('
        SELECT artist.oid FROM artist,track
        WHERE track.artist_name = artist.name
        AND track.length > ?
        ORDER BY artist.name',
      100 );

    This will be slower than sql - there will be another SQL query on the db
    for every row returned. That's life. There is much scope here for
    optimization - the simplest thing to do might be to return a list of
    proxies instead..

    Also consider that the SQL statement you're passing will be just thrown
    at the database. You can call Object->advanced_sql('DROP DATABASE
    people') and bad things will happen. This is, of course, almost equally
    true for the sql method, but it's easier to break things with this one.

OBJECT METHODS
  store()
    Store the object in DB and all objects within, whether it is a new
    object or an update. Storing an object will collapse all its
    relationships with other Class::Persist object into proxies.

  delete()
    Deletes the object and returns true if successful. It will delete
    recursively all objects within.

  deleteThis()
    Deletes the object from the DB, and returns true if successful. Does not
    delete recursively any objects within, so this method will leave
    orphans.

  revert()
    revert an object back to its state in the database. You will lose any
    changes you've made to it since the last store. This is recursive - all
    children of the object will be reverted as well.

    Throws a Class::Persist::Error::Revert if the object you're trying to
    revert isn't stored in the database.

  revertThis()
    Revert only this object to its DB state, not any of its children.

  clone( new_owner )
    Deep-clones the object - any child objects will also be cloned. All new
    objects will have new oids, and will not be stored in the database.
    Unlike delete and revert, clone is not depth-first.

    new_owner will own the newly cloned object, if passed. If not, the new
    object will have no owner.

  cloneThis( [new_owner] )
    Clones just this Class::Persist object, not any of its children.

    new_owner will own the newly cloned object, if passed. If not, the new
    object will have no owner.

  validate()
    Returns true if the object is in a good, consistent state and can be
    stored. The default implementation just returns true - Override this
    method if you want to make sure your objects are consistent before
    storing. Returning 0 from this will cause the store() method to fail.

  unique()
    Returns true if the current object is unique, ie there is no other row
    in the database that has the same value as this object. The query that
    is used to check for uniqueness is defined by the unique_params method.

    Only checked for unstored objects - objects that have come from the
    database are presumed to be unique.

RELATIONSHIPS AND CLASS SETUP
    Classes can have relationships with each other. The simplest way to
    define a class and its relationships is with the simple_db_spec method,
    but if you want more control you can use the more specific functions.

  simple_db_spec( column => "type", ... )
    The simplest of specifying the database spec, combining the field list,
    has_a and has_many relationships and the database spec in one command.

      Person::Foot->simple_db_spec(
        digits => 'INT',
        name => 'CHAR(10)',
        leg => 'Person::Leg',
        hairs => [ 'Person::Leg::Hair' ],
        grown_on => "DateTime",
      );

    For each column as the keys of the passed hash, specify a simple DB
    field with a DB type, a has_a relationship with a class name, and a
    has_many relationship with a listref continain a single element - the
    class name.

    This will also automatically create a name for the database table, if
    you don't want to supply one yourself. The name will be based on the
    package name.

    Any fields defined as BLOB, LONGBLOB or similar types will automatically
    be declared as binary fields - see binary_fields.

    Finally, defining a field type as 'DateTime' will let you store a
    DateTime object in that field, which will be stringified to
    yyyy-mm-ddThh::mm::ss in the database column.

  db_table( [table] )
    Get or set the name of the table that this class will be stored in. If
    you don't set it explicitly, and use simple_db_spec, a table name based
    on the package name will be generated automatically for you.
    Alternatively, you can set it specifically.

    If you don't use the simple_db_spec method, you must explicitly set a
    table name.

  db_fields( @fields )
    Instead of using simple_db_spec, you can tell Class::Persist which
    columns in the table are to store properties, and set up the
    relationships manually, using db_fields, has_a, has_many, etc.

    db_fields defines the fields in the DB that will store scalar values.

      My::Foo->db_fields(qw( foo bar baz ));

    Only define the fields that this particular subclass adds using this
    function - the db_fields_all function can be used to get a list of all
    fields that the object will provide, those from this class and all its
    superclasses.

  db_fields_all()
    Returns a list of all db fields that this class and all its superclasses
    use.

  binary_fields( @fields )
    By default, all properties of a Class::Persist object are assumed to
    contain a UTF8 string. If you want to put binary data into the database,
    you must explicitly declare a field to contain binary data using this
    functions.

      My::Foo->db_field(qw( foo bar baz ));
      My::Foo->binary_fields(qw( foo ));

  binary_fields_all()
    returns all binary fields of this object and its superclasses.

  has_a( $method => $class )
    Class method. Defines a has_a relationship with another class.

      Person::Body->has_a( head => "Person::Head" );
      my $nose = $body->head->nose;

    Allows you to store references to other Class::Persist objects. They
    will be serialised when stored in the database.

  has_a_all()
    Returns a hashref of all the has_a relationships a given class has, from
    itself and its superclasses.

  weak_reference( one, two, three )
    Sets the list of references from this object that should be considered
    'weak'. Weak references will not be recursed into when storing,
    deleting, etc, and objects on the other end of them won't have their
    'owner' fields set. This lets you use a field to point into some other
    part of an object tree without worrying about nasty loops.

  weak_reference_all
    Returns a hashref, the keys of which are the fields with weak references
    of this class and it's superclasses.

  has_many( $method => $class )
    Class method. Defines a one to many relationship with another class.

      Person::Body->has_many( arms => 'Person::Arm' );
      my $number_of_arms = $body->arms->count;

    Allows you to manipulate a number of other Class::Persist objects that
    are associated with this one. This method will return a
    Class::Persist::Proxy::Container that handles the child objects, it
    provides push, pop, count, etc, methods to add and remove objects from
    the list.

      my $left_arm = Person::Arm->new;
      $body->arms->push( $left_arm );

  has_many_all()
    Returns a hashref of all the has_many relationships a given class has,
    from itself and its superclasses.

  might_have( $method => $class )
    Call on a class to define a might_have relationship between that class
    and another class:

      My::Bar->might_have( jukebox => My::Jukebox );

    A might_have relationship differs from a has_a relationship in that, for
    has_a, there is a field in the parent table that points to the child
    object. For might_have, the owner field of the child object points to
    the parent, and the child object will have an 'owner' accessor that
    points at the parent.

    TODO - logically, has_a relationships should also provide an owner
    method to the child class.

    Objects on the other end of this relationship will be stored when the
    parent object is stored.

  might_have_all()
    For a given class, returns (not sets) a hashref of all of its might_have
    relationships, including those of its parent classes.

  unique_params()
    SQL query and binding params used to check unicity of object in DB

  db_fields_spec()
    SQL to specificy the database columns needed to store the attributes of
    this class - all parent class(es) columns are aggregated and used to
    build an SQL create table statement. Override this to specify the
    columns used by your class, if you want Class::Persist to be able to
    create your table for you. Remember to call the superclass
    db_fields_spec as well, though.

      sub db_fields_spec(
        shift->SUPER::db_fields_spec,
        'Colour VARCHAR(63)',
        'Mass VARCHAR(63)',
      );

  db_fields_spec_all()
DATABASE MANAGEMENT
  create_table()
    Create the table for this class in the database.

  drop_table()
    Drop the table for this class.

STORING MORE COMPLEX OBJECTS
    It may be that you want to put a complex object, say a hashref, into a
    db field. for a given db field name, there are two hooks:
    db_inflate_{name} and db_deflate_{name} that are called when we
    inflate/deflate an object from the database.

    db_inflate_{name}(db_value) is called when we inflate from the database,
    and is passed as its only parameter the value of the DB column - this is
    undef if the column value is NULL. The function should set up the object
    according to this db field - this will probably entail calling
    'set(field,val)'.

    db_deflate_{name} is called when we want to store the object back in to
    the db, and should return the value that should go into the DB column
    {name}.

    An example is probably best here.

      package Example;
  
      __PACKAGE__->simple_db_spec(
        hash => "text", # we'll deflate a hash here
      );

      sub db_inflate_hash {
        my ($self, $db_value) = @_;
    
        # empty db column means empty hash
        return $self->set( hash => {} ) unless $db_value;

        # values in the db are key\tvalue\tkey\tvalue
        my (%hash) = split(/\t/, $db_value);

        # store the inflated hash in the object
        return $self->set( hash => \%hash );
      }
  
      sub db_deflate_hash {
        my $self = shift;
    
        # get the hash from the object
        my %hash = %{ $self->get('hash') }

        # no hash? put nothing in the db
        return undef unless %hash;

        # store the hash in the DB as tab-seperated key/value pairs
        return join("\t", @%hash);
      }

    (Obviously this is a simple example - we should do something smarter to
    make sure there are no blessed objects in the hash, etc, etc.)

    This object will now have a db-persisted hashref in its 'hash' slot.

    These hooks are only supported for 'normal' db fields - defined with the
    db_fields() accessor or declared as simple types in simple_db_spec().
    Using them to hook has_a, has_many or other complex relationships is not
    advised.

STORAGE IMPLEMENTATION DETAILS
    The binary_fields accessor is there for a reason - there is a very
    strong implicit assumption that everything you want to put into
    Class::Persist is either a text string, in which case it will be stored
    in the database as a series of UTF8 octets, or a lumb of binary data, in
    which case it will go into the DB as-is, but you must flag it as such.
    Class::Persist does not use any db-specific character set tools, such as
    the utf-8 support in mysql 4.1, because I want to do things the same
    across all databases where possible - in this case, that meast that we
    assume the DB stores the exact bytes that we give it, and will give them
    back. Class::Persist handles the encoding and decoding from utf8, so you
    can store any valid perl string and will get back something that is at
    least equivalent.

BUGS
    The API isn't yet stabilised, so please keep an eye on the Changes file
    where incompatible changes will be noted.

    Storing invalid perl strings in the database, for instance using
    "_utf8_on" to flip the utf8 bit on a non-utf8 string, will break.
    Horribly. Don't Do It.

    Making recursive loops in the object tree is very easy. However, it'll
    lead to recursive storing and pain. Again, not a good idea. It'll be
    fixed soon, I hope.

    an object with more than parent-child relationship with a particular
    subclass is going to act very strangely, ie a has_a => "Some::Class" and
    a has_many => "Some::Class". Not sure what to do about that one.

AUTHORS
    Nicholas Clark <nclark@fotango.com>
    Pierre Denis <pdenis@fotango.com>
    Tom Insam <tinsam@fotango.com>
    Richard Clamp <richardc@unixbeard.net>

    This module was influnced by James Duncan and Piers Cawley's Pixie
    object persistence framework, and Class::DBI, by Michael Schwern and
    Tony Bowden (amongst many others), as well as suggestions from various
    people within Fotango.

COPYRIGHT
    Copyright 2004 Fotango. All Rights Reserved.

    This module is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

