/[webpac2]/branches/Sack/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 /branches/Sack/run.pl

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

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

Legend:
Removed from v.606  
changed lines
  Added in v.1098

  ViewVC Help
Powered by ViewVC 1.1.26