The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Anansi::DatabaseComponent - A manager template for database drivers.

SYNOPSIS

    package Anansi::Database::Example;

    use base qw(Anansi::DatabaseComponent);

    sub connect {
        my ($self, $channel, %parameters) = @_;
        return $self->SUPER::connect(
            undef,
            INPUT => [
                'some text',
                {
                    NAME => 'someParameter',
                }, {
                    INPUT => [
                        'more text',
                        {
                            NAME => 'anotherParameter',
                        },
                        'yet more text',
                    ]
                }, {
                    DEFAULT => 'abc',
                    NAME => 'yetAnotherParameter',
                },
            ],
            (%parameters),
        );
    }

    sub validate {
        my ($self, $channel, %parameters) = @_;
        $parameters{DRIVER} = 'Example';
        return Anansi::DatabaseComponent::validate(undef, %parameters);
    }

    Anansi::Component::addChannel('Anansi::Database::Example', 'AUTOCOMMIT' => 'Anansi::DatabaseComponent::autocommit');
    Anansi::Component::addChannel('Anansi::Database::Example', 'COMMIT' => 'Anansi::DatabaseComponent::commit');
    Anansi::Component::addChannel('Anansi::Database::Example', 'CONNECT' => 'connect');
    Anansi::Component::addChannel('Anansi::Database::Example', 'DISCONNECT' => 'Anansi::DatabaseComponent::disconnect');
    Anansi::Component::addChannel('Anansi::Database::Example', 'FINISH' => 'Anansi::DatabaseComponent::finish');
    Anansi::Component::addChannel('Anansi::Database::Example', 'HANDLE' => 'Anansi::DatabaseComponent::handle');
    Anansi::Component::addChannel('Anansi::Database::Example', 'PREPARE' => 'Anansi::DatabaseComponent::prepare');
    Anansi::Component::addChannel('Anansi::Database::Example', 'ROLLBACK' => 'Anansi::DatabaseComponent::rollback');
    Anansi::Component::addChannel('Anansi::Database::Example', 'STATEMENT' => 'Anansi::DatabaseComponent::statement');
    Anansi::Component::addChannel('Anansi::Database::Example', 'VALIDATE_AS_APPROPRIATE' => 'validate'); 

    1;

    package main;

    use Anansi::Database;

    my $database = Anansi::Database->new();
    my $component = $database->addComponent(undef,
        DRIVER => 'Example',
    );
    if(defined($component)) {
        if($database->connect(
            undef,
            $component,
            someParameter => 'some data',
            anotherParameter => 'more data',
            yetAnotherParameter => 'further data',
        )) {
            my $result = $database->statement(
                undef,
                $component,
                SQL => 'SELECT someThing FROM someTable where modified = ?;',
                INPUT => [
                    {
                        NAME => 'modified',
                    },
                ],
                modified => '2011-02-22 00:21:46',
            );
            if(!defined($result)) {
            } elsif(ref($result) =~ /^ARRAY$/i) {
                foreach my $record (@{$result}) {
                    next if(ref($record) !~ /^HASH$/i);
                    print 'someThing: "'.${$record}{someThing}.'"'."\n";
                }
            }
        }
    }

    1;

DESCRIPTION

Manages a database connection providing generic processes to allow it's opening, closing and various SQL interactions. Uses Anansi::Actor.

METHODS

Anansi::Class

See Anansi::Class for details. A parent module of Anansi::Component.

DESTROY

See Anansi::Class::DESTROY for details.

finalise

See Anansi::Class::finalise for details. Overridden by Anansi::DatabaseComponent::finalise. A virtual method.

implicate

See Anansi::Class::implicate for details. A virtual method.

import

See Anansi::Class::import for details.

initialise

See Anansi::Class::initialise for details. A virtual method.

new

See Anansi::Class::new for details.

old

See Anansi::Class::old for details.

used

See Anansi::Class::used for details.

uses

See Anansi::Class::uses for details.

using

See Anansi::Class::using for details.

Anansi::Component

See Anansi::Component for details. A parent module of Anansi::DatabaseComponent.

Anansi::Class

See Anansi::Class for details. A parent module of Anansi::Component.

addChannel

