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