more import pipeline improvement
[Evergreen.git] / Open-ILS / src / extras / import / pg_loader.pl
1 #!/usr/bin/perl
2 use strict;
3
4 use lib '/openils/lib/perl5/';
5
6 use OpenSRF::System;
7 use OpenSRF::EX qw/:try/;
8 use OpenSRF::Utils::SettingsClient;
9 use OpenILS::Utils::Fieldmapper;
10 use JSON;
11 use FileHandle;
12
13 use Time::HiRes qw/time/;
14 use Getopt::Long;
15
16 my @files;
17 my ($config, $output, @auto, @order) =
18         ('/openils/conf/bootstrap.conf');
19
20 GetOptions(
21         'config=s'      => \$config,
22         'output=s'      => \$output,
23         'autoprimary=s' => \@auto,
24         'order=s'       => \@order,
25 );
26
27 my %lineset;
28 my %fieldcache;
29
30 OpenSRF::System->bootstrap_client( config_file => $config );
31 Fieldmapper->import(IDL => OpenSRF::Utils::SettingsClient->new->config_value("IDL"));
32
33 my $count = 0;
34 my $starttime = time;
35 while ( my $rec = <> ) {
36         next unless ($rec);
37
38         my $row;
39         try {
40                 $row = JSON->JSON2perl($rec);
41         } catch Error with {
42                 my $e = shift;
43                 warn "\n\n !!! Error : $e \n\n at or around line $count\n";
44         };
45         die unless ($row);
46
47         my $class = $row->class_name;
48         my $hint = $row->json_hint;
49
50         if (!$lineset{$hint}) {
51                 $lineset{$hint} = [];
52                 my @cols = $row->real_fields;
53                 if (grep { $_ eq $hint} @auto) {
54                         @cols = grep { $_ ne $class->Identity } @cols;
55                 }
56
57                 $fieldcache{$hint} =
58                         { table => $class->Table,
59                           fields => \@cols,
60                         };
61         }
62
63         push @{ $lineset{$hint} }, [map { $row->$_ } @{ $fieldcache{$hint}{fields} }];
64
65         if (!($count % 500)) {
66                 print STDERR "\r$count\t". $count / (time - $starttime);
67         }
68
69         $count++;
70 }
71
72 print STDERR "\nWriting file ...\n";
73
74 $output = '&STDOUT' unless ($output);
75 $output = FileHandle->new(">$output") if ($output);
76
77 binmode($output,'utf8');
78
79 $output->print("SET CLIENT_ENCODING TO 'UNICODE';\n\n");
80
81 for my $h (@order) {
82         my $fields = join(',', @{ $fieldcache{$h}{fields} });
83         $output->print( "COPY $fieldcache{$h}{table} ($fields) FROM STDIN;\n" );
84
85         for my $line (@{ $lineset{$h} }) {
86                 my @data;
87                 for my $d (@$line) {
88                         if (!defined($d)) {
89                                 $d = '\N';
90                         } else {
91                                 $d =~ s/\t/\\t/go;
92                                 $d =~ s/\\/\\\\/go;
93                         }
94                         push @data, $d;
95                 }
96                 $output->print( join("\t", @data)."\n" );
97         }
98
99         $output->print('\.'."\n\n");
100 }