@@ -28,9 +28,13 @@ my %args = (
allow_pureperl => 0,
script_files => [glob('script/*'), glob('bin/*')],
+ c_source => [qw()],
+ PL_files => {},
test_files => ((-d '.git' || $ENV{RELEASE_TESTING}) && -d 'xt') ? 't/ xt/' : 't/',
recursive_test_files => 1,
+
+
);
if (-d 'share') {
$args{share_dir} = 'share';
@@ -1,4 +1,20 @@
-Revision history for Perl extension SQL::Maker
+Revision history for Perl module SQL::Maker
+
+1.15 2014-04-02T13:12:56Z
+
+ - add index_hint option to select method
+ (soh335)
+
+1.14 2014-03-04T23:39:17Z
+
+ - `{x => []}` generates `1=0`
+ (karupanerura)
+ - Add options for the DELETE ... USING statement.
+ (Gelu Lupas)
+
+1.13 2014-02-10T04:29:18Z
+
+ - Documentation update(Gelu Lupas)
1.12 2013-06-25T04:25:24Z
@@ -7,9 +23,9 @@ Revision history for Perl extension SQL::Maker
- join condition accepts HashRef. eg. {'user.id' => 'user_item.user_id'}
(songmu)
- switch to Minilla
- (songmu)
+ (tokuhirom)
- add document about \%opt for insert() method
- (songmu)
+ (Toshio Ito)
- cares skip quoting asterisk after table. eg. 'foo.*' => '"foo".*'
(songmu)
@@ -18,130 +34,146 @@ Revision history for Perl extension SQL::Maker
- Added SQL::Maker#where
(tokuhirom)
-1.10
+1.10 2012-12-23
- - [IMPOTANT] SQL::Maker::Condition::compose_or now returns the SQL bracketed.
+ [IMPORTANT]
+ - SQL::Maker::Condition::compose_or now returns the SQL bracketed.
(chiba)
-1.09
+1.09 2012-12-11
- added SQL::Maker::Plugin::InsertOnDuplicate
(tokuhirom)
-1.08
+1.08 2012-12-09
- - added 'make_set_clause' method to core, and SQL::Maker::Plugin::InsertMulti use it.
+ - added 'make_set_clause' method to core,
+ and SQL::Maker::Plugin::InsertMulti use it.
(tokuhirom)
-1.07 Mon Sep 24 03:51:15 UTC 2012
+1.07 2012-09-24 03:51:15 UTC
- fix behavior for empty condition compose
-1.06 Sun Sep 16 04:30:50 UTC 2012
+1.06 2012-09-16 04:30:50 UTC
- In SQL::Maker::Select
- Add "add_where_raw" method. (issm)
- In SQL::Maker::Condition
- Add "add_raw" method. (issm)
-1.05
+1.05 not released
- support group_by at SQL::Maker->select
-1.04
+1.04 not released
- - support $where as SQL::Maker::Condition at select, update and delete(nihen)
+ - support $where as SQL::Maker::Condition at select,
+ update and delete(nihen)
- support joins at select
-1.03
+1.03 2011-10-31
- support INSERT statement without parameters on SQLite3.
https://github.com/tokuhirom/SQL-Maker/issues/11
(requested by forwardever++)
-1.02
+1.02 2011-09-22
- doc fix(reported by xaicron++)
-1.01
+1.01 2011-09-04
- - support this form: ['created_on' => { '>', \'DATE_SUB(NOW(), INTERVAL 1 DAY)' }]
+ - support this form:
+ ['created_on' => { '>', \'DATE_SUB(NOW(), INTERVAL 1 DAY)' }]
-1.00
+1.00 2011-06-29
- remove alpha tag.
-0.14
+0.14 2011-04-23
- Type check for clear error messages(gfx)
- fixed testing issue on t/10_subquery.t(reported by gfx++)
-0.13
-
- - In SQL::Maker
- - Allow 'INSERT IGNORE' by $opts->{prefix} params at insert() method (zigorou)
- - Accept key-value as array at insert() method (zigorou)
- - Accept value using subquery at insert(), update() method (zigorou)
- - Allow table alias at select() method (zigorou)
- - In SQL::Maker::Plugin::InsertMulti
- - Accept values as arrayref at insert_multi() (zigorou)
- - Allow 'INSERT IGNORE' by $opts->{prefix} params at insert_multi() (zigorou)
- - Allow literal and subquery in values at insert_multi() (zigorou)
- - Supports 'ON DUPLICATE KEY UPDATE' syntax on mysql driver at insert_multi() (zigorou)
- - In SQL::Maker::Select
- - Allow no conditional join (zigorou)
+0.13 2011-04-23
+
+ [In SQL::Maker]
+ - Allow 'INSERT IGNORE' by $opts->{prefix} params at insert() method
+ (zigorou)
+ - Accept key-value as array at insert() method (zigorou)
+ - Accept value using subquery at insert(), update() method (zigorou)
+ - Allow table alias at select() method (zigorou)
+
+ [In SQL::Maker::Plugin::InsertMulti]
+ - Accept values as arrayref at insert_multi() (zigorou)
+ - Allow 'INSERT IGNORE' by $opts->{prefix} params at insert_multi()
+ (zigorou)
+ - Allow literal and subquery in values at insert_multi() (zigorou)
+ - Supports 'ON DUPLICATE KEY UPDATE' syntax on mysql driver
+ at insert_multi() (zigorou)
-0.12
+ [In SQL::Maker::Select]
+ - Allow no conditional join (zigorou)
- SQL::Maker::Plugin::InsertMulti before 0.12 have a critical issue.
- I highly recomment version up to 0.12+, if you are using SQL::Maker::Plugin::InsertMulti.
+0.12 2011-02-17
+
+ - SQL::Maker::Plugin::InsertMulti before 0.12 have a critical issue.
+ I highly recommend version up to 0.12+,
+ if you are using SQL::Maker::Plugin::InsertMulti.
- FIX: SQL::Maker::Plugin::InsertMulti doesn't works correctly.
- doc fix on SQL::Maker::Plugin::InsertMulti
-0.11
+0.11 2011-02-15
- added SQL::Maker#new_condition method(nekokak)
-0.10
+0.10 2011-01-14
- support union, intersect, except(makamaka)
-0.09
+0.09 2011-01-10
- allow SELECT object and alias to add_join(makamaka)
-0.08
+0.08 2011-01-09
- doc enhancements(tokuhirom)
- support $builder->select(order_by => {foo => 'DESC'}) form for skinny
-0.07
+0.07 2011-01-09
- allow subquery in from clause(makamaka)
-0.06
+0.06 2011-01-07
- allow hashref in new_select() method
-0.05
+0.05 2011-01-06
- doc fix(lestrrat)
-0.04
+0.04 2011-01-03
- add space each comma on using IN statement(zigorou)
-0.03
+0.03 2010-12-28
+
+ - 60ded52 (HEAD, zigorou/master, origin/master, master)
+ remove last new_line on as_sql(), add tests for different new args
+ (zigorou++)
+ - 1d54a09 add new_line opts to SQL::Maker, SQL::Maker::Select
+ (zigorou++)
+ - 0b84cd7 change the quote_char detection logic.
+ see http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
+
+0.02 2010-12-12
- - 60ded52 (HEAD, zigorou/master, origin/master, master) remove last new_line on as_sql(), add tests for different new args(zigorou++)
- - 1d54a09 add new_line opts to SQL::Maker, SQL::Maker::Select(zigorou++)
- - 0b84cd7 change the quote_char detection logic. see http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
+ - added new method 'new_select'.
+ - pod fix
-0.02
+0.01 2010-12-08
- - added new method 'new_select'.
- - pod fix
+ - original version
-0.01 Sat Nov 27 11:37:12 2010
- - original version
@@ -31,6 +31,7 @@ t/condition/01_where.t
t/condition/02_make_term.t
t/condition/03_add_raw.t
t/condition/04_compose_empty.t
+t/condition/05_empty_values.t
t/plugins/insert_multi/01_insert_multi.t
t/plugins/insert_on_duplicate/01_insert_on_duplicate.t
t/select/01_statement.t
@@ -4,8 +4,10 @@
"Tokuhiro Matsuno <tokuhirom AAJKLFJEF@ GMAIL COM>"
],
"dynamic_config" : 0,
- "generated_by" : "Minilla/v0.5.3",
- "license" : "perl_5",
+ "generated_by" : "Minilla/v0.13.0",
+ "license" : [
+ "perl_5"
+ ],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
@@ -19,7 +21,8 @@
"share",
"eg",
"examples",
- "author"
+ "author",
+ "builder"
]
},
"prereqs" : {
@@ -33,7 +36,7 @@
"develop" : {
"requires" : {
"Test::CPAN::Meta" : "0",
- "Test::MinimumVersion" : "0.10108",
+ "Test::MinimumVersion::Fast" : "0.04",
"Test::Pod" : "1.41",
"Test::Spellunker" : "v0.2.7"
}
@@ -59,7 +62,7 @@
"provides" : {
"SQL::Maker" : {
"file" : "lib/SQL/Maker.pm",
- "version" : "1.12"
+ "version" : "1.15"
},
"SQL::Maker::Condition" : {
"file" : "lib/SQL/Maker/Condition.pm"
@@ -97,7 +100,7 @@
"web" : "https://github.com/tokuhirom/SQL-Maker"
}
},
- "version" : "1.12",
+ "version" : "1.15",
"x_contributors" : [
"lestrrat <lestrrat+github@gmail.com>",
"makamaka <makamaka.donzoko@gmail.com>",
@@ -109,6 +112,10 @@
"Masahiro Chiba <chiba@everqueue.com>",
"Toshio Ito <debug.ito@gmail.com>",
"Masayuki Matsuki <y.songmu@gmail.com>",
- "tokuhirom <tokuhirom@gmail.com>"
+ "Neil Bowers <neil@bowers.com>",
+ "Gelu Lupas <gvl@cpan.org>",
+ "karupanerura <karupa@cpan.org>",
+ "soh335 <sugarbabe335@gmail.com>",
+ "Tokuhiro Matsuno <tokuhirom@gmail.com>"
]
}
@@ -3,19 +3,19 @@ abstract: 'Yet another SQL builder'
author:
- 'Tokuhiro Matsuno <tokuhirom AAJKLFJEF@ GMAIL COM>'
build_requires:
- Test::More: 0.98
- Test::Requires: 0
- Tie::IxHash: 0
+ Test::More: '0.98'
+ Test::Requires: '0'
+ Tie::IxHash: '0'
configure_requires:
- CPAN::Meta: 0
- CPAN::Meta::Prereqs: 0
- Module::Build: 0.38
+ CPAN::Meta: '0'
+ CPAN::Meta::Prereqs: '0'
+ Module::Build: '0.38'
dynamic_config: 0
-generated_by: 'Minilla/v0.5.3, CPAN::Meta::Converter version 2.130880'
+generated_by: 'Minilla/v0.13.0, CPAN::Meta::Converter version 2.133380'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
- version: 1.4
+ version: '1.4'
name: SQL-Maker
no_index:
directory:
@@ -26,10 +26,11 @@ no_index:
- eg
- examples
- author
+ - builder
provides:
SQL::Maker:
file: lib/SQL/Maker.pm
- version: 1.12
+ version: '1.15'
SQL::Maker::Condition:
file: lib/SQL/Maker/Condition.pm
SQL::Maker::Plugin::InsertMulti:
@@ -47,17 +48,17 @@ provides:
SQL::Maker::Util:
file: lib/SQL/Maker/Util.pm
requires:
- Class::Accessor::Lite: 0.05
- DBI: 0
- Module::Load: 0
- Scalar::Util: 0
- parent: 0
- perl: 5.008001
+ Class::Accessor::Lite: '0.05'
+ DBI: '0'
+ Module::Load: '0'
+ Scalar::Util: '0'
+ parent: '0'
+ perl: '5.008001'
resources:
bugtracker: https://github.com/tokuhirom/SQL-Maker/issues
homepage: https://github.com/tokuhirom/SQL-Maker
repository: git://github.com/tokuhirom/SQL-Maker.git
-version: 1.12
+version: '1.15'
x_contributors:
- 'lestrrat <lestrrat+github@gmail.com>'
- 'makamaka <makamaka.donzoko@gmail.com>'
@@ -69,4 +70,8 @@ x_contributors:
- 'Masahiro Chiba <chiba@everqueue.com>'
- 'Toshio Ito <debug.ito@gmail.com>'
- 'Masayuki Matsuki <y.songmu@gmail.com>'
- - 'tokuhirom <tokuhirom@gmail.com>'
+ - 'Neil Bowers <neil@bowers.com>'
+ - 'Gelu Lupas <gvl@cpan.org>'
+ - 'karupanerura <karupa@cpan.org>'
+ - 'soh335 <sugarbabe335@gmail.com>'
+ - 'Tokuhiro Matsuno <tokuhirom@gmail.com>'
@@ -17,7 +17,7 @@ SQL::Maker - Yet another SQL builder
($sql, @binds) = $builder->insert($table, \%values, \%opt);
# DELETE
- ($sql, @binds) = $builder->delete($table, \%where);
+ ($sql, @binds) = $builder->delete($table, \%where, \%opt);
# UPDATE
($sql, @binds) = $builder->update($table, \%set, \%where);
@@ -25,15 +25,15 @@ SQL::Maker - Yet another SQL builder
# DESCRIPTION
-SQL::Maker is yet another SQL builder class. It is based on [DBIx::Skinny](http://search.cpan.org/perldoc?DBIx::Skinny)'s SQL generator.
+SQL::Maker is yet another SQL builder class. It is based on [DBIx::Skinny](https://metacpan.org/pod/DBIx::Skinny)'s SQL generator.
# METHODS
-- my $builder = SQL::Maker->new(%args);
+- `my $builder = SQL::Maker->new(%args);`
Create new instance of SQL::Maker.
- Attributes are following:
+ Attributes are the following:
- driver: Str
@@ -57,145 +57,176 @@ SQL::Maker is yet another SQL builder class. It is based on [DBIx::Skinny](http:
Default: '\\n'
-- my $select = $builder->new\_select(%args|\\%args);
+- `my $select = $builder->new_select(%args|\%args);`
- Create new instance of [SQL::Maker::Select](http://search.cpan.org/perldoc?SQL::Maker::Select) from the settings from __$builder__.
+ Create new instance of [SQL::Maker::Select](https://metacpan.org/pod/SQL::Maker::Select) using the settings from __$builder__.
- This method returns instance of [SQL::Maker::Select](http://search.cpan.org/perldoc?SQL::Maker::Select).
+ This method returns an instance of [SQL::Maker::Select](https://metacpan.org/pod/SQL::Maker::Select).
-- my ($sql, @binds) = $builder->select($table|\\@tables, \\@fields, \\%where|\\@where|$where, \\%opt);
+- `my ($sql, @binds) = $builder->select($table|\@tables, \@fields, \%where|\@where|$where, \%opt);`
my ($sql, @binds) = $builder->select('user', ['*'], {name => 'john'}, {order_by => 'user_id DESC'});
# =>
# SELECT * FROM `user` WHERE (`name` = ?) ORDER BY user_id DESC
# ['john']
- This method returns SQL string and bind variables for SELECT statement.
+ This method returns the SQL string and bind variables for a SELECT statement.
- - $table
- - \\@tables
+ - `$table`
+ - `\@tables`
+
+ Table name for the __FROM__ clause as scalar or arrayref. You can specify the instance of __SQL::Maker::Select__ for a sub-query.
- Table name for __FROM__ clause in scalar or arrayref. You can specify the instance of __SQL::Maker::Select__ for sub-query.
+ If you are using `$opt->{joins}` this should be _undef_ since it's passed via the first join.
- - \\@fields
+ - `\@fields`
This is a list for retrieving fields from database.
- Each element of the `@field` is a scalar or a scalar ref of the column name normally.
- If you want to specify alias of the field, you can use ArrayRef containing the pair of column
- and alias name (e.g. `['foo.id' => 'foo_id']`).
+ Each element of the `@fields` is normally a scalar or a scalar ref containing the column name.
+ If you want to specify an alias of the field, you can use an arrayref containing a pair
+ of column and alias names (e.g. `['foo.id' => 'foo_id']`).
- - \\%where
- - \\@where
- - $where
+ - `\%where`
+ - `\@where`
+ - `$where`
- where clause from hashref or arrayref via [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition), or [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition) object.
+ where clause from hashref or arrayref via [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition), or [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition) object.
- - \\%opt
+ - `\%opt`
- This is a options for SELECT statement
+ These are the options for the SELECT statement
- - $opt->{prefix}
+ - `$opt->{prefix}`
- This is a prefix for SELECT statement.
+ This is a prefix for the SELECT statement.
For example, you can provide the 'SELECT SQL\_CALC\_FOUND\_ROWS '. It's useful for MySQL.
Default Value: 'SELECT '
- - $opt->{limit}
+ - `$opt->{limit}`
+
+ This option adds a 'LIMIT $n' clause.
+
+ - `$opt->{offset}`
+
+ This option adds an 'OFFSET $n' clause.
+
+ - `$opt->{order_by}`
+
+ This option adds an __ORDER BY__ clause
+
+ You can write it in any of the following forms:
- This option makes 'LIMIT $n' clause.
+ $builder->select(..., {order_by => 'foo DESC, bar ASC'});
+ $builder->select(..., {order_by => ['foo DESC', 'bar ASC']});
+ $builder->select(..., {order_by => {foo => 'DESC'}});
+ $builder->select(..., {order_by => [{foo => 'DESC'}, {bar => 'ASC'}]});
- - $opt->{offset}
+ - `$opt->{group_by}`
- This option makes 'OFFSET $n' clause.
+ This option adds a __GROUP BY__ clause
- - $opt->{order\_by}
+ You can write it in any of the following forms:
- This option makes __ORDER BY__ clause
+ $builder->select(..., {group_by => 'foo DESC, bar ASC'});
+ $builder->select(..., {group_by => ['foo DESC', 'bar ASC']});
+ $builder->select(..., {group_by => {foo => 'DESC'}});
+ $builder->select(..., {group_by => [{foo => 'DESC'}, {bar => 'ASC'}]});
- You can write it as following forms:
+ - `$opt->{having}`
- $builder->select(..., order_by => 'foo DESC, bar ASC');
- $builder->select(..., order_by => ['foo DESC', 'bar ASC']);
- $builder->select(..., order_by => {foo => 'DESC'});
- $builder->select(..., order_by => [{foo => 'DESC'}, {bar => 'ASC'}]);
+ This option adds a HAVING clause
- - $opt->{group\_by}
+ - `$opt->{for_update}`
- This option makes __GROUP BY__ clause
+ This option adds a 'FOR UPDATE" clause.
- You can write it as following forms:
+ - `$opt->{joins}`
- $builder->select(..., group_by => 'foo DESC, bar ASC');
- $builder->select(..., group_by => ['foo DESC', 'bar ASC']);
- $builder->select(..., group_by => {foo => 'DESC'});
- $builder->select(..., group_by => [{foo => 'DESC'}, {bar => 'ASC'}]);
+ This option adds a 'JOIN' via [SQL::Maker::Select](https://metacpan.org/pod/SQL::Maker::Select).
- - $opt->{having}
+ You can write it as follows:
- This option makes HAVING clause
+ $builder->select(undef, ..., {joins => [[user => {table => 'group', condition => 'user.gid = group.gid'}], ...]});
- - $opt->{for\_update}
+ - `$opt->{index_hint}`
- This option makes 'FOR UPDATE" clause.
+ This option adds an INDEX HINT like as 'USE INDEX' clause for MySQL via [SQL::Maker::Select](https://metacpan.org/pod/SQL::Maker::Select).
- - $opt->{joins}
+ You can write it as follows:
- This option makes 'JOIN' via [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition).
+ $builder->select(..., { index_hint => 'foo' });
+ $builder->select(..., { index_hint => ['foo', 'bar'] });
+ $builder->select(..., { index_hint => { list => 'foo' });
+ $builder->select(..., { index_hint => { type => 'FORCE', list => ['foo', 'bar'] });
-- my ($sql, @binds) = $builder->insert($table, \\%values|\\@values, \\%opt);
+- `my ($sql, @binds) = $builder->insert($table, \%values|\@values, \%opt);`
my ($sql, @binds) = $builder->insert(user => {name => 'john'});
# =>
# INSERT INTO `user` (`name`) VALUES (?)
# ['john']
- Generate INSERT query.
+ Generate an INSERT query.
- - $table
+ - `$table`
Table name in scalar.
- - \\%values
+ - `\%values`
- This is a values for INSERT statement.
+ These are the values for the INSERT statement.
- - \\%opt
+ - `\%opt`
- This is a options for INSERT statement
+ These are the options for the INSERT statement
- - $opt->{prefix}
+ - `$opt->{prefix}`
- This is a prefix for INSERT statement.
+ This is a prefix for the INSERT statement.
For example, you can provide 'INSERT IGNORE INTO' for MySQL.
Default Value: 'INSERT INTO'
-- my ($sql, @binds) = $builder->delete($table, \\%where|\\@where|$where);
+- `my ($sql, @binds) = $builder->delete($table, \%where|\@where|$where, \%opt);`
my ($sql, @binds) = $builder->delete($table, \%where);
# =>
# DELETE FROM `user` WHERE (`name` = ?)
# ['john']
- Generate DELETE query.
+ Generate a DELETE query.
- - $table
+ - `$table`
Table name in scalar.
- - \\%where
- - \\@where
- - $where
+ - `\%where`
+ - `\@where`
+ - `$where`
+
+ where clause from hashref or arrayref via [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition), or [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition) object.
+
+ - `\%opt`
+
+ These are the options for the DELETE statement
+
+ - `$opt->{using}`
+
+ This option adds a USING clause. It takes a scalar or an arrayref of table names as argument:
- where clause from hashref or arrayref via [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition), or [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition) object.
+ my ($sql, $binds) = $bulder->delete($table, \%where, { using => 'group' });
+ # =>
+ # DELETE FROM `user` USING `group` WHERE (`group`.`name` = ?)
+ # ['doe']
+ $bulder->delete(..., { using => ['bar', 'qux'] });
-- my ($sql, @binds) = $builder->update($table, \\%set|@set, \\%where|\\@where|$where);
+- `my ($sql, @binds) = $builder->update($table, \%set|@set, \%where|\@where|$where);`
- Generate UPDATE query.
+ Generate a UPDATE query.
my ($sql, @binds) = $builder->update('user', ['name' => 'john', email => 'john@example.com'], {user_id => 3});
# =>
@@ -214,21 +245,21 @@ SQL::Maker is yet another SQL builder class. It is based on [DBIx::Skinny](http:
- \\@where
- $where
- where clause from hashref or arrayref via [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition), or [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition) object.
+ where clause from a hashref or arrayref via [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition), or [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition) object.
-- $builder->new\_condition()
+- `$builder->new_condition()`
- Create new [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition) object from ` $builder ` settings.
+ Create new [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition) object from ` $builder ` settings.
-- my ($sql, @binds) = $builder->where(\\%where)
-- my ($sql, @binds) = $builder->where(\\@where)
-- my ($sql, @binds) = $builder->where(\\@where)
+- `my ($sql, @binds) = $builder->where(\%where)`
+- `my ($sql, @binds) = $builder->where(\@where)`
+- `my ($sql, @binds) = $builder->where(\@where)`
- Where clause from hashref or arrayref via [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition), or [SQL::Maker::Condition](http://search.cpan.org/perldoc?SQL::Maker::Condition) object.
+ Where clause from a hashref or arrayref via [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition), or [SQL::Maker::Condition](https://metacpan.org/pod/SQL::Maker::Condition) object.
# PLUGINS
-SQL::Maker supports plugin system. Write the code like following.
+SQL::Maker features a plugin system. Write the code as follows:
package My::SQL::Maker;
use parent qw/SQL::Maker/;
@@ -236,11 +267,11 @@ SQL::Maker supports plugin system. Write the code like following.
# FAQ
-- Why don't you use SQL::Abstract?
+- Why don't you use SQL::Abstract?
- I need more extensible one.
+ I need a more extensible one.
- So, this module contains [SQL::Maker::Select](http://search.cpan.org/perldoc?SQL::Maker::Select), the extensible __SELECT__ clause object.
+ So, this module contains [SQL::Maker::Select](https://metacpan.org/pod/SQL::Maker::Select), the extensible __SELECT__ clause object.
# AUTHOR
@@ -248,9 +279,9 @@ Tokuhiro Matsuno <tokuhirom AAJKLFJEF@ GMAIL COM>
# SEE ALSO
-[SQL::Abstract](http://search.cpan.org/perldoc?SQL::Abstract)
+[SQL::Abstract](https://metacpan.org/pod/SQL::Abstract)
-Whole code was taken from [DBIx::Skinny](http://search.cpan.org/perldoc?DBIx::Skinny) by nekokak++.
+The whole code was taken from [DBIx::Skinny](https://metacpan.org/pod/DBIx::Skinny) by nekokak++.
# LICENSE
@@ -46,27 +46,14 @@ sub _make_term {
}
else {
# make_term(foo => [1,2,3]) => foo IN (1,2,3)
- my $term = $self->_quote($col) . " IN (" . substr('?, ' x scalar(@$val), 0, -2) . ')';
- return ($term, $val);
+ return $self->_make_term_by_arrayref($col, 'IN', $val);
}
}
elsif ( ref($val) eq 'HASH' ) {
my ( $op, $v ) = ( %{$val} );
$op = uc($op);
if ( ( $op eq 'IN' || $op eq 'NOT IN' ) && ref($v) eq 'ARRAY' ) {
- if (@$v == 0) {
- if ($op eq 'IN') {
- # make_term(foo => +{'IN' => []}) => 0=1
- return ('0=1', []);
- } else {
- # make_term(foo => +{'NOT IN' => []}) => 1=1
- return ('1=1', []);
- }
- } else {
- # make_term(foo => +{ 'IN', [1,2,3] }) => foo IN (1,2,3)
- my $term = $self->_quote($col) . " $op (" . join( ', ', ('?') x scalar @$v ) . ')';
- return ($term, $v);
- }
+ return $self->_make_term_by_arrayref($col, $op, $v);
}
elsif ( ( $op eq 'IN' || $op eq 'NOT IN' ) && ref($v) eq 'REF' ) {
# make_term(foo => +{ 'IN', \['SELECT foo FROM bar'] }) => foo IN (SELECT foo FROM bar)
@@ -108,6 +95,23 @@ sub _make_term {
}
}
+sub _make_term_by_arrayref {
+ my ($self, $col, $op, $v) = @_;
+ if (@$v == 0) {
+ if ($op eq 'IN') {
+ # make_term(foo => +{'IN' => []}) => 0=1
+ return ('0=1', []);
+ } else {
+ # make_term(foo => +{'NOT IN' => []}) => 1=1
+ return ('1=1', []);
+ }
+ } else {
+ # make_term(foo => +{ 'IN', [1,2,3] }) => foo IN (1,2,3)
+ my $term = $self->_quote($col) . " $op (" . join( ', ', ('?') x scalar @$v ) . ')';
+ return ($term, $v);
+ }
+}
+
sub add {
my ( $self, $col, $val ) = @_;
@@ -110,10 +110,23 @@ sub add_join {
sub add_index_hint {
my ($self, $table, $hint) = @_;
+ my ($type, $list);
+
+ if (ref $hint eq 'HASH') {
+ # { type => '...', list => ['foo'] }
+ $type = $hint->{type} || 'USE';
+ $list = ref($hint->{list}) eq 'ARRAY' ? $hint->{list} : [ $hint->{list} ];
+ } else {
+ # ['foo, 'bar'] or just 'foo'
+ $type = 'USE';
+ $list = ref($hint) eq 'ARRAY' ? $hint : [ $hint ];
+ }
+
$self->{index_hint}->{$table} = {
- type => $hint->{type} || 'USE',
- list => ref($hint->{list}) eq 'ARRAY' ? $hint->{list} : [ $hint->{list} ],
+ type => $type,
+ list => $list,
};
+
return $self;
}
@@ -153,7 +166,8 @@ sub as_sql {
my ($table, $join) = map { $j->{$_} } qw( table joins );
$table = $self->_add_index_hint(@$table); ## index hint handling
$sql .= $table unless $initial_table_written++;
- $sql .= ' ' . uc($join->{type}) . ' JOIN ' . $self->_quote($join->{table});
+ $sql .= ' ' . uc($join->{type}) if $join->{type};
+ $sql .= ' JOIN ' . $self->_quote($join->{table});
$sql .= ' ' . $self->_quote($join->{alias}) if $join->{alias};
if ( defined $join->{condition} ) {
@@ -345,7 +359,7 @@ Render the SQL string.
=item C<< my @bind = $stmt->bind(); >>
-Get bind variables.
+Get the bind variables.
=item C<< $stmt->add_select('*') >>
@@ -353,11 +367,11 @@ Get bind variables.
=item C<< $stmt->add_select(\'COUNT(*)' => 'cnt') >>
-Add new select term. It's quote automatically.
+Add a new select term. It's automatically quoted.
=item C<< $stmt->add_from($table :Str | $select :SQL::Maker::Select) : SQL::Maker::Select >>
-Add new from clause. You can specify the table name or instance of L<SQL::Maker::Select> for sub-query.
+Add a new FROM clause. You can specify the table name or an instance of L<SQL::Maker::Select> for a sub-query.
I<Return:> $stmt itself.
@@ -367,7 +381,8 @@ I<Return:> $stmt itself.
=item C<< $stmt->add_join(user => {type => 'inner', table => 'config', condition => ['user_id']}); >>
-Add new JOIN clause. If you pass arrayref for 'condition' then it uses 'USING'.
+Add a new JOIN clause. If you pass an arrayref for 'condition' then it uses 'USING'. If 'type' is omitted
+it falls back to plain JOIN.
my $stmt = SQL::Maker::Select->new();
$stmt->add_join(
@@ -421,6 +436,10 @@ Add new JOIN clause. If you pass arrayref for 'condition' then it uses 'USING'.
=item C<< $stmt->add_index_hint(foo => {type => 'USE', list => ['index_hint']}); >>
+=item C<< $stmt->add_index_hint(foo => 'index_hint'); >>
+
+=item C<< $stmt->add_index_hint(foo => ['index_hint']); >>
+
my $stmt = SQL::Maker::Select->new();
$stmt->add_select('name');
$stmt->add_from('user');
@@ -430,7 +449,7 @@ Add new JOIN clause. If you pass arrayref for 'condition' then it uses 'USING'.
=item C<< $stmt->add_where('foo_id' => 'bar'); >>
-Add new where clause.
+Add a new WHERE clause.
my $stmt = SQL::Maker::Select->new()
->add_select('c')
@@ -442,7 +461,7 @@ Add new where clause.
=item C<< $stmt->add_where_raw('id = ?', [1]) >>
-Add new where clause from raw placeholder string and bind variables.
+Add a new WHERE clause from raw placeholder string and bind variables.
my $stmt = SQL::Maker::Select->new()
->add_select('c')
@@ -455,7 +474,7 @@ Add new where clause from raw placeholder string and bind variables.
=item C<< $stmt->set_where($condition) >>
-Set the where clause.
+Set the WHERE clause.
$condition should be instance of L<SQL::Maker::Condition>.
@@ -474,7 +493,7 @@ $condition should be instance of L<SQL::Maker::Condition>.
=item C<< $stmt->add_order_by({'foo' => 'DESC'}); >>
-Add new order by clause.
+Add a new ORDER BY clause.
my $stmt = SQL::Maker::Select->new()
->add_select('c')
@@ -486,7 +505,7 @@ Add new order by clause.
=item C<< $stmt->add_group_by('foo'); >>
-Add new GROUP BY clause.
+Add a new GROUP BY clause.
my $stmt = SQL::Maker::Select->new()
->add_select('c')
@@ -502,9 +521,23 @@ Add new GROUP BY clause.
->as_sql();
# => "SELECT c FROM foo GROUP BY id DESC"
+=item C<< $stmt->limit(30) >>
+
+=item C<< $stmt->offset(5) >>
+
+Add LIMIT and OFFSET.
+
+ my $stmt = SQL::Maker::Select->new()
+ ->add_select('c')
+ ->add_from('foo')
+ ->limit(30)
+ ->offset(5)
+ ->as_sql();
+ # => "SELECT c FROM foo LIMIT 30 OFFSET 5"
+
=item C<< $stmt->add_having(cnt => 2) >>
-Add having clause
+Add a HAVING clause.
my $stmt = SQL::Maker::Select->new()
->add_from('foo')
@@ -2,7 +2,7 @@ package SQL::Maker;
use strict;
use warnings;
use 5.008001;
-our $VERSION = '1.12';
+our $VERSION = '1.15';
use Class::Accessor::Lite 0.05 (
ro => [qw/quote_char name_sep new_line driver select_class/],
);
@@ -122,11 +122,19 @@ sub _quote {
}
sub delete {
- my ($self, $table, $where) = @_;
+ my ($self, $table, $where, $opt) = @_;
my $w = $self->_make_where_clause($where);
my $quoted_table = $self->_quote($table);
- my $sql = "DELETE FROM $quoted_table" . $w->[0];
+ my $sql = "DELETE FROM $quoted_table";
+ if ($opt->{using}) {
+ # $bulder->delete('foo', \%where, { using => 'bar' });
+ # $bulder->delete('foo', \%where, { using => ['bar', 'qux'] });
+ my $tables = ref($opt->{using}) eq 'ARRAY' ? $opt->{using} : [$opt->{using}];
+ my $using = join(', ', map { $self->_quote($_) } @$tables);
+ $sql .= " USING " . $using;
+ }
+ $sql .= $w->[0];
return ($sql, @{$w->[1]});
}
@@ -283,6 +291,9 @@ sub select_query {
$stmt->add_group_by(\$o);
}
}
+ if (my $o = $opt->{index_hint}) {
+ $stmt->add_index_hint($table, $o);
+ }
$stmt->limit( $opt->{limit} ) if $opt->{limit};
$stmt->offset( $opt->{offset} ) if $opt->{offset};
@@ -324,7 +335,7 @@ SQL::Maker - Yet another SQL builder
($sql, @binds) = $builder->insert($table, \%values, \%opt);
# DELETE
- ($sql, @binds) = $builder->delete($table, \%where);
+ ($sql, @binds) = $builder->delete($table, \%where, \%opt);
# UPDATE
($sql, @binds) = $builder->update($table, \%set, \%where);
@@ -338,11 +349,11 @@ SQL::Maker is yet another SQL builder class. It is based on L<DBIx::Skinny>'s SQ
=over 4
-=item my $builder = SQL::Maker->new(%args);
+=item C<< my $builder = SQL::Maker->new(%args); >>
Create new instance of SQL::Maker.
-Attributes are following:
+Attributes are the following:
=over 4
@@ -370,133 +381,150 @@ Default: '\n'
=back
-=item my $select = $builder->new_select(%args|\%args);
+=item C<< my $select = $builder->new_select(%args|\%args); >>
-Create new instance of L<SQL::Maker::Select> from the settings from B<$builder>.
+Create new instance of L<SQL::Maker::Select> using the settings from B<$builder>.
-This method returns instance of L<SQL::Maker::Select>.
+This method returns an instance of L<SQL::Maker::Select>.
-=item my ($sql, @binds) = $builder->select($table|\@tables, \@fields, \%where|\@where|$where, \%opt);
+=item C<< my ($sql, @binds) = $builder->select($table|\@tables, \@fields, \%where|\@where|$where, \%opt); >>
my ($sql, @binds) = $builder->select('user', ['*'], {name => 'john'}, {order_by => 'user_id DESC'});
# =>
# SELECT * FROM `user` WHERE (`name` = ?) ORDER BY user_id DESC
# ['john']
-This method returns SQL string and bind variables for SELECT statement.
+This method returns the SQL string and bind variables for a SELECT statement.
=over 4
-=item $table
+=item C<< $table >>
+
+=item C<< \@tables >>
-=item \@tables
+Table name for the B<FROM> clause as scalar or arrayref. You can specify the instance of B<SQL::Maker::Select> for a sub-query.
-Table name for B<FROM> clause in scalar or arrayref. You can specify the instance of B<SQL::Maker::Select> for sub-query.
+If you are using C<< $opt->{joins} >> this should be I<< undef >> since it's passed via the first join.
-=item \@fields
+=item C<< \@fields >>
This is a list for retrieving fields from database.
-Each element of the C<@field> is a scalar or a scalar ref of the column name normally.
-If you want to specify alias of the field, you can use ArrayRef containing the pair of column
-and alias name (e.g. C<< ['foo.id' => 'foo_id'] >>).
+Each element of the C<@fields> is normally a scalar or a scalar ref containing the column name.
+If you want to specify an alias of the field, you can use an arrayref containing a pair
+of column and alias names (e.g. C<< ['foo.id' => 'foo_id'] >>).
-=item \%where
+=item C<< \%where >>
-=item \@where
+=item C<< \@where >>
-=item $where
+=item C<< $where >>
where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
-=item \%opt
+=item C<< \%opt >>
-This is a options for SELECT statement
+These are the options for the SELECT statement
=over 4
-=item $opt->{prefix}
+=item C<< $opt->{prefix} >>
-This is a prefix for SELECT statement.
+This is a prefix for the SELECT statement.
For example, you can provide the 'SELECT SQL_CALC_FOUND_ROWS '. It's useful for MySQL.
Default Value: 'SELECT '
-=item $opt->{limit}
+=item C<< $opt->{limit} >>
+
+This option adds a 'LIMIT $n' clause.
-This option makes 'LIMIT $n' clause.
+=item C<< $opt->{offset} >>
-=item $opt->{offset}
+This option adds an 'OFFSET $n' clause.
-This option makes 'OFFSET $n' clause.
+=item C<< $opt->{order_by} >>
-=item $opt->{order_by}
+This option adds an B<ORDER BY> clause
-This option makes B<ORDER BY> clause
+You can write it in any of the following forms:
-You can write it as following forms:
+ $builder->select(..., {order_by => 'foo DESC, bar ASC'});
+ $builder->select(..., {order_by => ['foo DESC', 'bar ASC']});
+ $builder->select(..., {order_by => {foo => 'DESC'}});
+ $builder->select(..., {order_by => [{foo => 'DESC'}, {bar => 'ASC'}]});
- $builder->select(..., order_by => 'foo DESC, bar ASC');
- $builder->select(..., order_by => ['foo DESC', 'bar ASC']);
- $builder->select(..., order_by => {foo => 'DESC'});
- $builder->select(..., order_by => [{foo => 'DESC'}, {bar => 'ASC'}]);
+=item C<< $opt->{group_by} >>
-=item $opt->{group_by}
+This option adds a B<GROUP BY> clause
-This option makes B<GROUP BY> clause
+You can write it in any of the following forms:
-You can write it as following forms:
+ $builder->select(..., {group_by => 'foo DESC, bar ASC'});
+ $builder->select(..., {group_by => ['foo DESC', 'bar ASC']});
+ $builder->select(..., {group_by => {foo => 'DESC'}});
+ $builder->select(..., {group_by => [{foo => 'DESC'}, {bar => 'ASC'}]});
- $builder->select(..., group_by => 'foo DESC, bar ASC');
- $builder->select(..., group_by => ['foo DESC', 'bar ASC']);
- $builder->select(..., group_by => {foo => 'DESC'});
- $builder->select(..., group_by => [{foo => 'DESC'}, {bar => 'ASC'}]);
+=item C<< $opt->{having} >>
-=item $opt->{having}
+This option adds a HAVING clause
-This option makes HAVING clause
+=item C<< $opt->{for_update} >>
-=item $opt->{for_update}
+This option adds a 'FOR UPDATE" clause.
-This option makes 'FOR UPDATE" clause.
+=item C<< $opt->{joins} >>
-=item $opt->{joins}
+This option adds a 'JOIN' via L<SQL::Maker::Select>.
-This option makes 'JOIN' via L<SQL::Maker::Condition>.
+You can write it as follows:
+
+ $builder->select(undef, ..., {joins => [[user => {table => 'group', condition => 'user.gid = group.gid'}], ...]});
+
+=item C<< $opt->{index_hint} >>
+
+This option adds an INDEX HINT like as 'USE INDEX' clause for MySQL via L<SQL::Maker::Select>.
+
+You can write it as follows:
+
+ $builder->select(..., { index_hint => 'foo' });
+ $builder->select(..., { index_hint => ['foo', 'bar'] });
+ $builder->select(..., { index_hint => { list => 'foo' });
+ $builder->select(..., { index_hint => { type => 'FORCE', list => ['foo', 'bar'] });
=back
=back
-=item my ($sql, @binds) = $builder->insert($table, \%values|\@values, \%opt);
+=item C<< my ($sql, @binds) = $builder->insert($table, \%values|\@values, \%opt); >>
my ($sql, @binds) = $builder->insert(user => {name => 'john'});
# =>
# INSERT INTO `user` (`name`) VALUES (?)
# ['john']
-Generate INSERT query.
+Generate an INSERT query.
=over 4
-=item $table
+=item C<< $table >>
Table name in scalar.
-=item \%values
+=item C<< \%values >>
-This is a values for INSERT statement.
+These are the values for the INSERT statement.
-=item \%opt
+=item C<< \%opt >>
-This is a options for INSERT statement
+These are the options for the INSERT statement
=over 4
-=item $opt->{prefix}
+=item C<< $opt->{prefix} >>
-This is a prefix for INSERT statement.
+This is a prefix for the INSERT statement.
For example, you can provide 'INSERT IGNORE INTO' for MySQL.
@@ -506,34 +534,52 @@ Default Value: 'INSERT INTO'
=back
-=item my ($sql, @binds) = $builder->delete($table, \%where|\@where|$where);
+=item C<< my ($sql, @binds) = $builder->delete($table, \%where|\@where|$where, \%opt); >>
my ($sql, @binds) = $builder->delete($table, \%where);
# =>
# DELETE FROM `user` WHERE (`name` = ?)
# ['john']
-Generate DELETE query.
+Generate a DELETE query.
=over 4
-=item $table
+=item C<< $table >>
Table name in scalar.
-=item \%where
+=item C<< \%where >>
-=item \@where
+=item C<< \@where >>
-=item $where
+=item C<< $where >>
where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
+=item C<< \%opt >>
+
+These are the options for the DELETE statement
+
+=over 4
+
+=item C<< $opt->{using} >>
+
+This option adds a USING clause. It takes a scalar or an arrayref of table names as argument:
+
+ my ($sql, $binds) = $bulder->delete($table, \%where, { using => 'group' });
+ # =>
+ # DELETE FROM `user` USING `group` WHERE (`group`.`name` = ?)
+ # ['doe']
+ $bulder->delete(..., { using => ['bar', 'qux'] });
+
=back
-=item my ($sql, @binds) = $builder->update($table, \%set|@set, \%where|\@where|$where);
+=back
+
+=item C<< my ($sql, @binds) = $builder->update($table, \%set|@set, \%where|\@where|$where); >>
-Generate UPDATE query.
+Generate a UPDATE query.
my ($sql, @binds) = $builder->update('user', ['name' => 'john', email => 'john@example.com'], {user_id => 3});
# =>
@@ -556,27 +602,27 @@ Setting values.
=item $where
-where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
+where clause from a hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
=back
-=item $builder->new_condition()
+=item C<< $builder->new_condition() >>
Create new L<SQL::Maker::Condition> object from C< $builder > settings.
-=item my ($sql, @binds) = $builder->where(\%where)
+=item C<< my ($sql, @binds) = $builder->where(\%where) >>
-=item my ($sql, @binds) = $builder->where(\@where)
+=item C<< my ($sql, @binds) = $builder->where(\@where) >>
-=item my ($sql, @binds) = $builder->where(\@where)
+=item C<< my ($sql, @binds) = $builder->where(\@where) >>
-Where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
+Where clause from a hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
=back
=head1 PLUGINS
-SQL::Maker supports plugin system. Write the code like following.
+SQL::Maker features a plugin system. Write the code as follows:
package My::SQL::Maker;
use parent qw/SQL::Maker/;
@@ -586,9 +632,9 @@ SQL::Maker supports plugin system. Write the code like following.
=over 4
-=item Why don't you use SQL::Abstract?
+=item Why don't you use SQL::Abstract?
-I need more extensible one.
+I need a more extensible one.
So, this module contains L<SQL::Maker::Select>, the extensible B<SELECT> clause object.
@@ -602,7 +648,7 @@ Tokuhiro Matsuno E<lt>tokuhirom AAJKLFJEF@ GMAIL COME<gt>
L<SQL::Abstract>
-Whole code was taken from L<DBIx::Skinny> by nekokak++.
+The whole code was taken from L<DBIx::Skinny> by nekokak++.
=head1 LICENSE
@@ -73,6 +73,20 @@ subtest 'driver mysql' => sub {
is $sql, qq{DELETE FROM `foo`};
is join(',', @binds), '';
};
+
+ subtest 'delete using where_as_hashref' => sub {
+ my $builder = SQL::Maker->new(driver => 'mysql');
+ my ($sql, @binds) = $builder->delete('foo', [bar => 'baz', john => 'man'], {using => 'bar'});
+ is $sql, qq{DELETE FROM `foo` USING `bar` WHERE (`bar` = ?) AND (`john` = ?)};
+ is join(',', @binds), 'baz,man';
+ };
+
+ subtest 'delete using array where_as_hashref' => sub {
+ my $builder = SQL::Maker->new(driver => 'mysql');
+ my ($sql, @binds) = $builder->delete('foo', [bar => 'baz', john => 'man'], {using => ['bar', 'qux']});
+ is $sql, qq{DELETE FROM `foo` USING `bar`, `qux` WHERE (`bar` = ?) AND (`john` = ?)};
+ is join(',', @binds), 'baz,man';
+ };
};
subtest 'driver mysql, quote_char: "", new_line: " "' => sub {
@@ -106,6 +120,20 @@ subtest 'driver mysql, quote_char: "", new_line: " "' => sub {
is $sql, qq{DELETE FROM foo};
is join(',', @binds), '';
};
+
+ subtest 'delete using where_as_hashref' => sub {
+ my $builder = SQL::Maker->new(driver => 'mysql', quote_char => '', new_line => ' ');
+ my ($sql, @binds) = $builder->delete('foo', [bar => 'baz', john => 'man'], {using => 'bar'});
+ is $sql, qq{DELETE FROM foo USING bar WHERE (bar = ?) AND (john = ?)};
+ is join(',', @binds), 'baz,man';
+ };
+
+ subtest 'delete using array where_as_hashref' => sub {
+ my $builder = SQL::Maker->new(driver => 'mysql', quote_char => '', new_line => ' ');
+ my ($sql, @binds) = $builder->delete('foo', [bar => 'baz', john => 'man'], {using => ['bar', 'qux']});
+ is $sql, qq{DELETE FROM foo USING bar, qux WHERE (bar = ?) AND (john = ?)};
+ is join(',', @binds), 'baz,man';
+ };
};
done_testing;
@@ -432,6 +432,23 @@ subtest 'driver: mysql, quote_char: "", new_line: " "' => sub {
};
};
+ subtest 'index_hint' => sub {
+ subtest 'scalar' => sub {
+ my ($sql, @binds) = $builder->select('foo' => ['*'], +{}, {index_hint => 'bar'});
+ is $sql, qq{SELECT * FROM foo USE INDEX (bar)};
+ };
+
+ subtest 'array ref' => sub {
+ my ($sql, @binds) = $builder->select('foo' => ['*'], +{}, {index_hint => ['bar', 'baz']});
+ is $sql, qq{SELECT * FROM foo USE INDEX (bar,baz)};
+ };
+
+ subtest 'hash ref' => sub {
+ my ($sql, @binds) = $builder->select('foo' => ['*'], +{}, {index_hint => {type => 'FORCE', list => ['bar']}});
+ is $sql, qq{SELECT * FROM foo FORCE INDEX (bar)};
+ };
+ };
+
subtest 'from' => sub {
subtest 'multi from' => sub {
my ($sql, @binds) = $builder->select( [ qw/foo bar/ ], ['*'], +{}, );
diff --git a/var/tmp/source/TOKUHIROM/SQL-Maker-1.12/SQL-Maker-1.12/t/01_update.t b/var/tmp/source/TOKUHIROM/SQL-Maker-1.15/SQL-Maker-1.15/t/01_update.t
old mode 100644
new mode 100755
@@ -0,0 +1,28 @@
+use strict;
+use warnings;
+use Test::More;
+use SQL::Maker::Condition;
+
+subtest '[]' => sub {
+ my $w = SQL::Maker::Condition->new();
+ $w->add(x => []);
+ is $w->as_sql, '(0=1)';
+ is join(', ', $w->bind), '';
+};
+
+subtest 'in' => sub {
+ my $w = SQL::Maker::Condition->new();
+ $w->add(x => { 'IN' => [] });
+ is $w->as_sql, '(0=1)';
+ is join(', ', $w->bind), '';
+};
+
+subtest 'not in' => sub {
+ my $w2 = SQL::Maker::Condition->new();
+ $w2->add(x => { 'NOT IN' => [] });
+ is $w2->as_sql, '(1=1)';
+ is join(', ', $w2->bind), '';
+};
+
+done_testing;
+
diff --git a/var/tmp/source/TOKUHIROM/SQL-Maker-1.12/SQL-Maker-1.12/t/plugins/insert_multi/01_insert_multi.t b/var/tmp/source/TOKUHIROM/SQL-Maker-1.15/SQL-Maker-1.15/t/plugins/insert_multi/01_insert_multi.t
old mode 100644
new mode 100755
@@ -632,6 +632,22 @@ subtest 'index hint' => sub {
$stmt->add_index_hint('baz' => { type => 'USE', list => ['index_hint']});
is($stmt->as_sql, "SELECT foo FROM baz USE INDEX (index_hint)", "we can turn on USE INDEX");
};
+
+ subtest 'hint as scalar' => sub {
+ my $stmt = ns( quote_char => q{}, name_sep => q{.}, new_line => q{ } );
+ $stmt->add_select(foo => 'foo');
+ $stmt->add_from( qw(baz) );
+ $stmt->add_index_hint('baz' => 'index_hint');
+ is($stmt->as_sql, "SELECT foo FROM baz USE INDEX (index_hint)", "we can turn on USE INDEX");
+ };
+
+ subtest 'hint as array ref' => sub {
+ my $stmt = ns( quote_char => q{}, name_sep => q{.}, new_line => q{ } );
+ $stmt->add_select(foo => 'foo');
+ $stmt->add_from( qw(baz) );
+ $stmt->add_index_hint('baz' => ['index_hint']);
+ is($stmt->as_sql, "SELECT foo FROM baz USE INDEX (index_hint)", "we can turn on USE INDEX");
+ };
};
subtest 'index hint with joins' => sub {