bd35c82 13 years ago
1 contributor
1894 lines | 50.173kb
.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sh \" Subsection heading
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings.  \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote.  | will give a
.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
.\" expand to `' in nroff, nothing in troff, for use with C<>.
.tr \(*W-|\(bv\*(Tr
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
.    ds -- \(*W-
.    ds PI pi
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
.    ds L" ""
.    ds R" ""
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds -- \|\(em\|
.    ds PI \(*p
.    ds L" ``
.    ds R" ''
'br\}
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.if \nF \{\
.    de IX
.    tm Index:\\$1\t\\n%\t"\\$2"
..
.    nr % 0
.    rr F
.\}
.\"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.hy 0
.if n .na
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
.    \" fudge factors for nroff and troff
.if n \{\
.    ds #H 0
.    ds #V .8m
.    ds #F .3m
.    ds #[ \f1
.    ds #] \fP
.\}
.if t \{\
.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
.    ds #V .6m
.    ds #F 0
.    ds #[ \&
.    ds #] \&
.\}
.    \" simple accents for nroff and troff
.if n \{\
.    ds ' \&
.    ds ` \&
.    ds ^ \&
.    ds , \&
.    ds ~ ~
.    ds /
.\}
.if t \{\
.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
.    \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.    \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
.    \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
.    ds : e
.    ds 8 ss
.    ds o a
.    ds d- d\h'-1'\(ga
.    ds D- D\h'-1'\(hy
.    ds th \o'bp'
.    ds Th \o'LP'
.    ds ae ae
.    ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "DBIx::Custom 3"
.TH DBIx::Custom 3 "2011-08-06" "perl v5.8.8" "User Contributed Perl Documentation"
.SH "NAME"
DBIx::Custom \- Execute insert, update, delete, and select statement easily
.SH "SYNOPSYS"
.IX Header "SYNOPSYS"
.Vb 1
\&    use DBIx::Custom;
.Ve
.PP
.Vb 7
\&    # Connect
\&    my $dbi = DBIx::Custom->connect(
\&        dsn => "dbi:mysql:database=dbname",
\&        user => 'ken',
\&        password => '!LFKD%$&',
\&        dbi_option => {mysql_enable_utf8 => 1}
\&    );
.Ve
.PP
.Vb 2
\&    # Insert 
\&    $dbi->insert({title => 'Perl', author => 'Ken'}, table  => 'book');
.Ve
.PP
.Vb 3
\&    # Update 
\&    $dbi->update({title => 'Perl', author => 'Ken'}, table  => 'book',
\&      where  => {id => 5});
.Ve
.PP
.Vb 2
\&    # Delete
\&    $dbi->delete(table  => 'book', where => {author => 'Ken'});
.Ve
.PP
.Vb 3
\&    # Select
\&    my $result = $dbi->select(table  => 'book',
\&      column => ['title', 'author'], where  => {author => 'Ken'});
.Ve
.PP
.Vb 11
\&    # Select, more complex
\&    my $result = $dbi->select(
\&        table  => 'book',
\&        column => [
\&            {book => [qw/title author/]},
\&            {company => ['name']}
\&        ],
\&        where  => {'book.author' => 'Ken'},
\&        join => ['left outer join company on book.company_id = company.id'],
\&        append => 'order by id limit 5'
\&    );
.Ve
.PP
.Vb 2
\&    # Fetch
\&    while (my $row = $result->fetch) {
.Ve
.PP
.Vb 1
\&    }
.Ve
.PP
.Vb 2
\&    # Fetch as hash
\&    while (my $row = $result->fetch_hash) {
.Ve
.PP
.Vb 1
\&    }
.Ve
.PP
.Vb 5
\&    # Execute SQL with parameter.
\&    $dbi->execute(
\&        "select id from book where author = :author and title like :title",
\&        {author => 'ken', title => '%Perl%'}
\&    );
.Ve
.SH "DESCRIPTIONS"
.IX Header "DESCRIPTIONS"
DBIx::Custom is \s-1DBI\s0 wrapper module to execute \s-1SQL\s0 easily.
This module have the following features.
.IP "\(bu" 4
Execute \f(CW\*(C`insert\*(C'\fR, \f(CW\*(C`update\*(C'\fR, \f(CW\*(C`delete\*(C'\fR, or \f(CW\*(C`select\*(C'\fR statement easily
.IP "\(bu" 4
Create \f(CW\*(C`where\*(C'\fR clause flexibly
.IP "\(bu" 4
Named place holder support
.IP "\(bu" 4
Model support
.IP "\(bu" 4
Connection manager support
.IP "\(bu" 4
Choice your favorite relational database management system,
\&\f(CW\*(C`MySQL\*(C'\fR, \f(CW\*(C`SQLite\*(C'\fR, \f(CW\*(C`PostgreSQL\*(C'\fR, \f(CW\*(C`Oracle\*(C'\fR,
\&\f(CW\*(C`Microsoft SQL Server\*(C'\fR, \f(CW\*(C`Microsoft Access\*(C'\fR, \f(CW\*(C`DB2\*(C'\fR or anything, 
.IP "\(bu" 4
Filtering by data type or column name(\s-1EXPERIMENTAL\s0)
.IP "\(bu" 4
Create \f(CW\*(C`order by\*(C'\fR clause flexibly(\s-1EXPERIMENTAL\s0)
.SH "DOCUMENTATIONS"
.IX Header "DOCUMENTATIONS"
DBIx::Custom::Guide \- How to use DBIx::Custom
.PP
DBIx::Custom Wiki
\&\- Theare are various examples.
.PP
Module documentations \- 
DBIx::Custom::Result,
DBIx::Custom::Query,
DBIx::Custom::Where,
DBIx::Custom::Model,
DBIx::Custom::Order
.SH "ATTRIBUTES"
.IX Header "ATTRIBUTES"
.ie n .Sh """connector"""
.el .Sh "\f(CWconnector\fP"
.IX Subsection "connector"
.Vb 2
\&    my $connector = $dbi->connector;
\&    $dbi = $dbi->connector($connector);
.Ve
.PP
Connection manager object. if \f(CW\*(C`connector\*(C'\fR is set, you can get \f(CW\*(C`dbh\*(C'\fR
through connection manager. Conection manager object must have \f(CW\*(C`dbh\*(C'\fR mehtod.
.PP
This is DBIx::Connector example. Please pass
\&\f(CW\*(C`default_dbi_option\*(C'\fR to DBIx::Connector \f(CW\*(C`new\*(C'\fR method.
.PP
.Vb 6
\&    my $connector = DBIx::Connector->new(
\&        "dbi:mysql:database=$DATABASE",
\&        $USER,
\&        $PASSWORD,
\&        DBIx::Custom->new->default_dbi_option
\&    );
.Ve
.PP
.Vb 1
\&    my $dbi = DBIx::Custom->connect(connector => $connector);
.Ve
.ie n .Sh """dsn"""
.el .Sh "\f(CWdsn\fP"
.IX Subsection "dsn"
.Vb 2
\&    my $dsn = $dbi->dsn;
\&    $dbi = $dbi->dsn("DBI:mysql:database=dbname");
.Ve
.PP
Data source name, used when \f(CW\*(C`connect\*(C'\fR method is executed.
.ie n .Sh """dbi_option"""
.el .Sh "\f(CWdbi_option\fP"
.IX Subsection "dbi_option"
.Vb 2
\&    my $dbi_option = $dbi->dbi_option;
\&    $dbi = $dbi->dbi_option($dbi_option);
.Ve
.PP
\&\s-1DBI\s0 option, used when \f(CW\*(C`connect\*(C'\fR method is executed.
Each value in option override the value of \f(CW\*(C`default_dbi_option\*(C'\fR.
.ie n .Sh """default_dbi_option"""
.el .Sh "\f(CWdefault_dbi_option\fP"
.IX Subsection "default_dbi_option"
.Vb 2
\&    my $default_dbi_option = $dbi->default_dbi_option;
\&    $dbi = $dbi->default_dbi_option($default_dbi_option);
.Ve
.PP
\&\s-1DBI\s0 default option, used when \f(CW\*(C`connect\*(C'\fR method is executed,
default to the following values.
.PP
.Vb 5
\&    {
\&        RaiseError => 1,
\&        PrintError => 0,
\&        AutoCommit => 1,
\&    }
.Ve
.ie n .Sh """filters"""
.el .Sh "\f(CWfilters\fP"
.IX Subsection "filters"
.Vb 2
\&    my $filters = $dbi->filters;
\&    $dbi = $dbi->filters(\e%filters);
.Ve
.PP
Filters, registered by \f(CW\*(C`register_filter\*(C'\fR method.
.ie n .Sh """last_sql"""
.el .Sh "\f(CWlast_sql\fP"
.IX Subsection "last_sql"
.Vb 2
\&    my $last_sql = $dbi->last_sql;
\&    $dbi = $dbi->last_sql($last_sql);
.Ve
.PP
Get last successed \s-1SQL\s0 executed by \f(CW\*(C`execute\*(C'\fR method.
.ie n .Sh """models"""
.el .Sh "\f(CWmodels\fP"
.IX Subsection "models"
.Vb 2
\&    my $models = $dbi->models;
\&    $dbi = $dbi->models(\e%models);
.Ve
.PP
Models, included by \f(CW\*(C`include_model\*(C'\fR method.
.ie n .Sh """password"""
.el .Sh "\f(CWpassword\fP"
.IX Subsection "password"
.Vb 2
\&    my $password = $dbi->password;
\&    $dbi = $dbi->password('lkj&le`@s');
.Ve
.PP
Password, used when \f(CW\*(C`connect\*(C'\fR method is executed.
.ie n .Sh """query_builder"""
.el .Sh "\f(CWquery_builder\fP"
.IX Subsection "query_builder"
.Vb 2
\&    my $sql_class = $dbi->query_builder;
\&    $dbi = $dbi->query_builder(DBIx::Custom::QueryBuilder->new);
.Ve
.PP
Query builder, default to DBIx::Custom::QueryBuilder object.
.ie n .Sh """quote"""
.el .Sh "\f(CWquote\fP"
.IX Subsection "quote"
.Vb 2
\&     my quote = $dbi->quote;
\&     $dbi = $dbi->quote('"');
.Ve
.PP
Reserved word quote.
Default to double quote '"' except for mysql.
In mysql, default to back quote '`'
.PP
You can set quote pair.
.PP
.Vb 1
\&    $dbi->quote('[]');
.Ve
.ie n .Sh """result_class"""
.el .Sh "\f(CWresult_class\fP"
.IX Subsection "result_class"
.Vb 2
\&    my $result_class = $dbi->result_class;
\&    $dbi = $dbi->result_class('DBIx::Custom::Result');
.Ve
.PP
Result class, default to DBIx::Custom::Result.
.ie n .Sh """safety_character"""
.el .Sh "\f(CWsafety_character\fP"
.IX Subsection "safety_character"
.Vb 2
\&    my $safety_character = $self->safety_character;
\&    $dbi = $self->safety_character($character);
.Ve
.PP
Regex of safety character for table and column name, default to '\ew'.
Note that you don't have to specify like '[\ew]'.
.ie n .Sh """tag_parse"""
.el .Sh "\f(CWtag_parse\fP"
.IX Subsection "tag_parse"
.Vb 2
\&    my $tag_parse = $dbi->tag_parse(0);
\&    $dbi = $dbi->tag_parse;
.Ve
.PP
Enable \s-1DEPRECATED\s0 tag parsing functionality, default to 1.
If you want to disable tag parsing functionality, set to 0.
.ie n .Sh """user"""
.el .Sh "\f(CWuser\fP"
.IX Subsection "user"
.Vb 2
\&    my $user = $dbi->user;
\&    $dbi = $dbi->user('Ken');
.Ve
.PP
User name, used when \f(CW\*(C`connect\*(C'\fR method is executed.
.SH "METHODS"
.IX Header "METHODS"
DBIx::Custom inherits all methods from Object::Simple
and use all methods of \s-1DBI\s0
and implements the following new ones.
.ie n .Sh """available_data_type"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWavailable_data_type\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "available_data_type EXPERIMENTAL"
.Vb 1
\&    print $dbi->available_data_type;
.Ve
.PP
Get available data types. You can use these data types
in \f(CW\*(C`type rule\*(C'\fR's \f(CW\*(C`from1\*(C'\fR and \f(CW\*(C`from2\*(C'\fR section.
.ie n .Sh """available_type_name"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWavailable_type_name\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "available_type_name EXPERIMENTAL"
.Vb 1
\&    print $dbi->available_type_name;
.Ve
.PP
Get available type names. You can use these type names in
\&\f(CW\*(C`type_rule\*(C'\fR's \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR section.
.ie n .Sh """assign_param"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWassign_param\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "assign_param EXPERIMENTAL"
.Vb 1
\&    my $assign_param = $dbi->assign_param({title => 'a', age => 2});
.Ve
.PP
Create assign parameter.
.PP
.Vb 1
\&    title = :title, author = :author
.Ve
.PP
This is equal to \f(CW\*(C`update_param\*(C'\fR exept that set is not added.
.ie n .Sh """column"""
.el .Sh "\f(CWcolumn\fP"
.IX Subsection "column"
.Vb 1
\&    my $column = $dbi->column(book => ['author', 'title']);
.Ve
.PP
Create column clause. The follwoing column clause is created.
.PP
.Vb 2
\&    book.author as "book.author",
\&    book.title as "book.title"
.Ve
.PP
You can change separator by \f(CW\*(C`separator\*(C'\fR method.
.PP
.Vb 2
\&    # Separator is double underbar
\&    $dbi->separator('__');
.Ve
.PP
.Vb 2
\&    book.author as "book__author",
\&    book.title as "book__title"
.Ve
.PP
.Vb 2
\&    # Separator is hyphen
\&    $dbi->separator('-');
.Ve
.PP
.Vb 2
\&    book.author as "book-author",
\&    book.title as "book-title"
.Ve
.ie n .Sh """connect"""
.el .Sh "\f(CWconnect\fP"
.IX Subsection "connect"
.Vb 6
\&    my $dbi = DBIx::Custom->connect(
\&        dsn => "dbi:mysql:database=dbname",
\&        user => 'ken',
\&        password => '!LFKD%$&',
\&        dbi_option => {mysql_enable_utf8 => 1}
\&    );
.Ve
.PP
Connect to the database and create a new DBIx::Custom object.
.PP
DBIx::Custom is a wrapper of \s-1DBI\s0.
\&\f(CW\*(C`AutoCommit\*(C'\fR and \f(CW\*(C`RaiseError\*(C'\fR options are true, 
and \f(CW\*(C`PrintError\*(C'\fR option is false by default.
.Sh "create_model"
.IX Subsection "create_model"
.Vb 7
\&    my $model = $dbi->create_model(
\&        table => 'book',
\&        primary_key => 'id',
\&        join => [
\&            'inner join company on book.comparny_id = company.id'
\&        ],
\&    );
.Ve
.PP
Create DBIx::Custom::Model object and initialize model.
the module is also used from \f(CW\*(C`model\*(C'\fR method.
.PP
.Vb 1
\&   $dbi->model('book')->select(...);
.Ve
.ie n .Sh """dbh"""
.el .Sh "\f(CWdbh\fP"
.IX Subsection "dbh"
.Vb 1
\&    my $dbh = $dbi->dbh;
.Ve
.PP
Get \s-1DBI\s0 database handle. if \f(CW\*(C`connector\*(C'\fR is set, you can get
database handle through \f(CW\*(C`connector\*(C'\fR object.
.ie n .Sh """each_column"""
.el .Sh "\f(CWeach_column\fP"
.IX Subsection "each_column"
.Vb 3
\&    $dbi->each_column(
\&        sub {
\&            my ($dbi, $table, $column, $column_info) = @_;
.Ve
.PP
.Vb 1
\&            my $type = $column_info->{TYPE_NAME};
.Ve
.PP
.Vb 5
\&            if ($type eq 'DATE') {
\&                # ...
\&            }
\&        }
\&    );
.Ve
.PP
Iterate all column informations of all table from database.
Argument is callback when one column is found.
Callback receive four arguments, dbi object, table name,
column name and column information.
.ie n .Sh """each_table"""
.el .Sh "\f(CWeach_table\fP"
.IX Subsection "each_table"
.Vb 3
\&    $dbi->each_table(
\&        sub {
\&            my ($dbi, $table, $table_info) = @_;
.Ve
.PP
.Vb 3
\&            my $table_name = $table_info->{TABLE_NAME};
\&        }
\&    );
.Ve
.PP
Iterate all table informationsfrom database.
Argument is callback when one table is found.
Callback receive three arguments, dbi object, table name,
table information.
.ie n .Sh """execute"""
.el .Sh "\f(CWexecute\fP"
.IX Subsection "execute"
.Vb 4
\&    my $result = $dbi->execute(
\&      "select * from book where title = :title and author like :author",
\&      {title => 'Perl', author => '%Ken%'}
\&    );
.Ve
.PP
.Vb 4
\&    my $result = $dbi->execute(
\&      "select * from book where title = :book.title and author like :book.author",
\&      {'book.title' => 'Perl', 'book.author' => '%Ken%'}
\&    );
.Ve
.PP
Execute \s-1SQL\s0. \s-1SQL\s0 can contain column parameter such as :author and :title.
You can append table name to column name such as :book.title and :book.author.
Second argunet is data, embedded into column parameter.
Return value is DBIx::Custom::Result object when select statement is executed,
or the count of affected rows when insert, update, delete statement is executed.
.PP
Named placeholder such as \f(CW\*(C`:title\*(C'\fR is replaced by placeholder \f(CW\*(C`?\*(C'\fR.
.PP
.Vb 2
\&    # Original
\&    select * from book where title = :title and author like :author
.Ve
.PP
.Vb 2
\&    # Replaced
\&    select * from where title = ? and author like ?;
.Ve
.PP
You can specify operator with named placeholder
 by \f(CW\*(C`name{operator}\*(C'\fR syntax.
.PP
.Vb 2
\&    # Original
\&    select * from book where :title{=} and :author{like}
.Ve
.PP
.Vb 2
\&    # Replaced
\&    select * from where title = ? and author like ?;
.Ve
.PP
Note that colons in time format such as 12:13:15 is exeption,
it is not parsed as named placeholder.
If you want to use colon generally, you must escape it by \f(CW\*(C`\e\e\*(C'\fR
.PP
.Vb 1
\&    select * from where title = "aa\e\e:bb";
.Ve
.PP
The following opitons are available.
.ie n .IP """filter""" 4
.el .IP "\f(CWfilter\fR" 4
.IX Item "filter"
.Vb 4
\&    filter => {
\&        title  => sub { uc $_[0] }
\&        author => sub { uc $_[0] }
\&    }
.Ve
.Sp
.Vb 5
\&    # Filter name
\&    filter => {
\&        title  => 'upper_case',
\&        author => 'upper_case'
\&    }
.Ve
.Sp
.Vb 4
\&    # At once
\&    filter => [
\&        [qw/title author/]  => sub { uc $_[0] }
\&    ]
.Ve
.Sp
Filter. You can set subroutine or filter name
registered by by \f(CW\*(C`register_filter\*(C'\fR.
This filter is executed before data is saved into database.
and before type rule filter is executed.
.ie n .IP """query""" 4
.el .IP "\f(CWquery\fR" 4
.IX Item "query"
.Vb 1
\&    query => 1
.Ve
.Sp
\&\f(CW\*(C`execute\*(C'\fR method return DBIx::Custom::Query object, not executing \s-1SQL\s0.
You can check \s-1SQL\s0 or get statment handle.
.Sp
.Vb 3
\&    my $sql = $query->sql;
\&    my $sth = $query->sth;
\&    my $columns = $query->columns;
.Ve
.Sp
If you want to execute \s-1SQL\s0 fast, you can do the following way.
.Sp
.Vb 5
\&    my $query;
\&    foreach my $row (@$rows) {
\&      $query ||= $dbi->insert($row, table => 'table1', query => 1);
\&      $dbi->execute($query, $row, filter => {ab => sub { $_[0] * 2 }});
\&    }
.Ve
.Sp
Statement handle is reused and \s-1SQL\s0 parsing is finished,
so you can get more performance than normal way.
.Sp
If you want to execute \s-1SQL\s0 as possible as fast and don't need filtering.
You can do the following way.
.Sp
.Vb 7
\&    my $query;
\&    my $sth;
\&    foreach my $row (@$rows) {
\&      $query ||= $dbi->insert($row, table => 'book', query => 1);
\&      $sth ||= $query->sth;
\&      $sth->execute(map { $row->{$_} } sort keys %$row);
\&    }
.Ve
.Sp
Note that \f(CW$row\fR must be simple hash reference, such as
{title => 'Perl', author => 'Ken'}.
and don't forget to sort \f(CW$row\fR values by \f(CW$row\fR key asc order.
.ie n .IP """table""" 4
.el .IP "\f(CWtable\fR" 4
.IX Item "table"
.Vb 1
\&    table => 'author'
.Ve
.Sp
If you want to omit table name in column name
and enable \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR type filter,
You must set \f(CW\*(C`table\*(C'\fR option.
.Sp
.Vb 2
\&    $dbi->execute("select * from book where title = :title and author = :author",
\&        {title => 'Perl', author => 'Ken', table => 'book');
.Ve
.Sp
.Vb 4
\&    # Same
\&    $dbi->execute(
\&      "select * from book where title = :book.title and author = :book.author",
\&      {title => 'Perl', author => 'Ken');
.Ve
.ie n .IP """bind_type""" 4
.el .IP "\f(CWbind_type\fR" 4
.IX Item "bind_type"
Specify database bind data type.
.Sp
.Vb 2
\&    bind_type => [image => DBI::SQL_BLOB]
\&    bind_type => [[qw/image audio/] => DBI::SQL_BLOB]
.Ve
.Sp
This is used to bind parameter by \f(CW\*(C`bind_param\*(C'\fR of statment handle.
.Sp
.Vb 1
\&    $sth->bind_param($pos, $value, DBI::SQL_BLOB);
.Ve
.ie n .IP """table_alias"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtable_alias\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "table_alias EXPERIMENTAL"
.Vb 1
\&    table_alias => {user => 'hiker'}
.Ve
.Sp
Table alias. Key is real table name, value is alias table name.
If you set \f(CW\*(C`table_alias\*(C'\fR, you can enable \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR type rule
on alias table name.
.ie n .IP """type_rule_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule_off EXPERIMENTAL"
.Vb 1
\&    type_rule_off => 1
.Ve
.Sp
Turn \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR type rule off.
.ie n .IP """type_rule1_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule1_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule1_off EXPERIMENTAL"
.Vb 1
\&    type_rule1_off => 1
.Ve
.Sp
Turn \f(CW\*(C`into1\*(C'\fR type rule off.
.ie n .IP """type_rule2_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule2_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule2_off EXPERIMENTAL"
.Vb 1
\&    type_rule2_off => 1
.Ve
.Sp
Turn \f(CW\*(C`into2\*(C'\fR type rule off.
.ie n .Sh """delete"""
.el .Sh "\f(CWdelete\fP"
.IX Subsection "delete"
.Vb 1
\&    $dbi->delete(table => 'book', where => {title => 'Perl'});
.Ve
.PP
Execute delete statement.
.PP
The following opitons are available.
.ie n .IP """append""" 4
.el .IP "\f(CWappend\fR" 4
.IX Item "append"
Same as \f(CW\*(C`select\*(C'\fR method's \f(CW\*(C`append\*(C'\fR option.
.ie n .IP """filter""" 4
.el .IP "\f(CWfilter\fR" 4
.IX Item "filter"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`filter\*(C'\fR option.
.ie n .IP """id""" 4
.el .IP "\f(CWid\fR" 4
.IX Item "id"
.Vb 2
\&    id => 4
\&    id => [4, 5]
.Ve
.Sp
\&\s-1ID\s0 corresponding to \f(CW\*(C`primary_key\*(C'\fR.
You can delete rows by \f(CW\*(C`id\*(C'\fR and \f(CW\*(C`primary_key\*(C'\fR.
.Sp
.Vb 5
\&    $dbi->delete(
\&        parimary_key => ['id1', 'id2'],
\&        id => [4, 5],
\&        table => 'book',
\&    );
.Ve
.Sp
The above is same as the followin one.
.Sp
.Vb 1
\&    $dbi->delete(where => {id1 => 4, id2 => 5}, table => 'book');
.Ve
.ie n .IP """prefix""" 4
.el .IP "\f(CWprefix\fR" 4
.IX Item "prefix"
.Vb 1
\&    prefix => 'some'
.Ve
.Sp
prefix before table name section.
.Sp
.Vb 1
\&    delete some from book
.Ve
.ie n .IP """query""" 4
.el .IP "\f(CWquery\fR" 4
.IX Item "query"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`query\*(C'\fR option.
.ie n .IP """table""" 4
.el .IP "\f(CWtable\fR" 4
.IX Item "table"
.Vb 1
\&    table => 'book'
.Ve
.Sp
Table name.
.ie n .IP """where""" 4
.el .IP "\f(CWwhere\fR" 4
.IX Item "where"
Same as \f(CW\*(C`select\*(C'\fR method's \f(CW\*(C`where\*(C'\fR option.
.ie n .IP """primary_key""" 4
.el .IP "\f(CWprimary_key\fR" 4
.IX Item "primary_key"
See \f(CW\*(C`id\*(C'\fR option.
.ie n .IP """bind_type""" 4
.el .IP "\f(CWbind_type\fR" 4
.IX Item "bind_type"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`bind_type\*(C'\fR option.
.ie n .IP """type_rule_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule_off EXPERIMENTAL"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule_off\*(C'\fR option.
.ie n .IP """type_rule1_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule1_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule1_off EXPERIMENTAL"
.Vb 1
\&    type_rule1_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule1_off\*(C'\fR option.
.ie n .IP """type_rule2_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule2_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule2_off EXPERIMENTAL"
.Vb 1
\&    type_rule2_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule2_off\*(C'\fR option.
.ie n .Sh """delete_all"""
.el .Sh "\f(CWdelete_all\fP"
.IX Subsection "delete_all"
.Vb 1
\&    $dbi->delete_all(table => $table);
.Ve
.PP
Execute delete statement for all rows.
Options is same as \f(CW\*(C`delete\*(C'\fR.
.ie n .Sh """insert"""
.el .Sh "\f(CWinsert\fP"
.IX Subsection "insert"
.Vb 1
\&    $dbi->insert({title => 'Perl', author => 'Ken'}, table  => 'book');
.Ve
.PP
Execute insert statement. First argument is row data. Return value is
affected row count.
.PP
If you want to set constant value to row data, use scalar reference
as parameter value.
.PP
.Vb 1
\&    {date => \e"NOW()"}
.Ve
.PP
The following opitons are available.
.ie n .IP """append""" 4
.el .IP "\f(CWappend\fR" 4
.IX Item "append"
Same as \f(CW\*(C`select\*(C'\fR method's \f(CW\*(C`append\*(C'\fR option.
.ie n .IP """filter""" 4
.el .IP "\f(CWfilter\fR" 4
.IX Item "filter"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`filter\*(C'\fR option.
.ie n .IP """id""" 4
.el .IP "\f(CWid\fR" 4
.IX Item "id"
.Vb 2
\&    id => 4
\&    id => [4, 5]
.Ve
.Sp
\&\s-1ID\s0 corresponding to \f(CW\*(C`primary_key\*(C'\fR.
You can insert a row by \f(CW\*(C`id\*(C'\fR and \f(CW\*(C`primary_key\*(C'\fR.
.Sp
.Vb 6
\&    $dbi->insert(
\&        {title => 'Perl', author => 'Ken'}
\&        parimary_key => ['id1', 'id2'],
\&        id => [4, 5],
\&        table => 'book'
\&    );
.Ve
.Sp
The above is same as the followin one.
.Sp
.Vb 4
\&    $dbi->insert(
\&        {id1 => 4, id2 => 5, title => 'Perl', author => 'Ken'},
\&        table => 'book'
\&    );
.Ve
.ie n .IP """prefix""" 4
.el .IP "\f(CWprefix\fR" 4
.IX Item "prefix"
.Vb 1
\&    prefix => 'or replace'
.Ve
.Sp
prefix before table name section
.Sp
.Vb 1
\&    insert or replace into book
.Ve
.ie n .IP """primary_key""" 4
.el .IP "\f(CWprimary_key\fR" 4
.IX Item "primary_key"
.Vb 2
\&    primary_key => 'id'
\&    primary_key => ['id1', 'id2']
.Ve
.Sp
Primary key. This is used by \f(CW\*(C`id\*(C'\fR option.
.ie n .IP """query""" 4
.el .IP "\f(CWquery\fR" 4
.IX Item "query"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`query\*(C'\fR option.
.ie n .IP """table""" 4
.el .IP "\f(CWtable\fR" 4
.IX Item "table"
.Vb 1
\&    table => 'book'
.Ve
.Sp
Table name.
.ie n .IP """bind_type""" 4
.el .IP "\f(CWbind_type\fR" 4
.IX Item "bind_type"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`bind_type\*(C'\fR option.
.ie n .IP """type_rule_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule_off EXPERIMENTAL"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule_off\*(C'\fR option.
.ie n .IP """type_rule1_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule1_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule1_off EXPERIMENTAL"
.Vb 1
\&    type_rule1_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule1_off\*(C'\fR option.
.ie n .IP """type_rule2_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule2_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule2_off EXPERIMENTAL"
.Vb 1
\&    type_rule2_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule2_off\*(C'\fR option.
.ie n .Sh """insert_param"""
.el .Sh "\f(CWinsert_param\fP"
.IX Subsection "insert_param"
.Vb 1
\&    my $insert_param = $dbi->insert_param({title => 'a', age => 2});
.Ve
.Sp
.RS 4
Create insert parameters.
.Sp
.Vb 1
\&    (title, author) values (title = :title, age = :age);
.Ve
.ie n .Sh """include_model"""
.el .Sh "\f(CWinclude_model\fP"
.IX Subsection "include_model"
.Vb 1
\&    $dbi->include_model('MyModel');
.Ve
.Sp
Include models from specified namespace,
the following layout is needed to include models.
.Sp
.Vb 3
\&    lib / MyModel.pm
\&        / MyModel / book.pm
\&                  / company.pm
.Ve
.Sp
Name space module, extending DBIx::Custom::Model.
.Sp
\&\fBMyModel.pm\fR
.Sp
.Vb 2
\&    package MyModel;
\&    use DBIx::Custom::Model -base;
.Ve
.Sp
.Vb 1
\&    1;
.Ve
.Sp
Model modules, extending name space module.
.Sp
\&\fBMyModel/book.pm\fR
.Sp
.Vb 2
\&    package MyModel::book;
\&    use MyModel -base;
.Ve
.Sp
.Vb 1
\&    1;
.Ve
.Sp
\&\fBMyModel/company.pm\fR
.Sp
.Vb 2
\&    package MyModel::company;
\&    use MyModel -base;
.Ve
.Sp
.Vb 1
\&    1;
.Ve
.Sp
MyModel::book and MyModel::company is included by \f(CW\*(C`include_model\*(C'\fR.
.Sp
You can get model object by \f(CW\*(C`model\*(C'\fR.
.Sp
.Vb 2
\&    my $book_model = $dbi->model('book');
\&    my $company_model = $dbi->model('company');
.Ve
.Sp
See DBIx::Custom::Model to know model features.
.ie n .Sh """map_param"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWmap_param\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "map_param EXPERIMENTAL"
.Vb 8
\&    my $map_param = $dbi->map_param(
\&        {id => 1, authro => 'Ken', price => 1900},
\&        'id' => 'book.id',
\&        'author' => ['book.author' => sub { '%' . $_[0] . '%' }],
\&        'price' => [
\&            'book.price', {if => sub { length $_[0] }}
\&        ]
\&    );
.Ve
.Sp
Map paramters to other key and value. First argument is original
parameter. this is hash reference. Rest argument is mapping.
By default, Mapping is done if the value length is not zero.
.IP "Key mapping" 4
.IX Item "Key mapping"
.Vb 1
\&    'id' => 'book.id'
.Ve
.Sp
This is only key mapping. Value is same as original one.
.Sp
.Vb 1
\&    (id => 1) is mapped to ('book.id' => 1) if value length is not zero.
.Ve
.IP "Key and value mapping" 4
.IX Item "Key and value mapping"
.Vb 1
\&    'author' => ['book.author' => sub { '%' . $_[0] . '%' }]
.Ve
.Sp
This is key and value mapping. Frist element of array reference
is mapped key name, second element is code reference to map the value.
.Sp
.Vb 2
\&    (author => 'Ken') is mapped to ('book.author' => '%Ken%')
\&      if value length is not zero.
.Ve
.IP "Condition" 4
.IX Item "Condition"
.Vb 3
\&    'price' => ['book.price', {if => 'exists'}]
\&    'price' => ['book.price', sub { '%' . $_[0] . '%' }, {if => 'exists'}]
\&    'price' => ['book.price', {if => sub { defined shift }}]
.Ve
.Sp
If you need condition, you can sepecify it. this is code reference
or 'exists'. By default, condition is the following one.
.Sp
.Vb 1
\&    sub { defined $_[0] && length $_[0] }
.Ve
.RE
.RS 4
.ie n .Sh """merge_param"""
.el .Sh "\f(CWmerge_param\fP"
.IX Subsection "merge_param"
.Vb 1
\&    my $param = $dbi->merge_param({key1 => 1}, {key1 => 1, key2 => 2});
.Ve
.Sp
Merge parameters.
.Sp
.Vb 1
\&    {key1 => [1, 1], key2 => 2}
.Ve
.ie n .Sh """method"""
.el .Sh "\f(CWmethod\fP"
.IX Subsection "method"
.Vb 3
\&    $dbi->method(
\&        update_or_insert => sub {
\&            my $self = shift;
.Ve
.Sp
.Vb 4
\&            # Process
\&        },
\&        find_or_create   => sub {
\&            my $self = shift;
.Ve
.Sp
.Vb 3
\&            # Process
\&        }
\&    );
.Ve
.Sp
Register method. These method is called directly from DBIx::Custom object.
.Sp
.Vb 2
\&    $dbi->update_or_insert;
\&    $dbi->find_or_create;
.Ve
.ie n .Sh """model"""
.el .Sh "\f(CWmodel\fP"
.IX Subsection "model"
.Vb 1
\&    my $model = $dbi->model('book');
.Ve
.Sp
Get a DBIx::Custom::Model object,
.ie n .Sh """mycolumn"""
.el .Sh "\f(CWmycolumn\fP"
.IX Subsection "mycolumn"
.Vb 1
\&    my $column = $self->mycolumn(book => ['author', 'title']);
.Ve
.Sp
Create column clause for myself. The follwoing column clause is created.
.Sp
.Vb 2
\&    book.author as author,
\&    book.title as title
.Ve
.ie n .Sh """new"""
.el .Sh "\f(CWnew\fP"
.IX Subsection "new"
.Vb 6
\&    my $dbi = DBIx::Custom->new(
\&        dsn => "dbi:mysql:database=dbname",
\&        user => 'ken',
\&        password => '!LFKD%$&',
\&        dbi_option => {mysql_enable_utf8 => 1}
\&    );
.Ve
.Sp
Create a new DBIx::Custom object.
.ie n .Sh """not_exists"""
.el .Sh "\f(CWnot_exists\fP"
.IX Subsection "not_exists"
.Vb 1
\&    my $not_exists = $dbi->not_exists;
.Ve
.Sp
DBIx::Custom::NotExists object, indicating the column is not exists.
This is used by \f(CW\*(C`clause\*(C'\fR of DBIx::Custom::Where .
.ie n .Sh """order"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWorder\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "order EXPERIMENTAL"
.Vb 1
\&    my $order = $dbi->order;
.Ve
.Sp
Create a new DBIx::Custom::Order object.
.ie n .Sh """register_filter"""
.el .Sh "\f(CWregister_filter\fP"
.IX Subsection "register_filter"
.Vb 12
\&    $dbi->register_filter(
\&        # Time::Piece object to database DATE format
\&        tp_to_date => sub {
\&            my $tp = shift;
\&            return $tp->strftime('%Y-%m-%d');
\&        },
\&        # database DATE format to Time::Piece object
\&        date_to_tp => sub {
\&           my $date = shift;
\&           return Time::Piece->strptime($date, '%Y-%m-%d');
\&        }
\&    );
.Ve
.Sp
Register filters, used by \f(CW\*(C`filter\*(C'\fR option of many methods.
.ie n .Sh """type_rule"" \s-1EXPERIMENTAL\s0"
.el .Sh "\f(CWtype_rule\fP \s-1EXPERIMENTAL\s0"
.IX Subsection "type_rule EXPERIMENTAL"
.Vb 22
\&    $dbi->type_rule(
\&        into1 => {
\&            date => sub { ... },
\&            datetime => sub { ... }
\&        },
\&        into2 => {
\&            date => sub { ... },
\&            datetime => sub { ... }
\&        },
\&        from1 => {
\&            # DATE
\&            9 => sub { ... },
\&            # DATETIME or TIMESTAMP
\&            11 => sub { ... },
\&        }
\&        from2 => {
\&            # DATE
\&            9 => sub { ... },
\&            # DATETIME or TIMESTAMP
\&            11 => sub { ... },
\&        }
\&    );
.Ve
.Sp
Filtering rule when data is send into and get from database.
This has a little complex problem.
.Sp
In \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR you can specify
type name as same as type name defined
by create table, such as \f(CW\*(C`DATETIME\*(C'\fR or \f(CW\*(C`DATE\*(C'\fR.
.Sp
Note that type name and data type don't contain upper case.
If these contain upper case charactor, you convert it to lower case.
.Sp
\&\f(CW\*(C`into2\*(C'\fR is executed after \f(CW\*(C`into1\*(C'\fR.
.Sp
Type rule of \f(CW\*(C`into1\*(C'\fR and \f(CW\*(C`into2\*(C'\fR is enabled on the following
column name.
.IP "1. column name" 4
.IX Item "1. column name"
.Vb 2
\&    issue_date
\&    issue_datetime
.Ve
.Sp
This need \f(CW\*(C`table\*(C'\fR option in each method.
.IP "2. table name and column name, separator is dot" 4
.IX Item "2. table name and column name, separator is dot"
.Vb 2
\&    book.issue_date
\&    book.issue_datetime
.Ve
.RE
.RS 4
.Sp
You get all type name used in database by \f(CW\*(C`available_type_name\*(C'\fR.
.Sp
.Vb 1
\&    print $dbi->available_type_name;
.Ve
.Sp
In \f(CW\*(C`from1\*(C'\fR and \f(CW\*(C`from2\*(C'\fR you specify data type, not type name.
\&\f(CW\*(C`from2\*(C'\fR is executed after \f(CW\*(C`from1\*(C'\fR.
You get all data type by \f(CW\*(C`available_data_type\*(C'\fR.
.Sp
.Vb 1
\&    print $dbi->available_data_type;
.Ve
.Sp
You can also specify multiple types at once.
.Sp
.Vb 5
\&    $dbi->type_rule(
\&        into1 => [
\&            [qw/DATE DATETIME/] => sub { ... },
\&        ],
\&    );
.Ve
.ie n .Sh """select"""
.el .Sh "\f(CWselect\fP"
.IX Subsection "select"
.Vb 5
\&    my $result = $dbi->select(
\&        table  => 'book',
\&        column => ['author', 'title'],
\&        where  => {author => 'Ken'},
\&    );
.Ve
.Sp
Execute select statement.
.Sp
The following opitons are available.
.ie n .IP """append""" 4
.el .IP "\f(CWappend\fR" 4
.IX Item "append"
.Vb 1
\&    append => 'order by title'
.Ve
.Sp
Append statement to last of \s-1SQL\s0.
.ie n .IP """column""" 4
.el .IP "\f(CWcolumn\fR" 4
.IX Item "column"
.Vb 2
\&    column => 'author'
\&    column => ['author', 'title']
.Ve
.Sp
Column clause.
.Sp
if \f(CW\*(C`column\*(C'\fR is not specified, '*' is set.
.Sp
.Vb 1
\&    column => '*'
.Ve
.Sp
You can specify hash of array reference.
.Sp
.Vb 4
\&    column => [
\&        {book => [qw/author title/]},
\&        {person => [qw/name age/]}
\&    ]
.Ve
.Sp
This is expanded to the following one by using \f(CW\*(C`colomn\*(C'\fR method.
.Sp
.Vb 4
\&    book.author as "book.author",
\&    book.title as "book.title",
\&    person.name as "person.name",
\&    person.age as "person.age"
.Ve
.Sp
You can specify array of array reference, first argument is
column name, second argument is alias.
.Sp
.Vb 3
\&    column => [
\&        ['date(book.register_datetime)' => 'book.register_date']
\&    ];
.Ve
.Sp
Alias is quoted properly and joined.
.Sp
.Vb 1
\&    date(book.register_datetime) as "book.register_date"
.Ve
.ie n .IP """filter""" 4
.el .IP "\f(CWfilter\fR" 4
.IX Item "filter"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`filter\*(C'\fR option.
.ie n .IP """id""" 4
.el .IP "\f(CWid\fR" 4
.IX Item "id"
.Vb 2
\&    id => 4
\&    id => [4, 5]
.Ve
.Sp
\&\s-1ID\s0 corresponding to \f(CW\*(C`primary_key\*(C'\fR.
You can select rows by \f(CW\*(C`id\*(C'\fR and \f(CW\*(C`primary_key\*(C'\fR.
.Sp
.Vb 5
\&    $dbi->select(
\&        parimary_key => ['id1', 'id2'],
\&        id => [4, 5],
\&        table => 'book'
\&    );
.Ve
.Sp
The above is same as the followin one.
.Sp
.Vb 4
\&    $dbi->select(
\&        where => {id1 => 4, id2 => 5},
\&        table => 'book'
\&    );
.Ve
.ie n .IP """param"" \s-1EXPERIMETNAL\s0" 4
.el .IP "\f(CWparam\fR \s-1EXPERIMETNAL\s0" 4
.IX Item "param EXPERIMETNAL"
.Vb 1
\&    param => {'table2.key3' => 5}
.Ve
.Sp
Parameter shown before where clause.
.Sp
For example, if you want to contain tag in join clause, 
you can pass parameter by \f(CW\*(C`param\*(C'\fR option.
.Sp
.Vb 2
\&    join  => ['inner join (select * from table2 where table2.key3 = :table2.key3)' . 
\&              ' as table2 on table1.key1 = table2.key1']
.Ve
.Sp
.Vb 1
\&    prefix => 'SQL_CALC_FOUND_ROWS'
.Ve
.Sp
Prefix of column cluase
.Sp
.Vb 1
\&    select SQL_CALC_FOUND_ROWS title, author from book;
.Ve
.ie n .IP """join""" 4
.el .IP "\f(CWjoin\fR" 4
.IX Item "join"
.Vb 4
\&    join => [
\&        'left outer join company on book.company_id = company_id',
\&        'left outer join location on company.location_id = location.id'
\&    ]
.Ve
.Sp
Join clause. If column cluase or where clause contain table name like \*(L"company.name\*(R",
join clausees needed when \s-1SQL\s0 is created is used automatically.
.Sp
.Vb 9
\&    $dbi->select(
\&        table => 'book',
\&        column => ['company.location_id as location_id'],
\&        where => {'company.name' => 'Orange'},
\&        join => [
\&            'left outer join company on book.company_id = company.id',
\&            'left outer join location on company.location_id = location.id'
\&        ]
\&    );
.Ve
.Sp
In above select, column and where clause contain \*(L"company\*(R" table,
the following \s-1SQL\s0 is created
.Sp
.Vb 4
\&    select company.location_id as location_id
\&    from book
\&      left outer join company on book.company_id = company.id
\&    where company.name = ?;
.Ve
.Sp
You can specify two table by yourself. This is useful when join parser can't parse
the join clause correctly. This is \s-1EXPERIMENTAL\s0.
.Sp
.Vb 11
\&    $dbi->select(
\&        table => 'book',
\&        column => ['company.location_id as location_id'],
\&        where => {'company.name' => 'Orange'},
\&        join => [
\&            {
\&                clause => 'left outer join location on company.location_id = location.id',
\&                table => ['company', 'location']
\&            }
\&        ]
\&    );
.Ve
.ie n .IP """primary_key""" 4
.el .IP "\f(CWprimary_key\fR" 4
.IX Item "primary_key"
.Vb 2
\&    primary_key => 'id'
\&    primary_key => ['id1', 'id2']
.Ve
.Sp
Primary key. This is used by \f(CW\*(C`id\*(C'\fR option.
.ie n .IP """query""" 4
.el .IP "\f(CWquery\fR" 4
.IX Item "query"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`query\*(C'\fR option.
.ie n .IP """bind_type""" 4
.el .IP "\f(CWbind_type\fR" 4
.IX Item "bind_type"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`bind_type\*(C'\fR option.
.ie n .IP """table""" 4
.el .IP "\f(CWtable\fR" 4
.IX Item "table"
.Vb 1
\&    table => 'book'
.Ve
.Sp
Table name.
.ie n .IP """type_rule_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule_off EXPERIMENTAL"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule_off\*(C'\fR option.
.ie n .IP """type_rule1_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule1_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule1_off EXPERIMENTAL"
.Vb 1
\&    type_rule1_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule1_off\*(C'\fR option.
.ie n .IP """type_rule2_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule2_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule2_off EXPERIMENTAL"
.Vb 1
\&    type_rule2_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule2_off\*(C'\fR option.
.ie n .IP """where""" 4
.el .IP "\f(CWwhere\fR" 4
.IX Item "where"
.Vb 2
\&    # Hash refrence
\&    where => {author => 'Ken', 'title' => 'Perl'}
.Ve
.Sp
.Vb 5
\&    # DBIx::Custom::Where object
\&    where => $dbi->where(
\&        clause => ['and', 'author = :author', 'title like :title'],
\&        param  => {author => 'Ken', title => '%Perl%'}
\&    );
.Ve
.Sp
.Vb 5
\&    # Array reference 1 (array reference, hash referenc). same as above
\&    where => [
\&        ['and', 'author = :author', 'title like :title'],
\&        {author => 'Ken', title => '%Perl%'}
\&    ];
.Ve
.Sp
.Vb 5
\&    # Array reference 2 (String, hash reference)
\&    where => [
\&        'title like :title',
\&        {title => '%Perl%'}
\&    ]
.Ve
.Sp
.Vb 2
\&    # String
\&    where => 'title is null'
.Ve
.Sp
Where clause.
.ie n .IP """wrap"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWwrap\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "wrap EXPERIMENTAL"
Wrap statement. This is array reference.
.Sp
.Vb 1
\&    $dbi->select(wrap => ['select * from (', ') as t where ROWNUM < 10']);
.Ve
.Sp
This option is for Oracle and \s-1SQL\s0 Server paging process.
.RE
.RS 4
.ie n .Sh """update"""
.el .Sh "\f(CWupdate\fP"
.IX Subsection "update"
.Vb 1
\&    $dbi->update({title => 'Perl'}, table  => 'book', where  => {id => 4});
.Ve
.Sp
Execute update statement. First argument is update row data.
.Sp
If you want to set constant value to row data, use scalar reference
as parameter value.
.Sp
.Vb 1
\&    {date => \e"NOW()"}
.Ve
.Sp
The following opitons are available.
.ie n .IP """append""" 4
.el .IP "\f(CWappend\fR" 4
.IX Item "append"
Same as \f(CW\*(C`select\*(C'\fR method's \f(CW\*(C`append\*(C'\fR option.
.ie n .IP """filter""" 4
.el .IP "\f(CWfilter\fR" 4
.IX Item "filter"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`filter\*(C'\fR option.
.ie n .IP """id""" 4
.el .IP "\f(CWid\fR" 4
.IX Item "id"
.Vb 2
\&    id => 4
\&    id => [4, 5]
.Ve
.Sp
\&\s-1ID\s0 corresponding to \f(CW\*(C`primary_key\*(C'\fR.
You can update rows by \f(CW\*(C`id\*(C'\fR and \f(CW\*(C`primary_key\*(C'\fR.
.Sp
.Vb 6
\&    $dbi->update(
\&        {title => 'Perl', author => 'Ken'}
\&        parimary_key => ['id1', 'id2'],
\&        id => [4, 5],
\&        table => 'book'
\&    );
.Ve
.Sp
The above is same as the followin one.
.Sp
.Vb 5
\&    $dbi->update(
\&        {title => 'Perl', author => 'Ken'}
\&        where => {id1 => 4, id2 => 5},
\&        table => 'book'
\&    );
.Ve
.ie n .IP """prefix""" 4
.el .IP "\f(CWprefix\fR" 4
.IX Item "prefix"
.Vb 1
\&    prefix => 'or replace'
.Ve
.Sp
prefix before table name section
.Sp
.Vb 1
\&    update or replace book
.Ve
.ie n .IP """primary_key""" 4
.el .IP "\f(CWprimary_key\fR" 4
.IX Item "primary_key"
.Vb 2
\&    primary_key => 'id'
\&    primary_key => ['id1', 'id2']
.Ve
.Sp
Primary key. This is used by \f(CW\*(C`id\*(C'\fR option.
.ie n .IP """query""" 4
.el .IP "\f(CWquery\fR" 4
.IX Item "query"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`query\*(C'\fR option.
.ie n .IP """table""" 4
.el .IP "\f(CWtable\fR" 4
.IX Item "table"
.Vb 1
\&    table => 'book'
.Ve
.Sp
Table name.
.ie n .IP """where""" 4
.el .IP "\f(CWwhere\fR" 4
.IX Item "where"
Same as \f(CW\*(C`select\*(C'\fR method's \f(CW\*(C`where\*(C'\fR option.
.ie n .IP """bind_type""" 4
.el .IP "\f(CWbind_type\fR" 4
.IX Item "bind_type"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`bind_type\*(C'\fR option.
.ie n .IP """type_rule_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule_off EXPERIMENTAL"
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule_off\*(C'\fR option.
.ie n .IP """type_rule1_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule1_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule1_off EXPERIMENTAL"
.Vb 1
\&    type_rule1_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule1_off\*(C'\fR option.
.ie n .IP """type_rule2_off"" \s-1EXPERIMENTAL\s0" 4
.el .IP "\f(CWtype_rule2_off\fR \s-1EXPERIMENTAL\s0" 4
.IX Item "type_rule2_off EXPERIMENTAL"
.Vb 1
\&    type_rule2_off => 1
.Ve
.Sp
Same as \f(CW\*(C`execute\*(C'\fR method's \f(CW\*(C`type_rule2_off\*(C'\fR option.
.RE
.RS 4
.ie n .Sh """update_all"""
.el .Sh "\f(CWupdate_all\fP"
.IX Subsection "update_all"
.Vb 1
\&    $dbi->update_all({title => 'Perl'}, table => 'book', );
.Ve
.Sp
Execute update statement for all rows.
Options is same as \f(CW\*(C`update\*(C'\fR method.
.ie n .Sh """update_param"""
.el .Sh "\f(CWupdate_param\fP"
.IX Subsection "update_param"
.Vb 1
\&    my $update_param = $dbi->update_param({title => 'a', age => 2});
.Ve
.Sp
Create update parameter tag.
.Sp
.Vb 1
\&    set title = :title, author = :author
.Ve
.ie n .Sh """where"""
.el .Sh "\f(CWwhere\fP"
.IX Subsection "where"
.Vb 4
\&    my $where = $dbi->where(
\&        clause => ['and', 'title = :title', 'author = :author'],
\&        param => {title => 'Perl', author => 'Ken'}
\&    );
.Ve
.Sp
Create a new DBIx::Custom::Where object.
.ie n .Sh """setup_model"""
.el .Sh "\f(CWsetup_model\fP"
.IX Subsection "setup_model"
.Vb 1
\&    $dbi->setup_model;
.Ve
.Sp
Setup all model objects.
\&\f(CW\*(C`columns\*(C'\fR of model object is automatically set, parsing database information.
.SH "ENVIRONMENT VARIABLE"
.IX Header "ENVIRONMENT VARIABLE"
.ie n .Sh """DBIX_CUSTOM_DEBUG"""
.el .Sh "\f(CWDBIX_CUSTOM_DEBUG\fP"
.IX Subsection "DBIX_CUSTOM_DEBUG"
If environment variable \f(CW\*(C`DBIX_CUSTOM_DEBUG\*(C'\fR is set to true,
executed \s-1SQL\s0 and bind values are printed to \s-1STDERR\s0.
.ie n .Sh """DBIX_CUSTOM_DEBUG_ENCODING"""
.el .Sh "\f(CWDBIX_CUSTOM_DEBUG_ENCODING\fP"
.IX Subsection "DBIX_CUSTOM_DEBUG_ENCODING"
\&\s-1DEBUG\s0 output encoding. Default to \s-1UTF\-8\s0.
.SH "DEPRECATED FUNCTIONALITIES"
.IX Header "DEPRECATED FUNCTIONALITIES"
DBIx::Custom
.Sp
.Vb 6
\&    # Attribute methods
\&    data_source # will be removed at 2017/1/1
\&    dbi_options # will be removed at 2017/1/1
\&    filter_check # will be removed at 2017/1/1
\&    reserved_word_quote # will be removed at 2017/1/1
\&    cache_method # will be removed at 2017/1/1
.Ve
.Sp
.Vb 13
\&    # Methods
\&    create_query # will be removed at 2017/1/1
\&    apply_filter # will be removed at 2017/1/1
\&    select_at # will be removed at 2017/1/1
\&    delete_at # will be removed at 2017/1/1
\&    update_at # will be removed at 2017/1/1
\&    insert_at # will be removed at 2017/1/1
\&    register_tag # will be removed at 2017/1/1
\&    default_bind_filter # will be removed at 2017/1/1
\&    default_fetch_filter # will be removed at 2017/1/1
\&    insert_param_tag # will be removed at 2017/1/1
\&    register_tag_processor # will be removed at 2017/1/1
\&    update_param_tag # will be removed at 2017/1/1
.Ve
.Sp
.Vb 5
\&    # Options
\&    select method relation option # will be removed at 2017/1/1
\&    select method param option # will be removed at 2017/1/1
\&    select method column option [COLUMN, as => ALIAS] format
\&      # will be removed at 2017/1/1
.Ve
.Sp
.Vb 5
\&    # Others
\&    execute("select * from {= title}"); # execute method's
\&                                        # tag parsing functionality
\&                                        # will be removed at 2017/1/1
\&    Query caching # will be removed at 2017/1/1
.Ve
.Sp
DBIx::Custom::Model
.Sp
.Vb 4
\&    # Attribute methods
\&    filter # will be removed at 2017/1/1
\&    name # will be removed at 2017/1/1
\&    type # will be removed at 2017/1/1
.Ve
.Sp
DBIx::Custom::Query
.Sp
.Vb 4
\&    # Attribute methods
\&    default_filter # will be removed at 2017/1/1
\&    table # will be removed at 2017/1/1
\&    filters # will be removed at 2017/1/1
.Ve
.Sp
.Vb 2
\&    # Methods
\&    filter # will be removed at 2017/1/1
.Ve
.Sp
DBIx::Custom::QueryBuilder
.Sp
.Vb 3
\&    # Attribute methods
\&    tags # will be removed at 2017/1/1
\&    tag_processors # will be removed at 2017/1/1
.Ve
.Sp
.Vb 3
\&    # Methods
\&    register_tag # will be removed at 2017/1/1
\&    register_tag_processor # will be removed at 2017/1/1
.Ve
.Sp
.Vb 3
\&    # Others
\&    build_query("select * from {= title}"); # tag parsing functionality
\&                                            # will be removed at 2017/1/1
.Ve
.Sp
DBIx::Custom::Result
.Sp
.Vb 2
\&    # Attribute methods
\&    filter_check # will be removed at 2017/1/1
.Ve
.Sp
.Vb 5
\&    # Methods
\&    end_filter # will be removed at 2017/1/1
\&    remove_end_filter # will be removed at 2017/1/1
\&    remove_filter # will be removed at 2017/1/1
\&    default_filter # will be removed at 2017/1/1
.Ve
.Sp
DBIx::Custom::Tag
.Sp
.Vb 1
\&    This module is DEPRECATED! # will be removed at 2017/1/1
.Ve
.SH "BACKWORD COMPATIBLE POLICY"
.IX Header "BACKWORD COMPATIBLE POLICY"
If a functionality is \s-1DEPRECATED\s0, you can know it by \s-1DEPRECATED\s0 warnings
except for attribute method.
You can check all \s-1DEPRECATED\s0 functionalities by document.
\&\s-1DEPRECATED\s0 functionality is removed after five years,
but if at least one person use the functionality and tell me that thing
I extend one year each time he tell me it.
.Sp
\&\s-1EXPERIMENTAL\s0 functionality will be changed without warnings.
.Sp
This policy was changed at 2011/6/28
.SH "BUGS"
.IX Header "BUGS"
Please tell me bugs if found.
.Sp
\&\f(CW\*(C`<kimoto.yuki at gmail.com>\*(C'\fR
.Sp
<http://github.com/yuki\-kimoto/DBIx\-Custom>
.SH "AUTHOR"
.IX Header "AUTHOR"
Yuki Kimoto, \f(CW\*(C`<kimoto.yuki at gmail.com>\*(C'\fR
.SH "COPYRIGHT & LICENSE"
.IX Header "COPYRIGHT & LICENSE"
Copyright 2009\-2011 Yuki Kimoto, all rights reserved.
.Sp
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.