| ... | ... |
@@ -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; |