| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Bif::Sync::Plugin::Identity; |
|
2
|
1
|
|
|
1
|
|
8
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
51
|
|
|
3
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
51
|
|
|
4
|
1
|
|
|
1
|
|
480371
|
use Coro; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
use DBIx::ThinSQL qw/qv sq/; |
|
6
|
|
|
|
|
|
|
use Log::Any '$log'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.1.5_5'; |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
my %import_functions = ( |
|
11
|
|
|
|
|
|
|
CHANGESET => {}, |
|
12
|
|
|
|
|
|
|
QUIT => {}, |
|
13
|
|
|
|
|
|
|
CANCEL => {}, |
|
14
|
|
|
|
|
|
|
); |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $identity_functions = { |
|
17
|
|
|
|
|
|
|
entity_contact_method_delta => 'func_import_update_entity_contact_method', |
|
18
|
|
|
|
|
|
|
entity_contact_method => 'func_import_new_entity_contact_method', |
|
19
|
|
|
|
|
|
|
entity_delta => 'func_import_update_entity', |
|
20
|
|
|
|
|
|
|
entity => 'func_import_new_entity', |
|
21
|
|
|
|
|
|
|
identity_delta => 'func_import_update_identity', |
|
22
|
|
|
|
|
|
|
identity => 'func_import_new_identity', |
|
23
|
|
|
|
|
|
|
node => 'func_import_new_node', |
|
24
|
|
|
|
|
|
|
change_delta => 'func_import_update_change', |
|
25
|
|
|
|
|
|
|
change => 'func_import_new_change', |
|
26
|
|
|
|
|
|
|
}; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub Bif::Sync::real_import_identity { |
|
29
|
|
|
|
|
|
|
my $self = shift; |
|
30
|
|
|
|
|
|
|
my $result = $self->recv_changesets($identity_functions); |
|
31
|
|
|
|
|
|
|
return 'IdentityImported' if $result eq 'RecvChangesets'; |
|
32
|
|
|
|
|
|
|
return $result; |
|
33
|
|
|
|
|
|
|
} |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub Bif::Sync::real_sync_identity { |
|
36
|
|
|
|
|
|
|
my $self = shift; |
|
37
|
|
|
|
|
|
|
my $id = shift || die caller; |
|
38
|
|
|
|
|
|
|
my $prefix = shift; |
|
39
|
|
|
|
|
|
|
my $tmp = $self->temp_table; |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$prefix = '' unless defined $prefix; |
|
42
|
|
|
|
|
|
|
my $prefix2 = $prefix . '_'; |
|
43
|
|
|
|
|
|
|
my $db = $self->db; |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$self->trigger_on_update( 'matching: ' . $prefix2 ); |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
my @refs = $db->xarrayrefs( |
|
48
|
|
|
|
|
|
|
select => [qw/rm.prefix rm.hash/], |
|
49
|
|
|
|
|
|
|
from => 'self_related_changes_merkle rm', |
|
50
|
|
|
|
|
|
|
where => |
|
51
|
|
|
|
|
|
|
[ 'rm.self_id = ', qv($id), ' AND rm.prefix LIKE ', qv($prefix2) ], |
|
52
|
|
|
|
|
|
|
); |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
my $here = { map { $_->[0] => $_->[1] } @refs }; |
|
55
|
|
|
|
|
|
|
$self->write( 'MATCH', $prefix2, $here ); |
|
56
|
|
|
|
|
|
|
my ( $action, $mprefix, $there ) = $self->read; |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
return "expected MATCH $prefix2 {} (not $action $mprefix ...)" |
|
59
|
|
|
|
|
|
|
unless $action eq 'MATCH' |
|
60
|
|
|
|
|
|
|
and $mprefix eq $prefix2 |
|
61
|
|
|
|
|
|
|
and ref $there eq 'HASH'; |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
my @next; |
|
64
|
|
|
|
|
|
|
my @missing; |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
while ( my ( $k, $v ) = each %$here ) { |
|
67
|
|
|
|
|
|
|
if ( !exists $there->{$k} ) { |
|
68
|
|
|
|
|
|
|
push( @missing, $k ); |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
elsif ( $there->{$k} ne $v ) { |
|
71
|
|
|
|
|
|
|
push( @next, $k ); |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
if (@missing) { |
|
76
|
|
|
|
|
|
|
my @where; |
|
77
|
|
|
|
|
|
|
foreach my $miss (@missing) { |
|
78
|
|
|
|
|
|
|
push( @where, ' OR ' ) if @where; |
|
79
|
|
|
|
|
|
|
push( @where, "c.uuid LIKE ", qv( $miss . '%' ) ),; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
$self->db->xdo( |
|
83
|
|
|
|
|
|
|
insert_into => "$tmp(id,ucount)", |
|
84
|
|
|
|
|
|
|
select => [ 'c.id', 'c.ucount' ], |
|
85
|
|
|
|
|
|
|
from => 'changes c', |
|
86
|
|
|
|
|
|
|
inner_join => 'self_related_changes src', |
|
87
|
|
|
|
|
|
|
on => { |
|
88
|
|
|
|
|
|
|
'src.change_id' => \'c.id', |
|
89
|
|
|
|
|
|
|
'src.self_id' => $id, |
|
90
|
|
|
|
|
|
|
}, |
|
91
|
|
|
|
|
|
|
where => \@where, |
|
92
|
|
|
|
|
|
|
); |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
if (@next) { |
|
96
|
|
|
|
|
|
|
foreach my $next ( sort @next ) { |
|
97
|
|
|
|
|
|
|
$self->real_sync_identity( $id, $next, $tmp ); |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
return unless $prefix eq ''; |
|
102
|
|
|
|
|
|
|
return 'IdentitySync'; |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub Bif::Sync::real_transfer_identity_changes { |
|
106
|
|
|
|
|
|
|
my $self = shift; |
|
107
|
|
|
|
|
|
|
my $tmp = $self->temp_table; |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
my $fh = select; |
|
110
|
|
|
|
|
|
|
my $send = async { |
|
111
|
|
|
|
|
|
|
select $fh; |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
my $total = $self->db->xval( |
|
114
|
|
|
|
|
|
|
select => 'COALESCE(sum(t.ucount), 0)', |
|
115
|
|
|
|
|
|
|
from => "$tmp t", |
|
116
|
|
|
|
|
|
|
); |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
$self->changes_tosend( $self->changes_tosend + $total ); |
|
119
|
|
|
|
|
|
|
$self->write( 'TOTAL', $total ); |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
my $change_list = $self->db->xprepare( |
|
122
|
|
|
|
|
|
|
select => [ |
|
123
|
|
|
|
|
|
|
'c.id', 'c.uuid', |
|
124
|
|
|
|
|
|
|
'p.uuid AS parent_uuid', 'n.uuid AS identity_uuid', |
|
125
|
|
|
|
|
|
|
'c.mtime', 'c.mtimetz', |
|
126
|
|
|
|
|
|
|
'c.author', 'c.author_contact', |
|
127
|
|
|
|
|
|
|
'c.author_contact_method', 'c.author_shortname', |
|
128
|
|
|
|
|
|
|
'c.lang', 'c.message', |
|
129
|
|
|
|
|
|
|
'c.action', 'c.ucount', |
|
130
|
|
|
|
|
|
|
], |
|
131
|
|
|
|
|
|
|
from => "$tmp tmp", |
|
132
|
|
|
|
|
|
|
inner_join => 'changes c', |
|
133
|
|
|
|
|
|
|
on => 'c.id = tmp.id', |
|
134
|
|
|
|
|
|
|
left_join => 'nodes n', |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# Don't fetch the identity_uuid for the first identity |
|
137
|
|
|
|
|
|
|
# change |
|
138
|
|
|
|
|
|
|
on => 'n.id = c.identity_id AND n.first_change_id != c.id', |
|
139
|
|
|
|
|
|
|
left_join => 'changes p', |
|
140
|
|
|
|
|
|
|
on => 'p.id = c.parent_id', |
|
141
|
|
|
|
|
|
|
order_by => 'c.id ASC', |
|
142
|
|
|
|
|
|
|
); |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
$change_list->execute; |
|
145
|
|
|
|
|
|
|
return $self->send_identity_changes( $change_list, $total ); |
|
146
|
|
|
|
|
|
|
}; |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $r1 = $self->recv_identity_deltas; |
|
149
|
|
|
|
|
|
|
my $r2 = $send->join; |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
$self->db->xdo( delete_from => $tmp ); |
|
152
|
|
|
|
|
|
|
$self->db->xdo( |
|
153
|
|
|
|
|
|
|
insert_into => 'func_merge_changes', |
|
154
|
|
|
|
|
|
|
values => { merge => 1 }, |
|
155
|
|
|
|
|
|
|
); |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
if ( $r1 =~ m/^\d+$/ ) { |
|
158
|
|
|
|
|
|
|
$self->write( 'Recv', $r1 ); |
|
159
|
|
|
|
|
|
|
my ( $recv, $count ) = $self->read; |
|
160
|
|
|
|
|
|
|
return 'TransferIdentityChanges' if $recv eq 'Recv' and $count == $r2; |
|
161
|
|
|
|
|
|
|
$log->debug("MEH: $count $r2"); |
|
162
|
|
|
|
|
|
|
return $recv; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
$self->write( 'ProtocolError', $r1 ); |
|
166
|
|
|
|
|
|
|
return $r1; |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub Bif::Sync::real_export_identity { |
|
170
|
|
|
|
|
|
|
my $self = shift; |
|
171
|
|
|
|
|
|
|
my $id = shift; |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
my $total = $self->db->xval( |
|
174
|
|
|
|
|
|
|
select => 'COUNT(eru.change_id)', |
|
175
|
|
|
|
|
|
|
from => 'entity_related_changes eru', |
|
176
|
|
|
|
|
|
|
where => { 'eru.entity_id' => $id }, |
|
177
|
|
|
|
|
|
|
); |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
my $recv = $self->send_changesets( |
|
180
|
|
|
|
|
|
|
$total, |
|
181
|
|
|
|
|
|
|
[ |
|
182
|
|
|
|
|
|
|
select => 'eru.change_id AS id', |
|
183
|
|
|
|
|
|
|
from => 'entity_related_changes eru', |
|
184
|
|
|
|
|
|
|
where => { 'eru.entity_id' => $id }, |
|
185
|
|
|
|
|
|
|
order_by => 'eru.change_id ASC', |
|
186
|
|
|
|
|
|
|
] |
|
187
|
|
|
|
|
|
|
); |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
return 'IdentityExported' if $recv eq 'ChangesetsSent'; |
|
190
|
|
|
|
|
|
|
return $recv; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
1; |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head1 NAME |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=for bif-doc #perl |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Bif::Sync::Plugin::Identity - synchronisation plugin for identities |
|
200
|
|
|
|
|
|
|
|