NAME

Persist::Driver - Base class for Persist drivers

SYNOPSIS

package Some::Driver;

use Persist qw(:constants);
use Persist::Driver;
@ISA = qw( Persist::Driver );

sub new { ... }
sub is_dba { ... }
sub new_source { ... }
sub delete_source { ... }
sub new_table { ... }
sub delete_table { ... }
sub tables { ... }
sub open_table { ... }
sub open_join { ... }
sub open_explicit_join { ... }
sub insert { ... }
sub update { ... }
sub delete { ... }
sub columns { ... }
sub indexes { ... }
sub first { ... }
sub next { ... }
sub sequence_value { ... }

DESCRIPTION

This module defines the functionality required for all Persist drivers. The interface is meant to be independent of the backing store architecture. It should be able to relatively easily provide access to SQL database, LDAP directories, memory structures, file structures, etc.

Implementors should never call the SUPER version of any method in this package as they are all defined to die with an error message.

CHANGES FOR 0.5.0

As of the 0.5.0 release of Persist, the way drivers are written has changed. This change has been made for reasons of flexibility. Instead of taking positional paramters, all driver arguments will be passed in hyphen-named format. This will allow features to be added more easiler in the future.

NOTATION

Before getting into the method descriptions, a discussion on notation is required. Arguments are passed to driver methods using a hyphen-named parameter passing format--one that is used in a number of important Perl packages.

Basically, each method that takes arguments, accepts them in a single hash, which is always called %args in this documentation. Then a list of arguments is shown in the description of the method. The descriptions will give a general indication of the base-type required and the name of the argument, along with noting whether the argument is optional or not (a parameter is required unless otherwise noted).

For example, if there were a method "foo" described with these parameters:

$foo

Some foo.

@bar (optional)

Some bar.

Then, the method "foo" requires a scalar value passed as "-foo" and may have a parameter "-bar" that takes array reference. Thus, this could be a legal call for this fictional method:

$driver->foo(-foo => "baz", -bar => [ 1, 2, 3 ]);

Make sure to read the details of the parameter as it may provide further stipulations on the type.

METHODS

$driver = new Persist::Driver(%args)

The implementation may define any arguments it likes to be passed to the constructor. What the constructor does is completely up to the implementation.

$test = $driver->is_dba

Returns whether the connection is for a DBA/sysadmin user. This basically tells us whether or not a call to new_source and delete_source can succeed.

@connect_args = $driver->new_source(%args)

Creates a new data source if the current user is capable. It returns the arguments required to connect to this new database. The arguments that must be passed to the driver to create a connection are driver dependent.

$success = $driver->delete_source(%args)

Deletes an existing data source if the current user is capable. It returns true upon success. The arguments that must be passed to delete the source are driver dependent.

$success = $driver->create_table(%args)

Creates a new ``table'' in the data source. Even if the data source is not relational, the closest approximation to a table should be used. The implementation should provide the columns presented in this definition with lenient typing--that is, a column should be able to hold all values of the type given, but isn't required to restrict the values to only that type. The indexes are provided as a general guideline, but are not required to be enforced. In general, though, enforcing at least the PRIMARY index is recommended.

Even though a driver is not required to enforce them. It must, however, remember the settings for the purposes of the indexes method and for providing functionality for joining tables.

The arguments $args accepted are:

$table

The name of the table to create.

@columns

The column definition specification. This will be a series of keyword/value pairs. Each key is the name of the column and each value is the datatype descriptor. See Persist::Source for details. This will always be passed as an array reference, even though the front-end allows for this argument to be a hash reference.

@indexes

Specifies a list of indexes to add to this table. See Persist::Source for details.

The method returns true on successful table creation.

$success = $driver->delete_table(%args)

This operation will annihilate the table description and all data associated with it.

This method takes these arguments in %args:

$table

The name of the table to delete.

Returns true upon successful deletion of the table (or equivalent object in the store).

@tables = $driver->tables

Returns a list of all the table names in the data source. This may return tables that were not created by the source (such as preexisting data), but should not return system tables or the equivalent.

$handle = $driver->open_table(%args)

Returns a handle which may be used to fetch information out of a single table in the database.

The possible arguments %args are:

$table

The name of the table.

$filter (optional)

The $filter argument may be used to narrow the results. See "FILTERS" in Persist::Filter for details on the format of $filter.

$handle = $driver->open_join(%args)

Creates a handle to refer to for iterating over a selection of data in a set of tables.

@tables

The array @tables is a list of table names to join. If the list of tables contains a circular set of LINK constraints, then latter tables will not be completely joined. Otherwise, we might create a set of constraints that cannot be or can barely be satisfied. It is possible to join two unrelated tables, but doing so will create a cross-product of the records, which is generally undesirable for performance reasons.

@filters (optional)

In addition to the LINK constraints, the user may specify one or more filters. The @filters array contains one filter per table in @tables and the filters are matched to a table in @tables respectively. It is permissible for the filters array to be shorter than the array of tables if a filter is not defined for all tables. Undefined filters can be specified with the undef value.

