/[webpac2]/trunk/run.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/run.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 434 by dpavlin, Mon Apr 17 16:50:53 2006 UTC revision 1160 by dpavlin, Sat Apr 25 14:17:27 2009 UTC
# Line 4  use strict; Line 4  use strict;
4    
5  use Cwd qw/abs_path/;  use Cwd qw/abs_path/;
6  use File::Temp qw/tempdir/;  use File::Temp qw/tempdir/;
 use Data::Dumper;  
7  use lib './lib';  use lib './lib';
8    
9  use WebPAC::Common 0.02;  use WebPAC::Common 0.02;
10  use WebPAC::Lookup;  use WebPAC::Parser 0.08;
11  use WebPAC::Input 0.03;  use WebPAC::Input 0.16;
12  use WebPAC::Store 0.03;  use WebPAC::Store 0.15;
13  use WebPAC::Normalize::XML;  use WebPAC::Normalize 0.22;
14  use WebPAC::Output::TT;  use WebPAC::Output::TT;
15  use YAML qw/LoadFile/;  use WebPAC::Validate 0.11;
16    use WebPAC::Output::MARC;
17    use WebPAC::Config;
18  use Getopt::Long;  use Getopt::Long;
19  use File::Path;  use File::Path;
20  use Time::HiRes qw/time/;  use Time::HiRes qw/time/;
21    use File::Slurp;
22    use Data::Dump qw/dump/;
23    use Storable qw/dclone/;
24    use Pod::Usage qw/pod2usage/;
25    
26    use POSIX ":sys_wait_h"; # imports WNOHANG
27    
28  =head1 NAME  =head1 NAME
29    
# Line 24  run.pl - start WebPAC indexing Line 31  run.pl - start WebPAC indexing
31    
32  B<this command will probably go away. Don't get used to it!>  B<this command will probably go away. Don't get used to it!>
33    
34  Options:  =head1 OPTIONS
35    
36  =over 4  =over 4
37    
# Line 40  limit loading to 100 records Line 47  limit loading to 100 records
47    
48  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
49    
50  =item --only=database_name  =item --only=database_name/input_filter
51    
52  reindex just single database (legacy name is --one)  reindex just single database (legacy name is --one)
53    
54    C</input_filter> is optional part which can be C<name>
55    or C<type> from input
56    
57  =item --config conf/config.yml  =item --config conf/config.yml
58    
59  path to YAML configuration file  path to YAML configuration file
60    
61    =item --stats
62    
63    disable indexing, modify_* in configuration and dump statistics about field
64    and subfield usage for each input
65    
66    =item --validate path/to/validation_file
67    
68    turn on extra validation of imput records, see L<WebPAC::Validation>
69    
70    You can use special variables C<$database> and $C<$input> in this parametar
71    like C<--validate 'conf/validate/$database-$input'> to construct filename
72    
73    =item --validate-delimiters path/to/validate_delimiters_file
74    
75    this option is used with C<--validate> to turn on extra validation of
76    delimiters. If file is non existant, it will be created on first run.
77    
78    =item --marc-generate
79    
80    Generate MARC file. This will automatically be on if file contains C<marc*> directives.
81    You can use this option as C<--no-marc-generate> to disable MARC generation.
82    
83    =item --marc-lint
84    
85    By default turned on if normalisation file has C<marc*> directives. You can disable lint
86    messages with C<--no-marc-lint>.
87    
88    =item --marc-dump
89    
90    Force dump or input and marc record for debugging.
91    
92    =item --parallel 4
93    
94    Run databases in parallel (aproximatly same as number of processors in
95    machine if you want to use full load)
96    
97    =item --only-links
98    
99    Create just links
100    
101    =item --merge
102    
103    Create merged index of databases which have links
104    
105  =back  =back
106    
107  =cut  =cut
# Line 56  my $offset; Line 110  my $offset;
110  my $limit;  my $limit;
111    
112  my $clean = 0;  my $clean = 0;
113  my $config = 'conf/config.yml';  my $config_path;
114  my $debug = 0;  my $debug = 0;
115  my $only_db_name;  my $only_filter;
116    my $stats = 0;
117    my $validate_path;
118    my $validate_delimiters_path;
119    my $marc_generate = 1;
120    my $marc_lint = 1;
121    my $marc_dump = 0;
122    my $parallel = 0;
123    my $only_links = 0;
124    my $merge = 0;
125    my $help;
126    
127    my $log = _new WebPAC::Common()->_get_logger();
128    
129  GetOptions(  GetOptions(
130          "limit=i" => \$limit,          "limit=i" => \$limit,
131          "offset=i" => \$offset,          "offset=i" => \$offset,
132          "clean" => \$clean,          "clean" => \$clean,
133          "one=s" => \$only_db_name,          "one=s" => \$only_filter,
134          "only=s" => \$only_db_name,          "only=s" => \$only_filter,
135          "config" => \$config,          "config=s" => \$config_path,
136          "debug" => \$debug,          "debug+" => \$debug,
137            "stats" => \$stats,
138            "validate=s" => \$validate_path,
139            "validate-delimiters=s" => \$validate_delimiters_path,
140            "marc-generate!" => \$marc_generate,
141            "marc-lint!" => \$marc_lint,
142            "marc-dump!" => \$marc_dump,
143            "parallel=i" => \$parallel,
144            "only-links!" => \$only_links,
145            "merge" => \$merge,
146            "help" => \$help,
147  );  );
148    
149  $config = LoadFile($config);  $marc_generate = 0 if ( $validate_delimiters_path );
150    
151  print "config = ",Dumper($config) if ($debug);  pod2usage(-verbose => 2) if ($help);
152    
153  die "no databases in config file!\n" unless ($config->{databases});  my $config = new WebPAC::Config( path => $config_path );
154    
155  my $log = _new WebPAC::Common()->_get_logger();  WebPAC::Normalize::_debug( $debug - 1 ) if $debug > 1;
156    
157    #print "config = ",dump($config) if ($debug);
158    
159    die "no databases in config file!\n" unless ($config->databases);
160    
161    $log->info( "-" x 79 );
162    
163    my $log_file = 'log';
164    
165    if (-e $log_file ) {    # && -s $log_file > 5 * 1024 * 1024) {
166            $log->info("moved old log with ", -s $log_file, " bytes to '${log_file}.old'");
167            rename $log_file, "${log_file}.old" || $log->logwarn("can't rename $log_file to ${log_file}.old: $!");
168    }
169    
170    my $estcmd_fh;
171    my $estcmd_path = './estcmd-merge.sh';
172    if ($merge) {
173            open($estcmd_fh, '>', $estcmd_path) || $log->logdie("can't open $estcmd_path: $!");
174            print $estcmd_fh 'cd /data/estraier/_node/ || exit 1',$/;
175            print $estcmd_fh 'sudo /etc/init.d/hyperestraier stop',$/;
176            $log->info("created merge batch file $estcmd_path");
177    }
178    
179    my $validate;
180    $validate = new WebPAC::Validate(
181            delimiters => $config->webpac('delimiters'),
182    ) if ($validate_path || $validate_delimiters_path);
183    
184    my $use_indexer = $config->use_indexer;
185    $stats ||= $validate;
186    if ($stats) {
187            $log->debug("disabled indexing for stats collection");
188            $use_indexer = undef;
189    } elsif ( $use_indexer ) {
190            $log->info("using $use_indexer indexing engine...");
191    }
192    
193  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  # parse normalize files and create source files for lookup and normalization
194  $log->info("using $use_indexer indexing engine...");  
195    my ($only_database,$only_input) = split(m#/#, $only_filter) if $only_filter;
196    
197    my $parser = new WebPAC::Parser(
198            config => $config,
199            only_database => $only_database,
200            only_input => $only_input,
201    );
202    
203  my $total_rows = 0;  my $total_rows = 0;
204  my $start_t = time();  my $start_t = time();
205    
206  while (my ($database, $db_config) = each %{ $config->{databases} }) {  my @links;
207    
208          next if ($only_db_name && $database !~ m/$only_db_name/i);  if ($parallel) {
209            eval 'use Proc::Queue size => 1;';
210            die $@ if $@;
211            $log->info("Using $parallel processes for speedup");
212            Proc::Queue::size($parallel);
213    }
214    
215    sub create_ds_config {
216            my ($db_config, $database, $input, $mfn) = @_;
217            my $c = dclone( $db_config );
218            $c->{_} = $database || $log->logconfess("need database");
219            $c->{_mfn} = $mfn || $log->logconfess("need mfn");
220            $c->{input} = $input || $log->logconfess("need input");
221            return $c;
222    }
223    
224    foreach my $database ( sort keys %{ $config->databases } ) {
225            my $db_config = $config->databases->{$database};
226    
227            next if ($only_database && $database !~ m/$only_database/i);
228    
229            if ($parallel) {
230                    my $f=fork;
231                    if(defined ($f) and $f==0) {
232                            $log->info("Created processes $$ for speedup");
233                    } else {
234                            next;
235                    }
236            }
237    
238          my $indexer;          my $indexer;
239            if ($use_indexer && $parser->have_rules( 'search', $database )) {
240    
241          my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");                  my $cfg_name = $use_indexer;
242          $indexer_config->{database} = $database;                  $cfg_name =~ s/\-.*$//;
243          $indexer_config->{clean} = $clean;  
244          $indexer_config->{label} = $db_config->{name};                  my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
245                    $indexer_config->{database} = $database;
246          # important: clean database just once!                  $indexer_config->{clean} = $clean;
247          $clean = 0;                  $indexer_config->{label} = $db_config->{name};
248    
249          if ($use_indexer eq 'hyperestraier') {                  # force clean if database has links
250                    $indexer_config->{clean} = 1 if ($db_config->{links});
251                  # open Hyper Estraier database  
252                  use WebPAC::Output::Estraier '0.10';                  if ($use_indexer eq 'hyperestraier') {
253                  $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );  
254                                    # open Hyper Estraier database
255          } elsif ($use_indexer eq 'kinosearch') {                          require WebPAC::Output::Estraier;
256                            $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
257                    
258                    } elsif ($use_indexer eq 'hyperestraier-native') {
259    
260                            # open Hyper Estraier database
261                            require WebPAC::Output::EstraierNative;
262                            $indexer = new WebPAC::Output::EstraierNative( %{ $indexer_config } );
263    
264                    } elsif ($use_indexer eq 'kinosearch') {
265    
266                            die "no longer supported";
267    
268                    } else {
269                            $log->logdie("unknown use_indexer: $use_indexer");
270                    }
271    
272                    $log->logdie("can't continue without valid indexer") unless ($indexer);
273            }
274    
                 # open KinoSearch  
                 use WebPAC::Output::KinoSearch;  
                 $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});  
                 $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );  
