|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package DBR::Record::Helper;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
104
 | 
 use strict;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1479
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
722
 | 
    | 
| 
4
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
104
 | 
 use base 'DBR::Common';  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1439
 | 
    | 
| 
5
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
158
 | 
 use Carp;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4467
 | 
    | 
| 
6
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
112
 | 
 use DBR::Query::Part;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
387
 | 
    | 
| 
7
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
95
 | 
 use DBR::Query::Select;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
527
 | 
    | 
| 
8
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
8784
 | 
 use DBR::Query::Update;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
510
 | 
    | 
| 
9
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
9759
 | 
 use DBR::Query::Delete;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
490
 | 
    | 
| 
10
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
8981
 | 
 use DBR::ResultSet;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
693
 | 
    | 
| 
11
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
195
 | 
 use DBR::ResultSet::Empty;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
399
 | 
    | 
| 
12
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
100
 | 
 use DBR::Misc::Dummy;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
684
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # we can get away with making these once for all time  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use constant ({  | 
| 
16
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67445
 | 
 	       EMPTY => bless( [], 'DBR::ResultSet::Empty'),  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       DUMMY => bless( [], 'DBR::Misc::Dummy'),  | 
| 
18
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
146
 | 
 	      });  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
20
 | 
27
 | 
 
 | 
 
 | 
  
27
  
 | 
  
0
  
 | 
105
 | 
       my( $package ) = shift;  | 
| 
21
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
407
 | 
       my %params = @_;  | 
| 
22
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
226
 | 
       my $self = {  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  session  => $params{session},  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  instance => $params{instance},  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  tablemap => $params{tablemap},  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  flookup  => $params{flookup},  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  pkmap    => $params{pkmap},  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  scope    => $params{scope},  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  lastidx  => $params{lastidx},  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		 };  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
       bless( $self, $package ); # BS object  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
163
 | 
       $self->{session}  or return $self->_error('session is required');  | 
| 
35
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
111
 | 
       $self->{instance} or return $self->_error('instance is required');  | 
| 
36
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
       $self->{scope}    or return $self->_error('scope is required');  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
99
 | 
       $self->{tablemap} or return $self->_error('tablemap is required');  | 
| 
39
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
108
 | 
       $self->{pkmap}    or return $self->_error('pkmap is required');           # X  | 
| 
40
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
109
 | 
       $self->{flookup}  or return $self->_error('flookup is required');         # X  | 
| 
41
 | 
27
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
101
 | 
       defined($self->{lastidx}) or return $self->_error('lastidx is required');  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
