NAME
   SQL::Executor - Thin DBI wrapper using SQL::Maker

SYNOPSIS
     use DBI;
     use SQL::Executor;
     my $dbh = DBI->connect($dsn, $id, $pass);
     my $ex = SQL::Executor->new($dbh);
     #
     # SQL::Maker-like interfaces
     my @rows = $ex->select('SOME_TABLE', { id => 123 });
     $ex->insert('SOME_TABLE', { id => 124, value => 'xxxx'} );
     $ex->update('SOME_TABLE', { value => 'yyyy'}, { id => 124 } );
     $ex->delete('SOME_TABLE', { id => 124 } );
     #
     # select using SQL with named placeholder
     my @rows= $ex->select_named('SELECT id, value1 FROM SOME_TABLE WHERE value2 = :arg1', { arg1 => 'aaa' });

DESCRIPTION
   SQL::Executor is thin DBI wrapper using SQL::Maker. This module provides
   interfaces to make easier access to SQL.

   You can execute SQL via SQL::Maker-like interface in select(),
   select_row(), select_all(), select_with_fields(),
   select_row_with_fields(), select_all_with_fields(), insert(),
   insert_multi(), update() and delete().

   If you want to use more complex select query, you can use
   select_named(), select_row_named() or select_all_named() these execute
   SQL with named placeholder. If you don't want to use named placeholder,
   you can use select_by_sql(), select_row_by_sql() or select_all_by_sql()
   these execute SQL with normal placeholder('?').

METHODS
 new($dbh, $option_href)
   $dbh: Database Handler $option_href: option

   available option is as follows

   *   allow_empty_condition (BOOL default 1): allow empty condition(where)
       in select/delete/update

   *   callback (coderef): specify callback coderef. callback is called for
       each select* method

   *   check_empty_bind (BOOL default 0): if TRUE(1), select*_named() do
       not accept unbound parameter, see named_bind() for detail.

   These callbacks are useful for making row object.

     my $ex = SQL::Executor->new($dbh, {
         callback => sub {
             my ($self, $row, $table_name, $select_id) = @_;
             return CallBack::Class->new($row);
         },
     });

     my $row = $ex->select_by_sql($sql1, \@binds1, 'TEST');
     # $row isa 'CallBack::Class'

 connect($dsn, $user, $pass, $option_for_dbi, $option_href)
   $dsn: DSN $user: database user $pass: database password
   $option_href_for_dbi: options passed to DBI $option_href: option for
   SQL::Executor (options are same as new() method)

   connect database and create SQL::Executor instance. using this method,
   SQL::Executor uses managed connection and transaction via DBIx::Handler

 dbh()
   return database handler

 select($table_name, $where, $option)
   select row(s). parameter is the same as select method in SQL::Maker. But
   array ref for filed names are not needed. In array context, this method
   behaves the same as select_all. In scalar context, this method behaves
   the same as select_one

 select_row($table_name, $where, $option)
   select only one row. parameter is the same as select method in
   SQL::Maker. But array ref for filed names are not needed. this method
   returns hash ref and it is the same as return value in DBI's
   selectrow_hashref/fetchrow_hashref.

 select_all($table_name, $where, $option)
   select all rows. parameter is the same as select method in SQL::Maker.
   But array ref for filed names are not needed. this method returns array
   that is composed of hash refs. (hash ref is same as DBI's
   selectrow_hashref/fetchrow_hashref).

 select_itr($table_name, $where, $option)
   select and returns iterator. parameter is the same as select method in
   SQL::Maker. But array ref for field names are not needed. Iterator is
   SQL::Executor::Iterator object.

     my $itr = select_itr('SOME_TABLE', { name => 'aaa' });
     while( my $row = $itr->next ) {
         # ... using row
     }

 select_named($sql, $params_href, $table_name)
   select row(s). In array context, this method behaves the same as
   select_all_with_fields. In scalar context, this method behaves the same
   as select_one_with_fileds

   You can use named placeholder in SQL like this,

     my $ex = SQL::Executor->new($dbh);
     my $row = $ex->select_named("SELECT * FROM SOME_TABLE WHERE id = :id", { id => 1234 });

   $table_name is used for callback.

 select_row_named($sql, $params_href, $table_name)
   select only one row. You can use named placeholder in SQL like this,

     my $ex = SQL::Executor->new($dbh);
     my $row = $ex->select_row_named("SELECT * FROM SOME_TABLE WHERE id = :id", { id => 1234 });

   this method returns hash ref and it is the same as return value in DBI's
   selectrow_hashref/fetchrow_hashref.

   $table_name is used for callback.

 select_all_named($sql, $params_href, $table_name)
   select all rows. You can use named placeholder in SQL like this,

     my $ex = SQL::Executor->new($dbh);
     my @rows = $ex->select_all_named("SELECT * FROM SOME_TABLE WHERE id = :id", { id => 1234 });

   this method returns array that is composed of hash refs. (hash ref is
   same as DBI's selectrow_hashref/fetchrow_hashref). $table_name is used
   for callback.

 select_itr_named($sql, $params_href, $table_name)
   select and returns iterator. You can use named placeholder in SQL like
   this,

     my $ex = SQL::Executor->new($dbh);
     my $itr = $ex->select_itr_named("SELECT * FROM SOME_TABLE WHERE id = :id", { id => 1234 });

   $table_name is used for callback.

 named_bind($sql, $params_href, $check_empty_bind)
   returns sql which is executable in execute_query() and parameters for
   bind.

     my ($sql, @binds) = named_bind("SELECT * FROM SOME_TABLE WHERE id = :id", { id => 123 });
     # $sql   =>  "SELECT * FROM SOME_TABLE WHERE id = ?"
     # @binds => (123)

   parameter $check_empty_bind is optional. By default (or set
   $check_empty_bind=0), named_bind() accepts unbound parameter like this,

     my ($sql, @binds) = named_bind("SELECT * FROM SOME_TABLE WHERE id = :id", { });# do not bind :id
     # $sql   =>  "SELECT * FROM SOME_TABLE WHERE id = ?"
     # @binds => (undef)

   if $check_empty_bind is 1, named_bind() dies when unbound parameter is
   specified.

 select_by_sql($sql, \@binds, $table_name)
   select row(s). In array context, this method behaves the same as
   select_all_with_fields. In scalar context, this method behaves the same
   as select_one_with_fileds

     my $ex = SQL::Executor->new($dbh);
     my $row = $ex->select_by_sql("SELECT * FROM SOME_TABLE WHERE id = ?", [1234]);

   $table_name is only used for callback.

 select_row_by_sql($sql, \@binds, $table_name)
   select only one row.

     my $ex = SQL::Executor->new($dbh);
     my $row = $ex->select_row_by_sql("SELECT * FROM SOME_TABLE WHERE id = ?", [1234]);

   this method returns hash ref and it is the same as return value in DBI's
   selectrow_hashref/fetchrow_hashref.

 select_all_by_sql($sql, \@binds, $table_name)
   select all rows.

     my $ex = SQL::Executor->new($dbh);
     my @rows = $ex->select_all_by_sql("SELECT * FROM SOME_TABLE WHERE id = ?", [1234]);

   this method returns array that is composed of hash refs. (hash ref is
   same as DBI's selectrow_hashref/fetchrow_hashref).

 select_itr_by_sql($sql, \@binds, $table_name)
   select and returns iterator

     my $ex = SQL::Executor->new($dbh);
     my $itr = $ex->select_itr_by_sql("SELECT * FROM SOME_TABLE WHERE id = ?", [1234]);

   Iterator is SQL::Executor::Iterator object.

 select_with_fields($table_name, $fields_aref, $where, $option)
   select row(s). parameter is the same as select method in SQL::Maker. In
   array context, this method behaves the same as select_all_with_fields.
   In scalar context, this method behaves the same as
   select_one_with_fileds

 select_row_with_fields($table_name, $fields_aref, $where, $option)
   select only one row. parameter is the same as select method in
   SQL::Maker. this method returns hash ref and it is the same as return
   value in DBI's selectrow_hashref/fetchrow_hashref.

 select_all_with_fields($table_name, $fields_aref, $where, $option)
   select all rows. parameter is the same as select method in SQL::Maker.
   But array ref for filed names are not needed. this method returns array
   that is composed of hash refs. (hash ref is same as DBI's
   selectrow_hashref/fetchrow_hashref).

 select_itr_with_fields($table_name, $fields_aref, $where, $option)
   select and return iterator object(SQL::Executor::Iterator). parameter is
   the same as select method in SQL::Maker.

 insert($table_name, $values)
   Do INSERT statement. parameter is the same as select method in
   SQL::Maker.

 insert_multi($table_name, @args)
   Do INSERT-multi statement using SQL::Maker::Plugin::InsertMulti.

 insert_on_duplicate($table_name, $insert_value_href, $update_value_href)
   Do "INSERT ... ON DUPLICATE KEY UPDATE" query (works only MySQL) using
   SQL::Maker::Plugin::InsertOnDuplicate.

   this method is available when SQL::Maker >= 1.09 is installed. If older
   version is installed, you will got error like "Can't locate
   SQL/Maker/Plugin/InsertOnDuplicate.pm in @INC ..."

 delete($table_name, $where)
   Do DELETE statement. parameter is the same as select method in
   SQL::Maker.

 update($table_name, $set, $where)
   Do UPDATE statement. parameter is the same as select method in
   SQL::Maker.

 execute_query($sql, \@binds)
   execute query and returns statement handler($sth).

 execute_query_named($sql, $params_href)
   execute query with named placeholder and returns statement
   handler($sth).

 disable_callback()
   disable callback temporarily,

 restore_callback()
   restore disabled callback.

 last_insert_id(@args)
   If driver is mysql, return $dbh->{mysql_insertid}.If driver is SQLite,
   return $dbh->sqlite_last_insert_rowid. If other driver is used, return
   $dbh->last_insert_id(@args)

 handle_exception($sql, $binds_aref, $err_message)
   show error message. you can override this method in subclass to provide
   customized error message.

   default error message is like this,

   Error <I>$error_message</I> sql: <I>$sql</I>, binds:
   [<I>$binds_aref</I>]\n

 select_id()
   generate id for select statament. but by default, id is not generated.
   If you want to generate id, please override

How to use Transaction.
   When create instance using connect() method, you can use DBIx::Handler's
   transaction management,

     use SQL::Executor;
     my $ex = SQL::Executor->connect($dsn, $id, $pass);
     my $txn = $ex->handler->txn_scope();
     $ex->insert('SOME_TABLE', { id => 124, value => 'xxxx'} );
     $ex->insert('SOME_TABLE', { id => 125, value => 'yyy'} );
     $txn->commit();

   Or You can use DBI's transaction (begin_work and commit).

     use DBI;
     use SQL::Executor;
     my $dbh = DBI->connect($dsn, $id, $pass);
     my $ex = SQL::Executor->new($dbh);
     $dbh->begin_work();
     $ex->insert('SOME_TABLE', { id => 124, value => 'xxxx'} );
     $ex->insert('SOME_TABLE', { id => 125, value => 'yyy'} );
     $dbh->commit();

   Or you can also use transaction management modules like
   DBIx::TransactionManager.

     use DBI;
     use SQL::Executor;
     use DBIx::TransactionManager;
     my $dbh = DBI->connect($dsn, $id, $pass);
     my $ex = SQL::Executor->new($dbh);
     my $tm = DBIx::TransactionManager->new($dbh);
     my $txn = $tm->txn_scope;
     $ex->insert('SOME_TABLE', { id => 124, value => 'xxxx'} );
     $ex->insert('SOME_TABLE', { id => 125, value => 'yyy'} );
     $txn->commit;

FAQ
 Why don't you use DBIx::Simple?
   *   I want to use SQL::Maker.

   *   When I need to use complex query, I want to use named placeholder.

AUTHOR
   Takuya Tsuchida <tsucchi {at} cpan.org>

SEE ALSO
   DBI, SQL::Maker, DBIx::Simple

   Codes for named placeholder is taken from Teng's search_named.

LICENSE
   Copyright (C) Takuya Tsuchida

   This library is free software; you can redistribute it and/or modify it
   under the same terms as Perl itself.