=head1 NAME

DBI::DBD::SqlEngine::Developers - Developers documentation for DBI::DBD::SqlEngine

=head1 SYNOPSIS

    package DBD::myDriver;

    use base qw(DBI::DBD::SqlEngine);

    sub driver
    {
	...
	my $drh = $proto->SUPER::driver($attr);
	...
	return $drh->{class};
    }

    sub CLONE { ... }

    package DBD::myDriver::dr;

    @ISA = qw(DBI::DBD::SqlEngine::dr);

    sub data_sources { ... }
    ...

    package DBD::myDriver::db;

    @ISA = qw(DBI::DBD::SqlEngine::db);

    sub init_valid_attributes { ... }
    sub init_default_attributes { ... }
    sub set_versions { ... }
    sub validate_STORE_attr { my ($dbh, $attrib, $value) = @_; ... }
    sub validate_FETCH_attr { my ($dbh, $attrib) = @_; ... }
    sub get_myd_versions { ... }
    sub get_avail_tables { ... }

    package DBD::myDriver::st;

    @ISA = qw(DBI::DBD::SqlEngine::st);

    sub FETCH { ... }
    sub STORE { ... }

    package DBD::myDriver::Statement;

    @ISA = qw(DBI::DBD::SqlEngine::Statement);

    sub open_table { ... }

    package DBD::myDriver::Table;

    @ISA = qw(DBI::DBD::SqlEngine::Table);

    sub new { ... }

    sub fetch_row { ... }
    sub push_row { ... }
    sub push_names { ... }
    sub seek { ... }
    sub truncate { ... }
    sub drop { ... }

    # optimize the SQL engine by add one or more of
    sub update_current_row { ... }
    # or
    sub update_specific_row { ... }
    # or
    sub update_one_row { ... }
    # or
    sub insert_new_row { ... }
    # or
    sub delete_current_row { ... }
    # or
    sub delete_one_row { ... }

=head1 DESCRIPTION

This document describes the interface of DBI::DBD::SqlEngine for DBD
developers who write DBI::DBD::SqlEngine based DBI drivers. It supplements
L<DBI::DBD> and L<DBI::DBD::SqlEngine::HowTo>, which you should read first.

=head1 CLASSES

Each DBI driver must provide a package global C<< driver >> method and
three DBI related classes:

=over 4

=item DBI::DBD::SqlEngine::dr

Driver package, contains the methods DBI calls indirectly via DBI
interface:

  DBI->connect ('DBI:DBM:', undef, undef, {})

  # invokes
  package DBD::DBM::dr;
  @DBD::DBM::dr::ISA = qw(DBI::DBD::SqlEngine::dr);

  sub connect ($$;$$$)
  {
      ...
  }

Similar for C<< data_sources () >> and C<< disconnect_all() >>.

Pure Perl DBI drivers derived from DBI::DBD::SqlEngine do not usually need to
override any of the methods provided through the DBD::XXX::dr package
however if you need additional initialization in the connect method
you may need to.

=item DBI::DBD::SqlEngine::db

Contains the methods which are called through DBI database handles
(C<< $dbh >>). e.g.,

  $sth = $dbh->prepare ("select * from foo");
  # returns the f_encoding setting for table foo
  $dbh->csv_get_meta ("foo", "f_encoding");

DBI::DBD::SqlEngine provides the typical methods required here. Developers who
write DBI drivers based on DBI::DBD::SqlEngine need to override the methods
C<< set_versions >> and C<< init_valid_attributes >>.

=item DBI::DBD::SqlEngine::st

Contains the methods to deal with prepared statement handles. e.g.,

  $sth->execute () or die $sth->errstr;

=back

=head2 DBI::DBD::SqlEngine

This is the main package containing the routines to initialize
DBI::DBD::SqlEngine based DBI drivers. Primarily the
C<< DBI::DBD::SqlEngine::driver >> method is invoked, either directly
from DBI when the driver is initialized or from the derived class.

  package DBD::DBM;

  use base qw( DBI::DBD::SqlEngine );

  sub driver
  {
      my ( $class, $attr ) = @_;
      ...
      my $drh = $class->SUPER::driver( $attr );
      ...
      return $drh;
  }

It is not necessary to implement your own driver method as long as
additional initialization (e.g. installing more private driver
methods) is not required.  You do not need to call C<< setup_driver >>
as DBI::DBD::SqlEngine takes care of it.

=head2 DBI::DBD::SqlEngine::dr

The driver package contains the methods DBI calls indirectly via the DBI
interface (see L<DBI/DBI Class Methods>).

DBI::DBD::SqlEngine based DBI drivers usually do not need to implement anything here,
it is enough to do the basic initialization:

  package DBD:XXX::dr;

  @DBD::XXX::dr::ISA = qw (DBI::DBD::SqlEngine::dr);
  $DBD::XXX::dr::imp_data_size     = 0;
  $DBD::XXX::dr::data_sources_attr = undef;
  $DBD::XXX::ATTRIBUTION = "DBD::XXX $DBD::XXX::VERSION by Hans Mustermann";

=head2 DBI::DBD::SqlEngine::db

This package defines the database methods, which are called via the DBI
database handle C<< $dbh >>.

Methods provided by DBI::DBD::SqlEngine:

=over 4

=item ping

Simply returns the content of the C<< Active >> attribute. Override
when your driver needs more complicated actions here.

=item prepare

Prepares a new SQL statement to execute. Returns a statement handle,
C<< $sth >> - instance of the DBD:XXX::st. It is neither required nor
recommended to override this method.

=item FETCH

Fetches an attribute of a DBI database object. Private handle attributes
must have a prefix (this is mandatory). If a requested attribute is
detected as a private attribute without a valid prefix, the driver prefix
(written as C<$drv_prefix>) is added.

The driver prefix is extracted from the attribute name and verified against
C<< $dbh->{ $drv_prefix . "valid_attrs" } >> (when it exists). If the
requested attribute value is not listed as a valid attribute, this method
croaks. If the attribute is valid and readonly (listed in C<< $dbh->{
$drv_prefix . "readonly_attrs" } >> when it exists), a real copy of the
attribute value is returned. So it's not possible to modify
C<f_valid_attrs> from outside of DBI::DBD::SqlEngine::db or a derived class.

=item STORE

Stores a database private attribute. Private handle attributes must have a
prefix (this is mandatory). If a requested attribute is detected as a private
attribute without a valid prefix, the driver prefix (written as
C<$drv_prefix>) is added. If the database handle has an attribute
C<${drv_prefix}_valid_attrs> - for attribute names which are not listed in
that hash, this method croaks. If the database handle has an attribute
C<${drv_prefix}_readonly_attrs>, only attributes which are not listed there
can be stored (once they are initialized). Trying to overwrite such an
immutable attribute forces this method to croak.

An example of a valid attributes list can be found in
C<< DBI::DBD::SqlEngine::db::init_valid_attributes >>.

=item set_versions

This method sets the attributes C<< f_version >>, C<< sql_nano_version >>,
C<< sql_statement_version >> and (if not prohibited by a restrictive
C<< ${prefix}_valid_attrs >>) C<< ${prefix}_version >>.

This method is called at the end of the C<< connect () >> phase.

When overriding this method, do not forget to invoke the superior one.

=item init_valid_attributes

This method is called after the database handle is instantiated as the
first attribute initialization.

C<< DBI::DBD::SqlEngine::db::init_valid_attributes >> initializes the
attributes C<sql_valid_attrs> and C<sql_readonly_attrs>.

When overriding this method, do not forget to invoke the superior one,
preferably before doing anything else.

=item init_default_attributes

This method is called after the database handle is instantiated to
initialize the default attributes.

C<< DBI::DBD::SqlEngine::db::init_default_attributes >> initializes the
attributes C<sql_identifier_case>, C<sql_quoted_identifier_case>,
C<sql_handler>, C<sql_engine_version>, C<sql_nano_version> and
C<sql_statement_version> when L<SQL::Statement> is available.

When the derived implementor class provides the attribute to validate
attributes (e.g. C<< $dbh->{dbm_valid_attrs} = {...}; >>) or the attribute
containing the immutable attributes (e.g.  C<< $dbh->{dbm_readonly_attrs}
= {...}; >>), the attributes C<drv_valid_attrs>, C<drv_readonly_attrs> and
C<drv_version> are added (when available) to the list of valid and
immutable attributes (where C<drv_> is interpreted as the driver prefix).

=item get_versions

This method is called by the code injected into the instantiated driver to
provide the user callable driver method C<< ${prefix}versions >> (e.g.
C<< dbm_versions >>, C<< csv_versions >>, ...).

The DBI::DBD::SqlEngine implementation returns all version information known by
DBI::DBD::SqlEngine (e.g. DBI version, Perl version, DBI::DBD::SqlEngine version and
the SQL handler version).

C<get_versions> takes the C<$dbh> as the first argument and optionally a
second argument containing a table name. The second argument is not
evaluated in C<< DBI::DBD::SqlEngine::db::get_versions >> itself - but
might be in the future.

If the derived implementor class provides a method named
C<get_${drv_prefix}versions>, this is invoked and the return value of
it is associated to the derived driver name:

    if (my $dgv = $dbh->{ImplementorClass}->can ("get_" . $drv_prefix . "versions") {
	(my $derived_driver = $dbh->{ImplementorClass}) =~ s/::db$//;
	$versions{$derived_driver} = &$dgv ($dbh, $table);
    }

Override it to add more version information about your module, (e.g.
some kind of parser version in case of DBD::CSV, ...), if one line is not
enough room to provide all relevant information.

=item sql_parser_object

Returns a L<SQL::Parser> instance, when C<< sql_handler >> is set to
"SQL::Statement". The parser instance is stored in C<< sql_parser_object >>.

It is not recommended to override this method.

=item disconnect

Disconnects from a database. All local table information is discarded and
the C<< Active >> attribute is set to 0.

=item type_info_all

Returns information about all the types supported by DBI::DBD::SqlEngine.

=item table_info

Returns a statement handle which is prepared to deliver information about
all known tables.

=item list_tables

Returns a list of all known table names.

=item quote

Quotes a string for use in SQL statements.

=item commit

Warns about a useless call (if warnings enabled) and returns.
DBI::DBD::SqlEngine is typically a driver which commits every action instantly when
executed.

=item rollback

Warns about a useless call (if warnings enabled) and returns.
DBI::DBD::SqlEngine is typically a driver which commits every action instantly when
executed.

=back

=head2 DBI::DBD::SqlEngine::st

Contains the methods to deal with prepared statement handles:

=over 4

=item bind_param

Common routine to bind placeholders to a statement for execution. It
is dangerous to override this method without detailed knowledge about
the DBI::DBD::SqlEngine internal storage structure.

=item execute

Executes a previously prepared statement (with placeholders, if any).

=item finish

Finishes a statement handle, discards all buffered results. The prepared
statement is not discarded so the statement can be executed again.

=item fetch

Fetches the next row from the result-set. This method may be rewritten
in a later version and if it's overridden in a derived class, the
derived implementation should not rely on the storage details.

=item fetchrow_arrayref

Alias for C<< fetch >>.

=item FETCH

Fetches statement handle attributes. Supported attributes (for full overview
see L<DBI/Statement Handle Attributes>) are C<NAME>, C<TYPE>, C<PRECISION>
and C<NULLABLE>. Each column is returned as C<NULLABLE> which might be wrong
depending on the derived backend storage.  If the statement handle has
private attributes, they can be fetched using this method, too. B<Note> that
statement attributes are not associated with any table used in this statement.

This method usually requires extending in a derived implementation.
See L<DBD::CSV> or L<DBD::DBM> for some example.

=item STORE

Allows storing of statement private attributes. No special handling is
currently implemented here.

=item rows

Returns the number of rows affected by the last execute. This method might
return C<undef>.

=back

=head2 DBI::DBD::SqlEngine::Statement

Derives from DBI::SQL::Nano::Statement for unified naming when deriving
new drivers. No additional feature is provided from here.

=head2 DBI::DBD::SqlEngine::Table

Derives from DBI::SQL::Nano::Table for unified naming when deriving
new drivers. No additional feature is provided from here.

You should consult the documentation of C<< SQL::Eval::Table >> (see
L<SQL::Eval>) to get more information about the abstract methods of the
table's base class you have to override and a description of the table
meta information expected by the SQL engines.

=head1 AUTHOR

The module DBI::DBD::SqlEngine is currently maintained by

H.Merijn Brand < h.m.brand at xs4all.nl > and
Jens Rehsack  < rehsack at googlemail.com >

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2010 by H.Merijn Brand & Jens Rehsack

All rights reserved.

You may freely distribute and/or modify this module under the terms of
either the GNU General Public License (GPL) or the Artistic License, as
specified in the Perl README file.

=cut
