Class-DBI

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    %data consists of the initial information to place in your object and
    the database. The keys of %data match up with the columns of your
    objects and the values are the initial settings of those fields.

      my $cd = Music::CD->insert({ 
        cdid   => 1,
        artist => $artist,
        title  => 'October',
        year   => 1980,
      });

    If the table has a single primary key column and that column value is
    not defined in %data, insert() will assume it is to be generated. If a
    sequence() has been specified for this Class, it will use that.
    Otherwise, it will assume the primary key can be generated by
    AUTO_INCREMENT and attempt to use that.

    The "before_create" trigger is invoked directly after storing the
    supplied values into the new object and before inserting the record into
    the database. The object stored in $self may not have all the
    functionality of the final object after_creation, particularly if the
    database is going to be providing the primary key value.

    For tables with multi-column primary keys you need to supply all the key
    values, either in the arguments to the insert() method, or by setting
    the values in a "before_create" trigger.

    If the class has declared relationships with foreign classes via
    has_a(), you can pass an object to insert() for the value of that key.
    Class::DBI will Do The Right Thing.

    After the new record has been inserted into the database the data for
    non-primary key columns is discarded from the object. If those columns
    are accessed again they'll simply be fetched as needed. This ensures
    that the data in the application is consistent with what the database
    *actually* stored.

    The "after_create" trigger is invoked after the database insert has
    executed.

  find_or_create
      my $cd = Music::CD->find_or_create({ artist => 'U2', title => 'Boy' });

    This checks if a CD can be found to match the information passed, and if
    not inserts it.

  delete
      $obj->delete;
      Music::CD->search(year => 1980, title => 'Greatest %')->delete_all;

    Deletes this object from the database and from memory. If you have set
    up any relationships using "has_many" or "might_have", this will delete
    the foreign elements also, recursively (cascading delete). $obj is no
    longer usable after this call.

    Multiple objects can be deleted by calling delete_all on the Iterator
    returned from a search. Each object found will be deleted in turn, so
    cascading delete and other triggers will be honoured.

    The "before_delete" trigger is when an object instance is about to be
    deleted. It is invoked before any cascaded deletes. The "after_delete"
    trigger is invoked after the record has been deleted from the database
    and just before the contents in memory are discarded.

RETRIEVING OBJECTS
    Class::DBI provides a few very simple search methods.

    It is not the goal of Class::DBI to replace the need for using SQL.
    Users are expected to write their own searches for more complex cases.

    Class::DBI::AbstractSearch, available on CPAN, provides a much more
    complex search interface than Class::DBI provides itself.

  retrieve
      $obj = Class->retrieve( $id );
      $obj = Class->retrieve( %key_values );

    Given key values it will retrieve the object with that key from the
    database. For tables with a single column primary key a single parameter
    can be used, otherwise a hash of key-name key-value pairs must be given.

      my $cd = Music::CD->retrieve(1) or die "No such cd";

  retrieve_all
      my @objs = Class->retrieve_all;
      my $iterator = Class->retrieve_all;

    Retrieves objects for all rows in the database. This is probably a bad
    idea if your table is big, unless you use the iterator version.

  search
      @objs = Class->search(column1 => $value, column2 => $value ...);

    This is a simple search for all objects where the columns specified are
    equal to the values specified e.g.:

      @cds = Music::CD->search(year => 1990);
      @cds = Music::CD->search(title => "Greatest Hits", year => 1990);

    You may also specify the sort order of the results by adding a final
    hash of arguments with the key 'order_by':

      @cds = Music::CD->search(year => 1990, { order_by=>'artist' });

    This is passed through 'as is', enabling order_by clauses such as 'year
    DESC, title'.

  search_like
      @objs = Class->search_like(column1 => $like_pattern, ....);

    This is a simple search for all objects where the columns specified are
    like the values specified. $like_pattern is a pattern given in SQL LIKE
    predicate syntax. '%' means "any zero or more characters", '_' means
    "any single character".

      @cds = Music::CD->search_like(title => 'October%');
      @cds = Music::CD->search_like(title => 'Hits%', artist => 'Various%');

    You can also use 'order_by' with these, as with search().

ITERATORS

