|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: mock repository class  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Test::PONAPI::Repository::MockDB;  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
4
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
7563
 | 
 use Moose;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # We MUST use DBD::SQLite before ::Constants to get anything useful!  | 
| 
7
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
64355
 | 
 use DBD::SQLite;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234904
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
346
 | 
    | 
| 
8
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
4027
 | 
 use DBD::SQLite::Constants qw/:result_codes/;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7369
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2329
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
3812
 | 
 use Test::PONAPI::Repository::MockDB::Loader;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
344
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
4490
 | 
 use Test::PONAPI::Repository::MockDB::Table::Articles;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
327
 | 
    | 
| 
13
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
4791
 | 
 use Test::PONAPI::Repository::MockDB::Table::People;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
311
 | 
    | 
| 
14
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
4175
 | 
 use Test::PONAPI::Repository::MockDB::Table::Comments;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
327
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
71
 | 
 use PONAPI::Constants;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1146
 | 
    | 
| 
17
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
65
 | 
 use PONAPI::Exception;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35608
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 with 'PONAPI::Repository';  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has dbh => (  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     is     => 'ro',  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     isa    => 'DBI::db',  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     writer => '_set_dbh'  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has tables => (  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     is      => 'ro',  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     isa     => 'HashRef',  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     lazy    => 1,  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     default => sub {  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return +{  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             articles => Test::PONAPI::Repository::MockDB::Table::Articles->new,  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             people   => Test::PONAPI::Repository::MockDB::Table::People->new,  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             comments => Test::PONAPI::Repository::MockDB::Table::Comments->new,  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub BUILD {  | 
| 
41
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
  
0
  
 | 
46
 | 
     my ($self, $params) = @_;  | 
| 
42
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
589
 | 
     my $loader = Test::PONAPI::Repository::MockDB::Loader->new;  | 
| 
43
 | 
13
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
100
 | 
     $loader->load unless $params->{skip_data_load};  | 
| 
44
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108077
 | 
     $self->_set_dbh( $loader->dbh );  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_type {  | 
| 
48
 | 
257
 | 
 
 | 
 
 | 
  
257
  
 | 
  
0
  
 | 
1308
 | 
     my ( $self, $type ) = @_;  | 
| 
49
 | 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8112
 | 
     !! exists $self->tables->{$type};  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_relationship {  | 
| 
53
 | 
117
 | 
 
 | 
 
 | 
  
117
  
 | 
  
0
  
 | 
355
 | 
     my ( $self, $type, $rel_name ) = @_;  | 
| 
54
 | 
117
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3531
 | 
     if ( my $table = $self->tables->{$type} ) {  | 
| 
55
 | 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3983
 | 
         my $relations = $table->RELATIONS;  | 
| 
56
 | 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1014
 | 
         return !! exists $relations->{ $rel_name };  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
58
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 0;  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_one_to_many_relationship {  | 
| 
62
 | 
160
 | 
 
 | 
 
 | 
  
160
  
 | 
  
0
  
 | 
433
 | 
     my ( $self, $type, $rel_name ) = @_;  | 
| 
63
 | 
160
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5436
 | 
     if ( my $table = $self->tables->{$type} ) {  | 
| 
64
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5281
 | 
         my $relations = $table->RELATIONS;  | 
| 
65
 | 
160
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
480
 | 
         return if !exists $relations->{ $rel_name };  | 
| 
66
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6111
 | 
         return !$relations->{ $rel_name }->ONE_TO_ONE;  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
68
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub type_has_fields {  | 
| 
72
 | 
56
 | 
 
 | 
 
 | 
  
56
  
 | 
  
0
  
 | 
154
 | 
     my ($self, $type, $fields) = @_;  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Check for invalid 'fields'  | 
| 
75
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1689
 | 
     my $table_obj = $self->tables->{$type};  | 
| 
76
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
     my %columns   = map +($_=>1), @{ $table_obj->COLUMNS };  | 
| 
 
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
942
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
78
 | 
56
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
411
 | 
     return 1 unless grep !exists $columns{$_}, @$fields;  | 
| 
79
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     return;  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub retrieve_all {  | 
| 
83
 | 
54
 | 
 
 | 
 
 | 
  
54
  
 | 
  
0
  
 | 
327
 | 
     my ( $self, %args ) = @_;  | 
| 
84
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
177
 | 
     my $type = $args{type};  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
54
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
184
 | 
     $self->_validate_page($args{page}) if $args{page};  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1793
 | 
     my $stmt = $self->tables->{$type}->select_stmt(%args);  | 
| 
89
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
388
 | 
     $self->_add_resources( stmt => $stmt, %args );  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub retrieve {  | 
| 
93
 | 
37
 | 
 
 | 
 
 | 
  
37
  
 | 
  
0
  
 | 
257
 | 
     my ( $self, %args ) = @_;  | 
| 
94
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
153
 | 
     $args{filter}{id} = delete $args{id};  | 
| 
95
 | 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
233
 | 
     $self->retrieve_all(%args);  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub retrieve_relationships {  | 
| 
99
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
25
 | 
     my ( $self, %args ) = @_;  | 
| 
100
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     my ($type, $rel_type, $doc) = @args{qw/type rel_type document/};  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $page = $args{page};  | 
| 
103
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     $self->_validate_page($page) if $page;  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
4
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
16
 | 
     my $sort = $args{sort} || [];  | 
| 
106
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     if ( @$sort ) {  | 
| 
107
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
13
 | 
         PONAPI::Exception->throw(  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             message => "You can only sort by id in retrieve_relationships"  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ) if @$sort > 1 || $sort->[0] !~ /\A(-)?id\z/;  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
111
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         my $desc = !!$1;  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
         my $table_obj    = $self->tables->{$type};  | 
| 
114
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
         my $relation_obj = $table_obj->RELATIONS->{$rel_type};  | 
| 
115
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
         my $id_column    = $relation_obj->REL_ID_COLUMN;  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         @$sort = ($desc ? '-' : '') . $id_column;  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     my $rels = $self->_find_resource_relationships(  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         %args,  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # No need to fetch other relationship types  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields => { $type => [ $rel_type ] },  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
126
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     return unless @{ $rels || [] };  | 
| 
 
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     $doc->add_resource( %$_ ) for @$rels;  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
130
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4507
 | 
     $self->_add_pagination_links(  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         page     => $page,  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         document => $doc,  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ) if $page;  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub retrieve_by_relationship {  | 
| 
138
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
40
 | 
     my ( $self, %args ) = @_;  | 
| 
139
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     my ( $doc, $type, $rel_type, $fields, $include ) = @args{qw< document type rel_type fields include >};  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
141
 | 
6
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
22
 | 
     my $sort = delete $args{sort} || [];  | 
| 
142
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     my $page = delete $args{page};  | 
| 
143
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     $self->_validate_page($page) if $page;  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # We need to avoid passing sort and page here, since sort  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # will have columns for the actual data, not the relationship  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # table, and page needs to happen after sorting  | 
| 
148
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
     my $rels = $self->_find_resource_relationships(  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         %args,  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # No need to fetch other relationship types  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields => { $type => [ $rel_type ] },  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
154
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     return unless @$rels;  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my $q_type = $rels->[0]{type};  | 
| 
157
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my $q_ids  = [ map { $_->{id} } @{$rels} ];  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
252
 | 
     my $stmt = $self->tables->{$q_type}->select_stmt(  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         type   => $q_type,  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields => $fields,  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         filter => { id => $q_ids },  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sort   => $sort,  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         page   => $page,  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     $self->_add_resources(  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         document => $doc,  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         stmt     => $stmt,  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         type     => $q_type,  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields   => $fields,  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         include  => $include,  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         page     => $page,  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sort     => $sort,  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub create {  | 
| 
179
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
  
0
  
 | 
30
 | 
     my ( $self, %args ) = @_;  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
     my $dbh = $self->dbh;  | 
| 
182
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     $dbh->begin_work;  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
     my ($e, $failed);  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
186
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         local $@;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
187
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         eval  { $self->_create( %args ); 1; }  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
188
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         or do {  | 
| 
189
 | 
2
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
14
 | 
             ($failed, $e) = (1, $@||'Unknown error');  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
192
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     if ( $failed ) {  | 
| 
193
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
228
 | 
         $dbh->rollback;  | 
| 
194
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         die $e;  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29978
 | 
     $dbh->commit;  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
     return;  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _create {  | 
| 
203
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
26
 | 
     my ( $self, %args ) = @_;  | 
| 
204
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     my ( $doc, $type, $data ) = @args{qw< document type data >};  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
5
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
22
 | 
     my $attributes    = $data->{attributes} || {};  | 
| 
207
 | 
5
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
36
 | 
     my $relationships = delete $data->{relationships} || {};  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
172
 | 
     my $table_obj = $self->tables->{$type};  | 
| 
210
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     my ($stmt, $return, $extra) = $table_obj->insert_stmt(  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         table  => $type,  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         values => $attributes,  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     $self->_db_execute( $stmt );  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
217
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
169
 | 
     my $new_id = $self->dbh->last_insert_id("","","","");  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     foreach my $rel_type ( keys %$relationships ) {  | 
| 
220
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         my $rel_data = $relationships->{$rel_type};  | 
| 
221
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         $rel_data = [ $rel_data ] if ref($rel_data) ne 'ARRAY';  | 
| 
222
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         $self->_create_relationships(  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             %args,  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             id       => $new_id,  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             rel_type => $rel_type,  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             data     => $rel_data,  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Spec says we MUST return this, both here and in the Location header;  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # the DAO takes care of the header, but we need to put it in the doc  | 
| 
232
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     $doc->add_resource( type => $type, id => $new_id );  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2266
 | 
     return;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _create_relationships {  | 
| 
238
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
57
 | 
     my ( $self, %args ) = @_;  | 
| 
239
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     my ( $type, $id, $rel_type, $data ) = @args{qw< type id rel_type data >};  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
     my $table_obj     = $self->tables->{$type};  | 
| 
242
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
219
 | 
     my $relation_obj = $table_obj->RELATIONS->{$rel_type};  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
213
 | 
     my $rel_table = $relation_obj->TABLE;  | 
| 
245
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
197
 | 
     my $key_type  = $relation_obj->TYPE;  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
247
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
219
 | 
     my $id_column     = $relation_obj->ID_COLUMN;  | 
| 
248
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
234
 | 
     my $rel_id_column = $relation_obj->REL_ID_COLUMN;  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     my @all_values;  | 
| 
251
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     foreach my $orig ( @$data ) {  | 
| 
252
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
         my $relationship = { %$orig };  | 
| 
253
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
         my $data_type = delete $relationship->{type};  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
38
 | 
         if ( $data_type ne $key_type ) {  | 
| 
256
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
             PONAPI::Exception->throw(  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 message          => "Data has type `$data_type`, but we were expecting `$key_type`",  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bad_request_data => 1,  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
262
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         $relationship->{$id_column}     = $id;  | 
| 
263
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         $relationship->{$rel_id_column} = delete $relationship->{id};  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         push @all_values, $relationship;  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
268
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my $one_to_one = !$self->has_one_to_many_relationship($type, $rel_type);  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
270
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     foreach my $values ( @all_values ) {  | 
| 
271
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
         my ($stmt, $return, $extra) = $relation_obj->insert_stmt(  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             table  => $rel_table,  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             values => $values,  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         my ($failed, $e);  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         {  | 
| 
278
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
             local $@;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
279
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
             eval  { $self->_db_execute( $stmt ); 1; }  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
280
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
             or do {  | 
| 
281
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
7
 | 
                 ($failed, $e) = (1, $@||'Unknown error');  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             };  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
284
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         if ( $failed ) {  | 
| 
285
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
             if ( $one_to_one && do { local $@; eval { $e->sql_error } } ) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # Can't quite do ::Upsert  | 
| 
287
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $stmt = $relation_obj->update_stmt(  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     table  => $rel_table,  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     values => [ %$values ],  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     where  => { $id_column => $id },  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     driver => 'sqlite',  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 );  | 
| 
293
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $self->_db_execute( $stmt );  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
296
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                 die $e;  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
301
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     return PONAPI_UPDATED_NORMAL;  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub create_relationships {  | 
| 
305
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
34
 | 
     my ($self, %args) = @_;  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
     my $dbh = $self->dbh;  | 
| 
308
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     $dbh->begin_work;  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
     my ($ret, $e, $failed);  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
312
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         local $@;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
313
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
         eval  { $ret = $self->_create_relationships( %args ); 1; }  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
314
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         or do {  | 
| 
315
 | 
2
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
8
 | 
             ($failed, $e) = (1, $@||'Unknown error');  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
318
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     if ( $failed ) {  | 
| 
319
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
         $dbh->rollback;  | 
| 
320
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         die $e;  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
323
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16754
 | 
     $dbh->commit;  | 
| 
324
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     return $ret;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub update {  | 
| 
328
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
0
  
 | 
76
 | 
     my ( $self, %args ) = @_;  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
374
 | 
     my $dbh = $self->dbh;  | 
| 
331
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
     $dbh->begin_work;  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
252
 | 
     my ($ret, $e, $failed);  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
335
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
         local $@;  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
336
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
         eval  { $ret = $self->_update( %args ); 1 }  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
    | 
| 
337
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         or do {  | 
| 
338
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
6
 | 
             ($failed, $e) = (1, $@||'Unknown error');  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
341
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     if ( $failed ) {  | 
| 
342
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
         $dbh->rollback;  | 
| 
343
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         die $e;  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66909
 | 
     $dbh->commit;  | 
| 
347
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
171
 | 
     return $ret;  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _update {  | 
| 
351
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
62
 | 
     my ( $self, %args ) = @_;  | 
| 
352
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     my ( $type, $id, $data ) = @args{qw< type id data >};  | 
| 
353
 | 
12
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
26
 | 
     my ($attributes, $relationships) = map $_||{}, @{ $data }{qw/ attributes relationships /};  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
    | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
355
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     my $return = PONAPI_UPDATED_NORMAL;  | 
| 
356
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     if ( %$attributes ) {  | 
| 
357
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
261
 | 
         my $table_obj = $self->tables->{$type};  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Per the spec, the api behaves *very* differently if ->update does extra things  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # under the hood.  Case point: the updated column in Articles  | 
| 
360
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
289
 | 
         my ($stmt, $extra_return, $msg) = $table_obj->update_stmt(  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             table  => $type,  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             where  => { $table_obj->ID_COLUMN => $id },  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             values => $attributes,  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
366
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         $return = $extra_return if defined $extra_return;  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
368
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
         my $sth = $self->_db_execute( $stmt );  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # We had a successful update, but it updated nothing  | 
| 
371
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
123
 | 
         if ( !$sth->rows ) {  | 
| 
372
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
             $return = PONAPI_UPDATED_NOTHING;  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
376
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     foreach my $rel_type ( keys %$relationships ) {  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $update_rel_return = $self->_update_relationships(  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             type     => $type,  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             id       => $id,  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             rel_type => $rel_type,  | 
| 
381
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
             data     => $relationships->{$rel_type},  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # We tried updating the attributes but  | 
| 
385
 | 
8
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
162
 | 
         $return = $update_rel_return  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if $return            == PONAPI_UPDATED_NOTHING  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             && $update_rel_return != PONAPI_UPDATED_NOTHING;  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
390
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
     return $return;  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _update_relationships {  | 
| 
394
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
 
 | 
78
 | 
     my ($self, %args) = @_;  | 
| 
395
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     my ( $type, $id, $rel_type, $data ) = @args{qw< type id rel_type data >};  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
397
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
479
 | 
     my $table_obj    = $self->tables->{$type};  | 
| 
398
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
463
 | 
     my $relation_obj = $table_obj->RELATIONS->{$rel_type};  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
450
 | 
     my $column_rel_type = $relation_obj->TYPE;  | 
| 
401
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
428
 | 
     my $rel_table       = $relation_obj->TABLE;  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
403
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
480
 | 
     my $id_column     = $relation_obj->ID_COLUMN;  | 
| 
404
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
504
 | 
     my $rel_id_column = $relation_obj->REL_ID_COLUMN;  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Let's have an arrayref  | 
| 
407
 | 
13
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
115
 | 
     $data = $data  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ? ref($data) eq 'HASH' ? [ keys(%$data) ? $data : () ] : $data  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             : [];  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Let's start by clearing all relationships; this way  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # we can implement the SQL below without adding special cases  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # for ON DUPLICATE KEY UPDATE and sosuch.  | 
| 
414
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     my $stmt = $relation_obj->delete_stmt(  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         table => $rel_table,  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         where => { $id_column => $id },  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
418
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
70
 | 
     $self->_db_execute( $stmt );  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
420
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     my $return = PONAPI_UPDATED_NORMAL;  | 
| 
421
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     foreach my $insert ( @$data ) {  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ($stmt, $insert_return, $extra) = $table_obj->insert_stmt(  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             table  => $rel_table,  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             values => {  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $id_column     => $id,  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $rel_id_column => $insert->{id},  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             },  | 
| 
428
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
         );  | 
| 
429
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
         $self->_db_execute( $stmt );  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
431
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
         $return = $insert_return if $insert_return;  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
434
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     return $return;  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub update_relationships {  | 
| 
438
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
25
 | 
     my ( $self, %args ) = @_;  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117
 | 
     my $dbh = $self->dbh;  | 
| 
441
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     $dbh->begin_work;  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
443
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
     my ($ret, $e, $failed);  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
445
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         local $@;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
446
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         eval  { $ret = $self->_update_relationships( %args ); 1 }  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
447
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         or do {  | 
| 
448
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
             ($failed, $e) = (1, $@||'Unknown error');  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
451
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     if ( $failed ) {  | 
| 
452
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $dbh->rollback;  | 
| 
453
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die $e;  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
456
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27799
 | 
     $dbh->commit;  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
     return $ret;  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete : method {  | 
| 
462
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
18
 | 
     my ( $self, %args ) = @_;  | 
| 
463
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my ( $type, $id ) = @args{qw< type id >};  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
     my $table_obj = $self->tables->{$type};  | 
| 
466
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $stmt      = $table_obj->delete_stmt(  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         table => $type,  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         where => { id => $id },  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
471
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
     my $sth = $self->_db_execute( $stmt );  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
473
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
     return;  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete_relationships {  | 
| 
477
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
33
 | 
     my ( $self, %args ) = @_;  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
     my $dbh = $self->dbh;  | 
| 
480
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     $dbh->begin_work;  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
482
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
     my ($ret, $e, $failed);  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
484
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         local $@;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
485
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         eval  { $ret = $self->_delete_relationships( %args ); 1 }  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
    | 
| 
486
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         or do {  | 
| 
487
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
             ($failed, $e) = (1, $@||'Unknown error');  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
490
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     if ( $failed ) {  | 
| 
491
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $dbh->rollback;  | 
| 
492
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die $e;  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22400
 | 
     $dbh->commit;  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
497
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
     return $ret;  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _delete_relationships {  | 
| 
501
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
26
 | 
     my ( $self, %args ) = @_;  | 
| 
502
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     my ( $type, $id, $rel_type, $data ) = @args{qw< type id rel_type data >};  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
504
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
     my $table_obj    = $self->tables->{$type};  | 
| 
505
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
135
 | 
     my $relation_obj = $table_obj->RELATIONS->{$rel_type};  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
507
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
     my $table    = $relation_obj->TABLE;  | 
| 
508
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
130
 | 
     my $key_type = $relation_obj->TYPE;  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
510
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
133
 | 
     my $id_column     = $relation_obj->ID_COLUMN;  | 
| 
511
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
     my $rel_id_column = $relation_obj->REL_ID_COLUMN;  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
513
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my @all_values;  | 
| 
514
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     foreach my $resource ( @$data ) {  | 
| 
515
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         my $data_type = $resource->{type};  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
517
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         if ( $data_type ne $key_type ) {  | 
| 
518
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             PONAPI::Exception->throw(  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 message          => "Data has type `$data_type`, but we were expecting `$key_type`",  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 bad_request_data => 1,  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $delete_where = {  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $id_column     => $id,  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $rel_id_column => $resource->{id},  | 
| 
527
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
         };  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
529
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         push @all_values, $delete_where;  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
532
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my $ret = PONAPI_UPDATED_NORMAL;  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
534
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     my $rows_modified = 0;  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     DELETE:  | 
| 
536
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     foreach my $where ( @all_values ) {  | 
| 
537
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         my $stmt = $relation_obj->delete_stmt(  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             table => $table,  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             where => $where,  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
542
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         my $sth = $self->_db_execute( $stmt );  | 
| 
543
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
         $rows_modified += $sth->rows;  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
546
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     $ret = PONAPI_UPDATED_NOTHING if !$rows_modified;  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
548
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     return $ret;  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## --------------------------------------------------------  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _add_resources {  | 
| 
555
 | 
60
 | 
 
 | 
 
 | 
  
60
  
 | 
 
 | 
386
 | 
     my ( $self, %args ) = @_;  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $doc, $stmt, $type ) =  | 
| 
557
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
226
 | 
         @args{qw< document stmt type >};  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
559
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
225
 | 
     my $sth = $self->_db_execute( $stmt );  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2318
 | 
     while ( my $row = $sth->fetchrow_hashref() ) {  | 
| 
562
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
346
 | 
         my $id = delete $row->{id};  | 
| 
563
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
478
 | 
         my $rec = $doc->add_resource( type => $type, id => $id );  | 
| 
564
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63585
 | 
         $rec->add_attribute( $_ => $row->{$_} ) for keys %{$row};  | 
| 
 
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
593
 | 
    | 
| 
565
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49499
 | 
         $rec->add_self_link;  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
567
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53620
 | 
         $self->_add_resource_relationships($rec, %args);  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->_add_pagination_links(  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         page => $args{page},  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         rows => scalar $sth->rows,  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         document => $doc,  | 
| 
574
 | 
60
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
380
 | 
     ) if $args{page};  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
576
 | 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27492
 | 
     return;  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _add_pagination_links {  | 
| 
580
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
38
 | 
     my ($self, %args) = @_;  | 
| 
581
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     my ($page, $rows_fetched, $document) = @args{qw/page rows document/};  | 
| 
582
 | 
7
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
28
 | 
     $rows_fetched ||= -1;  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
584
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     my ($offset, $limit) = @{$page}{qw/offset limit/};  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
    | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
586
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     my %current = %$page;  | 
| 
587
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     my %first = ( %current, offset => 0, );  | 
| 
588
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     my (%previous, %next);  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
590
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     if ( ($offset - $limit) >= 0 ) {  | 
| 
591
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         %previous = %current;  | 
| 
592
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         $previous{offset} -= $current{limit};  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     if ( $rows_fetched >= $limit ) {  | 
| 
596
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
         %next = %current;  | 
| 
597
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         $next{offset} += $limit;  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $document->add_pagination_links(  | 
| 
601
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
         first => \%first,  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         self  => \%current,  | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         prev  => \%previous,  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         next  => \%next,  | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _validate_page {  | 
| 
609
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
19
 | 
     my ($self, $page) = @_;  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     exists $page->{limit}  | 
| 
612
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         or PONAPI::Exception->throw(message => "Limit missing for `page`");  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
614
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     $page->{limit} =~ /\A[0-9]+\z/  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         or PONAPI::Exception->throw(message => "Bad limit value ($page->{limit}) in `page`");  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
617
 | 
7
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
51
 | 
     !exists $page->{offset} || ($page->{offset} =~ /\A[0-9]+\z/)  | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         or PONAPI::Exception->throw(message => "Bad offset value in `page`");  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
7
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
32
 | 
     $page->{offset} ||= 0;  | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
622
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     return;  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _add_resource_relationships {  | 
| 
626
 | 
78
 | 
 
 | 
 
 | 
  
78
  
 | 
 
 | 
649
 | 
     my ( $self, $rec, %args ) = @_;  | 
| 
627
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
313
 | 
     my $doc    = $rec->find_root;  | 
| 
628
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11244
 | 
     my $type   = $rec->type;  | 
| 
629
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
711
 | 
     my $fields = $args{fields};  | 
| 
630
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
     my %include = map { $_ => 1 } @{ $args{include} };  | 
| 
 
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
    | 
| 
 
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
    | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Do not add sort or page here -- those were for the primary resource  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # *only*.  | 
| 
634
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2326
 | 
     my $rels = $self->_fetchall_relationships(  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         type     => $type,  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         id       => $rec->id,  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         document => $doc,  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields   => $fields,  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
640
 | 
78
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
267
 | 
     $rels or return;  | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
319
 | 
     for my $r ( keys %$rels ) {  | 
| 
643
 | 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8785
 | 
         my $relationship = $rels->{$r};  | 
| 
644
 | 
122
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
331
 | 
         @$relationship or next;  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
646
 | 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
232
 | 
         my $rel_type = $relationship->[0]{type};  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # skipping the relationship if the type has an empty `fields` set  | 
| 
649
 | 
98
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
344
 | 
         next if exists $fields->{$rel_type} and !@{ $fields->{$rel_type} };  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
651
 | 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
329
 | 
         my $one_to_many = $self->has_one_to_many_relationship($type, $r);  | 
| 
652
 | 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
268
 | 
         for ( @$relationship ) {  | 
| 
653
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121499
 | 
             $rec->add_relationship( $r, $_, $one_to_many )  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ->add_self_link  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 ->add_related_link;  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->_add_included(  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $rel_type,                            # included type  | 
| 
660
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
140
 | 
             +[ map { $_->{id} } @$relationship ], # included ids  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             %args                                 # filters / fields / etc.  | 
| 
662
 | 
96
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
483767
 | 
         ) if exists $include{$r};  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
665
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9170
 | 
     return;  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _add_included {  | 
| 
669
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
 
 | 
108
 | 
     my ( $self, $type, $ids, %args ) = @_;  | 
| 
670
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
     my ( $doc, $filter, $fields ) = @args{qw< document filter fields >};  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
672
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     $filter->{id} = $ids;  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Do NOT add sort -- sort here was for the *main* resource!  | 
| 
675
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
540
 | 
     my $stmt = $self->tables->{$type}->select_stmt(  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         type   => $type,  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         filter => $filter,  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fields => $fields,  | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
681
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     my $sth = $self->_db_execute( $stmt );  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
459
 | 
     while ( my $inc = $sth->fetchrow_hashref() ) {  | 
| 
684
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2768
 | 
         my $id = delete $inc->{id};  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $doc->add_included( type => $type, id => $id )  | 
| 
686
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
             ->add_attributes( %{$inc} )  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12299
 | 
    | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ->add_self_link;  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _find_resource_relationships {  | 
| 
692
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
64
 | 
     my ( $self, %args ) = @_;  | 
| 
693
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     my $rel_type = $args{rel_type};  | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
695
 | 
10
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
64
 | 
     if ( $rel_type and my $rels = $self->_fetchall_relationships(%args) ) {  | 
| 
696
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
71
 | 
         return $rels->{$rel_type} if exists $rels->{$rel_type};  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
699
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return [];  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _fetchall_relationships {  | 
| 
703
 | 
88
 | 
 
 | 
 
 | 
  
88
  
 | 
 
 | 
1135
 | 
     my ( $self, %args ) = @_;  | 
| 
704
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
321
 | 
     my ( $type, $id ) = @args{qw< type id >};  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # we don't want to autovivify $args{fields}{$type}  | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # since it will be checked in order to know whether  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # the key existed in the original fields argument  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my %type_fields = exists $args{fields}{$type}  | 
| 
710
 | 
88
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
484
 | 
         ? map { $_ => 1 } @{ $args{fields}{$type} }  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
 
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
    | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : ();  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
713
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
182
 | 
     my %ret;  | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @errors;  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
716
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
151
 | 
     for my $name ( keys %{ $self->tables->{$type}->RELATIONS } ) {  | 
| 
 
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2793
 | 
    | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # If we have fields, and this relationship is not mentioned, skip  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # it.  | 
| 
719
 | 
157
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
6546
 | 
         next if keys %type_fields > 0 and !exists $type_fields{$name};  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
721
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4512
 | 
         my $table_obj     = $self->tables->{$type};  | 
| 
722
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4379
 | 
         my $rel_table_obj = $table_obj->RELATIONS->{$name};  | 
| 
723
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4234
 | 
         my $rel_type      = $rel_table_obj->TYPE;  | 
| 
724
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4270
 | 
         my $rel_table     = $rel_table_obj->TABLE;  | 
| 
725
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4302
 | 
         my $id_column     = $rel_table_obj->ID_COLUMN;  | 
| 
726
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5118
 | 
         my $rel_id_column = $rel_table_obj->REL_ID_COLUMN;  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
728
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
923
 | 
         my $stmt = $rel_table_obj->select_stmt(  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             %args,  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             type   => $rel_table,  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             filter => { $id_column => $id },  | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             fields => [ $rel_id_column ],  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
735
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
567
 | 
         my $sth = $self->_db_execute( $stmt );  | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $ret{$name} = +[  | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             map +{ type => $rel_type, id => $_->{$rel_id_column} },  | 
| 
739
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
280
 | 
             @{ $sth->fetchall_arrayref({}) }  | 
| 
 
 | 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1308
 | 
    | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ];  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
743
 | 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7661
 | 
     return \%ret;  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Might not be there?  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $sqlite_constraint_failed = do {  | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     local $@;  | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     eval { SQLITE_CONSTRAINT() } // undef;  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _db_execute {  | 
| 
752
 | 
255
 | 
 
 | 
 
 | 
  
255
  
 | 
 
 | 
619
 | 
     my ( $self, $stmt ) = @_;  | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
754
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
460
 | 
     my ($sth, $ret, $failed, $e);  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
756
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
401
 | 
         local $@;  | 
| 
 
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
430
 | 
    | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         eval {  | 
| 
758
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8588
 | 
             $sth = $self->dbh->prepare($stmt->{sql});  | 
| 
759
 | 
255
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21571
 | 
             $ret = $sth->execute(@{ $stmt->{bind} || [] });  | 
| 
 
 | 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38544
 | 
    | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # This should never happen, since the DB handle is  | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # created with RaiseError.  | 
| 
762
 | 
252
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1207
 | 
             die $DBI::errstr if !$ret;  | 
| 
763
 | 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1004
 | 
             1;  | 
| 
764
 | 
255
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
489
 | 
         } or do {  | 
| 
765
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
             $failed = 1;  | 
| 
766
 | 
3
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
12
 | 
             $e = $@ || 'Unknown error';  | 
| 
767
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         };  | 
| 
768
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
769
 | 
255
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
635
 | 
     if ( $failed ) {  | 
| 
770
 | 
3
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
54
 | 
         my $errstr = $DBI::errstr || "Unknown SQL error";  | 
| 
771
 | 
3
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
24
 | 
         my $err_id = $DBI::err    || 0;  | 
| 
772
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
773
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         my $message;  | 
| 
774
 | 
3
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
33
 | 
         if ( $sqlite_constraint_failed && $err_id && $err_id == $sqlite_constraint_failed ) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
775
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
             PONAPI::Exception->throw(  | 
| 
776
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 message   => "Table constraint failed: $errstr",  | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 sql_error => 1,  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 status    => 409,  | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ( $err_id ) {  | 
| 
782
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             PONAPI::Exception->throw(  | 
| 
783
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 message   => $errstr,  | 
| 
784
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 sql_error => 1,  | 
| 
785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
786
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
787
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
788
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             PONAPI::Exception->throw(  | 
| 
789
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 message => "Non-SQL error while running query? $e"  | 
| 
790
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             )  | 
| 
791
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
793
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
794
 | 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
945
 | 
     return $sth;  | 
| 
795
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
796
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
797
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __PACKAGE__->meta->make_immutable;  | 
| 
798
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
78
 | 
 no Moose; 1;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
    | 
| 
799
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  | 
| 
801
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
803
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding UTF-8  | 
| 
805
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
806
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
807
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
808
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Test::PONAPI::Repository::MockDB - mock repository class  | 
| 
809
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
810
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
811
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
812
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 version 0.003003  | 
| 
813
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHORS  | 
| 
815
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
816
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
817
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
818
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
819
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Mickey Nasriachi <mickey@cpan.org>  | 
| 
821
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
823
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
824
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Stevan Little <stevan@cpan.org>  | 
| 
825
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
826
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Brian Fraser <hugmeir@cpan.org>  | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
831
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT AND LICENSE  | 
| 
833
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
834
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is copyright (c) 2019 by Mickey Nasriachi, Stevan Little, Brian Fraser.  | 
| 
835
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
836
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is free software; you can redistribute it and/or modify it under  | 
| 
837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the same terms as the Perl 5 programming language system itself.  | 
| 
838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
839
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |