... | ... |
@@ -1,5 +1,10 @@ |
1 | 1 |
0.1660 |
2 |
- - update pod |
|
2 |
+ - added EXPERIMENTAL DBIx::Custom::Model view() |
|
3 |
+ - added EXPERIMENTAL view() |
|
4 |
+ - DBIx::Custom::Model inherit DBIx::Custom |
|
5 |
+ - removed EXPERIMETNAL DBIx::Custom::Model method() |
|
6 |
+ - added table choice feature to select() EXPERIMENTAL all_column option |
|
7 |
+ - removed EXPERIMENTAL DBIx::Custom::Model column attribute for side effect |
|
3 | 8 |
0.1659 |
4 | 9 |
- EXPERIMETAL fork safety implementaion. |
5 | 10 |
- removed EXPERIMENTAL selection |
... | ... |
@@ -669,20 +669,34 @@ sub select { |
669 | 669 |
elsif ($all_column) { |
670 | 670 |
|
671 | 671 |
# Find tables |
672 |
- my $main_table = $tables->[-1] || ''; |
|
672 |
+ my $main_table; |
|
673 | 673 |
my %tables; |
674 |
- foreach my $j (@$join) { |
|
675 |
- my $tables = $self->_tables($j); |
|
676 |
- foreach my $table (@$tables) { |
|
677 |
- $tables{$table} = 1; |
|
674 |
+ if (ref $all_column eq 'ARRAY') { |
|
675 |
+ foreach my $table (@$all_column) { |
|
676 |
+ if (($table || '') eq $tables->[-1]) { |
|
677 |
+ $main_table = $table; |
|
678 |
+ } |
|
679 |
+ else { |
|
680 |
+ $tables{$table} = 1; |
|
681 |
+ } |
|
682 |
+ } |
|
683 |
+ } |
|
684 |
+ else { |
|
685 |
+ $main_table = $tables->[-1] || ''; |
|
686 |
+ foreach my $j (@$join) { |
|
687 |
+ my $tables = $self->_tables($j); |
|
688 |
+ foreach my $table (@$tables) { |
|
689 |
+ $tables{$table} = 1; |
|
690 |
+ } |
|
678 | 691 |
} |
692 |
+ delete $tables{$main_table}; |
|
679 | 693 |
} |
680 |
- delete $tables{$main_table}; |
|
681 |
- my @column_clause; |
|
682 | 694 |
|
683 | 695 |
# Column clause of main table |
684 |
- push @sql, $self->model($main_table)->column_clause; |
|
685 |
- push @sql, ','; |
|
696 |
+ if ($main_table) { |
|
697 |
+ push @sql, $self->model($main_table)->column_clause; |
|
698 |
+ push @sql, ','; |
|
699 |
+ } |
|
686 | 700 |
|
687 | 701 |
# Column cluase of other tables |
688 | 702 |
foreach my $table (keys %tables) { |
... | ... |
@@ -716,7 +730,12 @@ sub select { |
716 | 730 |
$found->{$table} = 1; |
717 | 731 |
} |
718 | 732 |
} |
719 |
- else { push @sql, $tables->[-1] } |
|
733 |
+ else { |
|
734 |
+ my $main_table = $tables->[-1] || ''; |
|
735 |
+ push @sql, $self->view($main_table) |
|
736 |
+ ? $self->view($main_table) |
|
737 |
+ : $main_table; |
|
738 |
+ } |
|
720 | 739 |
pop @sql if ($sql[-1] || '') eq ','; |
721 | 740 |
} |
722 | 741 |
|
... | ... |
@@ -892,6 +911,9 @@ sub include_model { |
892 | 911 |
# Set |
893 | 912 |
$self->model($model->name, $model); |
894 | 913 |
|
914 |
+ # View |
|
915 |
+ $self->view($model->table, $model->view) if $model->view; |
|
916 |
+ |
|
895 | 917 |
# Apply filter |
896 | 918 |
croak "${name_space}::$model_class filter must be array reference" |
897 | 919 |
unless ref $model->filter eq 'ARRAY'; |
... | ... |
@@ -1073,6 +1095,23 @@ sub update_param { |
1073 | 1095 |
return join ' ', @tag; |
1074 | 1096 |
} |
1075 | 1097 |
|
1098 |
+sub view { |
|
1099 |
+ my $self = shift; |
|
1100 |
+ my $name = shift; |
|
1101 |
+ |
|
1102 |
+ # View |
|
1103 |
+ $self->{view} ||= {}; |
|
1104 |
+ if (@_) { |
|
1105 |
+ $self->{view}->{$name} = $_[0]; |
|
1106 |
+ return $self; |
|
1107 |
+ } |
|
1108 |
+ else { |
|
1109 |
+ return $name && $self->{view}->{$name} |
|
1110 |
+ ? "(" . $self->{view}->{$name} . ") as $name" |
|
1111 |
+ : undef; |
|
1112 |
+ } |
|
1113 |
+} |
|
1114 |
+ |
|
1076 | 1115 |
sub where { |
1077 | 1116 |
my $self = shift; |
1078 | 1117 |
|
... | ... |
@@ -2189,12 +2228,16 @@ This create the following column clause. |
2189 | 2228 |
Columns of main table is consist of only column name, |
2190 | 2229 |
Columns of joined table is consist of table and column name joined C<__>. |
2191 | 2230 |
|
2192 |
-Note that this option is failed unless L<DBIx::Custom::Model> object is set to |
|
2193 |
-C<model> and C<columns> of the object is set. |
|
2231 |
+Note that this option is failed unless modles is included and |
|
2232 |
+C<columns> attribute is set. |
|
2194 | 2233 |
|
2195 | 2234 |
# Generally do the following way before using all_column option |
2196 | 2235 |
$dbi->include_model('MyModel')->setup_model; |
2197 | 2236 |
|
2237 |
+You can also specify table names to C<all_column>. |
|
2238 |
+ |
|
2239 |
+ $dbi->select(all_column => ['book', 'company']); |
|
2240 |
+ |
|
2198 | 2241 |
=item C<where> |
2199 | 2242 |
|
2200 | 2243 |
Where clause. This is hash reference or L<DBIx::Custom::Where> object. |
... | ... |
@@ -2506,6 +2549,27 @@ Create a new L<DBIx::Custom::Where> object. |
2506 | 2549 |
Setup all model objects. |
2507 | 2550 |
C<columns> of model object is automatically set, parsing database information. |
2508 | 2551 |
|
2552 |
+=head2 C<view> EXPERIMENTAL |
|
2553 |
+ |
|
2554 |
+ # Register view |
|
2555 |
+ $dbi->view( |
|
2556 |
+ book_issue_data |
|
2557 |
+ => 'select id, DATE(issue_datatime) as issue_date from book'); |
|
2558 |
+ ); |
|
2559 |
+ |
|
2560 |
+ # Get view |
|
2561 |
+ my $view = $dbi->view('book_issue_date'); |
|
2562 |
+ |
|
2563 |
+View. |
|
2564 |
+ |
|
2565 |
+C<view()> return the following statement when you get a view. |
|
2566 |
+ |
|
2567 |
+ (select id, DATE(issue_datetime) from book) as book_issue_date |
|
2568 |
+ |
|
2569 |
+You can use this view in from clause |
|
2570 |
+ |
|
2571 |
+ "select issue_date from " . $dbi->view('book_issue_date') |
|
2572 |
+ |
|
2509 | 2573 |
=head1 Tags |
2510 | 2574 |
|
2511 | 2575 |
The following tags is available. |
... | ... |
@@ -3,7 +3,7 @@ package DBIx::Custom::Model; |
3 | 3 |
use strict; |
4 | 4 |
use warnings; |
5 | 5 |
|
6 |
-use base 'Object::Simple'; |
|
6 |
+use base 'DBIx::Custom'; |
|
7 | 7 |
|
8 | 8 |
use Carp 'croak'; |
9 | 9 |
|
... | ... |
@@ -11,37 +11,13 @@ use Carp 'croak'; |
11 | 11 |
push @DBIx::Custom::CARP_NOT, __PACKAGE__; |
12 | 12 |
|
13 | 13 |
__PACKAGE__->attr( |
14 |
- ['dbi', 'name', 'table', 'column'], |
|
14 |
+ ['dbi', 'name', 'table', 'view'], |
|
15 | 15 |
columns => sub { [] }, |
16 | 16 |
filter => sub { [] }, |
17 |
- primary_key => sub { [] }, |
|
18 |
- join => sub { [] } |
|
17 |
+ join => sub { [] }, |
|
18 |
+ primary_key => sub { [] } |
|
19 | 19 |
); |
20 | 20 |
|
21 |
-our $AUTOLOAD; |
|
22 |
- |
|
23 |
-sub AUTOLOAD { |
|
24 |
- my $self = shift; |
|
25 |
- |
|
26 |
- # Method name |
|
27 |
- my ($package, $mname) = $AUTOLOAD =~ /^([\w\:]+)\:\:(\w+)$/; |
|
28 |
- |
|
29 |
- # Method |
|
30 |
- $self->{_methods} ||= {}; |
|
31 |
- if (my $method = $self->{_methods}->{$mname}) { |
|
32 |
- return $self->$method(@_) |
|
33 |
- } |
|
34 |
- elsif ($self->dbi->can($mname)) { |
|
35 |
- $self->dbi->$mname(@_); |
|
36 |
- } |
|
37 |
- elsif ($self->dbi->dbh->can($mname)) { |
|
38 |
- $self->dbi->dbh->$mname(@_); |
|
39 |
- } |
|
40 |
- else { |
|
41 |
- croak qq/Can't locate object method "$mname" via "$package"/ |
|
42 |
- } |
|
43 |
-} |
|
44 |
- |
|
45 | 21 |
sub column_clause { |
46 | 22 |
my $self = shift; |
47 | 23 |
|
... | ... |
@@ -104,21 +80,10 @@ sub insert_at { |
104 | 80 |
); |
105 | 81 |
} |
106 | 82 |
|
107 |
-sub method { |
|
108 |
- my $self = shift; |
|
109 |
- |
|
110 |
- # Merge |
|
111 |
- my $methods = ref $_[0] eq 'HASH' ? $_[0] : {@_}; |
|
112 |
- $self->{_methods} = {%{$self->{_methods} || {}}, %$methods}; |
|
113 |
- |
|
114 |
- return $self; |
|
115 |
-} |
|
116 |
- |
|
117 | 83 |
sub select { |
118 | 84 |
my $self = shift; |
119 | 85 |
$self->dbi->select( |
120 | 86 |
table => $self->table, |
121 |
- column => $self->column, |
|
122 | 87 |
join => $self->join, |
123 | 88 |
@_ |
124 | 89 |
); |
... | ... |
@@ -129,7 +94,6 @@ sub select_at { |
129 | 94 |
|
130 | 95 |
return $self->dbi->select_at( |
131 | 96 |
table => $self->table, |
132 |
- column => $self->column, |
|
133 | 97 |
primary_key => $self->primary_key, |
134 | 98 |
join => $self->join, |
135 | 99 |
@_ |
... | ... |
@@ -171,11 +135,6 @@ my $table = DBIx::Custom::Model->new(table => 'books'); |
171 | 135 |
|
172 | 136 |
=head1 ATTRIBUTES |
173 | 137 |
|
174 |
-=head2 C<columns> |
|
175 |
- |
|
176 |
- my $columns = $model->columns; |
|
177 |
- $model = $model->columns(['id', 'number']); |
|
178 |
- |
|
179 | 138 |
=head2 C<dbi> |
180 | 139 |
|
181 | 140 |
my $dbi = $model->dbi; |
... | ... |
@@ -222,6 +181,14 @@ Table name is real table name in database. |
222 | 181 |
Foreign key. This is used by C<insert_at>,C<update_at()>, |
223 | 182 |
C<delete_at()>,C<select_at()>. |
224 | 183 |
|
184 |
+=head2 C<view> |
|
185 |
+ |
|
186 |
+ my $view = $model->view; |
|
187 |
+ $model = $model->view('select id, DATE(issue_datetime) as date from book'); |
|
188 |
+ |
|
189 |
+View. This view is registered by C<view()> of L<DBIx::Custom> when |
|
190 |
+model is included by C<include_model>. |
|
191 |
+ |
|
225 | 192 |
=head1 METHODS |
226 | 193 |
|
227 | 194 |
L<DBIx::Custom> inherits all methods from L<Object::Simple>, |
... | ... |
@@ -279,19 +246,6 @@ you don't have to specify C<table> option. |
279 | 246 |
Same as C<delete()> of L<DBIx::Custom> except that |
280 | 247 |
you don't have to specify C<table> and C<primary_key> option. |
281 | 248 |
|
282 |
-=head2 C<method> |
|
283 |
- |
|
284 |
- $table->method( |
|
285 |
- count => sub { |
|
286 |
- my $self = shift; |
|
287 |
- |
|
288 |
- return $self->select(column => 'count(*)', @_) |
|
289 |
- ->fetch_first->[0]; |
|
290 |
- } |
|
291 |
- ); |
|
292 |
- |
|
293 |
-Add method to a L<DBIx::Custom::Table> object. |
|
294 |
- |
|
295 | 249 |
=head2 C<insert> |
296 | 250 |
|
297 | 251 |
$table->insert(...); |
... | ... |
@@ -1321,10 +1321,6 @@ is_deeply($model->list->fetch_hash_all, [{name => 'a'}], 'basic'); |
1321 | 1321 |
is($dbi->models->{'book'}, $dbi->model('book')); |
1322 | 1322 |
is($dbi->models->{'company'}, $dbi->model('company')); |
1323 | 1323 |
|
1324 |
-$dbi->model('book'); |
|
1325 |
-eval{$dbi->model('book')->no_exists}; |
|
1326 |
-like($@, qr/locate/); |
|
1327 |
- |
|
1328 | 1324 |
{ |
1329 | 1325 |
package MyDBI4; |
1330 | 1326 |
|
... | ... |
@@ -1807,11 +1803,46 @@ $dbi->setup_model; |
1807 | 1803 |
$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
1808 | 1804 |
$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 3}); |
1809 | 1805 |
$model = $dbi->model('table1'); |
1810 |
-$result = $model->select_at(where => 1); |
|
1806 |
+$result = $model->select_at( |
|
1807 |
+ all_column => ['table1', 'table2'], |
|
1808 |
+ where => 1 |
|
1809 |
+); |
|
1811 | 1810 |
is_deeply($result->fetch_hash_first, |
1812 | 1811 |
{key1 => 1, key2 => 2, table2__key1 => 1, table2__key3 => 3}); |
1813 |
-$model->column(undef); |
|
1814 | 1812 |
$result = $model->select(all_column => 1); |
1815 | 1813 |
is_deeply($result->fetch_hash_first, |
1816 | 1814 |
{key1 => 1, key2 => 2, table2__key1 => 1, table2__key3 => 3}); |
1817 | 1815 |
|
1816 |
+test 'view'; |
|
1817 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
1818 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
1819 |
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => ' a '}); |
|
1820 |
+$dbi->view('table1_trim' => 'select key1, trim(key2) as key2 from table1'); |
|
1821 |
+$result = $dbi->select( |
|
1822 |
+ table => 'table1', |
|
1823 |
+ column => ['table1_trim.key2 as table1_trim__key2'], |
|
1824 |
+ join => ["left outer join " . $dbi->view('table1_trim') . " on table1.key1 = table1_trim.key1"] |
|
1825 |
+); |
|
1826 |
+is($result->fetch_hash_first->{'table1_trim__key2'}, 'a'); |
|
1827 |
+ |
|
1828 |
+$result = $dbi->select(table => 'table1_trim'); |
|
1829 |
+is_deeply($result->fetch_hash_first, {key1 => 1, key2 => 'a'}); |
|
1830 |
+ |
|
1831 |
+{ |
|
1832 |
+ package MyDBI9; |
|
1833 |
+ |
|
1834 |
+ use base 'DBIx::Custom'; |
|
1835 |
+ |
|
1836 |
+ sub connect { |
|
1837 |
+ my $self = shift->SUPER::connect(@_); |
|
1838 |
+ |
|
1839 |
+ $self->include_model('MyModel8')->setup_model; |
|
1840 |
+ |
|
1841 |
+ return $self; |
|
1842 |
+ } |
|
1843 |
+} |
|
1844 |
+$dbi = MyDBI9->connect($NEW_ARGS->{0}); |
|
1845 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
1846 |
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => ' a '}); |
|
1847 |
+$result = $dbi->model('table1_trim')->select; |
|
1848 |
+is_deeply($result->fetch_hash_first, {key1 => 1, key2 => 'a'}); |
... | ... |
@@ -4,14 +4,6 @@ use base 'MyModel7'; |
4 | 4 |
|
5 | 5 |
__PACKAGE__->attr( |
6 | 6 |
primary_key => sub { ['key1'] }, |
7 |
- column => sub { |
|
8 |
- my $self = shift; |
|
9 |
- |
|
10 |
- return [ |
|
11 |
- $self->column_clause, |
|
12 |
- $self->model('table2')->column_clause(prefix => 'table2__') |
|
13 |
- ]; |
|
14 |
- }, |
|
15 | 7 |
join => sub { |
16 | 8 |
[ |
17 | 9 |
'left outer join table2 on table1.key1 = table2.key1' |
... | ... |
@@ -0,0 +1,5 @@ |
1 |
+package MyModel8; |
|
2 |
+ |
|
3 |
+use base 'DBIx::Custom::Model'; |
|
4 |
+ |
|
5 |
+1; |
... | ... |
@@ -0,0 +1,5 @@ |
1 |
+package MyModel8::table1; |
|
2 |
+ |
|
3 |
+use base 'MyModel8'; |
|
4 |
+ |
|
5 |
+1; |
... | ... |
@@ -0,0 +1,7 @@ |
1 |
+package MyModel8::table1_trim; |
|
2 |
+ |
|
3 |
+use base 'MyModel8'; |
|
4 |
+ |
|
5 |
+__PACKAGE__->attr(view => 'select key1, trim(key2) as key2 from table1'); |
|
6 |
+ |
|
7 |
+1; |