1 package System::Introspector::Report::Updater;
4 my $_flatten_id = sub {
6 return ref($value) ? join("\0", @$value) : $value;
10 my ($self, $original, $update) = @_;
11 my $old = $self->_map_reports_by_id($original);
12 my $new = $self->_map_reports_by_id($update);
13 my %add = map { ($_ => $new->{$_}) } grep { not($old->{$_}) } keys %$new;
14 return $self->_weave_additional([ map {
15 (ref($_) eq 'HASH') ? do {
17 my $id = $report->{id}->$_flatten_id;
19 ? $self->_merge_reports($report, $new->{$id})
22 } @$original ], \%add, $self->_calc_sequence($update));
25 sub _weave_additional {
26 my ($self, $stream, $additional, $sequence) = @_;
28 if (my $begin = $sequence->{''}) {
29 if (my $item = delete $additional->{$begin}) {
30 unshift @items, $item;
34 while (defined( my $item = shift @items )) {
35 if (ref($item) eq 'HASH') {
36 my $item_id = $item->{id}->$_flatten_id;
37 if (my $after = $sequence->{$item_id}) {
38 if (my $insert = $additional->{$after}) {
39 unshift @items, $insert;
49 my ($self, $stream) = @_;
51 $_->{id}->$_flatten_id;
56 for my $index (0 .. $#ids) {
57 $sequence{ $index ? $ids[$index - 1] : '' } = $ids[$index];
63 my ($self, $original, $update) = @_;
64 my $rowid = $update->{rowid};
67 join "\0", map $row->{$_}, @$rowid;
70 $current{$_->$ident} = $_
71 for @{$original->{rows}};
73 title => $update->{title},
75 rowid => $update->{rowid},
76 meta => $update->{meta} || {},
78 @{$update->{columns}},
81 } @{$original->{columns}}),
85 my $id = $row->$ident;
86 +{ %{$current{$id}||{}}, %$row };
87 } @{$update->{rows}} ],
91 sub _map_reports_by_id {
92 my ($self, $stream) = @_;
95 ($_->{id}->$_flatten_id, $_);