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.

$driver = new Persist::Driver(@construct_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(@create_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(@delete_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($name, \@columns, \@indexes)

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 method returns true on successful table creation.

$success = $driver->delete_table($name)

Deletes the table named by $name. Returns true upon successful deletion of the table (or equivalent object in the store). This should effectively annihilate the description of the table and all data associated with it.

@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($table [, $filter ] )

Returns a handle which may be used to fetch information out of a single table in the database. The name of the table is specified in the $table argument. The optional $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(\@tables [, \@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. 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.

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.

$handle = $driver->open_explicit_join(\@tables, \@as_exprs [, $filter ] )

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. The array @tables is a list of table name aliases followed by table names of those tables to join. The array @as_exprs contains the expressions used to join each set of tables. Tables are joined in the order given with each @as_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.

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.

$rows = $driver->insert($name, \%values)

Inserts a new row into the table named $name. 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($name, \%set [, $filter [, \@bindings ] ] )

Updates zero or more entries in the table named $name. The hash %set maps column names (keys) to values (values). The optional filter specifies the criteria by which rows will be matched to determine whether or not to update them. The final optional bindings array is an array of bindings values.

WARNING: An undefined filter will update all rows.

Returns the number of rows affected.

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

$rows = $driver->delete($name [, $filter [, \@bindings ] ] )

Deletes zero or more entries from the table named $name. The optional filter specifies the criteria by which rows will be matched for deletion. The final optional bindings argument is an array of binding values

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

Returns the number of rows affected.

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

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

Returns the column definition used to define the table. This must work for tables created by the driver and also for any others that are listed by tables.

@indexes = $driver->indexes($name)

Returns the index definition used to define the table. This must work for tables created by the driver and also for any others that are listed by tables.

$row = $driver->first($handle)

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($handle)

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($table, $column)

In the case of AUTONUMBER columns, this method returns the last inserted numeric value into column $column of table $table. 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.

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.