See "FILTERS" in Persist::Filter for details on the format of the filters.

Returns a handle which may be used to fetch information out of a group of tables that are joined according to their LINK indexes.

$handle = $driver->open_explicit_join(%args)

Creates a handle to refer to for iterating over a selection of data in a set of tables whose joining is explicitly defined.

This method accepts this arguments in %args:

@tables

The array @tables is a list of table name aliases followed by table names of those tables to join.

@on_exprs

The array @on_exprs contains the expressions used to join each set of tables. Tables are joined in the order given with each @on_exprs expression in the nth place joining the table in the (n+1)th with all tables prior to and including the nth. The table name aliases should be used in the expressions during join. Expressions that are set to undef should either result in an implicit join or a full cross-product of the relations--depending upon the driver implementation--so it's best to just specify it!

$filter (optional)

In addition to the explicit constraints, the user may specify a filter. The $filter string contains a filter expression and should use the table name aliasees in @tables.

See "FILTERS" in Persist::Filter for details on the format of the filters and AS expressions.

Returns a handle which may be used to fetch information out of a group of tables that are joined according to the explicit information given by the user.

$rows = $driver->insert(%args)

Inserts a new row into a table.

The arguments %args accepted are:

$table

The name of the table to insert into.

%values

The hash %values maps column names (keys) to values (values).

The result is the number of rows modified (should always be one on success).

$rows = $driver->update(%args)

Updates zero or more entries in a table.

The arguments %args accepted are:

$table

The name of the table to update.

%set

The hash %set maps column names (keys) to values (values).

$filter (optional)

The optional filter specifies the criteria by which rows will be matched to determine whether or not to update them.

WARNING: An undefined filter will update all rows.

See "FILTERS" in Persist::Filter for details on the format of the filter.

@bindings

The final optional bindings array is an array of bindings values.

Returns the number of rows affected.

$rows = $driver->delete(%args)

Deletes zero or more entries from a table.

The arguments %arg accepted are:

$table

The name of the table to delete records from.

$filter (optional)

The optional filter specifies the criteria by which rows will be matched for deletion.

WARNING: An undefined filter will delete all rows from the table.

See "FILTERS" in Persist::Filter for details on the format of the filter.

@bindings (optional)

The final optional bindings argument is an array of binding values.

Returns the number of rows affected.

%columns = $driver->columns(%args)

Fetches information about the columns of a table. This must work for all tables created by the driver. If the driver lists a table in tables, then it must be able to list columns for the table here.

The arguments %args accepted are:

$table

The name of the table to examine the columns of.

Returns the column definition used to define the table.

@indexes = $driver->indexes(%args)

Fetches information about the indexes of a table. This must work for all tables created by the driver. If the driver lists a table in tables, then it must be able to list columns for the table here.

The arguments %args accepted are:

$table

The name of the table to examine the columns of.

Returns the index definition used to define the table.

$row = $driver->first(%args)

Fetches the first row from a table.

The arguments %args accepted are:

$handle

This is a handle returned by a call to open_table, open_join, or open_explicit_join.

Returns the first record found according to the given $handle that was created with a call to open_table or open_join or open_explicit_join. The $row returned is a hash reference where column names are the keys and their values are the values. This is called as an alternative to next to reset the "cursor" position to the top of the results.

If no results are available, then this method will return undef.

$row = $driver->next(%args)

Fetches the next row from a table.

The arguments %args accepted are:

$handle

This is a handle returned by a call to open_table, open_join, or open_explicit_join.

Returns the next record found according to the given $handle that was created with a call to open_table or open_join open_explicit_join. The $row returned is a hash reference where column names are the keys and their values are the values. This moves the "cursor" position ahead one row.

If no more results remain, then this method will return undef. An exception may be thrown if this method is called after either first or next has already returned undef.

$value = $driver->sequence_value(%args)

$table, $column)

In the case of AUTONUMBER columns, this method returns the last inserted numeric value into a column. If no recent insert has been made or the column is not of type AUTONUMBER an exception will be thrown. Whether or not the last insert into a table is recent will depend upon back-end. However, it should generally be safe to assume that an insertion made since the current connection is recent. The arguments %args accepted are:

$table

The table the AUTONUMBER column belongs to.

$column

The column of the table to fetch the last sequence value from.

Returns the last, recently inserted, sequence value for the column.

SEE ALSO

Persist, Persist::Source, Persist::Table, Persist::Join

AUTHOR

Andrew Sterling Hanenkamp, <hanenkamp@users.sourceforge.net>

COPYRIGHT AND LICENSE

Copyright (c) 2003, Andrew Sterling Hanenkamp
All rights reserved.

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions 
are met:

  * Redistributions of source code must retain the above copyright 
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright 
    notice, this list of conditions and the following disclaimer in 
    the documentation and/or other materials provided with the 
    distribution.
  * Neither the name of the Contentment nor the names of its 
    contributors may be used to endorse or promote products derived 
    from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.