275    
276          } else {          #
277                  $log->logdie("unknown use_indexer: $use_indexer");          # store Hyper Estraier links to other databases
278            #
279            if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
280                    foreach my $link (@{ $db_config->{links} }) {
281                            if ($use_indexer eq 'hyperestraier') {
282                                    if ($merge) {
283                                            print $estcmd_fh 'sudo -u www-data estcmd merge ' . $database . ' ' . $link->{to},$/;
284                                    } else {
285                                            $log->info("saving link $database -> $link->{to} [$link->{credit}]");
286                                            push @links, sub {
287                                                    $log->info("adding link $database -> $link->{to} [$link->{credit}]");
288                                                    $indexer->add_link(
289                                                            from => $database,
290                                                            to => $link->{to},
291                                                            credit => $link->{credit},
292                                                    );
293                                            };
294                                    }
295                            } else {
296                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
297                            }
298                    }
299          }          }
300            next if ($only_links);
301    
         $log->logide("can't continue without valid indexer") unless ($indexer);  
302    
303          #          #
304          # now WebPAC::Store          # now WebPAC::Store
305          #          #
306          my $abs_path = abs_path($0);          my $store = new WebPAC::Store({
307          $abs_path =~ s#/[^/]*$#/#;                  debug => $debug,
308            });
309    
         my $db_path = $config->{webpac}->{db_path} . '/' . $database;  
