| ... | ... |
@@ -1,3 +1,6 @@ |
| 1 |
+0.1694 |
|
| 2 |
+ - DBIx::Custom::Model type attribute is DEPRECATED! |
|
| 3 |
+ this is renamed to bind_type. |
|
| 1 | 4 |
0.1693 |
| 2 | 5 |
- separate DBIx::Custom type_rule from filter |
| 3 | 6 |
- DBIx::Custom::Model filter attrribute is DEPRECATED! |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
package DBIx::Custom; |
| 2 | 2 |
|
| 3 |
-our $VERSION = '0.1693'; |
|
| 3 |
+our $VERSION = '0.1694'; |
|
| 4 | 4 |
use 5.008001; |
| 5 | 5 |
|
| 6 | 6 |
use Object::Simple -base; |
| ... | ... |
@@ -19,7 +19,8 @@ use Encode qw/encode encode_utf8 decode_utf8/; |
| 19 | 19 |
use constant DEBUG => $ENV{DBIX_CUSTOM_DEBUG} || 0;
|
| 20 | 20 |
use constant DEBUG_ENCODING => $ENV{DBIX_CUSTOM_DEBUG_ENCODING} || 'UTF-8';
|
| 21 | 21 |
|
| 22 |
-our @COMMON_ARGS = qw/table query filter type id primary_key type_rule_off/; |
|
| 22 |
+our @COMMON_ARGS = qw/bind_type table query filter id primary_key |
|
| 23 |
+ type_rule_off type/; |
|
| 23 | 24 |
|
| 24 | 25 |
has [qw/connector dsn password user/], |
| 25 | 26 |
cache => 0, |
| ... | ... |
@@ -359,8 +360,8 @@ sub execute {
|
| 359 | 360 |
$tables = [$tables] unless ref $tables eq 'ARRAY'; |
| 360 | 361 |
my $filter = delete $args{filter};
|
| 361 | 362 |
$filter = _array_to_hash($filter); |
| 362 |
- my $type = delete $args{type};
|
|
| 363 |
- $type = _array_to_hash($type); |
|
| 363 |
+ my $bind_type = delete $args{bind_type} || delete $args{type};
|
|
| 364 |
+ $bind_type = _array_to_hash($bind_type); |
|
| 364 | 365 |
my $type_rule_off = delete $args{type_rule_off};
|
| 365 | 366 |
my $query_return = delete $args{query};
|
| 366 | 367 |
|
| ... | ... |
@@ -434,7 +435,7 @@ sub execute {
|
| 434 | 435 |
$query->columns, |
| 435 | 436 |
$filter, |
| 436 | 437 |
$type_filter, |
| 437 |
- $type |
|
| 438 |
+ $bind_type |
|
| 438 | 439 |
); |
| 439 | 440 |
|
| 440 | 441 |
# Execute |
| ... | ... |
@@ -442,8 +443,12 @@ sub execute {
|
| 442 | 443 |
my $affected; |
| 443 | 444 |
eval {
|
| 444 | 445 |
for (my $i = 0; $i < @$bind; $i++) {
|
| 445 |
- my $type = $bind->[$i]->{type};
|
|
| 446 |
- $sth->bind_param($i + 1, $bind->[$i]->{value}, $type ? $type : ());
|
|
| 446 |
+ my $bind_type = $bind->[$i]->{bind_type};
|
|
| 447 |
+ $sth->bind_param( |
|
| 448 |
+ $i + 1, |
|
| 449 |
+ $bind->[$i]->{value},
|
|
| 450 |
+ $bind_type ? $bind_type : () |
|
| 451 |
+ ); |
|
| 447 | 452 |
} |
| 448 | 453 |
$affected = $sth->execute; |
| 449 | 454 |
}; |
| ... | ... |
@@ -1173,7 +1178,7 @@ sub _apply_filter {
|
| 1173 | 1178 |
} |
| 1174 | 1179 |
|
| 1175 | 1180 |
sub _create_bind_values {
|
| 1176 |
- my ($self, $params, $columns, $filter, $type_filter, $type) = @_; |
|
| 1181 |
+ my ($self, $params, $columns, $filter, $type_filter, $bind_type) = @_; |
|
| 1177 | 1182 |
|
| 1178 | 1183 |
# Create bind values |
| 1179 | 1184 |
my $bind = []; |
| ... | ... |
@@ -1210,7 +1215,7 @@ sub _create_bind_values {
|
| 1210 | 1215 |
$value = $tf->($value) if $tf; |
| 1211 | 1216 |
|
| 1212 | 1217 |
# Bind values |
| 1213 |
- push @$bind, {value => $value, type => $type->{$column}};
|
|
| 1218 |
+ push @$bind, {value => $value, bind_type => $bind_type->{$column}};
|
|
| 1214 | 1219 |
|
| 1215 | 1220 |
# Count up |
| 1216 | 1221 |
$count->{$column}++;
|
| ... | ... |
@@ -1409,7 +1414,7 @@ sub _where_to_obj {
|
| 1409 | 1414 |
|
| 1410 | 1415 |
# Check where argument |
| 1411 | 1416 |
croak qq{"where" must be hash reference or DBIx::Custom::Where object}
|
| 1412 |
- . qq{or array reference, which contains where clause and paramter}
|
|
| 1417 |
+ . qq{or array reference, which contains where clause and parameter}
|
|
| 1413 | 1418 |
. _subname |
| 1414 | 1419 |
unless ref $obj eq 'DBIx::Custom::Where'; |
| 1415 | 1420 |
|
| ... | ... |
@@ -1862,7 +1867,9 @@ Query builder, default to L<DBIx::Custom::QueryBuilder> object. |
| 1862 | 1867 |
my reserved_word_quote = $dbi->reserved_word_quote; |
| 1863 | 1868 |
$dbi = $dbi->reserved_word_quote('"');
|
| 1864 | 1869 |
|
| 1865 |
-Reserved word quote, default to empty string. |
|
| 1870 |
+Reserved word quote. |
|
| 1871 |
+Default to double quote '"' except for mysql. |
|
| 1872 |
+In mysql, default to back quote '`' |
|
| 1866 | 1873 |
|
| 1867 | 1874 |
=head2 C<result_class> |
| 1868 | 1875 |
|
| ... | ... |
@@ -2081,7 +2088,7 @@ Specify database data type. |
| 2081 | 2088 |
type => [image => DBI::SQL_BLOB] |
| 2082 | 2089 |
type => [[qw/image audio/] => DBI::SQL_BLOB] |
| 2083 | 2090 |
|
| 2084 |
-This is used to bind paramter by C<bind_param()> of statment handle. |
|
| 2091 |
+This is used to bind parameter by C<bind_param()> of statment handle. |
|
| 2085 | 2092 |
|
| 2086 | 2093 |
$sth->bind_param($pos, $value, DBI::SQL_BLOB); |
| 2087 | 2094 |
|
| ... | ... |
@@ -2305,7 +2312,7 @@ See L<DBIx::Custom::Model> to know model features. |
| 2305 | 2312 |
|
| 2306 | 2313 |
my $param = $dbi->merge_param({key1 => 1}, {key1 => 1, key2 => 2});
|
| 2307 | 2314 |
|
| 2308 |
-Merge paramters. |
|
| 2315 |
+Merge parameters. |
|
| 2309 | 2316 |
|
| 2310 | 2317 |
$param: |
| 2311 | 2318 |
|
| ... | ... |
@@ -1,5 +1,4 @@ |
| 1 | 1 |
package DBIx::Custom::Model; |
| 2 |
- |
|
| 3 | 2 |
use Object::Simple -base; |
| 4 | 3 |
|
| 5 | 4 |
use Carp 'croak'; |
| ... | ... |
@@ -9,9 +8,9 @@ use DBIx::Custom::Util '_subname'; |
| 9 | 8 |
push @DBIx::Custom::CARP_NOT, __PACKAGE__; |
| 10 | 9 |
|
| 11 | 10 |
has [qw/dbi table/], |
| 11 |
+ bind_type => sub { [] },
|
|
| 12 | 12 |
columns => sub { [] },
|
| 13 | 13 |
join => sub { [] },
|
| 14 |
- type => sub { [] },
|
|
| 15 | 14 |
primary_key => sub { [] };
|
| 16 | 15 |
|
| 17 | 16 |
our $AUTOLOAD; |
| ... | ... |
@@ -48,8 +47,9 @@ foreach my $method (@methods) {
|
| 48 | 47 |
|
| 49 | 48 |
my @args = ( |
| 50 | 49 |
table => $self->table, |
| 51 |
- type => $self->type, |
|
| 52 |
- primary_key => $self->primary_key |
|
| 50 |
+ bind_type => $self->bind_type, |
|
| 51 |
+ primary_key => $self->primary_key, |
|
| 52 |
+ type => $self->type, # DEPRECATED! |
|
| 53 | 53 |
); |
| 54 | 54 |
push @args, (join => $self->join) if $method =~ /^select/; |
| 55 | 55 |
unshift @args, shift if @_ % 2; |
| ... | ... |
@@ -101,6 +101,7 @@ sub new {
|
| 101 | 101 |
# DEPRECATED! |
| 102 | 102 |
has filter => sub { [] };
|
| 103 | 103 |
has 'name'; |
| 104 |
+has type => sub { [] };
|
|
| 104 | 105 |
|
| 105 | 106 |
1; |
| 106 | 107 |
|
| ... | ... |
@@ -119,43 +120,42 @@ my $table = DBIx::Custom::Model->new(table => 'books'); |
| 119 | 120 |
=head2 C<dbi> |
| 120 | 121 |
|
| 121 | 122 |
my $dbi = $model->dbi; |
| 122 |
- $model = $model->dbi($dbi); |
|
| 123 |
+ $model = $model->dbi($dbi); |
|
| 123 | 124 |
|
| 124 | 125 |
L<DBIx::Custom> object. |
| 125 | 126 |
|
| 126 | 127 |
=head2 C<join> |
| 127 | 128 |
|
| 128 | 129 |
my $join = $model->join; |
| 129 |
- $model = $model->join( |
|
| 130 |
+ $model = $model->join( |
|
| 130 | 131 |
['left outer join company on book.company_id = company.id'] |
| 131 | 132 |
); |
| 132 | 133 |
|
| 133 |
-Join clause, this is used as C<select()>'s C<join> option. |
|
| 134 |
+Join clause, this value is passed to C<select> method. |
|
| 134 | 135 |
|
| 135 | 136 |
=head2 C<primary_key> |
| 136 | 137 |
|
| 137 | 138 |
my $primary_key = $model->primary_key; |
| 138 |
- $model = $model->primary_key(['id', 'number']); |
|
| 139 |
+ $model = $model->primary_key(['id', 'number']); |
|
| 139 | 140 |
|
| 140 |
-Foreign key, this is used as C<primary_key> of C<insert_at>,C<update_at()>, |
|
| 141 |
-C<delete_at()>,C<select_at()>. |
|
| 141 |
+Primary key,this is passed to C<insert>, C<update>, |
|
| 142 |
+C<delete>, and C<select> method. |
|
| 142 | 143 |
|
| 143 | 144 |
=head2 C<table> |
| 144 | 145 |
|
| 145 | 146 |
my $table = $model->table; |
| 146 |
- $model = $model->table('book');
|
|
| 147 |
+ $model = $model->table('book');
|
|
| 147 | 148 |
|
| 148 |
-Table name, this is used as C<select()> C<table> option. |
|
| 149 |
-Generally, this is automatically set from class name. |
|
| 149 |
+Table name, this is passed to C<select> method. |
|
| 150 | 150 |
|
| 151 |
-=head2 C<type> |
|
| 151 |
+=head2 C<bind_type> |
|
| 152 | 152 |
|
| 153 |
- my $type = $model->type; |
|
| 154 |
- $model = $model->type(['image' => DBI::SQL_BLOB]); |
|
| 153 |
+ my $type = $model->bind_type; |
|
| 154 |
+ $model = $model->bind_type(['image' => DBI::SQL_BLOB]); |
|
| 155 | 155 |
|
| 156 |
-Database data type, this is used as type optioon of C<insert()>, C<insert_at()>, |
|
| 157 |
-C<update()>, C<update_at()>, C<update_all>, C<delete()>, C<delete_all()>, |
|
| 158 |
-C<select()>, C<select_at()> |
|
| 156 |
+Database data type, this is used as type optioon of C<insert>, |
|
| 157 |
+C<update>, C<update_all>, C<delete>, C<delete_all>, |
|
| 158 |
+C<select>, and C<execute> method |
|
| 159 | 159 |
|
| 160 | 160 |
=head1 METHODS |
| 161 | 161 |
|
| ... | ... |
@@ -167,21 +167,21 @@ and implements the following new ones. |
| 167 | 167 |
|
| 168 | 168 |
$table->delete(...); |
| 169 | 169 |
|
| 170 |
-Same as C<delete()> of L<DBIx::Custom> except that |
|
| 170 |
+Same as C<delete> of L<DBIx::Custom> except that |
|
| 171 | 171 |
you don't have to specify C<table> option. |
| 172 | 172 |
|
| 173 | 173 |
=head2 C<delete_all> |
| 174 | 174 |
|
| 175 | 175 |
$table->delete_all(...); |
| 176 | 176 |
|
| 177 |
-Same as C<delete_all()> of L<DBIx::Custom> except that |
|
| 177 |
+Same as C<delete_all> of L<DBIx::Custom> except that |
|
| 178 | 178 |
you don't have to specify C<table> option. |
| 179 | 179 |
|
| 180 | 180 |
=head2 C<insert> |
| 181 | 181 |
|
| 182 | 182 |
$table->insert(...); |
| 183 | 183 |
|
| 184 |
-Same as C<insert()> of L<DBIx::Custom> except that |
|
| 184 |
+Same as C<insert> of L<DBIx::Custom> except that |
|
| 185 | 185 |
you don't have to specify C<table> option. |
| 186 | 186 |
|
| 187 | 187 |
=head2 C<method> |
| ... | ... |
@@ -227,21 +227,21 @@ Create a L<DBIx::Custom::Table> object. |
| 227 | 227 |
|
| 228 | 228 |
$table->select(...); |
| 229 | 229 |
|
| 230 |
-Same as C<select()> of L<DBIx::Custom> except that |
|
| 230 |
+Same as C<select> of L<DBIx::Custom> except that |
|
| 231 | 231 |
you don't have to specify C<table> option. |
| 232 | 232 |
|
| 233 | 233 |
=head2 C<update> |
| 234 | 234 |
|
| 235 | 235 |
$table->update(...); |
| 236 | 236 |
|
| 237 |
-Same as C<update()> of L<DBIx::Custom> except that |
|
| 237 |
+Same as C<update> of L<DBIx::Custom> except that |
|
| 238 | 238 |
you don't have to specify C<table> option. |
| 239 | 239 |
|
| 240 | 240 |
=head2 C<update_all> |
| 241 | 241 |
|
| 242 | 242 |
$table->update_all(param => \%param); |
| 243 | 243 |
|
| 244 |
-Same as C<update_all()> of L<DBIx::Custom> except that |
|
| 244 |
+Same as C<update_all> of L<DBIx::Custom> except that |
|
| 245 | 245 |
you don't have to specify table name. |
| 246 | 246 |
|
| 247 | 247 |
=cut |
| ... | ... |
@@ -1,13 +1,11 @@ |
| 1 | 1 |
package DBIx::Custom::Where; |
| 2 |
- |
|
| 3 | 2 |
use Object::Simple -base; |
| 4 | 3 |
|
| 4 |
+use Carp 'croak'; |
|
| 5 |
+use DBIx::Custom::Util '_subname'; |
|
| 5 | 6 |
use overload 'bool' => sub {1}, fallback => 1;
|
| 6 | 7 |
use overload '""' => sub { shift->to_string }, fallback => 1;
|
| 7 | 8 |
|
| 8 |
-use DBIx::Custom::Util '_subname'; |
|
| 9 |
-use Carp 'croak'; |
|
| 10 |
- |
|
| 11 | 9 |
# Carp trust relationship |
| 12 | 10 |
push @DBIx::Custom::CARP_NOT, __PACKAGE__; |
| 13 | 11 |
|
| ... | ... |
@@ -102,12 +100,14 @@ sub _parse {
|
| 102 | 100 |
croak qq{Each part contains one column name: "$clause" (}
|
| 103 | 101 |
. _subname . ")"; |
| 104 | 102 |
} |
| 105 |
- |
|
| 103 |
+ |
|
| 104 |
+ # Remove quote |
|
| 106 | 105 |
my $column = $columns->[0]; |
| 107 | 106 |
if (my $q = $self->reserved_word_quote) {
|
| 108 | 107 |
$column =~ s/$q//g; |
| 109 | 108 |
} |
| 110 | 109 |
|
| 110 |
+ # Check safety |
|
| 111 | 111 |
my $safety = $self->safety_character; |
| 112 | 112 |
croak qq{"$column" is not safety column name (} . _subname . ")"
|
| 113 | 113 |
unless $column =~ /^[$safety\.]+$/; |
| ... | ... |
@@ -151,38 +151,51 @@ DBIx::Custom::Where - Where clause |
| 151 | 151 |
=head1 SYNOPSYS |
| 152 | 152 |
|
| 153 | 153 |
my $where = DBIx::Custom::Where->new; |
| 154 |
+ my $string_where = "$where"; |
|
| 154 | 155 |
|
| 155 | 156 |
=head1 ATTRIBUTES |
| 156 | 157 |
|
| 157 | 158 |
=head2 C<clause> |
| 158 | 159 |
|
| 159 |
- $where->clause( |
|
| 160 |
- ['and', '{= title}', ['or', '{< date}', '{> date}']]
|
|
| 160 |
+ my $clause = $where->clause; |
|
| 161 |
+ $where = $where->clause( |
|
| 162 |
+ ['and', |
|
| 163 |
+ 'title = :title', |
|
| 164 |
+ ['or', 'date < :date', 'date > :date'] |
|
| 165 |
+ ] |
|
| 161 | 166 |
); |
| 162 | 167 |
|
| 163 | 168 |
Where clause. Above one is expanded to the following SQL by to_string |
| 164 | 169 |
If all parameter names is exists. |
| 165 | 170 |
|
| 166 |
- "where ( {= title} and ( {< date} or {> date} ) )"
|
|
| 171 |
+ "where ( title = :title and ( date < :date or date > :date ) )" |
|
| 167 | 172 |
|
| 168 | 173 |
=head2 C<param> |
| 169 | 174 |
|
| 170 | 175 |
my $param = $where->param; |
| 171 |
- $where = $where->param({title => 'Perl',
|
|
| 172 |
- date => ['2010-11-11', '2011-03-05']}, |
|
| 173 |
- name => ['Ken', 'Taro']); |
|
| 176 |
+ $where = $where->param({
|
|
| 177 |
+ title => 'Perl', |
|
| 178 |
+ date => ['2010-11-11', '2011-03-05'], |
|
| 179 |
+ }); |
|
| 174 | 180 |
|
| 175 | 181 |
=head2 C<safety_character> |
| 176 | 182 |
|
| 177 | 183 |
my $safety_character = $self->safety_character; |
| 178 |
- $dbi = $self->safety_character($name); |
|
| 184 |
+ $where = $self->safety_character("\w");
|
|
| 179 | 185 |
|
| 180 | 186 |
=head1 METHODS |
| 181 | 187 |
|
| 188 |
+L<DBIx::Custom::Where> inherits all methods from L<Object::Simple> |
|
| 189 |
+and implements the following new ones. |
|
| 190 |
+ |
|
| 182 | 191 |
=head2 C<to_string> |
| 183 | 192 |
|
| 184 | 193 |
$where->to_string; |
| 185 | 194 |
|
| 186 |
-Convert where clause to string correspoinding to param name. |
|
| 195 |
+Convert where clause to string. |
|
| 196 |
+ |
|
| 197 |
+double quote is override to execute C<to_string> method. |
|
| 198 |
+ |
|
| 199 |
+ my $string_where = "$where"; |
|
| 187 | 200 |
|
| 188 | 201 |
=cut |
| ... | ... |
@@ -2207,7 +2207,7 @@ $result = $model->select( |
| 2207 | 2207 |
is_deeply($result->one, |
| 2208 | 2208 |
{'table2_alias-key1' => 1, 'table2_alias-key3' => 4});
|
| 2209 | 2209 |
|
| 2210 |
-test 'type() option'; |
|
| 2210 |
+test 'type option'; # DEPRECATED! |
|
| 2211 | 2211 |
$dbi = DBIx::Custom->connect( |
| 2212 | 2212 |
data_source => 'dbi:SQLite:dbname=:memory:', |
| 2213 | 2213 |
dbi_option => {
|
| ... | ... |
@@ -2232,6 +2232,50 @@ $result = $dbi->execute('select length(key1) as key1_length from table1');
|
| 2232 | 2232 |
$row = $result->one; |
| 2233 | 2233 |
is($row->{key1_length}, length $binary);
|
| 2234 | 2234 |
|
| 2235 |
+ |
|
| 2236 |
+test 'bind_type option'; |
|
| 2237 |
+$dbi = DBIx::Custom->connect( |
|
| 2238 |
+ data_source => 'dbi:SQLite:dbname=:memory:', |
|
| 2239 |
+ dbi_option => {
|
|
| 2240 |
+ $DBD::SQLite::VERSION > 1.26 ? (sqlite_unicode => 1) : (unicode => 1) |
|
| 2241 |
+ } |
|
| 2242 |
+); |
|
| 2243 |
+$binary = pack("I3", 1, 2, 3);
|
|
| 2244 |
+$dbi->execute('create table table1(key1, key2)');
|
|
| 2245 |
+$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, bind_type => [key1 => DBI::SQL_BLOB]);
|
|
| 2246 |
+$result = $dbi->select(table => 'table1'); |
|
| 2247 |
+$row = $result->one; |
|
| 2248 |
+is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
|
|
| 2249 |
+$result = $dbi->execute('select length(key1) as key1_length from table1');
|
|
| 2250 |
+$row = $result->one; |
|
| 2251 |
+is($row->{key1_length}, length $binary);
|
|
| 2252 |
+ |
|
| 2253 |
+$dbi->insert(table => 'table1', param => {key1 => $binary, key2 => 'あ'}, bind_type => [['key1'] => DBI::SQL_BLOB]);
|
|
| 2254 |
+$result = $dbi->select(table => 'table1'); |
|
| 2255 |
+$row = $result->one; |
|
| 2256 |
+is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
|
|
| 2257 |
+$result = $dbi->execute('select length(key1) as key1_length from table1');
|
|
| 2258 |
+$row = $result->one; |
|
| 2259 |
+is($row->{key1_length}, length $binary);
|
|
| 2260 |
+ |
|
| 2261 |
+test 'model type attribute'; |
|
| 2262 |
+$dbi = DBIx::Custom->connect( |
|
| 2263 |
+ data_source => 'dbi:SQLite:dbname=:memory:', |
|
| 2264 |
+ dbi_option => {
|
|
| 2265 |
+ $DBD::SQLite::VERSION > 1.26 ? (sqlite_unicode => 1) : (unicode => 1) |
|
| 2266 |
+ } |
|
| 2267 |
+); |
|
| 2268 |
+$binary = pack("I3", 1, 2, 3);
|
|
| 2269 |
+$dbi->execute('create table table1(key1, key2)');
|
|
| 2270 |
+$model = $dbi->create_model(table => 'table1', bind_type => [key1 => DBI::SQL_BLOB]); |
|
| 2271 |
+$model->insert(param => {key1 => $binary, key2 => 'あ'});
|
|
| 2272 |
+$result = $dbi->select(table => 'table1'); |
|
| 2273 |
+$row = $result->one; |
|
| 2274 |
+is_deeply($row, {key1 => $binary, key2 => 'あ'}, "basic");
|
|
| 2275 |
+$result = $dbi->execute('select length(key1) as key1_length from table1');
|
|
| 2276 |
+$row = $result->one; |
|
| 2277 |
+is($row->{key1_length}, length $binary);
|
|
| 2278 |
+ |
|
| 2235 | 2279 |
test 'create_model'; |
| 2236 | 2280 |
$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
|
| 2237 | 2281 |
$dbi->execute($CREATE_TABLE->{0});
|