Showing 3 changed files with 107 additions and 65 deletions
+1 -1
Build.PL
... ...
@@ -11,7 +11,7 @@ my $builder = Module::Build->new(
11 11
         'Test::More' => 0,
12 12
     },
13 13
     requires => {
14
-        'Object::Simple' => 2.0701,
14
+        'Object::Simple' => 2.0702,
15 15
         'DBI'            => 1.605,
16 16
     },
17 17
     add_to_cleanup      => [ 'DBI-Custom-*' ],
+92 -50
lib/DBI/Custom.pm
... ...
@@ -12,6 +12,7 @@ use DBI::Custom::Result;
12 12
 sub user        : ClassObjectAttr { initialize => {clone => 'scalar'} }
13 13
 sub password    : ClassObjectAttr { initialize => {clone => 'scalar'} }
14 14
 sub data_source : ClassObjectAttr { initialize => {clone => 'scalar'} }
15
+sub database    : ClassObjectAttr { initialize => {clone => 'scalar'} }
15 16
 
16 17
 sub dbi_option : ClassObjectAttr { initialize => {clone => 'hash', 
17 18
                                                   default => sub { {} } } }
... ...
@@ -19,6 +20,8 @@ sub dbi_option : ClassObjectAttr { initialize => {clone => 'hash',
19 20
 sub bind_filter  : ClassObjectAttr { initialize => {clone => 'scalar'} }
20 21
 sub fetch_filter : ClassObjectAttr { initialize => {clone => 'scalar'} }
21 22
 
23
+sub no_filters   : ClassObjectAttr { initialize => {clone => 'array'} }
24
+
22 25
 sub filters : ClassObjectAttr {
23 26
     type => 'hash',
24 27
     deref => 1,
... ...
@@ -47,6 +50,7 @@ sub dbh          : Attr {}
47 50
 
48 51
 
49 52
 ### Methods
53
+
50 54
 # Add filter
51 55
 sub add_filter {
52 56
     my $invocant = shift;
... ...
@@ -143,44 +147,46 @@ sub run_tranzaction {
143 147
     $self->_auto_commit(1);
144 148
 }
145 149
 
146
-# Create SQL from SQL template
147
-sub _create_sql {
148
-    my $self = shift;
150
+sub create_query {
151
+    my ($self, $template) = @_;
149 152
     
150
-    my ($sql, @bind) = $self->sql_template->create_sql(@_);
153
+    # Create query from SQL template
154
+    my $query = $self->sql_template->create_query($template);
151 155
     
152
-    return ($sql, @bind);
153
-}
154
-
155
-# Prepare and execute SQL
156
-sub query {
157
-    my ($self, $template, $values, $filter)  = @_;
156
+    # Create Query object;
157
+    my $query = DBI::Custom::Query->new($query);
158 158
     
159
-    my $sth_options;
159
+    # connect if not
160
+    $self->connect unless $self->connected;
160 161
     
161
-    # Rearrange when argumets is hash referecne 
162
-    if (ref $template eq 'HASH') {
163
-        my $args = $template;
164
-        ($template, $values, $filter, $sth_options)
165
-          = @{$args}{qw/template values filter sth_options/};
166
-    }
162
+    # Prepare statement handle
163
+    my $sth = $self->dbh->prepare($query->{sql});
167 164
     
168
-    $filter ||= $self->bind_filter;
165
+    $query->sth($sth);
169 166
     
170
-    my ($sql, @bind_values) = $self->_create_sql($template, $values, $filter);
167
+    return $query;
168
+}
169
+
170
+sub execute {
171
+    my ($self, $query, $params)  = @_;
171 172
     
172
-    $self->connect unless $self->connected;
173
+    # Create query if First argument is template
174
+    if (!ref $query) {
175
+        my $template = $query;
176
+        $query = $sefl->create_query($tempalte);
177
+    }
173 178
     
174
-    my $sth = $self->dbh->prepare($sql);
179
+    # Set bind filter
180
+    $query->bind_filter($self->bind_filter) unless $query->bind_filter;
175 181
     
176
-    if ($sth_options) {
177
-        foreach my $key (keys %$sth_options) {
178
-            $sth->{$key} = $sth_options->{$key};
179
-        }
180
-    }
182
+    # Set no filter keys
183
+    $query->no_filters($self->no_filters) unless $query->no_filters;
184
+    
185
+    # Create bind value
186
+    my $bind_values = $self->_build_bind_values($query, $params);
181 187
     
182 188
     # Execute
183
-    my $ret_val = $sth->execute(@bind_values);
189
+    my $ret_val = $query->sth->execute(@$bind_values);
184 190
     
185 191
     # Return resultset if select statement is executed
186 192
     if ($sth->{NUM_OF_FIELDS}) {
... ...
@@ -194,34 +200,67 @@ sub query {
194 200
     return $ret_val;
195 201
 }
196 202
 
197
-# Prepare and execute raw SQL
198
-sub query_raw_sql {
199
-    my ($self, $sql, @bind_values) = @_;
200
-    
201
-    # Connect
202
-    $self->connect unless $self->connected;
203
-    
204
-    # Add semicolon if not exist;
205
-    $sql .= ';' unless $sql =~ /;$/;
203
+sub _build_bind_values {
204
+    my ($self, $query, $params) = @_;
205
+    my $bind_filter = $query->bind_filter;
206
+    my $no_filters_map  = $query->_no_filters_map || {};
206 207
     
207
-    # Prepare
208
-    my $sth = $self->dbh->prepare($sql);
208
+    # binding values
209
+    my @bind_values;
209 210
     
210
-    # Execute
211
-    my $ret_val = $sth->execute(@bind_values);
212
-    
213
-    # Return resultset if select statement is executed
214
-    if ($sth->{NUM_OF_FIELDS}) {
215
-        my $result_class = $self->result_class;
216
-        my $result = $result_class->new({
217
-            sth => $sth,
218
-            fetch_filter => $self->fetch_filter
219
-        });
220
-        return $result;
211
+    # Filter and sdd bind values
212
+    foreach my $param_key_info (@$param_key_infos) {
213
+        my $filtering_key = $param_key_info->{key};
214
+        my $access_keys = $param_key_info->{access_keys};
215
+        
216
+        my $original_key = $param_key_info->{original_key} || '';
217
+        my $table        = $param_key_info->{table}        || '';
218
+        my $column       = $param_key_info->{column}       || '';
219
+        
220
+        ACCESS_KEYS :
221
+        foreach my $access_key (@$access_keys) {
222
+            my $root_params = $params;
223
+            for (my $i = 0; $i < @$access_key; $i++) {
224
+                my $key = $access_key->[$i];
225
+                
226
+                croak("'access_keys' each value must be string or array reference")
227
+                  unless (ref $key eq 'ARRAY' || ($key && !ref $key));
228
+                
229
+                if ($i == @$access_key - 1) {
230
+                    if (ref $key eq 'ARRAY') {
231
+                        if ($bind_filter && !$no_filters_map->{$original_key}) {
232
+                            push @bind_values, $bind_filter->($root_params->[$key->[0]], $original_key, $table, $column);
233
+                        }
234
+                        else {
235
+                            push @bind_values, scalar $root_params->[$key->[0]];
236
+                        }
237
+                    }
238
+                    else {
239
+                        next ACCESS_KEYS unless exists $root_params->{$key};
240
+                        if ($bind_filter && !$no_filters_map->{$original_key}) {
241
+                            push @bind_values, scalar $bind_filter->($root_params->{$key}, $original_key, $table, $column);
242
+                        }
243
+                        else {
244
+                            push @bind_values, scalar $root_params->{$key};
245
+                        }
246
+                    }
247
+                    return @bind_values;
248
+                }
249
+                
250
+                if ($key eq 'ARRAY') {
251
+                    $root_params = $root_params->[$key->[0]];
252
+                }
253
+                else {
254
+                    next ACCESS_KEYS unless exists $root_params->{$key};
255
+                    $root_params = $root_params->{$key};
256
+                }
257
+            }
258
+        }
259
+        croak("Cannot find key");
221 260
     }
222
-    return $ret_val;
223 261
 }
224 262
 
263
+
225 264
 Object::Simple->build_class;
226 265
 
227 266
 =head1 NAME
... ...
@@ -237,6 +276,9 @@ Version 0.0101
237 276
 =head1 SYNOPSIS
238 277
 
239 278
   my $dbi = DBI::Custom->new;
279
+  
280
+  my $query = $dbi->create_query($template);
281
+  $dbi->execute($query);
240 282
 
241 283
 =head1 CLASS-OBJECT ACCESSORS
242 284
 
+14 -14
t/02-sqlite.t
... ...
@@ -41,12 +41,12 @@ sub create_table1 {
41 41
 
42 42
 sub insert {
43 43
     my ($self, @values_list) = @_;
44
-    my $table = ref $values_list[0] ? '' : shift;
44
+    my $table = ref $params_list[0] ? '' : shift;
45 45
     $table ||= 't1';
46 46
     
47
-    foreach my $values (@values_list) {
48
-        my $sql = $self->dbi->query(
49
-            "insert into $table {insert_values}", {insert_values => $values}
47
+    foreach my $params (@values_list) {
48
+        my $sql = $self->dbi->execute(
49
+            "insert into $table {insert_values}", {insert_values => $params}
50 50
         );
51 51
     }
52 52
     return $self;
... ...
@@ -69,7 +69,7 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
69 69
     my @rows;
70 70
     my $rows;
71 71
     
72
-    $r = $dbi->query("select k1, k2 from t1");
72
+    $r = $dbi->execute("select k1, k2 from t1");
73 73
     
74 74
     @rows = ();
75 75
     while (my $row = $r->fetch) {
... ...
@@ -78,7 +78,7 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
78 78
     is_deeply(\@rows, [[1, 2], [3, 4]], 'fetch');
79 79
     
80 80
     
81
-    $r = $dbi->query("select k1, k2 from t1");
81
+    $r = $dbi->execute("select k1, k2 from t1");
82 82
     
83 83
     @rows = ();
84 84
     while (my @row = $r->fetch) {
... ...
@@ -87,7 +87,7 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
87 87
     is_deeply(\@rows, [[1, 2], [3, 4]], 'fetch list context');
88 88
     
89 89
     
90
-    $r = $dbi->query("select k1, k2 from t1;");
90
+    $r = $dbi->execute("select k1, k2 from t1;");
91 91
     
92 92
     @rows = ();
93 93
     while (my $row = $r->fetch_hash) {
... ...
@@ -96,7 +96,7 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
96 96
     is_deeply(\@rows, [{k1 => 1, k2 => 2}, {k1 => 3, k2 => 4}], 'fetch_hash');
97 97
     
98 98
     
99
-    $r = $dbi->query("select k1, k2 from t1;");
99
+    $r = $dbi->execute("select k1, k2 from t1;");
100 100
     
101 101
     @rows = ();
102 102
     while (my %row = $r->fetch_hash) {
... ...
@@ -105,25 +105,25 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
105 105
     is_deeply(\@rows, [{k1 => 1, k2 => 2}, {k1 => 3, k2 => 4}], 'fetch hash list context');
106 106
     
107 107
     
108
-    $r = $dbi->query("select k1, k2 from t1");
108
+    $r = $dbi->execute("select k1, k2 from t1");
109 109
     
110 110
     $rows = $r->fetch_all;
111 111
     is_deeply($rows, [[1, 2], [3, 4]], 'fetch_all');
112 112
     
113 113
     
114
-    $r = $dbi->query("select k1, k2 from t1");
114
+    $r = $dbi->execute("select k1, k2 from t1");
115 115
     
116 116
     @rows = $r->fetch_all;
117 117
     is_deeply(\@rows, [[1, 2], [3, 4]], 'fetch_all list context');
118 118
     
119 119
     
120
-    $r = $dbi->query("select k1, k2 from t1");
120
+    $r = $dbi->execute("select k1, k2 from t1");
121 121
     
122 122
     @rows = $r->fetch_all_hash;
123 123
     is_deeply($rows, [[1, 2], [3, 4]], 'fetch_all_hash');
124 124
     
125 125
     
126
-    $r = $dbi->query("select k1, k2 from t1");
126
+    $r = $dbi->execute("select k1, k2 from t1");
127 127
     
128 128
     @rows = $r->fetch_all;
129 129
     is_deeply(\@rows, [[1, 2], [3, 4]], 'fetch_all_hash list context');
... ...
@@ -137,14 +137,14 @@ $t->new->create_table1->insert({k1 => 1, k2 => 2}, {k1 => 3, k2 => 4})->test(sub
137 137
         return $value;
138 138
     });
139 139
     
140
-    $r = $dbi->query("select k1, k2 from t1");
140
+    $r = $dbi->execute("select k1, k2 from t1");
141 141
     
142 142
     $rows = $r->fetch_all;
143 143
     
144 144
     is_deeply($rows, [[3, 2], [3, 4]], 'fetch_filter array');
145 145
     
146 146
     
147
-    $r = $dbi->query("select k1, k2 from t1");
147
+    $r = $dbi->execute("select k1, k2 from t1");
148 148
     
149 149
     $rows = $r->fetch_all_hash;
150 150