See Anansi::Component::addChannel for details.

channel

See Anansi::Component::channel for details.

componentManagers

See Anansi::Component::componentManagers for details.

removeChannel

See Anansi::Component::removeChannel for details.

autoCommit

    if(1 == Anansi::DatabaseComponent::autocommit($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'AUTOCOMMIT'));

    if(1 == $OBJECT->autocommit(undef));

    if(1 == $OBJECT->channel('AUTOCOMMIT'));
self (Blessed Hash, Required)

An object of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

Attempts to perform a database autocommit. Returns 1 (one) on success and 0 (zero) on failure.

bind

    if(Anansi::DatabaseComponent::bind($OBJECT,
        HANDLE => $HANDLE,
        INPUT => [
            {
                NAME => 'someParameter'
            }, {
                DEFAULT => 123,
                NAME => 'anotherParameter'
            }
        ],
        VALUE => {
            someParameter => 'abc'
        }
    ));

    if($OBJECT->bind(
        HANDLE => $HANDLE,
        INPUT => [
            {
                NAME => 'yetAnotherParameter',
                TYPE => 'TEXT'
            }
        ],
        VALUE => [
            yetAnotherParameter => 456
        ]
    ));
self (Blessed Hash or String, Required)

Either an object or a string of this namespace.

parameters (Hash, Optional)

Named parameters.

HANDLE (DBI::st, Required)

The database statement handle.

INPUT (Array, Required)

An array of hashes. Each element of the array corresponds to an equivalent ? (Question mark) within the prepared SQL statement. Each hash contains a NAME key with a value that represents a possible key within the VALUE parameter. Each hash may also contain a DEFAULT key which contains the value to use if the equivalent VALUE parameter does not exist and a TYPE key which contains the SQL type to associate with the assigned value. When no corresponding VALUE parameter key exists and no DEFAULT key has been defined then an empty string is used for the value.

VALUE (Hash, Required)

A hash of values to assign in the order specified by the INPUT parameter.

Attempts to use the supplied parameters to assign values to a SQL statement that has already been prepared to accept them. Returns 0 (zero) on failure and the database statement handle on success.

binding

    if(1 == Anansi::DatabaseComponent::binding($OBJECT));

    if(1 == $OBJECT->binding());
self (Blessed Hash or String, Required)

Either an object or a string of this namespace.

parameters (Array, Optional)

An array of hashes. Each hash should contain a NAME key with a string value.

Verifies that the supplied parameters are all hashes and that they each contain a NAME key with a string value. Returns 1 (one) when validity is confirmed and 0 (zero) when an invalid structure is determined. Used to validate the INPUT parameter of the bind method.

commit

    if(1 == Anansi::DatabaseComponent::commit($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'COMMIT'));

    if(1 == $OBJECT->commit(undef));

    if(1 == $OBJECT->channel('COMMIT'));
self (Blessed Hash or String, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

Attempts to perform a database commit. Returns 1 (one) on success and 0 (zero) on failure.

connect

    if(1 == Anansi::DatabaseComponent::connect($OBJECT, undef
        INPUT => [
            'some text',
            {
                NAME => 'someParameter'
            }, {
                INPUT => [
                    'more text',
                    {
                        NAME => 'anotherParameter'
                    },
                    'yet more text'
                ]
            }, {
                DEFAULT => 'abc',
                NAME => 'yetAnotherParameter'
            }
        ],
        someParameter => 12345,
        anotherParameter => 'blah blah blah'
    ));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'CONNECT',
        INPUT => [
            'blah blah blah',
            {
                DEFAULT => 123,
                NAME => 'someParameter',
            }
        ],
        someParameter => 'some text'
    ));

    if(1 == $OBJECT->connect(undef,
        INPUT => [
            {
                INPUT => [
                    'some text',
                    {
                        NAME => 'someParameter'
                    },
                    'more text'
                ]
            }
        ],
        someParameter => 'in between'
    ));

    if(1 == $OBJECT->channel('CONNECT',
        INPUT => [
            {
                INPUT => [
                    {
                        NAME => 'abc'
                    }, {
                        NAME => 'def'
                    }
                },
                REF => 'HASH'
            }
        ]
    ));
self (Blessed Hash, Required)

