|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # vim:ts=8:sw=2:et:sta:sts=2  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #########  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Author: rmp  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Created: 2006-10-31  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package ClearPress::model;  | 
| 
8
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
130818
 | 
 use strict;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
190
 | 
    | 
| 
9
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
37
 | 
 use warnings;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
184
 | 
    | 
| 
10
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
40
 | 
 use base qw(Class::Accessor);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1054
 | 
    | 
| 
11
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
4190
 | 
 use ClearPress::util;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
    | 
| 
12
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
235
 | 
 use English qw(-no_match_vars);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
13
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
2241
 | 
 use Carp;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
364
 | 
    | 
| 
14
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
3349
 | 
 use Lingua::EN::Inflect qw(PL);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157898
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
888
 | 
    | 
| 
15
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
2430
 | 
 use Lingua::EN::PluralToSingular qw(to_singular);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11496
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
511
 | 
    | 
| 
16
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
55
 | 
 use POSIX qw(strftime);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
    | 
| 
17
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
559
 | 
 use Readonly;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13060
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = q[476.4.2];  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Readonly::Scalar our $DBI_CACHE_OVERWRITE => 3;  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $EXPERIMENTAL_PL = 0;  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
654
 | 
 sub fields { return (); }  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _plfunc {  | 
| 
28
 | 
31
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
75
 | 
   my $thing = shift;  | 
| 
29
 | 
31
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
159
 | 
   return $EXPERIMENTAL_PL ? PL(to_singular($thing)) : PL($thing);  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub primary_key {  | 
| 
33
 | 
201
 | 
 
 | 
 
 | 
  
201
  
 | 
  
1
  
 | 
1217
 | 
   my $self = shift;  | 
| 
34
 | 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
823
 | 
   return ($self->fields())[0];  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
  
83
  
 | 
  
1
  
 | 
 
 | 
 sub secondary_key {  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub table {  | 
| 
41
 | 
46
 | 
 
 | 
 
 | 
  
46
  
 | 
  
1
  
 | 
898
 | 
   my $self = shift;  | 
| 
42
 | 
46
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
225
 | 
   my $tbl  = (ref $self) || $self;  | 
| 
43
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
157
 | 
   if(!$tbl) {  | 
| 
44
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     return;  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
46
 | 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
497
 | 
   ($tbl)   = $tbl =~ /.*::([^:]+)/smx;  | 
| 
47
 | 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
254
 | 
   return $tbl;  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
  
77
  
 | 
  
1
  
 | 
 
 | 
 sub init  { }  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
53
 | 
77
 | 
 
 | 
 
 | 
  
77
  
 | 
  
1
  
 | 
26277
 | 
   my ($class, $ref) = @_;  | 
| 
54
 | 
77
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
383
 | 
   $ref ||= {};  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
342
 | 
   my $pk = $class->primary_key();  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
77
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
667
 | 
   if(!ref $ref) {  | 
| 
59
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     if($pk) {  | 
| 
60
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       $ref = {  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      $pk => $ref,  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	     };  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
64
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak q[Could not set primary key in an object with no fields];  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
68
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
   bless $ref, $class;  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
299
 | 
   my $sk   = $ref->secondary_key();  | 
| 
71
 | 
77
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
241
 | 
   if($sk && $ref->{$sk} &&  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      !$ref->{$pk}) {  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $table = $ref->table;  | 
| 
75
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $util  = $ref->util;  | 
| 
76
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $dbh   = $util->dbh;  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     eval {  | 
| 
78
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $id   = $dbh->selectall_arrayref(qq[/* model::new */ SELECT $pk FROM $table WHERE $sk=?], {}, $ref->{$sk})->[0]->[0];  | 
| 
79
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $ref->{$pk} = $id;  | 
| 
80
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       1;  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
82
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     } or do {  | 
| 
83
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       carp $EVAL_ERROR;  | 
| 
84
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
348
 | 
   $ref->init($ref);  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
403
 | 
   return $ref;  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub util {  | 
| 
94
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
  
1
  
 | 
5174
 | 
   my ($self, $util) = @_;  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
59
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
220
 | 
   if(!ref $self) {  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If we're being accessed as a class method (e.g. for retrieving  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # type dictionaries) Then play nicely and return a util.  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Note, this currently needs subclassing if you want class-method  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # support in your own namespace.  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
104
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     return ClearPress::util->new();  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
107
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
185
 | 
   if($util) {  | 
| 
108
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     $self->{util} = $util;  | 
| 
109
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     return $util;  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
112
 | 
57
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
263
 | 
   if($self->{util}) {  | 
| 
113
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
269
 | 
     return $self->{util};  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # attempt to instantiate a util using $self's namespace  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
119
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   my ($ref) = (ref $self) =~ /^([^:]+)/smx;  | 
| 
120
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   my $nsutil;  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
122
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my $ns  = "${ref}::util";  | 
| 
123
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     $nsutil = $ns->new();  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   } or do {  | 
| 
126
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
239
 | 
     carp qq[Failed to construct a util from the current namespace ($ref).];  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
129
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
172
 | 
   if($nsutil) {  | 
| 
130
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     $self->{util} = $nsutil;  | 
| 
131
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     return $self->{util};  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # ClearPress::driver is now a Class::Singleton so, casually ignoring  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # the state of any open transactions, we should be able to  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # instantiate more copies on demand  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
139
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   my $cputil    = ClearPress::util->new();  | 
| 
140
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my $config    = $cputil->config();  | 
| 
141
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   my $namespace = $config->val('application', 'namespace') ||  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   $config->val('application', 'name');  | 
| 
143
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $util         = "${namespace}::util"->new();  | 
| 
144
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->{util} = $util;  | 
| 
145
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $util;  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get {  | 
| 
149
 | 
98
 | 
 
 | 
 
 | 
  
98
  
 | 
  
1
  
 | 
35435
 | 
   my ($self, $field) = @_;  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
98
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
354
 | 
   if(!exists $self->{$field}) {  | 
| 
152
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
     $self->read();  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
   return $self->SUPER::get($field);  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getarray {  | 
| 
159
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
83
 | 
   my ($self, $class, $query, @args) = @_;  | 
| 
160
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
   my $util = $self->util();  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   if(!ref $self) {  | 
| 
163
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self = $self->new({  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			util => $util,  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		       });  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
   my $res  = [];  | 
| 
169
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
   my $sth;  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
172
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     my $dbh = $util->dbh();  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # statement caching removed as cache conflicts are dangerous  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # and could be easily generated by accident  | 
| 
176
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
132
 | 
     $sth = $dbh->prepare($query);  | 
| 
177
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3839
 | 
     $sth->execute(@args);  | 
| 
178
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     1; # sth->execute() does not return true!  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
   } or do {  | 
| 
181
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $query =~ s/\s+/ /smxg;  | 
| 
182
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     local $LIST_SEPARATOR = q[, ];  | 
| 
183
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     carp qq[GEN_GETARRAY ERROR\nEVAL_ERROR: $EVAL_ERROR\nCaller: @{[q[].caller]}\nQuery:\n$query\nDBH: @{[$util->dbh]}\nUTIL: $util\nParams: @{[map { (defined $_)?$_:'NULL' } @args]}];  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
184
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
187
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
405
 | 
   while(my $ref = $sth->fetchrow_hashref()) {  | 
| 
188
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     $ref->{util} = $util;  | 
| 
189
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     push @{$res}, $class->new($ref);  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
191
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
   $sth->finish();  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
   return $res;  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getall {  | 
| 
197
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
26
 | 
   my ($self, $class, $cachekey) = @_;  | 
| 
198
 | 
6
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
53
 | 
   $class ||= ref $self;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   if(!$cachekey) {  | 
| 
201
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     ($cachekey) = $class =~ /([^:]+)$/smx;  | 
| 
202
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     $cachekey   = _plfunc($cachekey);  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3507
 | 
   if(!$self->{$cachekey}) {  | 
| 
206
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my $sortk = $self->secondary_key;  | 
| 
207
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     if(!$sortk) {  | 
| 
208
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
       $sortk = $self->primary_key;  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
210
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
     my $query = <<"EOT";  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 /* model::gen_getall */  | 
| 
212
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
 SELECT   @{[join q(, ), $class->fields()]}  | 
| 
213
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
 FROM     @{[$class->table()]}  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ORDER BY $sortk  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
216
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     $self->{$cachekey} = $self->gen_getarray($class, $query);  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   return $self->{$cachekey};  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getfriends {  | 
| 
223
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
6
 | 
   my ($self, $class, $cachekey) = @_;  | 
| 
224
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
   $class ||= ref $self;  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   if(!$cachekey) {  | 
| 
227
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     ($cachekey) = $class =~ /([^:]+)$/smx;  | 
| 
228
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $cachekey   = _plfunc($cachekey);  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
231
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   if(!$self->{$cachekey}) {  | 
| 
232
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $link  = $self->primary_key();  | 
| 
233
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     my $query = <<"EOT";  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 /* model::gen_getfriends */  | 
| 
235
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 SELECT   @{[join q(, ), $class->fields()]}  | 
| 
236
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 FROM     @{[$class->table()]}  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE    $link=?  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ORDER BY $link  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
240
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $self->{$cachekey} = $self->gen_getarray($class, $query, $self->$link());  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
243
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   return $self->{$cachekey};  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getfriends_through {  | 
| 
247
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
17
 | 
   my ($self, $class, $through, $cachekey) = @_;  | 
| 
248
 | 
4
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
118
 | 
   $class ||= ref $self;  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   if(!$cachekey) {  | 
| 
251
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     ($cachekey) = $class =~ /([^:]+)$/smx;  | 
| 
252
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $cachekey   = _plfunc($cachekey);  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   if(!$self->{$cachekey}) {  | 
| 
256
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     my ($through_pkg) = (ref $self) =~ /^(.*::)[^:]+$/smx;  | 
| 
257
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $through_pkg     .= $through;  | 
| 
258
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $through_key   = $self->primary_key();  | 
| 
259
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $friend_key    = $class->primary_key();  | 
| 
260
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $query         = <<"EOT";  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 /* model::gen_getfriends_through */  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 SELECT @{[join q(, ),  | 
| 
263
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
                (map { "f.$_" } $class->fields()),  | 
| 
264
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
                (map { "t.$_" } $through_pkg->fields())]}  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
    | 
| 
265
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 FROM   @{[$class->table()]} f,  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        $through             t  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE  t.$through_key = ?  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 AND    t.$friend_key  = f.$friend_key  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
270
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     $self->{$cachekey} = $self->gen_getarray($class, $query, $self->$through_key());  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
273
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
   return $self->{$cachekey};  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getobj {  | 
| 
277
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
17
 | 
   my ($self, $class)   = @_;  | 
| 
278
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
   $class             ||= ref $self;  | 
| 
279
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   my $pk               = $class->primary_key();  | 
| 
280
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   my ($cachekey)       = $class =~ /([^:]+)$/smx;  | 
| 
281
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
16
 | 
   $self->{$cachekey} ||= $class->new({  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				      util => $self->util(),  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				      $pk  => $self->$pk(),  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				     });  | 
| 
285
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   return $self->{$cachekey};  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub gen_getobj_through {  | 
| 
289
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
9
 | 
   my ($self, $class, $through, $cachekey) = @_;  | 
| 
290
 | 
2
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
   $class ||= ref $self;  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   if(!$cachekey) {  | 
| 
293
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     ($cachekey) = $class =~ /([^:]+)$/smx;  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   if(!$self->{$cachekey}) {  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # todo: use $through class to determine $through_key  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #       - but $through class may not always be implemented  | 
| 
299
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $through_key = q(id_).$through;  | 
| 
300
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $friend_key  = $class->primary_key();  | 
| 
301
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $query       = <<"EOT";  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 /* model::gen_getobj_through */  | 
| 
303
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 SELECT @{[join q(, ), map { "f.$_" } $class->fields()]}  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
304
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 FROM   @{[$class->table()]} f,  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        $through            t  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE  t.$through_key = ?  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 AND    t.$friend_key  = f.$friend_key  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     $self->{$cachekey} = $self->gen_getarray($class, $query, $self->$through_key())->[0];  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
313
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   return $self->{$cachekey};  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub belongs_to {  | 
| 
317
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my ($class, @args) = @_;  | 
| 
318
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $class->has_a(@args);  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub hasa {  | 
| 
322
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
5827
 | 
   my ($class, @args) = @_;  | 
| 
323
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
187
 | 
   carp q[hasa is deprecated. Use has_a];  | 
| 
324
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
   return $class->has_a(@args);  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_a {  | 
| 
328
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
79
 | 
   my ($class, $attr) = @_;  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   if(ref $attr ne 'ARRAY') {  | 
| 
331
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     $attr = [$attr];  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
334
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   for my $single (@{$attr}) {  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
335
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     my $pkg = $single;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     if(ref $single eq 'HASH') {  | 
| 
338
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($pkg)    = values %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
339
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($single) = keys %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     my $namespace = "${class}::$pkg";  | 
| 
343
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     my $yield     = $class;  | 
| 
344
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     if($yield !~ /model/smx) {  | 
| 
345
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq[$pkg is not under a model:: namespace. Friend relationships will not work.];  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
348
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
     $yield =~ s/^(.*model::).*$/$1$pkg/smx;  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     if (defined &{$namespace}) {  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65
 | 
    | 
| 
351
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
55
 | 
     no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2176
 | 
    | 
| 
355
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     *{$namespace} = sub {  | 
| 
356
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
       my $self = shift;  | 
| 
357
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return $self->gen_getobj($yield);  | 
| 
358
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     };  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
361
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
233
 | 
   return;  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub hasmany {  | 
| 
365
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2781
 | 
   my ($class, @args) = @_;  | 
| 
366
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
   carp q[hasmany is deprecated. Use has_many];  | 
| 
367
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
   return $class->has_many(@args);  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_many {  | 
| 
371
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
1
  
 | 
51
 | 
   my ($class, $attr) = @_;  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
373
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
   if(ref $attr ne 'ARRAY') {  | 
| 
374
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     $attr = [$attr];  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
377
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   for my $single (@{$attr}) {  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
378
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my $pkg = $single;  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     if(ref $single eq 'HASH') {  | 
| 
381
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       ($pkg)    = values %{$single};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
382
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
       ($single) = keys %{$single};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
385
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     my $plural    = _plfunc($single);  | 
| 
386
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1385
 | 
     my $namespace = "${class}::$plural";  | 
| 
387
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $yield     = $class;  | 
| 
388
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     $yield        =~ s/^(.*model::).*$/$1$pkg/smx;  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
390
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     if($yield !~ /model/smx) {  | 
| 
391
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq[$pkg is not under a model:: namespace. Friend relationships will not work.];  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     if (defined &{$namespace}) {  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
    | 
| 
395
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
398
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
55
 | 
     no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2454
 | 
    | 
| 
399
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     *{$namespace} = sub {  | 
| 
400
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
       my $self = shift;  | 
| 
401
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       return $self->gen_getfriends($yield, $plural);  | 
| 
402
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     };  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
405
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   return;  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub belongs_to_through {  | 
| 
409
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my ($class, @args) = @_;  | 
| 
410
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $class->has_a_through(@args);  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_a_through {  | 
| 
414
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
43
 | 
   my ($class, $attr) = @_;  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   if(ref $attr ne 'ARRAY') {  | 
| 
417
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     $attr = [$attr];  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
420
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   for my $single (@{$attr}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
421
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $pkg = $single;  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     if(ref $single eq 'HASH') {  | 
| 
424
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($pkg)    = values %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
425
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($single) = keys %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
427
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     $pkg =~ s/[|].*//smx;  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
429
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     my $through;  | 
| 
430
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     ($single, $through) = split /[|]/smx, $single;  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
432
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     if(!$through) {  | 
| 
433
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq(Cannot build belongs_to_through for $single);  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
436
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $namespace = "${class}::$pkg";  | 
| 
437
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $yield     = $class;  | 
| 
438
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     $yield        =~ s/^(.*model::).*$/$1$pkg/smx;  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if($yield !~ /model/smx) {  | 
| 
441
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq[$pkg is not under a model:: namespace. Friend relationships will not work.];  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
444
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     if (defined &{$namespace}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
    | 
| 
445
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
448
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
61
 | 
     no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2191
 | 
    | 
| 
449
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     *{$namespace} = sub {  | 
| 
450
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
7
 | 
       my $self = shift;  | 
| 
451
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       return $self->gen_getobj_through($yield, $through);  | 
| 
452
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     };  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
455
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   return;  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_many_through {  | 
| 
459
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
59
 | 
   my ($class, $attr) = @_;  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
461
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   if(ref $attr ne 'ARRAY') {  | 
| 
462
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $attr = [$attr];  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   for my $single (@{$attr}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
466
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $pkg = $single;  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
468
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     if(ref $single eq 'HASH') {  | 
| 
469
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($pkg)    = values %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
470
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       ($single) = keys %{$single};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
472
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     $pkg =~ s/[|].*//smx;  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
474
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $through;  | 
| 
475
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     ($single, $through) = split /[|]/smx, $single;  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
477
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     if(!$through) {  | 
| 
478
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq(Cannot build has_many_through for $single);  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
481
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     my $plural    = _plfunc($single);  | 
| 
482
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1267
 | 
     my $namespace = "${class}::$plural";  | 
| 
483
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     my $yield     = $class;  | 
| 
484
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     $yield        =~ s/^(.*model::).*$/$1$pkg/smx;  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     if($yield !~ /model/smx) {  | 
| 
487
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq[$pkg is not under a model:: namespace. Friend relationships will not work.];  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
490
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     if (defined &{$namespace}) {  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
    | 
| 
491
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
494
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
50
 | 
     no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1225
 | 
    | 
| 
495
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     *{$namespace} = sub {  | 
| 
496
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
14
 | 
       my $self = shift;  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
498
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
       return $self->gen_getfriends_through($yield, $through, $plural);  | 
| 
499
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     };  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
502
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   return;  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_all {  | 
| 
506
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
  
1
  
 | 
16976
 | 
   my ($class) = @_;  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
508
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
129
 | 
   my ($single)  = $class =~ /([^:]+)$/smx;  | 
| 
509
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
   my $plural    = _plfunc($single);  | 
| 
510
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18262
 | 
   my $namespace = "${class}::$plural";  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
512
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
   if (defined &{$namespace}) {  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
    | 
| 
513
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
516
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
49
 | 
   no strict 'refs'; ## no critic (TestingAndDebugging::ProhibitNoStrict)  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8605
 | 
    | 
| 
517
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
   *{$namespace} = sub {  | 
| 
518
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
38515
 | 
     my $self = shift;  | 
| 
519
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
     return $self->gen_getall();  | 
| 
520
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
   };  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
   return 1;  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub create {  | 
| 
526
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
  
1
  
 | 
228
 | 
   my $self     = shift;  | 
| 
527
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
   my $util     = $self->util();  | 
| 
528
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
127
 | 
   my $dbh      = $util->dbh();  | 
| 
529
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
   my $pk       = $self->primary_key();  | 
| 
530
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
180
 | 
   my $tr_state = $util->transactions();  | 
| 
531
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
365
 | 
   my $table    = $self->table();  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
95
 | 
   if(!$table) {  | 
| 
534
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak q(No table defined);  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # disallow saving against zero  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
540
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
109
 | 
   if(!$self->$pk()) {  | 
| 
541
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
     delete $self->{$pk};  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
544
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
   my $query = <<"EOT";  | 
| 
545
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
 INSERT INTO $table (@{[join q(, ), $self->fields()]})  | 
| 
546
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
198
 | 
 VALUES (@{[join q(, ), map { q(?) } $self->fields()]})  | 
| 
 
 | 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
290
 | 
    | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
549
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
   my @args = map { $self->{$_} } $self->fields();  | 
| 
 
 | 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
236
 | 
    | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
551
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
     my $drv = $util->driver();  | 
| 
552
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     my $id  = $drv->create($query, @args);  | 
| 
553
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
     $self->$pk($id);  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   } or do {  | 
| 
556
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tr_state and $dbh->rollback();  | 
| 
557
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     carp qq[CREATE Query was:\n$query\n\nParams: @{[map { (defined $_)?$_:'NULL' } @args]}];  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
558
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR;  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
562
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
259701
 | 
     $tr_state and $dbh->commit();  | 
| 
563
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
229
 | 
     1;  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
565
 | 
16
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
476
 | 
   } or do {  | 
| 
566
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tr_state and $dbh->rollback();  | 
| 
567
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR;  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
461
 | 
   return 1;  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub read { ## no critic (homonym)  | 
| 
574
 | 
25
 | 
 
 | 
 
 | 
  
25
  
 | 
  
1
  
 | 
97
 | 
   my ($self, $query, @args) = @_;  | 
| 
575
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
   my $pk   = $self->primary_key();  | 
| 
576
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
215
 | 
   my $util = $self->util;  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
578
 | 
25
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
205
 | 
   if(!$query && !$self->{$pk}) {  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    carp q(No primary key);  | 
| 
580
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     return;  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $table = $self->table();  | 
| 
584
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   if(!$table) {  | 
| 
585
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak q(No table defined);  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
588
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
   if(!$self->{_loaded}) {  | 
| 
589
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     if(!$query) {  | 
| 
590
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
       $query = <<"EOT";  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 /* model::read */  | 
| 
592
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
 SELECT @{[join q(, ), $self->fields()]}  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 FROM   $table  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE  $pk=?  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
596
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
       @args = ($self->{$pk});  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     eval {  | 
| 
600
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
       my $sth = $util->dbh->prepare($query);  | 
| 
601
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2212
 | 
       $sth->execute(@args);  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
466
 | 
       my $ref = $sth->fetchrow_hashref();  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
       if(!$sth->rows()) {  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#########  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# entity not in database  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#  | 
| 
609
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	$sth->finish();  | 
| 
610
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
247
 | 
 	croak q[missing entity];  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
       $sth->finish();  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
615
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
       my $warnings = $util->driver->sth_has_warnings($sth);  | 
| 
616
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
       if(!$warnings) {  | 
| 
617
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
         for my $f ($self->fields()) {  | 
| 
618
 | 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
179
 | 
           $self->{$f} = $ref->{$f};  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
622
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for my $w (@{$warnings}) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
623
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
           carp qq[ClearPress::model::read: mysql warning: $w->[2]];  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
627
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
227
 | 
       1;  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
629
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     } or do {  | 
| 
630
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
71
 | 
       if($EVAL_ERROR =~ /missing\sentity/smx) {  | 
| 
631
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	return;  | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
633
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       carp qq[SELECT ERROR\nEVAL_ERROR: $EVAL_ERROR\nQuery:\n$query\n\nParams: @{[map { (defined $_)?$_:'NULL' } @args]}\n];  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
636
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
   $self->{_loaded} = 1;  | 
| 
637
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
   return 1;  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub update {  | 
| 
641
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
64
 | 
   my $self  = shift;  | 
| 
642
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
   my $pk    = $self->primary_key();  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
644
 | 
4
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
55
 | 
   if(!$pk || !$self->$pk()) {  | 
| 
645
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak q(No primary key);  | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
648
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
   my $table = $self->table();  | 
| 
649
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
   if(!$table) {  | 
| 
650
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak q(No table defined);  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
653
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my $util     = $self->util();  | 
| 
654
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
   my $tr_state = $util->transactions();  | 
| 
655
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
   my $dbh      = $util->dbh();  | 
| 
656
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
   my @fields   = grep { exists $self->{$_} }  | 
| 
657
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
                  grep { $_ ne $pk }  | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  $self->fields();  | 
| 
659
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   my $query   = <<"EOT";  | 
| 
660
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 UPDATE @{[$self->table()]}  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 SET    @{[join q(, ),  | 
| 
662
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                map  { qq[$_ = ?] }  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
    | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                @fields]}  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE  $pk=?  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
668
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     $dbh->do($query, {}, (map { $self->$_() } @fields), $self->$pk);  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
    | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
670
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   } or do {  | 
| 
671
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tr_state and $dbh->rollback();  | 
| 
672
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR.q[ ].$query;  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
676
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
46665
 | 
     $tr_state and $dbh->commit();  | 
| 
677
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     1;  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
679
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1280
 | 
   } or do {  | 
| 
680
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR;  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
   return 1;  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete { ## no critic (homonym)  | 
| 
687
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
16
 | 
   my $self     = shift;  | 
| 
688
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   my $util     = $self->util();  | 
| 
689
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my $tr_state = $util->transactions();  | 
| 
690
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   my $dbh      = $util->dbh();  | 
| 
691
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   my $pk       = $self->primary_key();  | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
693
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
15
 | 
   if(!$pk || !$self->$pk()) {  | 
| 
694
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak q(No primary key);  | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
697
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   my $query = <<"EOT";  | 
| 
698
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 DELETE FROM @{[$self->table()]}  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 WHERE $pk=?  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 EOT  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
703
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     $dbh->do($query, {}, $self->$pk());  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
705
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   } or do {  | 
| 
706
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $tr_state and $dbh->rollback();  | 
| 
707
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR.$query;  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
711
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23247
 | 
     $tr_state and $dbh->commit();  | 
| 
712
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     1;  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
714
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
517
 | 
   } or do {  | 
| 
715
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR;  | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
718
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
   return 1;  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub save {  | 
| 
722
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
723
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $pk   = $self->primary_key();  | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
725
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   if($pk && defined $self->{$pk}) {  | 
| 
726
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->update();  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
729
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return $self->create();  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub zdate {  | 
| 
733
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
15
 | 
   my $self = shift;  | 
| 
734
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   my $date = q[];  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
736
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   if(scalar grep { $_ eq 'date' } $self->fields()) {  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
    | 
| 
737
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     $date = $self->date() || q[];  | 
| 
738
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $date =~ s/[ ]/T/smx;  | 
| 
739
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $date .='Z';  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
742
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   if(!$date) {  | 
| 
743
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
     $date = strftime q(%Y-%m-%dT%H:%M:%SZ), gmtime;  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
746
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   return $date;  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub isodate {  | 
| 
750
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
150
 | 
   return strftime q(%Y-%m-%d %H:%M:%S), gmtime;  | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |