File Coverage

blib/lib/Bif/DB/Plugin/ChangeUUIDv1.pm
Criterion Covered Total %
statement 31 56 55.3
branch 2 8 25.0
condition 4 20 20.0
subroutine 4 5 80.0
pod n/a
total 41 89 46.0


line stmt bran cond sub pod time code
1             package Bif::DB::Plugin::ChangeUUIDv1;
2 41     41   309 use strict;
  41         92  
  41         1433  
3 41     41   233 use warnings;
  41         961  
  41         1714  
4 41     41   223 use DBIx::ThinSQL qw/case qv/;
  41         1166  
  41         2425  
5              
6             our $VERSION = '0.1.5_6';
7              
8             our %statements = (
9             new_hub => [
10             select => [
11             '"new_hub" AS _delta',
12             'hd.location AS location',
13             'n.uuid AS uuid',
14             ],
15             from => 'hub_deltas hd',
16             inner_join => 'nodes n',
17             on => 'n.id = hd.hub_id',
18             where => 'hd.id = ?',
19             ],
20              
21             update_hub => [
22             select => [
23             '"update_hub" AS _delta',
24             'nd.name AS name',
25             'pd.title AS title',
26             'n.uuid AS uuid',
27             ],
28             from => 'project_deltas pd',
29             inner_join => 'node_deltas nd',
30             on => 'nd.id = pd.id',
31             inner_join => 'nodes n',
32             on => 'n.id = pd.project_id',
33             where => 'pd.id = ?',
34             ],
35              
36             new_hub_repo => [
37             select => [
38             '"new_hub_repo" AS _delta',
39             'h.uuid AS hub_uuid',
40             'hrd.location AS location',
41             'hr.uuid AS uuid',
42             ],
43             from => 'hub_repo_deltas hrd',
44             inner_join => 'nodes hr',
45             on => 'hr.id = hrd.hub_repo_id',
46             left_join => 'nodes h',
47             on => 'h.id = hrd.hub_id',
48             where => 'hrd.id = ?',
49             ],
50              
51             update_hub_repo => [
52             select => [
53             '"update_hub_repo" AS _delta',
54             'h.uuid AS hub_uuid', # should never change, remove?
55             'hrd.location AS location',
56             'hr.uuid AS uuid',
57             ],
58             from => 'hub_repo_deltas hrd',
59             inner_join => 'nodes hr',
60             on => 'hr.id = hrd.hub_repo_id',
61             left_join => 'nodes h',
62             on => 'h.id = hrd.hub_id',
63             where => 'hrd.id = ?',
64             ],
65              
66             new_identity => [
67             select => [
68             '"new_identity" AS _delta',
69             'ed.name AS name',
70             'id.shortname AS shortname',
71             'con.uuid AS contact_uuid',
72             'dcm.uuid AS default_contact_method_uuid',
73             'i.uuid AS uuid',
74             ],
75             from => 'identity_deltas id',
76             inner_join => 'entity_deltas ed',
77             on => 'ed.id = id.id',
78             inner_join => 'nodes i',
79             on => 'i.id = id.identity_id',
80             left_join => 'nodes con',
81             on => 'con.id = ed.contact_id',
82             left_join => 'nodes dcm',
83             on => 'dcm.id = ed.default_contact_method_id',
84             where => 'id.id = ?',
85             ],
86              
87             update_identity => [
88             select => [
89             '"update_identity" AS _delta',
90             'n.uuid AS uuid',
91             'ed.name AS name',
92             'id.shortname AS shortname',
93             'con.uuid AS contact_uuid',
94             'dcm.uuid AS default_contact_method_uuid',
95             ],
96             from => 'identity_deltas id',
97             inner_join => 'entity_deltas ed',
98             on => 'ed.id = id.id',
99             inner_join => 'nodes n',
100             on => 'n.id = id.identity_id',
101             left_join => 'nodes con',
102             on => 'con.id = ed.contact_id',
103             left_join => 'nodes dcm',
104             on => 'dcm.id = ed.default_contact_method_id',
105             where => 'id.id = ?',
106             ],
107              
108             new_identity_contact_method => [
109             select => [
110             '"new_identity_contact_method" AS _delta',
111             'i.uuid AS identity_uuid',
112             'ecmd.method AS method',
113             'ecmd.mvalue AS mvalue',
114             'ecmn.uuid AS uuid',
115             ],
116             from => 'entity_contact_method_deltas ecmd',
117             inner_join => 'entity_contact_methods ecm',
118             on => 'ecm.id = ecmd.entity_contact_method_id',
119             inner_join => 'nodes ecmn',
120             on => 'ecmn.id = ecm.id',
121             inner_join => 'nodes i',
122             on => 'i.id = ecm.entity_id',
123             where => 'ecmd.id = ?',
124             ],
125              
126             update_identity_contact_method => [
127             select => [
128             'n.uuid AS identity_contact_method_uuid',
129             'ecmd.method AS method',
130             'ecmd.mvalue AS mvalue',
131             ],
132             from => 'entity_contact_method_deltas ecmd',
133             inner_join => 'nodes n',
134             on => 'n.id = ecmd.id',
135             where => 'ecmd.id = ?',
136             ],
137              
138             new_project => [
139             select => [
140             '"new_project" AS _delta',
141             'nd.name AS name',
142             'pp.uuid AS parent_uuid',
143             'pd.title AS title',
144             'p.uuid AS uuid',
145             ],
146             from => 'project_deltas pd',
147             inner_join => 'node_deltas nd',
148             on => 'nd.id = pd.id',
149             inner_join => 'nodes p',
150             on => 'p.id = pd.project_id',
151             left_join => 'nodes pp',
152             on => 'pp.id = nd.parent_id',
153             where => 'pd.id = ?',
154             ],
155              
156             update_project => [
157             select => [
158             '"update_project" AS _delta',
159             'h.uuid AS hub_uuid',
160             'nd.name AS name',
161             'pp.uuid AS parent_uuid',
162             'ps.uuid AS project_status_uuid',
163             'pd.title AS title',
164             'p.uuid AS uuid',
165             ],
166             from => 'project_deltas pd',
167             inner_join => 'node_deltas nd',
168             on => 'nd.id = pd.id',
169             inner_join => 'nodes p',
170             on => 'p.id = pd.project_id',
171             left_join => 'nodes ps',
172             on => 'ps.id = pd.project_status_id',
173             left_join => 'nodes pp',
174             on => 'pp.id = nd.parent_id',
175             left_join => 'nodes h',
176             on => 'h.id = pd.hub_id',
177             where => 'pd.id = ?',
178             ],
179              
180             new_project_status => [
181             select => [
182             '"new_project_status" AS _delta',
183             'p.uuid AS project_uuid',
184             'psd.rank AS rank',
185             'psd.status AS status',
186             'n.uuid AS uuid',
187             ],
188             from => 'project_status_deltas psd',
189             inner_join => 'project_status ps',
190             on => 'ps.id = psd.project_status_id',
191             inner_join => 'nodes n',
192             on => 'n.id = ps.id',
193             inner_join => 'nodes p',
194             on => 'p.id = ps.project_id',
195             where => 'psd.id = ?',
196             ],
197              
198             update_project_status => [
199             select => [
200             '"update_project_status" AS _delta',
201             'psd.rank AS rank',
202             'psd.status AS status',
203             'ps.uuid AS uuid',
204             ],
205             from => 'project_status_deltas psd',
206             inner_join => 'nodes ps',
207             on => 'ps.id = psd.project_status_id',
208             where => 'psd.id = ?',
209             ],
210              
211             new_link_topic => [
212             select => [ '"new_link_topic" AS _delta', 'n.uuid AS uuid', ],
213             from => 'node_deltas nd',
214             inner_join => 'nodes n',
215             on => 'n.id = nd.node_id',
216             where => 'nd.id = ?',
217             ],
218              
219             new_topic => [
220             select => [
221             '"new_topic" AS _delta',
222             'ts.uuid AS topic_status_uuid',
223             'lt.uuid AS link_topic_uuid',
224             'ltd.title AS title',
225             't.tkind AS tkind',
226             'p.uuid AS project_uuid',
227             'n.uuid AS uuid',
228             ],
229             from => 'link_topic_deltas ltd',
230             inner_join => 'nodes n',
231             on => 'n.id = ltd.topic_id',
232             inner_join => 'topics t',
233             on => 't.id = ltd.topic_id',
234             inner_join => 'nodes lt',
235             on => 'lt.id = t.link_topic_id',
236             inner_join => 'nodes p',
237             on => 'p.id = t.project_id',
238             inner_join => 'nodes ts',
239             on => 'ts.id = ltd.topic_status_id',
240             where => 'ltd.id = ?',
241             ],
242              
243             update_topic => [
244             select => [
245             '"update_topic" AS _delta',
246             'ts.uuid AS topic_status_uuid',
247             'ltd.title AS title',
248             'n.uuid AS uuid',
249             ],
250             from => 'link_topic_deltas ltd',
251             inner_join => 'nodes n',
252             on => 'n.id = ltd.topic_id',
253             left_join => 'nodes ts',
254             on => 'ts.id = ltd.topic_status_id',
255             where => 'ltd.id = ?',
256             ],
257              
258             new_topic_status => [
259             select => [
260             '"new_topic_status" AS _delta',
261             'tsd.def AS def',
262             'p.uuid AS project_uuid',
263             'ts.tkind AS tkind',
264             'tsd.rank AS rank',
265             'tsd.status AS status',
266             'n.uuid AS uuid',
267             ],
268             from => 'topic_status_deltas tsd',
269             inner_join => 'topic_status ts',
270             on => 'ts.id = tsd.topic_status_id',
271             inner_join => 'nodes n',
272             on => 'n.id = ts.id',
273             inner_join => 'nodes p',
274             on => 'p.id = ts.project_id',
275             where => 'tsd.id = ?',
276             ],
277              
278             update_topic_status => [
279             select => [
280             '"update_topic_status" AS _delta',
281             'tsd.def AS def',
282             'tsd.rank AS rank',
283             'tsd.status AS status',
284             'ts.uuid AS uuid',
285             ],
286             from => 'topic_status_deltas tsd',
287             inner_join => 'nodes ts',
288             on => 'ts.id = ts.id',
289             where => 'tsd.id = ?',
290             ],
291              
292             new_work => [
293             select => [
294             '"new_work" AS _delta',
295             'wd.offset AS offset',
296             'wd.start AS start',
297             'wd.stop AS stop',
298             'wd.start_comment AS start_comment',
299             'wd.stop_comment AS stop_comment',
300             'n.uuid AS node_uuid',
301             ],
302             from => 'work_deltas wd',
303             inner_join => 'nodes n',
304             on => 'n.id = wd.node_id',
305             where => 'wd.id = ?',
306             ],
307              
308             );
309              
310             my %prepared;
311              
312             sub Bif::DB::db::uchangeset_v1 {
313 41     41   107 my $self = shift;
314 41         108 my $id = shift;
315 41         103 my @changeset = ();
316              
317 41   33     780 my $begin_change = $prepared{$self}{begin_change} ||= $self->xprepare(
318             select => [
319             'p.uuid AS parent_uuid',
320             'c.mtime AS mtime',
321             'c.mtimef AS mtimef',
322             'c.mtimetz AS mtimetz',
323             'c.author AS author',
324             'c.author_contact AS author_contact',
325             'c.author_contact_method AS author_contact_method',
326             'c.author_shortname AS author_shortname',
327             'c.lang AS lang',
328             ],
329             from => 'changes c',
330             left_join => 'changes p',
331             on => 'p.id = c.parent_id',
332             where => 'c.id = ?',
333             );
334 41         22518 $begin_change->execute($id);
335 41         242 push( @changeset, $begin_change->hashref );
336 41         2331 $begin_change->finish;
337              
338 41   33     490 my $deltas = $prepared{$self}{deltas} ||= $self->xprepare(
339             select => [ 'd.id AS id', 'd.action AS action', ],
340             from => 'deltas d',
341             where => 'd.change_id = ?',
342             order_by => 'd.id',
343             );
344 41         12092 $deltas->execute($id);
345              
346 41         101 my $sth;
347 41         623 foreach my $delta ( $deltas->hashrefs ) {
348             $sth = $prepared{$self}{ $delta->{action} } ||= $self->xprepare(
349             @{
350 164   33     4262 $statements{ $delta->{action} }
351 164 50       1128 || die "action unimplemented: $delta->{action}"
352             }
353             );
354 164         78580 $sth->execute( $delta->{id} );
355 164 50       621 if ( my $ref = $sth->hashref ) {
356 164         5879 push( @changeset, $ref );
357             }
358             else {
359 0         0 warn "missing delta $delta->{id}: $delta->{action}";
360             }
361 164         1046 $sth->finish;
362             }
363              
364 41   33     579 my $end_change = $prepared{$self}{end_change} ||= $self->xprepare(
365             select => [
366             'c.action_format AS action_format',
367             'n1.uuid AS action_node_uuid_1',
368             'n2.uuid AS action_node_uuid_2',
369             'i.uuid AS identity_uuid',
370             'c.message AS message',
371             'c.uuid AS uuid',
372             ],
373             from => 'changes c',
374             inner_join => 'nodes i',
375             on => 'i.id = c.identity_id',
376             left_join => 'nodes n1',
377             on => 'n1.id = c.action_node_id_1',
378             left_join => 'nodes n2',
379             on => 'n2.id = c.action_node_id_2',
380             where => 'c.id = ?',
381             );
382              
383 41         19348 $end_change->execute($id);
384 41         195 push( @changeset, $end_change->hashref );
385 41         1656 $end_change->finish;
386              
387 41         266 return \@changeset;
388             }
389              
390             our %import = (
391             new_hub => 'func_import_new_hub',
392             new_hub_repo => 'func_import_new_hub_repo',
393             new_identity_contact_method => 'func_import_new_identity_contact_method',
394             new_identity => 'func_import_new_identity',
395             new_project => 'func_import_new_project',
396             new_project_status => 'func_import_new_project_status',
397             new_topic => 'func_import_new_topic',
398             new_link_topic => 'func_import_new_link_topic',
399             new_topic_status => 'func_import_new_topic_status',
400             new_work => 'func_import_new_work',
401             update_hub => 'func_import_update_hub',
402             update_hub_repo => 'func_import_update_hub_repo',
403             update_identity_contact_method =>
404             'func_import_update_identity_contact_method',
405             update_identity => 'func_import_update_identity',
406             update_project => 'func_import_update_project',
407             update_topic => 'func_import_update_topic',
408             );
409              
410             sub Bif::DB::db::save_uchangeset_v1 {
411 0     0     my $self = shift;
412 0           my $changeset = shift;
413              
414 0           my $begin = shift @$changeset;
415 0           my $end = pop @$changeset;
416              
417 0           my @keys = sort keys %$begin;
418 0           my @values = map { qv( $begin->{$_} ) } @keys;
  0            
419              
420             # Only insert if the uuid does not exist
421             my $have_change = $prepared{$self}{have_change} ||= $self->xprepare(
422             select => 'count(id)',
423             from => 'changes c',
424             where => {
425             'c.uuid' => $end->{uuid},
426             },
427 0   0       );
428 0           $have_change->execute( $end->{uuid} );
429 0           my $res = $have_change->val;
430 0           $have_change->finish;
431 0 0         return ( 0, $end->{uuid} ) if $res;
432              
433 0           $self->xdo(
434             insert_into => 'func_import_begin_change',
435             values => $begin,
436             );
437              
438 0           foreach my $delta (@$changeset) {
439 0           my $delta_action = $delta->{_delta};
440             my $func = $import{ delete $delta->{_delta} }
441 0   0       || die "Missing \%import for $delta";
442              
443 0           $self->xdo(
444             insert_into => $func,
445             values => $delta,
446             );
447             }
448              
449             $self->xdo(
450 0           insert_into => 'func_import_end_change',
451             values => $end,
452             );
453              
454             my $is_valid = $prepared{$self}{is_valid} ||= $self->xprepare(
455             select => case (
456             when => 'c.valid = 0',
457             then => -1,
458             else => 1
459             ),
460             from => 'changes c',
461             where => {
462             'c.uuid' => $end->{uuid},
463             },
464 0   0       );
465 0           $is_valid->execute( $end->{uuid} );
466 0           $res = $is_valid->val;
467 0           $is_valid->finish;
468              
469             $self->xdo(
470             delete_from => 'changes',
471             where => { uuid => $end->{uuid} },
472 0 0         ) if -1 == $res;
473              
474 0           return ( $res, $end->{uuid} );
475             }
476              
477             1;
478              
479             =head1 NAME
480              
481             =for bif-doc #perl
482              
483             Bif::DB::Plugin::ChangeUUIDv1 - read-write helper methods for a bif
484             database
485              
486             =head1 VERSION
487              
488             0.1.5_6 (2015-10-20)
489              
490             =head1 SYNOPSIS
491              
492             use strict;
493             use warnings;
494             use Bif::DB;
495             use Bif::DB::Plugin::ChangeUUIDv1;
496              
497             my $db = Bif::DB->connect(...);
498              
499             # Now use dbh/st methods from ChangeUUIDv1
500              
501             =head1 DESCRIPTION
502              
503             B adds some changeet methods to
504             L.
505              
506             =head1 DBH METHODS
507              
508             =over
509              
510             =item xprepare_uchangeset_v1() -> $sth
511              
512             =back
513              
514             =head1 ST METHODS
515              
516             =over
517              
518             =item uchangeset_v1() -> ArrayRef
519              
520             =back
521              
522             =head1 SEE ALSO
523              
524             L
525              
526             =head1 AUTHOR
527              
528             Mark Lawrence Enomad@null.netE
529              
530             =head1 COPYRIGHT AND LICENSE
531              
532             Copyright 2013-2015 Mark Lawrence
533              
534             This program is free software; you can redistribute it and/or modify it
535             under the terms of the GNU General Public License as published by the
536             Free Software Foundation; either version 3 of the License, or (at your
537             option) any later version.
538