174
 | 
       return $self;  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub set{  | 
| 
47
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
0
  
 | 
9
 | 
       my $self = shift;  | 
| 
48
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
       my $record = shift;  | 
| 
49
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
       my %params = @_;  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       my %sets;  | 
| 
52
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
       foreach my $fieldname (keys %params){  | 
| 
53
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 	    my $field = $self->{flookup}->{$fieldname} or return $self->_error("$fieldname is not a valid field");  | 
| 
54
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
 	    $field->is_readonly && return $self->_error("Field $fieldname is readonly");  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 	    my $setvalue = $field->makevalue($params{$fieldname}) or return $self->_error('failed to create setvalue object');  | 
| 
57
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 	    $setvalue->count == 1 or return $self->_error("Field ${\$field->name} allows only a single value");  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 	    my $setobj   = DBR::Query::Part::Set->new( $field, $setvalue ) or return $self->_error('failed to create set object');  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
61
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	    push @{$sets{$field->table_id}}, $setobj;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
63
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
       my $ct = scalar(keys %sets);  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
65
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
       return $self->_error('Must specify at least one field to set') unless $ct > 0;  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       my $dbrh;  | 
| 
68
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
       if($ct > 1){  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # create a new DBRH here to ensure proper transactional handling  | 
| 
70
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $dbrh = $self->{instance}->connect or return $self->_error('failed to connect');  | 
| 
71
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $dbrh->begin;  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
       foreach my $table_id (keys %sets){  | 
| 
75
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	    $self->_set($record, $table_id, $sets{$table_id}) or return $self->_error('failed to set');  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
78
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
       $dbrh->commit if $ct > 1;  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
       return 1;  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # set a field REGARDLESS of whether it was prefetched or not  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub setfield{  | 
| 
85
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
0
  
 | 
23
 | 
       my $self = shift;  | 
| 
86
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
       my $record = shift;  | 
| 
87
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
       my $field = shift;  | 
| 
88
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
       my $value = shift;  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
59
 | 
       my $setvalue = $field->makevalue($value) or return $self->_error('failed to create value object');  | 
| 
91
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
       $setvalue->count == 1 or return $self->_error("Value of ${\$field->name} must have only a single value");  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
66
 | 
       my $setobj   = DBR::Query::Part::Set->new( $field, $setvalue ) or return $self->_error('failed to create set object');  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
95
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
       return $self->_set($record, $field->table_id, [$setobj]);  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _set{  | 
| 
99
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
27
 | 
       my $self = shift;  | 
| 
100
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       my $record = shift;  | 
| 
101
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
       my $table_id = shift;  | 
| 
102
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
       my $sets = shift;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
62
 | 
       my ($outwhere,$table) = $self->_pk_where($record,$table_id) or return $self->_error('failed to create where tree');  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
114
 | 
       my $query = DBR::Query::Update->new(  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  session  => $self->{session},  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  instance => $self->{instance},  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  tables   => $table,  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  where    => $outwhere,  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  sets     => $sets  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					 ) or return $self->_error('failed to create Query object');  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
       my $rv = $query->run() or return $self->_error('failed to execute');  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
       foreach my $set (@$sets){  | 
| 
117
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
 	    $self->_setlocalval($record, $set->field, $set->value->raw->[0]);  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
289
 | 
       return $rv;  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub delete{  | 
| 
124
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
3
 | 
        my $self = shift;  | 
| 
125
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
        my $record = shift;  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
        return $self->_error('Cannot call delete on join record')  | 
| 
128
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	 if scalar(keys %{$self->{tablemap}}) > 1;  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
130
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
        my ($table_id) = keys %{$self->{tablemap}};  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
132
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
        my ($outwhere,$table) = $self->_pk_where($record,$table_id) or return $self->_error('failed to create where tree');  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
        my $query = DBR::Query::Delete->new(  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   session  => $self->{session},  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   instance => $self->{instance},  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   tables   => $table,  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   where    => $outwhere,  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  ) or return $self->_error('failed to create Query object');  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
141
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
        $query->run or return $self->_error('failed to execute');  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
        return 1;  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Fetch a field ONLY if it was not prefetched  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub getfield{  | 
| 
149
 | 
42
 | 
 
 | 
 
 | 
  
42
  
 | 
  
0
  
 | 
731
 | 
        my $self = shift;  | 
| 
150
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10106
 | 
        my $record = shift;  | 
| 
151
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
        my $field = shift;  | 
| 
152
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
        my $want_sref = shift;  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        # Check to see if we've previously been assigned an index. if so, see if our record already has it fetched  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        # This could happen if the field was not fetched in the master query, but was already fetched with getfield  | 
| 
156
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
444
 | 
        my $idx = $field->index;  | 
| 
157
 | 
42
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
14097
 | 
        return $record->[$idx] if defined($idx) && exists($record->[$idx]);  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
347
 | 
        $self->{scope}->addfield($field) or return $self->_error('Failed to add field to scope');  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
279
 | 
        my ($outwhere,$table)  = $self->_pk_where($record,$field->table_id) or return $self->_error('failed to create where tree');  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        # Because we are doing a new select, which will set the indexes on  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        # its fields, we must clone the field provided by the original query  | 
| 
165
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
213
 | 
        my $newfield = $field->clone;  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
429
 | 
        my $query = DBR::Query::Select->new(  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   session  => $self->{session},  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   instance => $self->{instance},  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   tables   => $table,  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   where    => $outwhere,  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   fields   => [ $newfield ] # use the new cloned field  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  ) or return $self->_error('failed to create Query object');  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
175
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
283
 | 
        my $sth = $query->run or return $self->_error('failed to execute');  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5606
 | 
        $sth->execute() or return $self->_error('Failed to execute sth');  | 
| 
178
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
936
 | 
        my $row  = $sth->fetchrow_arrayref() or return $self->_error('Failed to fetchrow');  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
222
 | 
        my $val = $row->[ $newfield->index ];  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
182
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
        $self->_setlocalval($record,$field,$val);  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
42
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
295
 | 
        return $want_sref?\$val:$val; # return a scalarref if requested  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub getrelation{  | 
| 
188
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
  
0
  
 | 
70
 | 
       my $self = shift;  | 
| 
189
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
       my $obj = shift;  | 
| 
190
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
       my $relation = shift;  | 
| 
191
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
       my $field  = shift;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
       my $record = $obj->[0];  | 
| 
194
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
       my $buddy  = $obj->[1];  | 
| 
195
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
       my $rowcache = $buddy->[0];  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
167
 | 
       my $ridx = $relation->index;  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # Check to see if this record has a cached version of the resultset  | 
| 
199
 | 
30
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
472
 | 
       return $record->[$ridx] if defined($ridx) && exists($record->[$ridx]); # skip the rest if we have that  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
       my $fidx = $field->index();  | 
| 
202
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
       my $val;  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
135
 | 
       my $to1 = $relation->is_to_one;                                                        # Candidate for pre-processing  | 
| 
205
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
103
 | 
       my $table    = $relation->table    or return $self->_error('Failed to fetch table'   );# Candidate for pre-processing  | 
| 
206
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
57
 | 
       my $maptable = $relation->maptable or return $self->_error('Failed to fetch maptable');# Candidate for pre-processing  | 
| 
207
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
       my $mapfield = $relation->mapfield or return $self->_error('Failed to fetch mapfield');# Candidate for pre-processing  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       my @allvals; # For uniq-ing  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
211
 | 
12
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
99
 | 
       if( defined($fidx) && exists($record->[$fidx]) ){  | 
| 
212
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	    $val = $record->[ $fidx ]; # My value  | 
| 
213
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
 	    @allvals = $self->_uniq( $val, map { $_->[ $fidx ] } grep {defined} @$rowcache ); # look forward in the rowcache and add those too  | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
    | 
| 
 
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }else{  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # I forget, I think I'm using scalar ref as a way to represent undef and still have a true rvalue *ugh*  | 
| 
216
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
 	    my $sref = $self->getfield($record,$field, 1 ); # go fetch the value in the form of a scalarref  | 
| 
217
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
 	    defined ($sref) or return $self->_error("failed to fetch the value of ${\ $field->name }");  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
218
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	    $val = $$sref;  | 
| 
219
 | 
6
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
40
 | 
 	    $fidx ||= $field->index;  | 
| 
220
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	    confess('field object STILL does not have an index') unless defined($fidx);  | 
| 
221
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 	    push @allvals, $val;  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
       my $rowcount = scalar @allvals; # Cheapest way to get a rowcount is here, before we filter  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
       unless($mapfield->is_nullable){ # Candidate for pre-defined global  | 
| 
227
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
 	    @allvals = grep { defined } @allvals;  | 
| 
 
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
80
 | 
    | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
230
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
       unless(scalar @allvals){  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # no values? then for sure, the relationship for this record must be empty.  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    # Cache the emptyness so we don't have to repeat this work  | 
| 
233
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	    return $self->_setlocalval( $record, $relation, $to1 ? DUMMY : EMPTY );  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
236
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
       my $value    = $mapfield->makevalue( \@allvals );  | 
| 
237
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
       my $outwhere = DBR::Query::Part::Compare->new( field => $mapfield, value => $value );  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
       my $scope = DBR::Config::Scope->new(  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  session       => $self->{session},  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  conf_instance => $maptable->conf_instance,  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  extra_ident   => $maptable->name,  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  offset        => 2,  # because getrelation is being called indirectly, look at the scope two levels up  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					 ) or return $self->_error('Failed to get calling scope');  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6801
 | 
       my $pk        = $maptable->primary_key or return $self->_error('Failed to fetch primary key');  | 
| 
247
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
63
 | 
       my $prefields = $scope->fields or return $self->_error('Failed to determine fields to retrieve');  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
249
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
       my %uniq;  | 
| 
250
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
       my @fields = grep { !$uniq{ $_->field_id }++ } ($mapfield, @$pk, @$prefields );  | 
| 
 
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
       my $mapinstance = $self->{instance};  | 
| 
253
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
71
 | 
       unless ( $relation->is_same_schema ){  | 
| 
254
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $mapinstance = $maptable->schema->get_instance( $mapinstance->class ) or return $self->_error('Failed to retrieve db instance for the maptable');  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
257
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
       $self->_logDebug2( "Relationship from instance " . $self->{instance}->guid . "->" . $mapinstance->guid );  | 
| 
258
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
182
 | 
       my $query = DBR::Query::Select->new(  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  session  => $self->{session},  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  instance => $mapinstance,  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  tables   => $maptable,  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  where    => $outwhere,  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  fields   => \@fields,  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  scope    => $scope,  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					  splitfield  => $mapfield  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					 ) or return $self->_error('failed to create Query object');  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
269
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
42
 | 
       if($rowcount > 1){  | 
| 
270
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	    my $myresult;  | 
| 
271
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 	    if($to1){  | 
| 
272
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 		  my $resultset =  DBR::ResultSet->new( $query ) or croak('Failed to create resultset');  | 
| 
273
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 		  $self->_logDebug2('mapping to individual records');  | 
| 
274
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 		  my $resultmap = $resultset->hashmap_single(  $mapfield->name  ) or return $self->_error('failed to split resultset');  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  # look forward in the rowcache and assign the resultsets for whatever we find  | 
| 
277
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 		  foreach my $row (grep {defined} @$rowcache) {  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
278
 | 
6
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
52
 | 
 			$self->_setlocalval(  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    $row,  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    $relation,  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    $resultmap->{ $row->[$fidx] } || DUMMY  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   );  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  }  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
285
 | 
2
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
32
 | 
 		  $myresult = $resultmap->{$val} || DUMMY;  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }else{  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  # look forward in the rowcache and assign the resultsets for whatever we find  | 
| 
289
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 		  foreach my $row (grep {defined} @$rowcache) {  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
290
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
 			$self->_setlocalval($row,  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    $relation,  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					    DBR::ResultSet->new( $query, $row->[$fidx] )  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 					   );  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		  }  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 		  $myresult = DBR::ResultSet->new( $query, $val );  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
299
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	    $self->_setlocalval($record,$relation,$myresult);  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
301
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
 	    return $myresult;  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }else{  | 
| 
304
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
 	    my $resultset =  DBR::ResultSet->new( $query ) or croak('Failed to create resultset');  | 
| 
305
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	    my $result = $resultset;  | 
| 
306
 | 
4
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
18
 | 
 	    if($to1){  | 
| 
307
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
 		  $result = $resultset->next;  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
310
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
 	    $self->_setlocalval($record,$relation,$result);  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
 	    return $result;  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _pk_where{  | 
| 
317
 | 
55
 | 
 
 | 
 
 | 
  
55
  
 | 
 
 | 
130
 | 
       my $self = shift;  | 
| 
318
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
114
 | 
       my $record = shift;  | 
| 
319
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
       my $table_id = shift;  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
321
 | 
55
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
326
 | 
       my $table = $self->{tablemap}->{ $table_id } || return $self->_error('Missing table for table_id ' . $table_id );  | 
| 
322
 | 
55
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
269
 | 
       my $pk    = $self->{pkmap}->{ $table_id }    || return $self->_error('Missing primary key');  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
324
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
305
 | 
       my @and;  | 
| 
325
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
       foreach my $part (@{ $pk }){  | 
| 
 
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
230
 | 
    | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
55
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
300
 | 
 	    my $value = $part->makevalue( $record->[ $part->index ] ) or return $self->_error('failed to create value object');  | 
| 
328
 | 
55
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
468
 | 
 	    my $outfield = DBR::Query::Part::Compare->new( field => $part, value => $value ) or return $self->_error('failed to create compare object');  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
213
 | 
 	    push @and, $outfield;  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
334
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
758
 | 
       return (DBR::Query::Part::And->new(@and), $table);  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _setlocalval{  | 
| 
338
 | 
82
 | 
 
 | 
 
 | 
  
82
  
 | 
 
 | 
175
 | 
       my $self   = shift;  | 
| 
339
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
       my $record = shift;  | 
| 
340
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
130
 | 
       my $field  = shift; # Could also be a relationship object  | 
| 
341
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
       my $val    = shift;  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
343
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
339
 | 
       my $idx = $field->index;  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # update the field object to give it an index if necessary  | 
| 
345
 | 
82
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
240
 | 
       if(!defined $idx){ #Could be 0  | 
| 
346
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
 	    $idx = ++$self->{lastidx};  | 
| 
347
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
 	    $field->index($idx); # so we'll have it for next time this gets accessed  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # Update this record to reflect the new value  | 
| 
351
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
364
 | 
       return $record->[$idx] = $val;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |