File Coverage

blib/lib/Bif/DB/Plugin/ChangeUUIDv1.pm
Criterion Covered Total %
statement 31 56 55.3
branch 1 6 16.6
condition 4 20 20.0
subroutine 4 5 80.0
pod n/a
total 40 87 45.9


line stmt bran cond sub pod time code
1             package Bif::DB::Plugin::ChangeUUIDv1;
2 50     50   243 use strict;
  50         80  
  50         1735  
3 50     50   225 use warnings;
  50         87  
  50         1996  
4 50     50   236 use DBIx::ThinSQL qw/case qv/;
  50         11796  
  50         1610  
5              
6             our $VERSION = '0.1.5_5';
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_issue => [
139             select => [
140             '"new_issue" AS _delta',
141             's.uuid AS issue_status_uuid',
142             'src.uuid AS src_uuid',
143             'id.title AS title',
144             'n.uuid AS uuid',
145             ],
146             from => 'issue_deltas id',
147             inner_join => 'nodes n',
148             on => 'n.id = id.issue_id',
149             inner_join => 'nodes s',
150             on => 's.id = id.issue_status_id',
151             left_join => 'issues i',
152             on => 'i.id = id.issue_id',
153             left_join => 'nodes src',
154             on => 'src.id = i.src_id',
155             where => 'id.id = ?',
156             ],
157              
158             update_issue => [
159             select => [
160             '"update_issue" AS _delta',
161             'ist.uuid AS issue_status_uuid',
162             'id.title AS title',
163             'n.uuid AS uuid',
164             ],
165             from => 'issue_deltas id',
166             inner_join => 'nodes n',
167             on => 'n.id = id.issue_id',
168             left_join => 'nodes ist',
169             on => 'ist.id = id.issue_status_id',
170             where => 'id.id = ?',
171             ],
172              
173             new_issue_status => [
174             select => [
175             '"new_issue_status" AS _delta',
176             'isd.def AS def',
177             'p.uuid AS project_uuid',
178             'isd.rank AS rank',
179             'isd.status AS status',
180             'n.uuid AS uuid',
181             ],
182             from => 'issue_status_deltas isd',
183             inner_join => 'issue_status ist',
184             on => 'ist.id = isd.issue_status_id',
185             inner_join => 'nodes n',
186             on => 'n.id = ist.id',
187             inner_join => 'nodes p',
188             on => 'p.id = ist.project_id',
189             where => 'isd.id = ?',
190             ],
191              
192             update_issue_status => [
193             select => [
194             '"update_issue_status" AS _delta',
195             'isd.def AS def',
196             'isd.rank AS rank',
197             'isd.status AS status',
198             'ist.uuid AS uuid',
199             ],
200             from => 'issue_status_deltas isd',
201             inner_join => 'nodes ist',
202             on => 'ist.id = ist.id',
203             where => 'isd.id = ?',
204             ],
205              
206             new_project => [
207             select => [
208             '"new_project" AS _delta',
209             'nd.name AS name',
210             'pp.uuid AS parent_uuid',
211             'pd.title AS title',
212             'p.uuid AS uuid',
213             ],
214             from => 'project_deltas pd',
215             inner_join => 'node_deltas nd',
216             on => 'nd.id = pd.id',
217             inner_join => 'nodes p',
218             on => 'p.id = pd.project_id',
219             left_join => 'nodes pp',
220             on => 'pp.id = nd.parent_id',
221             where => 'pd.id = ?',
222             ],
223              
224             update_project => [
225             select => [
226             '"update_project" AS _delta',
227             'h.uuid AS hub_uuid',
228             'nd.name AS name',
229             'pp.uuid AS parent_uuid',
230             'ps.uuid AS project_status_uuid',
231             'pd.title AS title',
232             'p.uuid AS uuid',
233             ],
234             from => 'project_deltas pd',
235             inner_join => 'node_deltas nd',
236             on => 'nd.id = pd.id',
237             inner_join => 'nodes p',
238             on => 'p.id = pd.project_id',
239             left_join => 'nodes ps',
240             on => 'ps.id = pd.project_status_id',
241             left_join => 'nodes pp',
242             on => 'pp.id = nd.parent_id',
243             left_join => 'nodes h',
244             on => 'h.id = pd.hub_id',
245             where => 'pd.id = ?',
246             ],
247              
248             new_project_status => [
249             select => [
250             '"new_project_status" AS _delta',
251             'p.uuid AS project_uuid',
252             'psd.rank AS rank',
253             'psd.status AS status',
254             'n.uuid AS uuid',
255             ],
256             from => 'project_status_deltas psd',
257             inner_join => 'project_status ps',
258             on => 'ps.id = psd.project_status_id',
259             inner_join => 'nodes n',
260             on => 'n.id = ps.id',
261             inner_join => 'nodes p',
262             on => 'p.id = ps.project_id',
263             where => 'psd.id = ?',
264             ],
265              
266             update_project_status => [
267             select => [
268             '"update_project_status" AS _delta',
269             'psd.rank AS rank',
270             'psd.status AS status',
271             'ps.uuid AS uuid',
272             ],
273             from => 'project_status_deltas psd',
274             inner_join => 'nodes ps',
275             on => 'ps.id = psd.project_status_id',
276             where => 'psd.id = ?',
277             ],
278              
279             new_task => [
280             select => [
281             '"new_task" AS _delta',
282             'ts.uuid AS task_status_uuid',
283             'nd.title AS title',
284             'n.uuid AS uuid',
285             ],
286             from => 'task_deltas nd',
287             inner_join => 'nodes n',
288             on => 'n.id = nd.task_id',
289             inner_join => 'nodes ts',
290             on => 'ts.id = nd.task_status_id',
291             where => 'nd.id = ?',
292             ],
293              
294             update_task => [
295             select => [
296             '"update_task" AS _delta',
297             'ts.uuid AS task_status_uuid',
298             'nd.title AS title',
299             'n.uuid AS uuid',
300             ],
301             from => 'task_deltas nd',
302             inner_join => 'nodes n',
303             on => 'n.id = nd.task_id',
304             left_join => 'nodes ts',
305             on => 'ts.id = nd.task_status_id',
306             where => 'nd.id = ?',
307             ],
308              
309             new_task_status => [
310             select => [
311             '"new_task_status" AS _delta',
312             'tsd.def AS def',
313             'p.uuid AS project_uuid',
314             'tsd.rank AS rank',
315             'tsd.status AS status',
316             'n.uuid AS uuid',
317             ],
318             from => 'task_status_deltas tsd',
319             inner_join => 'task_status ts',
320             on => 'ts.id = tsd.task_status_id',
321             inner_join => 'nodes n',
322             on => 'n.id = ts.id',
323             inner_join => 'nodes p',
324             on => 'p.id = ts.project_id',
325             where => 'tsd.id = ?',
326             ],
327              
328             update_task_status => [
329             select => [
330             '"update_task_status" AS _delta',
331             'tsd.def AS def',
332             'tsd.rank AS rank',
333             'tsd.status AS status',
334             'ts.uuid AS uuid',
335             ],
336             from => 'task_status_deltas tsd',
337             inner_join => 'nodes ts',
338             on => 'ts.id = ts.id',
339             where => 'tsd.id = ?',
340             ],
341              
342             new_work => [
343             select => [
344             '"new_work" AS _delta',
345             'wd.offset AS offset',
346             'wd.start AS start',
347             'wd.stop AS stop',
348             'wd.start_comment AS start_comment',
349             'wd.stop_comment AS stop_comment',
350             'n.uuid AS node_uuid',
351             ],
352             from => 'work_deltas wd',
353             inner_join => 'nodes n',
354             on => 'n.id = wd.node_id',
355             where => 'wd.id = ?',
356             ],
357              
358             );
359              
360             my %prepared;
361              
362             sub Bif::DB::db::uchangeset_v1 {
363 50     50   128 my $self = shift;
364 50         100 my $id = shift;
365 50         127 my @changeset = ();
366              
367 50   33     1070 my $begin_change = $prepared{$self}{begin_change} ||= $self->xprepare(
368             select => [
369             'p.uuid AS parent_uuid',
370             'c.mtime AS mtime',
371             'c.mtimetz AS mtimetz',
372             'c.author AS author',
373             'c.author_contact AS author_contact',
374             'c.author_contact_method AS author_contact_method',
375             'c.author_shortname AS author_shortname',
376             'c.lang AS lang',
377             ],
378             from => 'changes c',
379             left_join => 'changes p',
380             on => 'p.id = c.parent_id',
381             where => 'c.id = ?',
382             );
383 50         26025 $begin_change->execute($id);
384 50         322 push( @changeset, $begin_change->hashref );
385 50         2821 $begin_change->finish;
386              
387 50   33     519 my $deltas = $prepared{$self}{deltas} ||= $self->xprepare(
388             select => [ 'd.id AS id', 'd.action AS action', ],
389             from => 'deltas d',
390             where => 'd.change_id = ?',
391             order_by => 'd.id',
392             );
393 50         12867 $deltas->execute($id);
394              
395 50         111 my $sth;
396 50         745 foreach my $delta ( $deltas->hashrefs ) {
397             $sth = $prepared{$self}{ $delta->{action} } ||=
398 200   33     5042 $self->xprepare( @{ $statements{ $delta->{action} } } );
  200         1094  
399 200         78652 $sth->execute( $delta->{id} );
400 200 50       694 if ( my $ref = $sth->hashref ) {
401 200         7253 push( @changeset, $ref );
402             }
403             else {
404 0         0 warn "missing delta $delta->{id}: $delta->{action}";
405             }
406 200         1162 $sth->finish;
407             }
408              
409 50   33     730 my $end_change = $prepared{$self}{end_change} ||= $self->xprepare(
410             select => [
411             'c.action_format AS action_format',
412             'n1.uuid AS action_node_uuid_1',
413             'n2.uuid AS action_node_uuid_2',
414             'i.uuid AS identity_uuid',
415             'c.message AS message',
416             'c.uuid AS uuid',
417             ],
418             from => 'changes c',
419             inner_join => 'nodes i',
420             on => 'i.id = c.identity_id',
421             left_join => 'nodes n1',
422             on => 'n1.id = c.action_node_id_1',
423             left_join => 'nodes n2',
424             on => 'n2.id = c.action_node_id_2',
425             where => 'c.id = ?',
426             );
427              
428 50         19380 $end_change->execute($id);
429 50         222 push( @changeset, $end_change->hashref );
430 50         1903 $end_change->finish;
431              
432 50         344 return \@changeset;
433             }
434              
435             our %import = (
436             new_hub => 'func_import_new_hub',
437             new_hub_repo => 'func_import_new_hub_repo',
438             new_identity_contact_method => 'func_import_new_identity_contact_method',
439             new_identity => 'func_import_new_identity',
440             new_issue => 'func_import_new_issue',
441             new_issue_status => 'func_import_new_issue_status',
442             new_project => 'func_import_new_project',
443             new_project_status => 'func_import_new_project_status',
444             new_task => 'func_import_new_task',
445             new_task_status => 'func_import_new_task_status',
446             new_work => 'func_import_new_work',
447             update_hub => 'func_import_update_hub',
448             update_hub_repo => 'func_import_update_hub_repo',
449             update_identity_contact_method =>
450             'func_import_update_identity_contact_method',
451             update_identity => 'func_import_update_identity',
452             update_issue => 'func_import_update_issue',
453             update_project => 'func_import_update_project',
454             update_task => 'func_import_update_task',
455             );
456              
457             sub Bif::DB::db::save_uchangeset_v1 {
458 0     0     my $self = shift;
459 0           my $changeset = shift;
460              
461 0           my $begin = shift @$changeset;
462 0           my $end = pop @$changeset;
463              
464 0           my @keys = sort keys %$begin;
465 0           my @values = map { qv( $begin->{$_} ) } @keys;
  0            
466              
467             # Only insert if the uuid does not exist
468             my $have_change = $prepared{$self}{have_change} ||= $self->xprepare(
469             select => 'count(id)',
470             from => 'changes c',
471             where => {
472             'c.uuid' => $end->{uuid},
473             },
474 0   0       );
475 0           $have_change->execute( $end->{uuid} );
476 0           my $res = $have_change->val;
477 0           $have_change->finish;
478 0 0         return ( 0, $end->{uuid} ) if $res;
479              
480 0           $self->xdo(
481             insert_into => 'func_import_begin_change',
482             values => $begin,
483             );
484              
485 0           foreach my $delta (@$changeset) {
486 0           my $delta_action = $delta->{_delta};
487             my $func = $import{ delete $delta->{_delta} }
488 0   0       || die "Missing \%import for $delta";
489              
490 0           $self->xdo(
491             insert_into => $func,
492             values => $delta,
493             );
494             }
495              
496             $self->xdo(
497 0           insert_into => 'func_import_end_change',
498             values => $end,
499             );
500              
501             my $is_valid = $prepared{$self}{is_valid} ||= $self->xprepare(
502             select => case (
503             when => 'c.valid = 0',
504             then => -1,
505             else => 1
506             ),
507             from => 'changes c',
508             where => {
509             'c.uuid' => $end->{uuid},
510             },
511 0   0       );
512 0           $is_valid->execute( $end->{uuid} );
513 0           $res = $is_valid->val;
514 0           $is_valid->finish;
515              
516             $self->xdo(
517             delete_from => 'changes',
518             where => { uuid => $end->{uuid} },
519 0 0         ) if -1 == $res;
520              
521 0           return ( $res, $end->{uuid} );
522             }
523              
524             1;
525              
526             =head1 NAME
527              
528             =for bif-doc #perl
529              
530             Bif::DB::Plugin::ChangeUUIDv1 - read-write helper methods for a bif
531             database
532              
533             =head1 VERSION
534              
535             0.1.5_5 (2015-08-13)
536              
537             =head1 SYNOPSIS
538              
539             use strict;
540             use warnings;
541             use Bif::DB;
542             use Bif::DB::Plugin::ChangeUUIDv1;
543              
544             my $db = Bif::DB->connect(...);
545              
546             # Now use dbh/st methods from ChangeUUIDv1
547              
548             =head1 DESCRIPTION
549              
550             B adds some changeet methods to
551             L.
552              
553             =head1 DBH METHODS
554              
555             =over
556              
557             =item xprepare_uchangeset_v1() -> $sth
558              
559             =back
560              
561             =head1 ST METHODS
562              
563             =over
564              
565             =item uchangeset_v1() -> ArrayRef
566              
567             =back
568              
569             =head1 SEE ALSO
570              
571             L
572              
573             =head1 AUTHOR
574              
575             Mark Lawrence Enomad@null.netE
576              
577             =head1 COPYRIGHT AND LICENSE
578              
579             Copyright 2013-2015 Mark Lawrence
580              
581             This program is free software; you can redistribute it and/or modify it
582             under the terms of the GNU General Public License as published by the
583             Free Software Foundation; either version 3 of the License, or (at your
584             option) any later version.
585