remove hash from first column name
[MojoFacets.git] / lib / MojoFacets / Changes.pm
1 package MojoFacets::Changes;
2
3 use strict;
4 use warnings;
5
6 use base 'Mojolicious::Controller';
7
8 use Storable;
9 use Data::Dump qw(dump);
10 use MojoFacets::Data;
11
12 sub _changes_path {
13         my $self = shift;
14         my $path = $self->param('path') || $self->session('path');
15         $self->app->home->rel_file('data') . '/' . $path . '.changes';
16 }
17
18 sub _hash_eq {
19         my ( $a_ref, $b_ref ) = @_;
20
21         warn "# _hash_eq ",dump($a_ref,$b_ref);
22
23         local $Storable::canonical = 1;
24         return eval { Storable::freeze( $a_ref ) } eq eval { Storable::freeze( $b_ref ) };
25 }
26
27 sub index {
28         my ( $self ) = @_;
29         my $path = $self->param('path') || $self->session('path');
30         my $on_path = $self->param('on_path');
31         my $commit = $self->param('commit');
32         my $apply = $self->param('apply');
33         my ( $items, $unique2id );
34         if ( $on_path ) {
35                 $items = $MojoFacets::Data::loaded->{$on_path}->{data}->{items};
36                 if ( ! $items ) {
37                         warn "$on_path not loaded";
38                         return $self->redirect_to('/data/index?path=' . $on_path);
39                 }
40                 warn "using ", $#$items + 1, " items from $on_path\n";
41         }
42         my $invalidate_columns;
43         my $changes;
44         my $stats;
45         my $glob = $self->_changes_path . '/*';
46         my $status = 'unknown';
47         foreach my $t ( sort { $a cmp $b } glob $glob ) {
48                 my $e = retrieve($t);
49                 $e->{old} = [ $e->{old} ] unless ref $e->{old} eq 'ARRAY';
50                 if ( $items && exists $e->{unique} ) {
51                         my ($pk,$id) = %{ $e->{unique} };
52                         if ( ! $pk ) {
53                                 $e->{_status} = 'skip';
54                                 $stats->{skip}++;
55                                 push @$changes, $e;
56                                 next;
57                         }
58                         if ( ! defined $unique2id->{$pk} ) {
59                                 warn "unique2id $pk on ", $#$items + 1 ," items\n";
60                                 foreach my $i ( 0 .. $#$items ) {
61                                         $unique2id->{$pk}->{ $items->[$i]->{$pk}->[0] } = $i;
62                                 }
63                         }
64                         $status = 'missing';
65                         if ( my $i = $unique2id->{$pk}->{$id} ) {
66                                 if ( _hash_eq( $e->{old}, $items->[$i]->{$e->{column}} ) ) {
67                                         $status = 'found';
68                                         if ( $commit ) {
69                                                 my $column = $e->{column} or die "no column";
70                                                 $items->[$i]->{$column} = $e->{new};
71                                                 warn "# commit $i $column ",dump( $e->{new} );
72                                                 $invalidate_columns->{$column}++;
73                                         }
74                                 } else {
75                                         $status = 'source-changed';
76                                 }
77                         }
78                 } elsif ( my $code = $e->{code} ) {
79                         if ( $commit ) {
80                                 my $commit_changed;
81                                 my $t = time();
82                                 foreach my $i ( 0 .. $#$items ) {
83                                         MojoFacets::Data::__commit_path_code( $on_path, $i, $code, \$commit_changed );
84                                 }
85                                 $t = time() - $t;
86                                 $self->stash( 'commit_changed', $commit_changed );
87                                 warn "commit_changed in $t s ",dump( $e->{commit_changed}, $commit_changed );
88                                 $e->{commit_changed_this} = $commit_changed;
89                                 MojoFacets::Data::__invalidate_path_column( $on_path, $_ ) foreach keys %$commit_changed;
90                                 MojoFacets::Data::__path_rebuild_stats( $on_path );
91                         }
92                         $status = 'code';
93                         if ( ( $apply || $commit ) && $e->{commit_changed} ) {
94                                 $status = 'found';
95                                 foreach my $c ( keys %{ $e->{commit_changed} } ) {
96                                         $status = 'missing' unless defined $MojoFacets::Data::loaded->{$path}->{stats}->{$c};
97                                 }
98                         }
99                 } else {
100                         $status = 'unknown';
101                 }
102
103                 $e->{_status} = $status;
104                 $stats->{$status}++;
105
106                 push @$changes, $e;
107         }
108
109
110         foreach my $name ( keys %$invalidate_columns ) {
111                 MojoFacets::Data::__invalidate_path_column( $on_path, $name );
112         }
113
114         MojoFacets::Data::__path_modified( $on_path );
115
116         my @loaded = MojoFacets::Data::__loaded_paths();
117         warn "# loaded paths ",dump @loaded;
118
119         $self->render(
120                 on_path => $on_path || $path,
121                 changes => $changes,
122                 loaded => \@loaded,
123                 stats => $stats,
124         );
125 }
126
127 sub remove {
128         my $self = shift;
129
130         if ( my $t = $self->param('time') ) {
131                 unlink $self->_changes_path . '/' . $t;
132         }
133
134         return $self->redirect_to('/changes');
135 }
136
137 1;