An object of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Required)

Named parameters.

HANDLE (DBI::db, Optional)

The database handle of an existing database connection. Used in preference to the INPUT parameter.

INPUT (Array or Scalar, Optional)

An array or single value containing a description of each parameter in the order that it is passed to the database driver's connect method. Used when the HANDLE parameter does not exist.

(Non-Hash)

An element that does not contain a hash value will be used as the corresponding connect method's parameter value.

(Hash)

An element that contains a hash value is assumed to be a description of how to generate the corresponding connect method's parameter value. when a value can not be generated, an undef value will be used.

DEFAULT (Optional)

The value to use if no other value can be determined.

INPUT (Array or Scalar, Optional)

Contains a structure like that given in INPUT above with the exception that any further INPUT keys will be ignored. As this key is only valid when NAME is undefined and REF either specifies a string or a hash, it's value will be either a concatenation of all the calculated strings or a hash containing all of the specified keys and values.

NAME (String, Optional)

The name of the parameter that contains the value to use.

REF (Array or String, Optional)

The data types used to validate the value to use.

Either uses an existing database connection or attempts to perform a database connection using the supplied parameters. Returns 1 (one) on success and 0 (zero) on failure.

disconnect

    if(1 == Anansi::DatabaseComponent::disconnect($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'DISCONNECT'));

    if(1 == $OBJECT->disconnect(undef));

    if(1 == $OBJECT->channel('DISCONNECT'));