310    
311          if ($clean) {          #
312                  $log->info("creating new database $database in $db_path");          # prepare output
313                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");          #
314          } else {          my @outputs = force_array( $db_config->{output}, sub {
315                  $log->debug("working on $database in $db_path");                  $log->error("Database $database doesn't have any outputs defined. Do you want to remove it from configuration?" );
316          }          } );
317    
318          my $db = new WebPAC::Store(          my @output_modules;
319                  path => $db_path,  
320                  database => $database,          foreach my $output ( @outputs ) {
321                  debug => $debug,  
322          );  #warn '## output = ',dump( $output );
323    
324                    my $module = $output->{module} || $log->logdie("need module in output section of $database");
325                    $module = 'WebPAC::Output::' . $module unless $module =~ m/::/;
326            
327                    $log->debug("loading output module $module");
328                    eval "require $module";
329    
330                    # add database to arugemnts for output filter
331                    $output->{database} = $database;
332                    $output->{clean} = $clean;
333    
334                    $log->debug("calling $module->new(",dump( $output ),")");
335                    my $out = new $module->new( $output );
336                    if ( $out->init ) {
337                            push @output_modules, $out;
338                    } else {
339                            $log->warn("SKIPPED $module");
340                    }
341            }
342    
343    
344          #          #
345          # now, iterate through input formats          # now, iterate through input formats
346          #          #
347    
348          my @inputs;  
349          if (ref($db_config->{input}) eq 'ARRAY') {          my @inputs = force_array( $db_config->{input}, sub {
                 @inputs = @{ $db_config->{input} };  
         } elsif ($db_config->{input}) {  
                 push @inputs, $db_config->{input};  
         } else {  
350                  $log->info("database $database doesn't have inputs defined");                  $log->info("database $database doesn't have inputs defined");
351          }          } );
352    
353          my @supported_inputs = keys %{ $config->{webpac}->{inputs} };          if ( -e 'out/debug' ) { # FIXME flag?
354                    my $out;
355                    foreach my $i ( @inputs ) {
356                            warn dump( $i );
357                            next unless defined $i->{normalize};
358                            warn dump( $i->{normalize} );
359                            foreach my $normalize ( @{ $i->{normalize} } ) {
360                                    my $path = $normalize->{path};
361                                    $out .= qq/\n##\n## $path\n##\n\n/;
362                                    $out .= read_file( $path );
363                            }
364                    }
365                    my $all = "out/debug/all-normalize.pl";
366                    write_file( $all, $out );
367                    warn "### all normalize for this input saved to: $all";
368            };
369    
370          foreach my $input (@inputs) {          foreach my $input (@inputs) {
371    
372                    my $input_name = $input->{name} || $log->logdie("input without a name isn't valid: ",dump($input));
373    
374                    if ( $input->{skip} ) {
375                            $log->info("skip $input_name");
376                            next;
377                    }
378    
379                    next if ($only_input && ($input_name !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));
380    
381                  my $type = lc($input->{type});                  my $type = lc($input->{type});
382    
383                  die "I know only how to handle input types ", join(",", @supported_inputs), " not '$type'!\n" unless (grep(/$type/, @supported_inputs));                  # FIXME check if input module exists
384                    my $input_module = $input->{module};
385    
386                  my $lookup = new WebPAC::Lookup(                  if ( ! $input_module ) {
387                          lookup_file => $input->{lookup},                          if ( grep(/$type/, $config->webpac('inputs')) ) {
388                  );                                  $input_module = $config->webpac('inputs')->{$type};
389                            } else {
390                                    $log->logdie("I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!" );
391                            }
392                    }
393    
394                    my @lookups = $parser->have_lookup_create($database, $input);
395    
396                  my $input_module = $config->{webpac}->{inputs}->{$type};                  $log->info("working on $database/$input_name with $input_module on $input->{path}",
397                            @lookups ? " creating lookups: ".join(", ", @lookups) : ""
398                    );
399    
400                  $log->info("working on input '$input->{path}' [$input->{type}] using $input_module lookup '$input->{lookup}'");                  if ($stats) {
401                            # disable modification of records if --stats is in use
402                            delete($input->{modify_records});
403                            delete($input->{modify_file});
404                    }
405    
406                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
407                          module => $input_module,                          module => $input_module,
                         code_page => $config->{webpac}->{webpac_encoding},  
408                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
409                          offset => $offset,                          offset => $offset,
                         lookup => $lookup,  
410                          recode => $input->{recode},                          recode => $input->{recode},
411                            stats => $stats,
412                            modify_records => $input->{modify_records},
413                            modify_file => $input->{modify_file},
414                            input_config => $input,
415                  );                  );
416                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
417    
418                    if (defined( $input->{lookup} )) {
419                            $log->warn("$database/$input_name has depriciated lookup definition, removing it...");
420                            delete( $input->{lookup} );
421                    }
422    
423                    my $lookup_coderef;
424    
425                    if (@lookups) {
426    
427                            my $rules = $parser->lookup_create_rules($database, $input) || $log->logdie("no rules found for $database/$input");
428    
429                            $lookup_coderef = sub {
430                                    my $rec = shift || die "need rec!";
431                                    my $mfn = $rec->{'000'}->[0] || die "need mfn in 000";
432    
433                                    WebPAC::Normalize::data_structure(
434                                            row => $rec,
435                                            rules => $rules,
436                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
437                                    );
438    
439                                    #warn "current lookup: ", dump(WebPAC::Normalize::_get_lookup());
440                            };
441    
442                            WebPAC::Normalize::_set_lookup( undef );
443    
444                            $log->debug("created lookup_coderef using:\n$rules");
445    
446                    };
447    
448                    my $lookup_jar;
449    
450                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
451                          path => $input->{path},                          path => $input->{path},
452                          code_page => $input->{encoding},        # database encoding                          input_encoding => $input->{encoding},   # database encoding
453                  );                          lookup_coderef => $lookup_coderef,
454                            lookup => $lookup_jar,
455                            %{ $input },
456                            load_row => sub {
457                                    my $a = shift;
458                                    return $store->load_row(
459                                            database => $database,
460                                            input => $input_name,
461                                            id => $a->{id},
462                                    );
463                            },
464                            save_row => sub {
465                                    my $a = shift;
466                                    return $store->save_row(
467                                            database => $database,
468                                            input => $input_name,
469                                            id => $a->{id},
470                                            row => $a->{row},
471                                    );
472                            },
473    
                 my $n = new WebPAC::Normalize::XML(  
                 #       filter => { 'foo' => sub { shift } },  
                         db => $db,  
                         lookup_regex => $lookup->regex,  
                         lookup => $lookup,  
                         prefix => $input->{name},  
474                  );                  );
475    
476                  my $normalize_path = $input->{normalize}->{path};                  my $lookup_data = WebPAC::Normalize::_get_lookup();
477    
478                  if ($normalize_path =~ m/\.xml$/i) {                  if (defined( $lookup_data->{$database}->{$input_name} )) {
479                          $n->open(                          $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
480                                  tag => $input->{normalize}->{tag},  
481                                  xml_file => $input->{normalize}->{path},                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
482                          );                                  $store->save_lookup(
483                  } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {                                          database => $database,
484                          $n->open_yaml(                                          input => $input_name,
485                                  path => $normalize_path,                                          key => $key,
486                                  tag => $input->{normalize}->{tag},                                          data => $lookup_data->{$database}->{$input_name}->{$key},
487                                    );
488                            }
489                    }
490    
491                    my $report_fh;
492                    if ($stats || $validate) {
493                            my $path = "out/report/${database}-${input_name}.txt";
494                            open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
495    
496                            print $report_fh "Report for database '$database' input '$input_name' records ",
497                                    $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
498                            $log->info("Generating report file $path");
499    
500                            if ( $validate ) {
501                                    $validate->read_validate_file( $validate->fill_in( $validate_path, database => $database, input => $input_name ) ) if ( $validate_path );
502                                    $validate->read_validate_delimiters_file( $validate->fill_in( $validate_delimiters_path, database => $database, input => $input_name ) ) if ( $validate_delimiters_path );
503                            }
504                    }
505    
506                    my $marc;
507                    if ($marc_generate && $parser->have_rules( 'marc', $database, $input_name )) {
508                            $marc = new WebPAC::Output::MARC(
509                                    path => "out/marc/${database}-${input_name}.marc",
510                                    lint => $marc_lint,
511                                    dump => $marc_dump,
512                          );                          );
513                  }                  }
514    
515                    my $rules = $parser->normalize_rules($database,$input_name);
516                    $log->logwarn("no normalize rules for $database/$input_name") unless $rules;
517    
518                    $log->debug("parsed normalize rules:\n$rules");
519    
520                    # reset position in database
521                    $input_db->seek(1);
522    
523                    # generate name of config key for indexer (strip everything after -)
524                    my $indexer_config = $use_indexer;
525                    $indexer_config =~ s/^(\w+)-?.*$/$1/g if ($indexer_config);
526    
527                    my $lookup_hash;
528                    my $depends = $parser->depends($database,$input_name);
529            
530                    if ($depends) {
531                            $log->debug("$database/$input_name depends on: ", dump($depends)) if ($depends);
532                            $log->logdie("parser->depends didn't return HASH") unless (ref($depends) eq 'HASH');
533    
534                            foreach my $db (keys %$depends) {
535                                    foreach my $i (keys %{$depends->{$db}}) {
536                                            foreach my $k (keys %{$depends->{$db}->{$i}}) {
537                                                    my $t = time();
538                                                    $log->debug("loading lookup $db/$i");
539                                                    $lookup_hash->{$db}->{$i}->{$k} = $store->load_lookup(
540                                                            database => $db,
541                                                            input => $i,
542                                                            key => $k,
543                                                    );
544                                                    $log->debug(sprintf("lookup $db/$i took %.2fs", time() - $t));
545                                            }
546                                    }
547                            }
548    
549                            $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
550                    }
551    
552    
553                    # setup input name for all output filters
554                    foreach my $out ( @output_modules ) {
555                            if ( $out->can('input') ) {
556                                    $out->input( $input_name );
557                            } else {
558                                    $log->warn("output filter ",ref($out)," doesn't support input name");
559                            }
560                    }
561    
562    
563                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $pos ( 0 ... $input_db->size ) {
564    
565                          my $row = $input_db->fetch || next;                          my $row = $input_db->fetch || next;
566    
567                            $total_rows++;
568    
569                          my $mfn = $row->{'000'}->[0];                          my $mfn = $row->{'000'}->[0];
570    
571                          if (! $mfn || $mfn !~ m#^\d+$#) {                          if (! $mfn || $mfn !~ m{^\d+$}) {
572                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");                                  $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
573                                  $mfn = $pos;                                  $mfn = $pos;
574                                  push @{ $row->{'000'} }, $pos;                                  push @{ $row->{'000'} }, $pos;
575                          }                          }
576    
                         my $ds = $n->data_structure($row);  
