e25ac3348649c16d9627c6b835e41a06de321762
[scpubgit/stemmatology.git] / analysis / idp_server / idprestore.pl
1 #!/usr/bin/env perl
2
3 use lib 'lib';
4 use feature 'say';
5 use strict;
6 use warnings;
7 use IPC::Run qw/ run /;
8 use JSON;
9 use Text::Tradition::Analysis::Result;
10 use Text::Tradition::Directory;
11 use TryCatch;
12
13 binmode STDOUT, ':utf8';
14 binmode STDERR, ':utf8';
15 eval { no warnings; binmode $DB::OUT, ':utf8'; $DB::deep = 1000 };
16
17 my %VARS = (
18         DBTYPE => 'mysql',
19         DBHOST => '127.0.0.1',
20         DBPORT => '3006',
21         DBNAME => 'idpresult',
22         DSN => undef,
23         DBUSER => undef,
24         DBPASS => undef,
25         TMPDIR => '/var/tmp'
26 );
27
28 if( -f "/etc/graphcalc.conf" ) {
29         # Read the variables in from here.
30         open( GCCONF, "/etc/graphcalc.conf" ) 
31                 or die "Could not open configuration file /etc/graphcalc.conf";
32         while(<GCCONF>) {
33                 chomp;
34                 s/^\s+//;
35                 my( $name, $val ) = split( /\s*\=\s*/, $_ );
36                 if( exists $VARS{$name} ) {
37                         $VARS{$name} = $val;
38                 }
39         }
40         close GCCONF;
41 }
42 unless( $VARS{DSN} ) {
43         $VARS{DSN} = sprintf( "dbi:%s:dbname=%s;host=%s;port=%s",
44                 $VARS{DBTYPE}, $VARS{DBNAME}, $VARS{DBHOST}, $VARS{DBPORT} );
45 }
46
47 say 'Dropping tables in ' . $VARS{DBNAME};
48 my @connectargs = (     '-h', $VARS{DBHOST}, '-P', $VARS{DBPORT}, '-u'.$VARS{DBUSER}, 
49         '-p'.$VARS{DBPASS}, $VARS{DBNAME} );
50 my( $ret, $err );
51 my @dump = ( 'mysqldump', '--add-drop-table', '--no-data', @connectargs );
52 my @grep = ( 'grep', '^DROP' );
53 my @sort = ( 'sort', '-r' );
54 my @drop = ( 'mysql', @connectargs );
55 run( \@dump, '|', \@grep, '|', \@sort, '|', \@drop, '>' ,\$ret, '2>', \$err )
56         or die "Drop command returned $?:\n$err";
57
58 my $dirargs = { create => 1 };
59 $dirargs->{user} = $VARS{DBUSER} if $VARS{DBUSER};
60 $dirargs->{password} = $VARS{DBPASS} if $VARS{DBPASS};
61 my $dir = Text::Tradition::Directory->new( 
62         'dsn' => $VARS{DSN}, 'extra_args' => $dirargs );
63
64 my $scope = $dir->new_scope();
65 my $dumpfile = $VARS{TMPDIR}.'/idpbackup.json';
66 open( IDPBACKUP, "$dumpfile" )
67         or die "Could not open dump file $dumpfile for reading";
68 binmode IDPBACKUP, ':utf8';
69 my $nodel;
70 my $ctr = 0;
71 my $restored = 0;
72 while( <IDPBACKUP> ) {
73         chomp;
74         $ctr++;
75         say STDERR "...$ctr results" unless ( $ctr % 500 );
76         my $struct = from_json( $_ );
77         my $result = Text::Tradition::Analysis::Result->new( $struct );
78         if( $result ) {
79                 try {
80                         $dir->store( $result->object_key => $result );
81                         $restored++;
82                 } catch ($err) {
83                         $nodel = 1;
84                         if( $err =~ /already in use / || $err =~ /Duplicate/) {
85                                 say STDERR "Duplicate entry " . $result->object_key;
86                         } else {
87                                 say STDERR "Error saving result " . $result->object_key . ": $err";
88                         }
89                 }
90         } else {
91                 warn "Failed to parse result in $_";
92                 $nodel = 1;
93         }
94 }
95 close IDPBACKUP;
96 say "Restored $restored / $ctr results.";
97
98 unlink( $dumpfile ) unless $nodel;