self (Blessed Hash or String, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

Attempts to perform a database disconnection. Returns 1 (one) on success and 0 (zero) on failure.

finalise

Overrides Anansi::Class::finalise. A virtual method.

finish

    if(1 == Anansi::DatabaseComponent::finish($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'FINISH'));

    if(1 == $OBJECT->finish(undef));

    if(1 == $OBJECT->channel('FINISH'));
self (Blessed Hash, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

STATEMENT (String, Optional)

The name associated with a prepared SQL statement.

Either releases the named SQL statement preparation or all of the SQL statement preparations. Returns 1 (one) on success and 0 (zero) on failure.

handle

    my $HANDLE = Anansi::DatabaseComponent::handle($OBJECT, undef);

    my $HANDLE = Anansi::DatabaseComponent::channel($OBJECT, 'HANDLE');

    my $HANDLE = $OBJECT->handle(undef);

    my $dbh = DBI->connect('DBI:mysql:database=someDatabase', 'someUser', 'somePassword');
    my $HANDLE = $OBJECT->channel('HANDLE', $dbh);
    if(defined($HANDLE));
self (Blessed Hash, Required)

An object of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

handle (DBI::db, Optional)

A replacement database handle.

Attempts to redefine an existing database handle when a handle is supplied. Either returns the database handle or undef on failure.

initialise

Overrides Anansi::Class::initialise. A virtual method.

prepare

    my $PREPARATION = if(1 == Anansi::DatabaseComponent::prepare($OBJECT, undef,
        STATEMENT => 'an associated name'
    );
    if(defined($PREPARATION));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'PREPARE',
        INPUT => [
            {
                NAME => 'someParameter'
            }
        ],
        SQL => 'SELECT abc, def FROM some_table WHERE ghi = ?',
        STATEMENT => 'another associated name'
    ));

    if(1 == $OBJECT->prepare(undef,
        INPUT => [
            {
                NAME => 'abc'
            }, {
                NAME => 'def'
            }, {
                NAME => 'ghi'
            }
        ],
        SQL => 'INSERT INTO some_table (abc, def, ghi) VALUES (?, ?, ?);',
        STATEMENT => 'yet another name'
    ));

    if(1 == $OBJECT->channel('PREPARE',
        INPUT => [
            {
                NAME => ''
            }
        ],
        SQL => '',
        STATEMENT => 'and another',
    ));
self (Blessed Hash, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Required)

Named parameters.

INPUT Array, Optional

An array of hashes. Each hash should contain a NAME key with a string value that represents the name of a parameter to associate with the corresponding ? (Question mark). See the bind method for details.

SQL (String, Optional)

The SQL statement to prepare.

STATEMENT (String, Required)

The name to associate with the prepared SQL statement.

Attempts to prepare a SQL statement to accept named parameters in place of ? (Question mark)s as required. Either returns all of the preparation data required to fulfill the SQL statement when called as a namespace method or 1 (one) when called through a channel on success and 0 (zero) on failure.

rollback

    if(1 == Anansi::DatabaseComponent::rollback($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'ROLLBACK'));

    if(1 == $OBJECT->rollback(undef));

    if(1 == $OBJECT->channel('ROLLBACK'));
self (Blessed Hash, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

Attempts to undo all of the database changes since the last database commit. Returns 1 (one) on success and 0 (zero) on failure.

statement

    my $result = Anansi::DatabaseComponent::statement($OBJECT, undef,
        INPUT => [
            'hij' => 'someParameter',
            'klm' => 'anotherParameter'
        ],
        SQL => 'SELECT abc, def FROM some_table WHERE hij = ? AND klm = ?;',
        STATEMENT => 'someStatement',
        someParameter => 123,
        anotherParameter => 456
    );

    my $result = Anansi::DatabaseComponent::channel($OBJECT, 'STATEMENT',
        STATEMENT => 'someStatement',
        someParameter => 234,
        anotherParameter => 'abc'
    );

    my $result = $OBJECT->statement(
        undef,
        STATEMENT => 'someStatement',
        someParameter => 345,
        anotherParameter => 789
    );

    my $result = $OBJECT->channel('STATEMENT',
        STATEMENT => 'someStatement',
        someParameter => 456,
        anotherParameter => 'def'
    );
self (Blessed Hash, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

INPUT (Array, Optional)

An array of hashes with each element corresponding to an equivalent ? (Question mark) found within the supplied SQL. If the number of elements is not the same as the number of ? (Question mark)s found in the statement then the statement is invalid. See the bind method for details.

SQL (String, Optional)

The SQL statement to execute.

STATEMENT (String, Optional)

The name associated with a prepared SQL statement. This is interchangeable with the SQL parameter but helps to speed up repetitive database interaction.

Attempts to execute the supplied SQL with the supplied named parameters. Either returns an array of retrieved record data or a 1 (one) on success and a 0 (zero) on failure as appropriate to the SQL statement.

validate

    if(1 == Anansi::DatabaseComponent::validate($OBJECT, undef));

    if(1 == Anansi::DatabaseComponent::channel($OBJECT, 'VALIDATE_AS_APPROPRIATE'));

    if(1 == Anansi::DatabaseComponent->validate(undef, DRIVERS => ['some::driver::module', 'anotherDriver']));

    if(1 == Anansi::DatabaseComponent->channel('VALIDATE_AS_APPROPRIATE'));

    if(1 == $OBJECT->validate(undef, DRIVER => 'Example'));

    if(1 == $OBJECT->channel('VALIDATE_AS_APPROPRIATE', DRIVER => 'Example'));

    if(1 == Anansi::DatabaseComponent->validate(undef, DRIVER => 'Example', DRIVERS => 'some::driver'));

    if(1 == Anansi::DatabaseComponent->channel('VALIDATE_AS_APPROPRIATE', DRIVER => 'Example'));
self (Blessed Hash or String, Required)

Either an object or a string of this namespace.

channel (String, Required)

The abstract identifier of a subroutine.

parameters (Hash, Optional)

Named parameters.

DRIVER (String, Optional)

Either the namespace of a database driver or the name of a database driver that should be used.

DRIVERS (Array or String, Optional)

An array of strings or a single string containing either the namespace of a valid database driver or the name of a database driver that should be looked for among the installed modules.

HANDLE DBI::db, Optional

An existing database connection handle.

Generic validation for whether a database should be handled by a component. If the driver name is supplied then an attempt will be made to use that driver as long as it matches any of the acceptable DRIVERS, otherwise one of the acceptable DRIVERS will be tried or a generic driver if none have been supplied. Returns 1 (one) for valid and 0 (zero) for invalid.

NOTES

This module is designed to make it simple, easy and quite fast to code your design in perl. If for any reason you feel that it doesn't achieve these goals then please let me know. I am here to help. All constructive criticisms are also welcomed.

AUTHOR

Kevin Treleaven <kevin AT treleaven DOT net>