Showing 8 changed files with 148 additions and 85 deletions
+6 -1
Changes
... ...
@@ -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
+76 -12
lib/DBIx/Custom.pm
... ...
@@ -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.
+12 -58
lib/DBIx/Custom/Model.pm
... ...
@@ -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(...);
+37 -6
t/dbix-custom-core-sqlite.t
... ...
@@ -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'});
-8
t/dbix-custom-core-sqlite/MyModel7/table1.pm
... ...
@@ -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'
+5
t/dbix-custom-core-sqlite/MyModel8.pm
... ...
@@ -0,0 +1,5 @@
1
+package MyModel8;
2
+
3
+use base 'DBIx::Custom::Model';
4
+
5
+1;
+5
t/dbix-custom-core-sqlite/MyModel8/table1.pm
... ...
@@ -0,0 +1,5 @@
1
+package MyModel8::table1;
2
+
3
+use base 'MyModel8';
4
+
5
+1;
+7
t/dbix-custom-core-sqlite/MyModel8/table1_trim.pm
... ...
@@ -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;