577    
578                          $indexer->add(                          if ($validate) {
579                                  id => $input->{name} . "/" . $mfn,                                  if ( my $errors = $validate->validate_rec( $row, $input_db->dump_ascii ) ) {
580                                  ds => $ds,                                          $log->error( "MFN $mfn validation error:\n",
581                                  type => $config->{$use_indexer}->{type},                                                  $validate->report_error( $errors )
582                          );                                          );
583                                    }
584                                    next;   # validation doesn't create any output
585                            }
586    
587                            if ($rules) {
588    
589                                    my $ds = WebPAC::Normalize::data_structure(
590                                            row => $row,
591                                            rules => $rules,
592                                            lookup => $lookup_hash,
593                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
594                                            marc_encoding => 'utf-8',
595                                            load_row_coderef => sub {
596                                                    my ($database,$input,$mfn) = @_;
597    #warn "### load_row($database,$input,$mfn) from data_structure\n";
598                                                    return $store->load_row(
599                                                            database => $database,
600                                                            input => $input,
601                                                            id => $mfn,
602                                                    );
603                                            },
604                                    );
605    
606                                    $log->debug("ds = ", sub { dump($ds) });
607    
608                                    if ( $ds ) {
609    
610                                            $store->save_ds(
611                                                    database => $database,
612                                                    input => $input_name,
613                                                    id => $mfn,
614                                                    ds => $ds,
615                                            ) if !$stats;
616    
617                                            $indexer->add(
618                                                    id => "${input_name}/${mfn}",
619                                                    ds => $ds,
620                                                    type => $config->get($indexer_config)->{type},
621                                            ) if $indexer;
622    
623                                            foreach my $out ( @output_modules ) {
624                                                    $out->add( $mfn, $ds ) if $out->can('add');
625                                            }
626    
627                                    } else {
628                                            $log->warn("record $pos didn't produce any output after normalization rules!") unless $marc;
629                                    }
630                            }
631    
632                            if ($marc) {
633                                    my $i = 0;
634    
635                                    while (my $fields = WebPAC::Normalize::MARC::_get_marc_fields( fetch_next => 1 ) ) {
636                                            $marc->add(
637                                                    id => $mfn . ( $i ? "/$i" : '' ),
638                                                    fields => $fields,
639                                                    leader => WebPAC::Normalize::MARC::_get_marc_leader(),
640                                                    row => $row,
641                                            );
642                                            $i++;
643                                    }
644    
645                                    $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
646                            }
647    
                         $total_rows++;  