README  view on Meta::CPAN


      my $track6 = Music::Track->insert({
        cd       => $cd,
        position => 6,
        title    => 'Tomorrow',
      });

    When setting up the relationship the foreign class's has_a()
    declarations are examined to discover which of its columns reference our
    class. (Note that because this happens at compile time, if the foreign
    class is defined in the same file, the class with the has_a() must be
    defined earlier than the class with the has_many(). If the classes are
    in different files, Class::DBI should usually be able to do the right
    things, as long as all classes inherit Class::DBI before 'use'ing any
    other classes.)

    If the foreign class has no has_a() declarations linking to this class,
    it is assumed that the foreign key in that class is named after the
    moniker() of this class.

    If this is not true you can pass an additional third argument to the
    has_many() declaration stating which column of the foreign class is the
    foreign key to this class.

   Limiting
      Music::Artist->has_many(cds => 'Music::CD');
      my @cds = $artist->cds(year => 1980);

    When calling the method created by has_many, you can also supply any
    additional key/value pairs for restricting the search. The above example
    will only return the CDs with a year of 1980.

   Ordering
      Music::CD->has_many(tracks => 'Music::Track', { order_by => 'playorder' });

    has_many takes an optional final hashref of options. If an 'order_by'
    option is set, its value will be set in an ORDER BY clause in the SQL
    issued. This is passed through 'as is', enabling order_by clauses such
    as 'length DESC, position'.

   Mapping
      Music::CD->has_many(styles => [ 'Music::StyleRef' => 'style' ]);

    If the second argument to has_many is turned into a listref of the
    Classname and an additional method, then that method will be called in
    turn on each of the objects being returned.

    The above is exactly equivalent to:

      Music::CD->has_many(_style_refs => 'Music::StyleRef');

      sub styles { 
        my $self = shift;
        return map $_->style, $self->_style_refs;
      }

    For an example of where this is useful see "MANY TO MANY RELATIONSHIPS"
    below.

   Cascading Delete
      Music::Artist->has_many(cds => 'Music::CD', { cascade => 'Fail' });

    It is also possible to control what happens to the 'child' objects when
    the 'parent' object is deleted. By default this is set to 'Delete' - so,
    for example, when you delete an artist, you also delete all their CDs,
    leaving no orphaned records. However you could also set this to 'None',
    which would leave all those orphaned records (although this generally
    isn't a good idea), or 'Fail', which will throw an exception when you
    try to delete an artist that still has any CDs.

    You can also write your own Cascade strategies by supplying a Class Name
    here.

    For example you could write a Class::DBI::Cascade::Plugin::Nullify which
    would set all related foreign keys to be NULL, and plug it into your
    relationship:

      Music::Artist->has_many(cds => 'Music::CD', { 
        cascade => 'Class::DBI::Cascade::Plugin::Nullify' 
      });

  might_have
      Music::CD->might_have(method_name => Class => (@fields_to_import));

      Music::CD->might_have(liner_notes => LinerNotes => qw/notes/);

      my $liner_notes_object = $cd->liner_notes;
      my $notes = $cd->notes; # equivalent to $cd->liner_notes->notes;

    might_have() is similar to has_many() for relationships that can have at
    most one associated objects. For example, if you have a CD database to
    which you want to add liner notes information, you might not want to add
    a 'liner_notes' column to your main CD table even though there is no
    multiplicity of relationship involved (each CD has at most one 'liner
    notes' field). So, you create another table with the same primary key as
    this one, with which you can cross-reference.

    But you don't want to have to keep writing methods to turn the the
    'list' of liner_notes objects you'd get back from has_many into the
    single object you'd need. So, might_have() does this work for you. It
    creates an accessor to fetch the single object back if it exists, and it
    also allows you import any of its methods into your namespace. So, in
    the example above, the LinerNotes class can be mostly invisible - you
    can just call $cd->notes and it will call the notes method on the
    correct LinerNotes object transparently for you.

    Making sure you don't have namespace clashes is up to you, as is
    correctly creating the objects, but this may be made simpler in later
    versions. (Particularly if someone asks for this!)

  Notes
    has_a(), might_have() and has_many() check that the relevant class has
    already been loaded. If it hasn't then they try to load the module of
    the same name using require. If the require fails because it can't find
    the module then it will assume it's not a simple require (i.e.,
    Foreign::Class isn't in Foreign/Class.pm) and that you will take care of
    it and ignore the warning. Any other error, such as a syntax error,
    triggers an exception.

    NOTE: The two classes in a relationship do not have to be in the same
    database, on the same machine, or even in the same type of database! It
    is quite acceptable for a table in a MySQL database to be connected to a
    different table in an Oracle database, and for cascading delete etc to
    work across these. This should assist greatly if you need to migrate a
    database gradually.

MANY TO MANY RELATIONSHIPS
    Class::DBI does not currently support Many to Many relationships, per
    se. However, by combining the relationships that already exist it is
    possible to set these up.

    Consider the case of Films and Actors, with a linking Role table with a
    multi-column Primary Key. First of all set up the Role class:

      Role->table('role');
      Role->columns(Primary => qw/film actor/);
      Role->has_a(film => 'Film');
      Role->has_a(actor => 'Actor');



( run in 0.721 second using v1.01-cache-2.11-cpan-39bf76dae61 )