File Coverage

blib/lib/Mojolicious/DBIxCustom/Model.pm
Criterion Covered Total %
statement 15 244 6.1
branch 0 122 0.0
condition 0 61 0.0
subroutine 5 15 33.3
pod 0 9 0.0
total 20 451 4.4


line stmt bran cond sub pod time code
1             package Mojolicious::DBIxCustom::Model;
2 1     1   918 use strict;
  1         2  
  1         25  
3 1     1   4 use warnings;
  1         2  
  1         25  
4 1     1   4 use DBIx::Custom::Model -base;
  1         1  
  1         5  
5 1     1   87 use utf8;
  1         2  
  1         6  
6 1     1   31 use Carp qw/confess cluck/;
  1         1  
  1         1905  
7              
8             has 'sdel';
9              
10              
11             sub last_id{
12 0     0 0   my $self = shift;
13 0           my $dbi = $self->dbi;
14 0 0         confess "extension DBIx::Custom and implement [last_id] method please" unless($dbi->can("last_id"));
15 0           return $dbi->last_id(@_);
16             }
17              
18             sub model{
19 0     0 0   return shift->dbi->model(@_);
20             }
21              
22              
23             ## 添加
24             ## 返回值为 hashref
25             ## rows 影响了多少行
26             ## 表名 ,param执行过滤后的待写入对象
27             ## object ,写入成功后,查询得到的数据对象
28             ## param ,参数原样返回
29             sub create{
30 0     0 0   my $self = shift;
31 0           my $param = shift;
32            
33             ## 添加软删除标记
34 0           my $sdel = $self->sdel;
35 0 0 0       if($sdel && !exists($param->{$sdel})){
36 0           $param->{$sdel} = 0;
37             }
38            
39             ## 过滤param ,保证只有表中有的字段才会出现在insert语句中
40 0           my $mapper = $self->dbi->mapper(param => $param, pass => $self->columns);
41 0           my $obj = $mapper->map;
42 0           my $rows = $self->insert($obj);
43 0           my $pk = $self->primary_key;
44            
45             ## 表的主键只有一个,且primary_key属性为字符串时 说明主键是自增的
46             ## 其他情况,如primary_key属性为arrayref时,主键不是自增的
47 0           my $object;
48 0 0         unless(ref $pk){
49 0 0         $param->{$pk} = $obj->{$pk} = $self->last_id($obj) unless(defined $param->{$pk});
50 0           $object = $self->get_by_id($obj->{$pk});
51 0 0 0       $object = $object->{$self->name} if($object && $object->{$self->name});
52             }else{
53 0           my @pa = ();
54 0           for(@{$pk}){
  0            
55 0           push(@pa, $obj->{$_});
56             }
57 0           $object = $self->get_by_id(@pa);
58 0 0 0       $object = $object->{$self->name} if($object && $object->{$self->name});
59             }
60 0           return {rows => $rows, $self->name => $obj, object => $object, param => $param};
61             }
62              
63             ## 修改
64             ## 返回值为 hashref
65             ## rows 影响了多少行
66             ## 表名 ,param执行过滤后的待更新对象
67             ## list , update语句修改的数据对象,修改前的值
68             ## object ,update语句修改的数据对象中的第一个,修改前的值
69             ## param ,参数原样返回
70             ## where ,执行update时的where条件 hashref
71             sub edit{
72 0     0 0   my $self = shift;
73 0           my $param = shift;
74 0           my $where = shift;
75 0           my $pk = $self->primary_key;
76 0           my $have_pk = 1;
77 0           my %w = ();
78            
79             ## 如果param中有主键信息存在,则把param中的主键合并到where中
80             ## 为了保证被修改的字段中不包含主键,需要把主键从param中删除
81 0 0         if(ref $pk){
82 0           for(@{$pk}){
  0            
83 0   0       $have_pk &&= exists($param->{$_});
84 0 0         $w{$_} = delete $param->{$_} if(exists($param->{$_}));
85             }
86             }else{
87 0   0       $have_pk &&= exists($param->{$pk});
88 0 0         $w{$pk} = delete $param->{$pk} if(exists($param->{$pk}));
89             }
90 0 0 0       unless($where || $have_pk){
91 0           cluck("required [where] parameter");
92 0           return undef;
93             }
94            
95             ## 合并where条件
96 0   0       $where ||= {};
97 0           $where = {%w, %{$where}};
  0            
98            
99             ## 添加软删除标记
100 0           my $sdel = $self->sdel;
101 0 0 0       if($sdel && !exists($where->{$sdel})){
102 0           $where->{$sdel} = 0;
103             }
104            
105             ## 过滤param中的字段,保证只有表中有的字段才会出现在update语句中
106 0           my $mapper = $self->dbi->mapper(param => $param, pass => $self->columns);
107 0           $mapper->condition('exists');
108 0           my $obj = $mapper->map;
109            
110            
111             ## 查询得到修改前的结果
112 0           my $list = $self->select(where => $where)->all;
113            
114             ## 执行修改操作
115 0           my $rows = $self->update($obj, where => $where);
116            
117             ## 把主键还原给param 和obj,方便service层使用
118 0 0         if(ref $pk){
119 0           for(@{$pk}){
  0            
120 0 0         if(exists($where->{$_})){
121 0           $obj->{$_} = $where->{$_};
122 0           $param->{$_} = $where->{$_};
123             }
124             }
125             }else{
126 0 0         if(exists($where->{$pk})){
127 0           $obj->{$pk} = $where->{$pk};
128 0           $param->{$pk} = $where->{$pk};
129             }
130             }
131            
132             return {
133 0           rows => $rows,
134             $self->name => $obj,
135             param => $param,
136             object => $list->[0],
137             list => $list,
138             where => $where
139             };
140             }
141              
142             ## 硬删除
143             ## 根据参数 构造 where 条件
144             ## 支持 hash ,以and形式组成各个键
145             ## 支持 id 的列表
146             ## 支持 id 的数组引用
147             ## 返回值为 hashref
148             ## rows 影响了多少行
149             ## list , delete语句删除的数据对象,删除前的值
150             ## object ,delete语句删除的数据对象中的第一个,删除前的值
151             ## where ,执行delete时的where条件
152             sub remove{
153 0     0 0   my $self = shift;
154 0           my $where = shift;
155            
156             ## 根据参数 构造 where 条件
157 0 0 0       if(defined $where && !ref $where){
    0          
158             ## 参数为id列表时的解析
159 0           my $pk = $self->primary_key;
160 0 0         if(ref $pk){
161 0 0         if(@{$pk} == 1){
  0            
162 0           $where = {$pk->[0] => $where};
163             }else{
164 0           unshift(@_, $where);
165 0 0         if(@{$pk} <= @_){
  0            
166 0           $where = {};
167 0           for(@{$pk}){
  0            
168 0           $where->{$_} = shift;
169             }
170             }
171             }
172             }else{
173 0           $where = {$pk => $where};
174             }
175             }elsif(ref $where eq "ARRAY"){
176             ## 参数为id 的数组引用时的解析
177 0           my $pk = $self->primary_key;
178 0           my @ids = @{$where};
  0            
179 0 0         if(@{$pk} <= @ids){
  0            
180 0           $where = {};
181 0           for(@{$pk}){
  0            
182 0           $where->{$_} = shift(@ids);
183             }
184             }
185             }
186            
187             ## 如果where不是一个hash则给出提示
188 0 0         if(ref $where ne "HASH"){
189 0           cluck("[where] parameter required a hashref");
190 0           return undef;
191             }
192            
193             ## 添加软删除标记
194 0           my $sdel = $self->sdel;
195 0 0 0       if($sdel && !exists($where->{$sdel})){
196 0           $where->{$sdel} = 0;
197             }
198            
199             ## 查询需要出将要删除的内容
200 0           my $list = $self->select(where => $where)->all;
201            
202             ## 执行删除
203 0           my $rows = $self->delete(where => $where);
204 0           return {rows => $rows, list => $list, object => $list->[0], where => $where};
205             }
206              
207              
208             ## 硬删除
209             ## 根据参数 构造 where 条件
210             ## 支持 id 的列表
211             ## 支持 id 的数组引用
212             ## 返回值为 hashref
213             ## rows 影响了多少行
214             ## object ,delete语句删除的数据对象,删除前的值
215             ## where ,执行delete时的where条件
216             sub remove_by_id{
217 0     0 0   my $self = shift;
218            
219             ## 获取参数
220 0 0         my $t = ref $_[0] ? shift : undef;
221 0 0         my @ids = $t ? @{$t} : @_;
  0            
222            
223             ## 构造where 条件
224 0           my $pk = $self->primary_key;
225 0           my $where = {};
226 0 0 0       if(ref $pk eq "ARRAY" && @ids >= @{$pk}){
  0 0          
227 0           for(@{$pk}){
  0            
228 0           $where->{$_} = shift(@ids);
229             }
230             }elsif(ref $pk eq "ARRAY"){
231 0           cluck("parameter number is insufficient");
232             }else{
233 0           $where->{$pk} = shift(@ids);
234             }
235            
236             ## 添加软删除标记
237 0           my $sdel = $self->sdel;
238 0 0 0       if($sdel && !exists($where->{$sdel})){
239 0           $where->{$sdel} = 0;
240             }
241            
242             ## 调用 remove 方法 执行删除操作
243 0           return $self->remove($where);
244             }
245              
246              
247             ## 软删除
248             ## 根据参数 构造 where 条件
249             ## 支持 hash ,以and形式组成各个键
250             ## 支持 id 的列表
251             ## 支持 id 的数组引用
252             ## 返回值为 hashref
253             ## rows 影响了多少行
254             ## list , update语句删除的数据对象,删除前的值
255             ## object ,update语句删除的数据对象中的第一个,删除前的值
256             ## where ,执行update时的where条件
257             sub sremove{
258 0     0 0   my $self = shift;
259 0           my $where = shift;
260            
261             ## 根据参数 构造 where 条件
262            
263 0 0 0       if(defined $where && !ref $where){
    0          
264             ## 参数为id列表时的解析
265 0           my $pk = $self->primary_key;
266 0 0         if(ref $pk){
267 0 0         if(@{$pk} == 1){
  0            
268 0           $where = {$pk->[0] => $where};
269             }else{
270 0           unshift(@_, $where);
271 0 0         if(@{$pk} <= @_){
  0            
272 0           $where = {};
273 0           for(@{$pk}){
  0            
274 0           $where->{$_} = shift;
275             }
276             }
277             }
278             }else{
279 0           $where = {$pk => $where};
280             }
281             }elsif(ref $where eq "ARRAY"){
282             ## 参数为id 的数组引用时的解析
283 0           my $pk = $self->primary_key;
284 0           my @ids = @{$where};
  0            
285 0 0         if(@{$pk} <= @ids){
  0            
286 0           $where = {};
287 0           for(@{$pk}){
  0            
288 0           $where->{$_} = shift(@ids);
289             }
290             }
291             }
292            
293 0   0       my $flag = shift || 1;
294            
295             ## 添加软删除标记
296 0           my $sdel = $self->sdel;
297 0 0 0       if($sdel && !exists($where->{$sdel})){
298 0           $where->{$sdel} = 0;
299             }
300            
301 0 0         if($sdel){
302             ## 查询需要出将要删除的内容
303 0           my $list = $self->select(where => $where)->all;
304            
305             ## 执行软删除操作
306 0           my $rows = $self->update({$sdel => $flag}, where => $where);
307 0           return {rows => $rows, list => $list, object => $list->[0], where => $where};
308             }else{
309 0           cluck "dont support sremove";
310             }
311             }
312              
313              
314             ## 软删除
315             ## 根据参数 构造 where 条件
316             ## 支持 id 的列表
317             ## 支持 id 的数组引用
318             ## 支持 flag 等 sremove 所支持的参数
319             ## 返回值为 hashref
320             ## rows 影响了多少行
321             ## object ,update语句删除的数据对象,删除前的值
322             ## where ,执行update时的where条件
323             sub sremove_by_id{
324 0     0 0   my $self = shift;
325            
326            
327             ## 获取参数
328 0 0         my $t = ref $_[0] ? shift : undef;
329 0 0         my @ids = $t ? @{$t} : @_;
  0            
330            
331             ## 构造where 条件
332 0           my $pk = $self->primary_key;
333 0           my $where = {};
334 0 0 0       if(ref $pk eq "ARRAY" && @ids >= @{$pk}){
  0 0          
335 0           for(@{$pk}){
  0            
336 0           $where->{$_} = shift(@ids);
337             }
338             }elsif(ref $pk eq "ARRAY"){
339 0           cluck("parameter number is insufficient");
340             }else{
341 0           $where->{$pk} = shift(@ids);
342             }
343            
344             ## 添加软删除标记
345 0           my $sdel = $self->sdel;
346 0 0 0       if($sdel && !exists($where->{$sdel})){
347 0           $where->{$sdel} = 0;
348             }
349            
350 0 0         if($sdel){
351             ## 调用 sremove 方法 执行软删除
352 0 0         return $self->sremove($where, $t ? @_ : @ids);
353             }else{
354 0           cluck "dont support sremove";
355             }
356             }
357              
358             ## 允许的参数类型如下:
359             ## 1. 要查询的字段:arrayref (可选,默认查询表中所有字段)
360             ## 2. 主键的值:arrayref or array (必选)
361             ## 返回值为 hashref
362             ## rows 影响了多少行
363             ## 表名 查询得到的数据对象
364             ## object ,查询得到的数据对象
365             ## where ,执行select时的where条件
366             sub get_by_id{
367 0     0 0   my $self = shift;
368            
369             ## 获取参数,构造fields 和 ids
370 0           my ($fields, $ids);
371 0 0         if(ref $_[0]){
372 0           $fields = shift;
373 0 0         if(@_ > 0){
374 0 0         $ids = ref $_[0] ? shift : [@_];
375             }
376             }else{
377 0           $ids = [@_];
378             }
379 0 0         unless($ids){
380 0           $ids = $fields;
381 0           $fields = undef;
382             }
383            
384             ## 构造where条件
385 0           my $pk = $self->primary_key;
386 0           my $where = {};
387 0 0 0       if(ref $pk && @{$pk} <= @{$ids}){
  0 0          
  0            
388 0           for(@{$pk}){
  0            
389 0           $where->{$_} = shift(@{$ids});
  0            
390             }
391             }elsif(ref $pk){
392 0           cluck "parameter number is insufficient";
393             }else{
394 0           $where->{$pk} = shift(@{$ids});
  0            
395             }
396            
397             ## 添加软删除标记
398 0           my $sdel = $self->sdel;
399 0 0 0       if($sdel && !exists($where->{$sdel})){
400 0           $where->{$sdel} = 0;
401             }
402            
403             ## 执行查询操作
404 0 0         if(defined $ids){
405 0 0         my $obj = $self->select($fields ? $fields : (), where => $where)->one;
406 0           return {$self->name => $obj, object => $obj, where => $where};
407             }
408 0           return undef;
409             }
410              
411              
412             sub AUTOLOAD{
413 0     0     my $self = shift;
414 0           my ($package, $method) = our $AUTOLOAD =~ /^(.+)::(.+)$/;
415            
416             ## --------参数支持--------
417             ## columns 可选
418             ## field 值 必选
419             ## 后面可以跟其他select方法可接收的参数,如:append等
420             ## --------返回值为 hashref--------
421             ## rows 查到了多少行
422             ## 表名 查询得到的数据对象的第一条
423             ## object ,查询得到的数据对象的第一条
424             ## list , 查询得到的数据对象的列表
425             ## where ,执行select时的where条件
426 0 0         if($method =~ /^get_by_(.+)$/){
427 0           my $wk = $1;
428 0           my ($columns);
429 0 0         if(ref $_[0]){
430 0           $columns = shift;
431             }
432 0           my $where = {$wk => shift};
433            
434             ## 添加软删除标记
435 0           my $sdel = $self->sdel;
436 0 0 0       if($sdel && !exists($where->{$sdel})){
437 0           $where->{$sdel} = 0;
438             }
439            
440 0 0         my $list = $self->select($columns ? $columns : (), where => $where, @_)->all;
441             return {
442 0           rows => scalar(@{$list}),
  0            
443             $self->name => $list->[0],
444             object => $list->[0],
445             list => $list,
446             where => $where
447             };
448             }
449            
450            
451             ## --------参数支持--------
452             ## columns 可选
453             ## field 值 必选
454             ## 后面可以跟其他select方法可接收的参数,如:append等
455             ## --------返回值为 整数--------
456             ## 共计多少行
457 0 0         if($method =~ /^count_by_(.+)$/){
458 0           my $wk = $1;
459 0           my ($columns);
460 0 0         if(ref $_[0]){
461 0           $columns = shift;
462             }
463 0           my $where = {$wk => shift};
464            
465             ## 添加软删除标记
466 0           my $sdel = $self->sdel;
467 0 0 0       if($sdel && !exists($where->{$sdel})){
468 0           $where->{$sdel} = 0;
469             }
470            
471 0 0         return $self->count($columns ? $columns : (), where => $where, @_);
472             }
473            
474             ## 与remove 方法的返回值格式相同
475             ## 返回值为 hashref
476             ## rows 影响了多少行
477             ## list , delete语句删除的数据对象,删除前的值
478             ## object ,delete语句删除的数据对象中的第一个,删除前的值
479             ## where ,执行delete时的where条件
480 0 0         if($method =~ /^remove_by_(.+)$/){
481 0           my $wk = $1;
482 0           my $where = {$wk => shift};
483 0           return $self->remove($where);
484             }
485            
486             ## 与sremove 方法的返回值格式相同
487             ## 返回值为 hashref
488             ## rows 影响了多少行
489             ## list , update语句删除的数据对象,删除前的值
490             ## object ,update语句删除的数据对象中的第一个,删除前的值
491             ## where ,执行update时的where条件
492             ## 支持 flag 等更多 sremove 所支持的参数
493 0 0         if($method =~ /^sremove_by_(.+)$/){
494 0           my $wk = $1;
495 0           my $where = {$wk => shift};
496 0           return $self->sremove($where, @_);
497             }
498            
499 0           confess qq{Can't locate obj method "$method" via package "$package"}
500             }
501              
502              
503             1;