648                  }                  }
649    
650          };                  if ($validate) {
651                            my $errors = $validate->report;
652                            if ($errors) {
653                                    $log->info("validation errors:\n$errors\n" );
654                                    print $report_fh "$errors\n" if ($report_fh);
655                            }
656    
657                            print $report_fh "\nAll possible subfields/delimiter templates:\n", $validate->delimiters_templates( report => 1, current_input => 1 ), "\n\n";
658    
659                            # must be last thing that touches $validate for this input
660                            $validate->reset;
661                    }
662    
663          eval { $indexer->finish } if ($indexer->can('finish'));                  if ($stats) {
664                            my $s = $input_db->stats;
665                            $log->info("statistics of fields usage:\n$s");
666                            print $report_fh "Statistics of fields usage:\n$s" if ($report_fh);
667                    }
668    
669                    # close MARC file
670                    $marc->finish if ($marc);
671    
672                    # close report
673                    close($report_fh) if ($report_fh);
674            }
675    
676            $indexer->finish if $indexer && $indexer->can('finish');
677    
678            foreach my $out ( @output_modules ) {
679                    $out->finish if $out->can('finish');
680            }
681    
682          my $dt = time() - $start_t;          my $dt = time() - $start_t;
683          $log->info("$total_rows records indexed in " .          $log->info("$total_rows records ", $indexer ? "indexed " : "",
684                  sprintf("%.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
685                          $dt, ($total_rows / $dt)                          $dt, ($total_rows / $dt)
686                  )                  )
687          );          );
688    
689          #  
690          # add Hyper Estraier links to other databases          # end forked process
691          #          if ($parallel) {
692          if (ref($db_config->{links}) eq 'ARRAY') {                  $log->info("parallel process $$ finished");
693                  foreach my $link (@{ $db_config->{links} }) {                  exit(0);
                         if ($use_indexer eq 'hyperestraier') {  
                                 $log->info("adding link $database -> $link->{to} [$link->{credit}]");  
                                 $indexer->add_link(  
                                         from => $database,  
                                         to => $link->{to},  
                                         credit => $link->{credit},  
                                 );  
                         } else {  
                                 $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");  
                         }  
                 }  
694          }          }
695    
696  }  }
697    
698    if ($parallel) {
699            # wait all children to finish
700            sleep(1) while wait != -1;
701            $log->info("all parallel processes finished");
702    }
703    
704    # save new delimiters if needed
705    $validate->save_delimiters_templates if ( $validate_delimiters_path );
706    
707    #
708    # handle links or merge after indexing
709    #
710    
711    if ($merge) {
712            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
713            close($estcmd_fh);
714            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
715            system $estcmd_path;
716    } else {
717            foreach my $link (@links) {
718                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
719                    $link->();
720            }
721    }

Legend:
Removed from v.434  
changed lines
  Added in v.1160

  ViewVC Help
Powered by ViewVC 1.1.26