... | ... |
@@ -1,4 +1,8 @@ |
1 | 1 |
0.1692 |
2 |
+ - separate DBIx::Custom type_rule from filter |
|
3 |
+ - DBIx::Custom Model filter attrribute is DEPRECATED! |
|
4 |
+ - removed EXPERIMENTAL DBIx::Custom::Model alias_table |
|
5 |
+ - added DBIx::Custom column method's table option |
|
2 | 6 |
- separate DBIx::Custom::Result type_rule from filter again |
3 | 7 |
0.1692 |
4 | 8 |
- removed EXPERIMENTAL DBIx::Model result_filter |
... | ... |
@@ -99,7 +99,16 @@ sub assign_param { |
99 | 99 |
} |
100 | 100 |
|
101 | 101 |
sub column { |
102 |
- my ($self, $table, $columns) = @_; |
|
102 |
+ my $self = shift; |
|
103 |
+ my $option = pop if ref $_[-1] eq 'HASH'; |
|
104 |
+ my $real_table = shift; |
|
105 |
+ my $columns = shift; |
|
106 |
+ my $table = $option->{alias} || $real_table; |
|
107 |
+ |
|
108 |
+ # Columns |
|
109 |
+ unless ($columns) { |
|
110 |
+ $columns ||= $self->model($real_table)->columns; |
|
111 |
+ } |
|
103 | 112 |
|
104 | 113 |
# Reserved word quote |
105 | 114 |
my $q = $self->reserved_word_quote; |
... | ... |
@@ -305,17 +314,10 @@ sub create_model { |
305 | 314 |
my $filter = ref $model->filter eq 'HASH' |
306 | 315 |
? [%{$model->filter}] |
307 | 316 |
: $model->filter; |
317 |
+ warn "DBIx::Custom::Model filter method is DEPRECATED!" |
|
318 |
+ if @$filter; |
|
308 | 319 |
$self->_apply_filter($model->table, @$filter); |
309 |
- |
|
310 |
- # Associate table with model |
|
311 |
- croak "Table name is duplicated " . _subname |
|
312 |
- if exists $self->{_model_from}->{$model->table}; |
|
313 |
- $self->{_model_from}->{$model->table} = $model->name; |
|
314 | 320 |
|
315 |
- # Table alias |
|
316 |
- $self->{_table_alias} ||= {}; |
|
317 |
- $self->{_table_alias} = {%{$self->{_table_alias}}, %{$model->table_alias}}; |
|
318 |
- |
|
319 | 321 |
# Set model |
320 | 322 |
$self->model($model->name, $model); |
321 | 323 |
|
... | ... |
@@ -381,33 +383,6 @@ sub execute { |
381 | 383 |
$_ =~ s/$q//g for @$tables; |
382 | 384 |
} |
383 | 385 |
|
384 |
- # Table alias |
|
385 |
- foreach my $table (@$tables) { |
|
386 |
- |
|
387 |
- # No need |
|
388 |
- next unless my $alias = $self->{_table_alias}->{$table}; |
|
389 |
- $self->{filter} ||= {}; |
|
390 |
- next if $self->{filter}{out}{$table}; |
|
391 |
- |
|
392 |
- # Filter |
|
393 |
- $self->{filter}{out} ||= {}; |
|
394 |
- $self->{filter}{in} ||= {}; |
|
395 |
- $self->{filter}{end} ||= {}; |
|
396 |
- |
|
397 |
- # Create alias filter |
|
398 |
- foreach my $type (qw/out in end/) { |
|
399 |
- my @filter_names = keys %{$self->{filter}{$type}{$alias} || {}}; |
|
400 |
- foreach my $filter_name (@filter_names) { |
|
401 |
- my $filter_name_alias = $filter_name; |
|
402 |
- $filter_name_alias =~ s/^$alias\./$table\./; |
|
403 |
- $filter_name_alias =~ s/^${alias}__/${table}__/; |
|
404 |
- $filter_name_alias =~ s/^${alias}-/${table}-/; |
|
405 |
- $self->{filter}{$type}{$table}{$filter_name_alias} |
|
406 |
- = $self->{filter}{$type}{$alias}{$filter_name} |
|
407 |
- } |
|
408 |
- } |
|
409 |
- } |
|
410 |
- |
|
411 | 386 |
# Type rule |
412 | 387 |
my $applied_filter = {}; |
413 | 388 |
unless ($type_rule_off) { |
... | ... |
@@ -981,7 +956,7 @@ sub type_rule { |
981 | 956 |
# Into |
982 | 957 |
$type_rule->{into} = _array_to_hash($type_rule->{into}); |
983 | 958 |
$self->{type_rule} = $type_rule; |
984 |
- $self->{_into} ||= {}; |
|
959 |
+ $self->{_into} = {}; |
|
985 | 960 |
foreach my $type_name (keys %{$type_rule->{into} || {}}) { |
986 | 961 |
croak qq{type name of into section must be lower case} |
987 | 962 |
if $type_name =~ /[A-Z]/; |
... | ... |
@@ -9,9 +9,7 @@ use DBIx::Custom::Util '_subname'; |
9 | 9 |
push @DBIx::Custom::CARP_NOT, __PACKAGE__; |
10 | 10 |
|
11 | 11 |
has [qw/dbi name table view/], |
12 |
- table_alias => sub { {} }, |
|
13 | 12 |
columns => sub { [] }, |
14 |
- filter => sub { [] }, |
|
15 | 13 |
join => sub { [] }, |
16 | 14 |
type => sub { [] }, |
17 | 15 |
primary_key => sub { [] }; |
... | ... |
@@ -64,23 +62,6 @@ foreach my $method (@methods) { |
64 | 62 |
*{"${class}::$method"} = $code; |
65 | 63 |
} |
66 | 64 |
|
67 |
-sub column { |
|
68 |
- my ($self, $table, $columns) = @_; |
|
69 |
- |
|
70 |
- $self->{_table_alias} ||= {}; |
|
71 |
- my $dist; |
|
72 |
- $dist = $self->dbi->{_table_alias}{$table} |
|
73 |
- ? $self->dbi->{_table_alias}{$table} |
|
74 |
- : $table; |
|
75 |
- |
|
76 |
- $self->dbi->{_model_from} ||= {}; |
|
77 |
- my $model = $self->dbi->{_model_from}->{$dist}; |
|
78 |
- |
|
79 |
- $columns ||= $self->model($model)->columns; |
|
80 |
- |
|
81 |
- return $self->dbi->column($table, $columns); |
|
82 |
-} |
|
83 |
- |
|
84 | 65 |
sub DESTROY { } |
85 | 66 |
|
86 | 67 |
sub method { |
... | ... |
@@ -117,6 +98,9 @@ sub new { |
117 | 98 |
return $self; |
118 | 99 |
} |
119 | 100 |
|
101 |
+# DEPRECATED! |
|
102 |
+has filter => sub { [] }; |
|
103 |
+ |
|
120 | 104 |
1; |
121 | 105 |
|
122 | 106 |
=head1 NAME |
... | ... |
@@ -138,16 +122,6 @@ my $table = DBIx::Custom::Model->new(table => 'books'); |
138 | 122 |
|
139 | 123 |
L<DBIx::Custom> object. |
140 | 124 |
|
141 |
-=head2 C<filter> |
|
142 |
- |
|
143 |
- my $dbi = $model->filter |
|
144 |
- $model = $model->filter( |
|
145 |
- title => {out => 'tp_to_date', in => 'date_to_tp'} |
|
146 |
- author => {out => ..., in => ...}, |
|
147 |
- ); |
|
148 |
- |
|
149 |
-This filter is applied when L<DBIx::Custom>'s C<include_model()> is called. |
|
150 |
- |
|
151 | 125 |
=head2 C<name> |
152 | 126 |
|
153 | 127 |
my $name = $model->name; |
... | ... |
@@ -180,15 +154,6 @@ C<delete_at()>,C<select_at()>. |
180 | 154 |
Table name, this is used as C<select()> C<table> option. |
181 | 155 |
Generally, this is automatically set from class name. |
182 | 156 |
|
183 |
-=head2 C<table_alias> EXPERIMENTAL |
|
184 |
- |
|
185 |
- my $table_alias = $model->table_alias; |
|
186 |
- $model = $model->table_alias(user1 => 'user', user2 => 'user'); |
|
187 |
- |
|
188 |
-Table alias. If you define table alias, |
|
189 |
-same filter as the table is avaliable |
|
190 |
-, and can write $dbi->column('user1') to get all columns. |
|
191 |
- |
|
192 | 157 |
=head2 C<type> |
193 | 158 |
|
194 | 159 |
my $type = $model->type; |
... | ... |
@@ -208,22 +173,10 @@ model is included by C<include_model>. |
208 | 173 |
|
209 | 174 |
=head1 METHODS |
210 | 175 |
|
211 |
-L<DBIx::Custom> inherits all methods from L<Object::Simple>, |
|
212 |
-and you can use all methods of the object set to C<dbi>. |
|
176 |
+L<DBIx::Custom::Model> inherits all methods from L<Object::Simple>, |
|
177 |
+and you can use all methods of L<DBIx::Custom> and L<DBI> |
|
213 | 178 |
and implements the following new ones. |
214 | 179 |
|
215 |
-=head2 C<column> EXPERIMETNAL |
|
216 |
- |
|
217 |
- my $column = $model->column(book => ['author', 'title']); |
|
218 |
- my $column = $model->column('book'); |
|
219 |
- |
|
220 |
-Create column clause. The follwoing column clause is created. |
|
221 |
- |
|
222 |
- book.author as "book.author", |
|
223 |
- book.title as "book.title" |
|
224 |
- |
|
225 |
-If Second argument is ommited, all columns set by C<columns> is used. |
|
226 |
- |
|
227 | 180 |
=head2 C<delete> |
228 | 181 |
|
229 | 182 |
$table->delete(...); |
... | ... |
@@ -107,183 +107,137 @@ sub register_tag { |
107 | 107 |
# DEPRECATED! |
108 | 108 |
sub _parse_tag { |
109 | 109 |
my ($self, $source) = @_; |
110 |
- |
|
111 | 110 |
# Source |
112 | 111 |
$source ||= ''; |
113 |
- |
|
114 | 112 |
# Tree |
115 | 113 |
my @tree; |
116 |
- |
|
117 | 114 |
# Value |
118 | 115 |
my $value = ''; |
119 |
- |
|
120 | 116 |
# State |
121 | 117 |
my $state = 'text'; |
122 |
- |
|
123 | 118 |
# Before charactor |
124 | 119 |
my $before = ''; |
125 |
- |
|
126 | 120 |
# Position |
127 | 121 |
my $pos = 0; |
128 |
- |
|
129 | 122 |
# Parse |
130 | 123 |
my $original = $source; |
131 | 124 |
my $tag_count = 0; |
132 | 125 |
while (defined(my $c = substr($source, $pos, 1))) { |
133 |
- |
|
134 | 126 |
# Last |
135 | 127 |
last unless length $c; |
136 |
- |
|
137 | 128 |
# Parameter |
138 | 129 |
if ($c eq ':' && (substr($source, $pos + 1, 1) || '') =~ /\w/) { |
139 | 130 |
push @tree, {type => 'param'};; |
140 | 131 |
} |
141 |
- |
|
142 | 132 |
# State is text |
143 | 133 |
if ($state eq 'text') { |
144 |
- |
|
145 | 134 |
# Tag start charactor |
146 | 135 |
if ($c eq '{') { |
147 |
- |
|
148 | 136 |
# Escaped charactor |
149 | 137 |
if ($before eq "\\") { |
150 | 138 |
substr($value, -1, 1, ''); |
151 | 139 |
$value .= $c; |
152 | 140 |
} |
153 |
- |
|
154 | 141 |
# Tag start |
155 | 142 |
else { |
156 |
- |
|
157 | 143 |
# Change state |
158 | 144 |
$state = 'tag'; |
159 |
- |
|
160 | 145 |
# Add text |
161 | 146 |
push @tree, {type => 'text', value => $value} |
162 | 147 |
if $value; |
163 |
- |
|
164 | 148 |
# Clear |
165 | 149 |
$value = ''; |
166 | 150 |
} |
167 | 151 |
} |
168 |
- |
|
169 | 152 |
# Tag end charactor |
170 | 153 |
elsif ($c eq '}') { |
171 |
- |
|
172 | 154 |
# Escaped charactor |
173 | 155 |
if ($before eq "\\") { |
174 | 156 |
substr($value, -1, 1, ''); |
175 | 157 |
$value .= $c; |
176 | 158 |
} |
177 |
- |
|
178 | 159 |
# Unexpected |
179 | 160 |
else { |
180 | 161 |
croak qq{Parsing error. unexpected "\}". } |
181 | 162 |
. qq{pos $pos of "$original" } . _subname |
182 | 163 |
} |
183 | 164 |
} |
184 |
- |
|
185 | 165 |
# Normal charactor |
186 | 166 |
else { $value .= $c } |
187 | 167 |
} |
188 |
- |
|
189 | 168 |
# State is tags |
190 | 169 |
else { |
191 |
- |
|
192 | 170 |
# Tag start charactor |
193 | 171 |
if ($c eq '{') { |
194 |
- |
|
195 | 172 |
# Escaped charactor |
196 | 173 |
if ($before eq "\\") { |
197 | 174 |
substr($value, -1, 1, ''); |
198 | 175 |
$value .= $c; |
199 | 176 |
} |
200 |
- |
|
201 | 177 |
# Unexpected |
202 | 178 |
else { |
203 | 179 |
croak qq{Parsing error. unexpected "\{". } |
204 | 180 |
. qq{pos $pos of "$original" } . _subname |
205 | 181 |
} |
206 | 182 |
} |
207 |
- |
|
208 | 183 |
# Tag end charactor |
209 | 184 |
elsif ($c eq '}') { |
210 |
- |
|
211 | 185 |
# Escaped charactor |
212 | 186 |
if ($before eq "\\") { |
213 | 187 |
substr($value, -1, 1, ''); |
214 | 188 |
$value .= $c; |
215 | 189 |
} |
216 |
- |
|
217 | 190 |
# Tag end |
218 | 191 |
else { |
219 |
- |
|
220 | 192 |
# Change state |
221 | 193 |
$state = 'text'; |
222 |
- |
|
223 | 194 |
# Add tag |
224 | 195 |
my ($tag_name, @tag_args) = split /\s+/, $value; |
225 | 196 |
push @tree, {type => 'tag', tag_name => $tag_name, |
226 | 197 |
tag_args => \@tag_args}; |
227 |
- |
|
228 | 198 |
# Clear |
229 | 199 |
$value = ''; |
230 |
- |
|
231 | 200 |
# Countup |
232 | 201 |
$tag_count++; |
233 | 202 |
} |
234 | 203 |
} |
235 |
- |
|
236 | 204 |
# Normal charactor |
237 | 205 |
else { $value .= $c } |
238 | 206 |
} |
239 |
- |
|
240 | 207 |
# Save before charactor |
241 | 208 |
$before = $c; |
242 |
- |
|
243 | 209 |
# increment position |
244 | 210 |
$pos++; |
245 | 211 |
} |
246 |
- |
|
247 | 212 |
# Tag not finished |
248 | 213 |
croak qq{Tag not finished. "$original" } . _subname |
249 | 214 |
if $state eq 'tag'; |
250 |
- |
|
251 | 215 |
# Not contains tag |
252 | 216 |
return DBIx::Custom::Query->new(sql => $source, tag_count => $tag_count) |
253 | 217 |
if $tag_count == 0; |
254 |
- |
|
255 | 218 |
# Add rest text |
256 | 219 |
push @tree, {type => 'text', value => $value} |
257 | 220 |
if $value; |
258 |
- |
|
259 | 221 |
# SQL |
260 | 222 |
my $sql = ''; |
261 |
- |
|
262 | 223 |
# All Columns |
263 | 224 |
my $all_columns = []; |
264 |
- |
|
265 | 225 |
# Tables |
266 | 226 |
my $tables = []; |
267 |
- |
|
268 | 227 |
# Build SQL |
269 | 228 |
foreach my $node (@tree) { |
270 |
- |
|
271 | 229 |
# Text |
272 | 230 |
if ($node->{type} eq 'text') { $sql .= $node->{value} } |
273 |
- |
|
274 | 231 |
# Parameter |
275 | 232 |
elsif ($node->{type} eq 'param') { |
276 | 233 |
push @$all_columns, 'RESERVED_PARAMETER'; |
277 | 234 |
} |
278 | 235 |
# Tag |
279 | 236 |
else { |
280 |
- |
|
281 | 237 |
# Tag name |
282 | 238 |
my $tag_name = $node->{tag_name}; |
283 |
- |
|
284 | 239 |
# Tag arguments |
285 | 240 |
my $tag_args = $node->{tag_args}; |
286 |
- |
|
287 | 241 |
# Table |
288 | 242 |
if ($tag_name eq 'table') { |
289 | 243 |
my $table = $tag_args->[0]; |
... | ... |
@@ -291,38 +245,29 @@ sub _parse_tag { |
291 | 245 |
$sql .= $table; |
292 | 246 |
next; |
293 | 247 |
} |
294 |
- |
|
295 | 248 |
# Get tag |
296 | 249 |
my $tag = $self->tag_processors->{$tag_name} |
297 | 250 |
|| $self->tags->{$tag_name}; |
298 |
- |
|
299 | 251 |
# Tag is not registered |
300 | 252 |
croak qq{Tag "$tag_name" is not registered } . _subname |
301 | 253 |
unless $tag; |
302 |
- |
|
303 | 254 |
# Tag not sub reference |
304 | 255 |
croak qq{Tag "$tag_name" must be sub reference } . _subname |
305 | 256 |
unless ref $tag eq 'CODE'; |
306 |
- |
|
307 | 257 |
# Execute tag |
308 | 258 |
my $r = $tag->(@$tag_args); |
309 |
- |
|
310 | 259 |
# Check tag return value |
311 | 260 |
croak qq{Tag "$tag_name" must return [STRING, ARRAY_REFERENCE] } |
312 | 261 |
. _subname |
313 | 262 |
unless ref $r eq 'ARRAY' && defined $r->[0] && ref $r->[1] eq 'ARRAY'; |
314 |
- |
|
315 | 263 |
# Part of SQL statement and colum names |
316 | 264 |
my ($part, $columns) = @$r; |
317 |
- |
|
318 | 265 |
# Add columns |
319 | 266 |
push @$all_columns, @$columns; |
320 |
- |
|
321 | 267 |
# Join part tag to SQL |
322 | 268 |
$sql .= $part; |
323 | 269 |
} |
324 | 270 |
} |
325 |
- |
|
326 | 271 |
# Query |
327 | 272 |
my $query = DBIx::Custom::Query->new( |
328 | 273 |
sql => $sql, |
... | ... |
@@ -330,7 +275,6 @@ sub _parse_tag { |
330 | 275 |
tables => $tables, |
331 | 276 |
tag_count => $tag_count |
332 | 277 |
); |
333 |
- |
|
334 | 278 |
return $query; |
335 | 279 |
} |
336 | 280 |
|
... | ... |
@@ -340,13 +284,10 @@ has tag_processors => sub { {} }; |
340 | 284 |
# DEPRECATED! |
341 | 285 |
sub register_tag_processor { |
342 | 286 |
my $self = shift; |
343 |
- |
|
344 | 287 |
warn "register_tag_processor is DEPRECATED! use register_tag instead"; |
345 |
- |
|
346 | 288 |
# Merge tag |
347 | 289 |
my $tag_processors = ref $_[0] eq 'HASH' ? $_[0] : {@_}; |
348 | 290 |
$self->tag_processors({%{$self->tag_processors}, %{$tag_processors}}); |
349 |
- |
|
350 | 291 |
return $self; |
351 | 292 |
} |
352 | 293 |
|
... | ... |
@@ -423,6 +423,7 @@ Fetch multiple rows and put them into array of array reference. |
423 | 423 |
|
424 | 424 |
Set filter for column. |
425 | 425 |
You can use subroutine or filter name as filter. |
426 |
+This filter is executed after C<type_rule> filter. |
|
426 | 427 |
|
427 | 428 |
=head2 C<one> |
428 | 429 |
|
... | ... |
@@ -2170,7 +2170,7 @@ $model = $dbi->model('table1'); |
2170 | 2170 |
eval{$model->execute('select * from table1')}; |
2171 | 2171 |
ok(!$@); |
2172 | 2172 |
|
2173 |
-test 'table_alias'; |
|
2173 |
+test 'column table option'; |
|
2174 | 2174 |
$dbi = MyDBI9->connect($NEW_ARGS->{0}); |
2175 | 2175 |
$dbi->execute($CREATE_TABLE->{0}); |
2176 | 2176 |
$dbi->execute($CREATE_TABLE->{2}); |
... | ... |
@@ -2180,32 +2180,32 @@ $dbi->execute('insert into table2 (key1, key3) values (1, 4);'); |
2180 | 2180 |
$model = $dbi->model('table1'); |
2181 | 2181 |
$result = $model->select( |
2182 | 2182 |
column => [ |
2183 |
- $model->column('table2_alias') |
|
2183 |
+ $model->column('table2', {alias => 'table2_alias'}) |
|
2184 | 2184 |
], |
2185 |
- where => {'table2_alias.key3' => 2} |
|
2185 |
+ where => {'table2_alias.key3' => 4} |
|
2186 | 2186 |
); |
2187 | 2187 |
is_deeply($result->one, |
2188 |
- {'table2_alias.key1' => 1, 'table2_alias.key3' => 48}); |
|
2188 |
+ {'table2_alias.key1' => 1, 'table2_alias.key3' => 4}); |
|
2189 | 2189 |
|
2190 | 2190 |
$dbi->separator('__'); |
2191 | 2191 |
$result = $model->select( |
2192 | 2192 |
column => [ |
2193 |
- $model->column('table2_alias') |
|
2193 |
+ $model->column('table2', {alias => 'table2_alias'}) |
|
2194 | 2194 |
], |
2195 |
- where => {'table2_alias.key3' => 2} |
|
2195 |
+ where => {'table2_alias.key3' => 4} |
|
2196 | 2196 |
); |
2197 | 2197 |
is_deeply($result->one, |
2198 |
- {'table2_alias__key1' => 1, 'table2_alias__key3' => 48}); |
|
2198 |
+ {'table2_alias__key1' => 1, 'table2_alias__key3' => 4}); |
|
2199 | 2199 |
|
2200 | 2200 |
$dbi->separator('-'); |
2201 | 2201 |
$result = $model->select( |
2202 | 2202 |
column => [ |
2203 |
- $model->column('table2_alias') |
|
2203 |
+ $model->column('table2', {alias => 'table2_alias'}) |
|
2204 | 2204 |
], |
2205 |
- where => {'table2_alias.key3' => 2} |
|
2205 |
+ where => {'table2_alias.key3' => 4} |
|
2206 | 2206 |
); |
2207 | 2207 |
is_deeply($result->one, |
2208 |
- {'table2_alias-key1' => 1, 'table2_alias-key3' => 48}); |
|
2208 |
+ {'table2_alias-key1' => 1, 'table2_alias-key3' => 4}); |
|
2209 | 2209 |
|
2210 | 2210 |
test 'type() option'; |
2211 | 2211 |
$dbi = DBIx::Custom->connect( |
... | ... |
@@ -2,7 +2,6 @@ package MyModel8::table1; |
2 | 2 |
use MyModel8 -base; |
3 | 3 |
|
4 | 4 |
has join => sub { ['left join table2 as table2_alias on table1.key1 = table2_alias.key1'] }; |
5 |
-has table_alias => sub { {'table2_alias' => 'table2'} }; |
|
6 | 5 |
|
7 | 6 |
|
8 | 7 |
1; |