.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .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. \*(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- .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" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "README 3pm" .TH README 3pm "2017-04-18" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" DBIx::DR \- easy DBI helper (perl inside SQL and blessed results) .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& my $dbh = DBIx::DR\->connect($dsn, $login, $passed); \& \& $dbh\->perform( \& \*(AqUPDATE tbl SET a = 1 WHERE id = <%= $id %>\*(Aq, \& id => 123 \& ); \& \& my $rowset = $dbh\->select( \& \*(AqSELECT * FROM tbl WHERE id IN (<% list @$ids %>)\*(Aq, \& ids => [ 123, 456 ] \& ); \& my $rowset = $dbh\->select(\-f => \*(Aqsqlfile.sql.ep\*(Aq, ids => [ 123, 456 ]); \& \& while(my $row = $rowset\->next) { \& print "id: %d, value: %s\en", $row\->id, $row\->value; \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The package \fIextends\fR \s-1DBI\s0 and allows You: .IP "\(bu" 4 to use perl inside Your \s-1SQL\s0 requests; .IP "\(bu" 4 to bless resultsets into Your package; .IP "\(bu" 4 to place Your \s-1SQL\s0's into dedicated directory; .IP "\(bu" 4 to use usual \s-1DBI\s0 methods. .SH "Additional 'connect' options." .IX Header "Additional 'connect' options." .SS "dr_iterator" .IX Subsection "dr_iterator" A string describes iterator class. Default value is '\fBdbix\-dr\-iterator#new\fR' (decamelized string). .SS "dr_item" .IX Subsection "dr_item" A string describes item (one row) class. Default value is '\fBdbix\-dr\-iterator\-item#new\fR' (decamelized string). .SS "dr_sql_dir" .IX Subsection "dr_sql_dir" Directory path to seek sql files (If You use dedicated SQLs). .SS "dr_decode_errors" .IX Subsection "dr_decode_errors" Decode database errors into utf\-8 .SS "dr_sql_utf8" .IX Subsection "dr_sql_utf8" Default value: \f(CW\*(C`true\*(C'\fR. If true, it will open sql files with option \f(CW\*(C`:utf8\*(C'\fR. .SH "METHODS" .IX Header "METHODS" All methods can receive the following arguments: .ie n .IP "\-f => $sql_file_name" 4 .el .IP "\-f => \f(CW$sql_file_name\fR" 4 .IX Item "-f => $sql_file_name" It will load SQL-request from file. It will seek file in directory that was defined in dr_sql_dir param of connect. .Sp You needn't to use suffixes (\fB.sql.ep\fR) here, but You can. .IP "\-item => 'decamelized_obj_define'" 4 .IX Item "-item => 'decamelized_obj_define'" It will bless (or construct) row into specified class. See below. Default value defined by dr_item argument of \fBDBI::connect\fR. .IP "\-noitem" 4 .IX Item "-noitem" Do not bless row into any class. .IP "\-iterator => 'decamelized_obj_define'" 4 .IX Item "-iterator => 'decamelized_obj_define'" It will bless (or construct) rowset into specified class. Default value defined by dr_iterator argument of \fBDBI::connect\fR. .IP "\-noiterator" 4 .IX Item "-noiterator" Do not bless rowset into any class. .IP "\-noitem_iter" 4 .IX Item "-noitem_iter" Do not pass iterator as second argument to item constructor. .IP "\-dbi => \s-1HASHREF\s0" 4 .IX Item "-dbi => HASHREF" Additional \s-1DBI\s0 arguments. .IP "\-hash => \s-1FIELDNAME\s0" 4 .IX Item "-hash => FIELDNAME" Selects into \s-1HASH.\s0 Iterator will operate by names (not numbers). .IP "\-die => 0|1" 4 .IX Item "-die => 0|1" If \fBtrue\fR the method will die with SQL-request. .IP "\-warn => 0|1" 4 .IX Item "-warn => 0|1" If \fBtrue\fR the method will warn with SQL-request. .SS "Decamelized strings" .IX Subsection "Decamelized strings" Are strings that represent class [ and method ]. .PP .Vb 3 \& foo_bar => FooBar \& foo_bar#subroutine => FooBar\->subroutine \& foo_bar\-baz => FooBar::Baz .Ve .SS "perform" .IX Subsection "perform" Does SQL-request like '\fB\s-1UPDATE\s0\fR', '\fB\s-1INSERT\s0\fR', etc. .PP .Vb 2 \& $dbh\->perform($sql, value => 1, other_value => \*(Aqabc\*(Aq); \& $dbh\->perform(\-f => $sql_file_name, value => 1, other_value => \*(Aqabc\*(Aq); .Ve .SS "select" .IX Subsection "select" Does SQL-request, pack results into iterator class. By default it uses DBIx::DR::Iterator class. .PP .Vb 4 \& my $res = $dbh\->select(\-f => $sql_file_name, value => 1); \& while(my $row = $res\->next) { \& printf "RowId: %d, RowValue: %s\en", $row\->id, $row\->value; \& } \& \& my $row = $row\->get(15); # row 15 \& \& my $res = $dbh\->select(\-f => $sql_file_name, \& value => 1, \-hash => \*(Aqname\*(Aq); \& while(my $row = $res\->next) { \& printf "RowId: %d, RowName: %s\en", $row\->id, $row\->name; \& } \& \& my $row = $row\->get(\*(AqVasya\*(Aq); # row with name eq \*(AqVasya\*(Aq .Ve .SS "single" .IX Subsection "single" Does SQL-request that returns one row. Pack results into item class. Does SQL-request, pack results (one row) into item class. By default it uses DBIx::DR::Iterator::Item class. .SH "Template language" .IX Header "Template language" You can use perl inside Your \s-1SQL\s0 requests: .PP .Vb 3 \& % my $foo = 1; \& % my $bar = 2; \& <% my $foo_bar = $foo + $bar %> \& \& .. \& \& % use POSIX; \& % my $gid = POSIX::getgid; .Ve .PP There are two functions available inside perl: .SS "quote" .IX Subsection "quote" Replaces argument to '\fB?\fR', add argument value into bindlist. You can also use shortcut '\fB=\fR' instead of the function. .PP \&\fBExample 1\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = <% quote $id %> .Ve .PP \&\fBResult\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = ? .Ve .PP and \fBbindlist\fR will contain \fBid\fR value. .PP If You use DBIx::DR::ByteStream in place of string the function will recall immediate function. .PP \&\fBExample 2\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = <%= $id %> .Ve .SS "immediate" .IX Subsection "immediate" Replaces argument to its value. You can also use shortcut '\fB==\fR' instead of the function. .PP \&\fBExample 1\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = <% immediate $id %> .Ve .PP \&\fBResult\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = 123 .Ve .PP Where 123 is \fBid\fR value. .PP Be carful! Using the operator You can produce code that will be amenable to SQL-injection. .PP \&\fBExample 2\fR .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& id = <%== $id %> .Ve .SH "Helpers" .IX Header "Helpers" There are a few default helpers. .SS "list" .IX Subsection "list" Expands array into Your \s-1SQL\s0 request. .PP \fIExample\fR .IX Subsection "Example" .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& status IN (<% list @$ids %>) .Ve .PP Result .IX Subsection "Result" .PP .Vb 6 \& SELECT \& * \& FROM \& tbl \& WHERE \& status IN (?,?,? ...) .Ve .PP and \fBbindlist\fR will contain \fBids\fR values. .SS "hlist" .IX Subsection "hlist" Expands array of hash into Your \s-1SQL\s0 request. The first argument can be a list of required keys. Places each group into brackets. .PP \fIExample\fR .IX Subsection "Example" .PP .Vb 5 \& INSERT INTO \& tbl \& (\*(Aqa\*(Aq, \*(Aqb\*(Aq) \& VALUES \& <% hlist [\*(Aqa\*(Aq, \*(Aqb\*(Aq] => @$inserts .Ve .PP Result .IX Subsection "Result" .PP .Vb 5 \& INSERT INTO \& tbl \& (\*(Aqa\*(Aq, \*(Aqb\*(Aq) \& VALUES \& (?, ?), (?, ?) ... .Ve .PP and \fBbindlist\fR will contain all \fBinserts\fR values. .SS "include" .IX Subsection "include" Includes the other SQL-part. .PP \fIExample\fR .IX Subsection "Example" .PP .Vb 1 \& % include \*(Aqother_sql\*(Aq, argument1 => 1, argument2 => 2; .Ve .SS "stacktrace" .IX Subsection "stacktrace" Returns perl stacktrace. You can use the helper for debug Your code. The helper receives the following position-arguments: .ie n .IP "(first) $skip (default = 0)" 4 .el .IP "(first) \f(CW$skip\fR (default = 0)" 4 .IX Item "(first) $skip (default = 0)" How many frames to skip. .ie n .IP "(second) $dept (default = 0)" 4 .el .IP "(second) \f(CW$dept\fR (default = 0)" 4 .IX Item "(second) $dept (default = 0)" How many frames to print. .ie n .IP "(third) $separator (default "", "")" 4 .el .IP "(third) \f(CW$separator\fR (default ``, '')" 4 .IX Item "(third) $separator (default , )" Separator between stackframes. .PP \fIExamples\fR .IX Subsection "Examples" .PP .Vb 1 \& /* <%= stacktrace %> */ \& \& /* <%= stacktrace $skip, $depth, $separator %> */ .Ve .SH "User's helpers" .IX Header "User's helpers" You can add Your helpers using method set_helper. .SS "set_helper" .IX Subsection "set_helper" Sets (or replaces) helpers. .PP .Vb 1 \& $dbh\->set_helper(foo => sub { ... }, bar => sub { ... }); .Ve .PP Each helper receives template object as the first argument. .PP Examples: .PP .Vb 4 \& $dbh\->set_helper(foo_AxB => sub { \& my ($tpl, $a, $b) = @_; \& $tpl\->quote($a * $b); \& }); .Ve .PP You can use quote and immediate functions inside Your helpers. .PP If You want use the other helper inside Your helper You have to do that by Yourself. To call the other helper You can also use \f(CW\*(C`$tpl\->call_helper\*(C'\fR function. .PP \fIcall_helper\fR .IX Subsection "call_helper" .PP .Vb 10 \& $dbh\->set_helper( \& foo => sub { \& my ($tpl, $a, $b) = @_; \& $tpl\->quote(\*(Aqfoo\*(Aq . $a . $b); \& }, \& bar => sub { \& my $tpl = shift; \& $tpl\->call_helper(foo => \*(Aqb\*(Aq, \*(Aqc\*(Aq); \& } \& ); .Ve .SH "COPYRIGHT" .IX Header "COPYRIGHT" .Vb 2 \& Copyright (C) 2011 Dmitry E. Oboukhov \& Copyright (C) 2011 Roman V. Nikolaev \& \& This program is free software, you can redistribute it and/or \& modify it under the terms of the Artistic License. .Ve .SH "VCS" .IX Header "VCS" The project is placed git repo on github: