/[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 978 by dpavlin, Sat Nov 3 12:35:42 2007 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    #print "config = ",dump($config) if ($debug);
157    
158    die "no databases in config file!\n" unless ($config->databases);
159    
 my $log = _new WebPAC::Common()->_get_logger();  
160  $log->info( "-" x 79 );  $log->info( "-" x 79 );
161    
162    my $log_file = 'log';
163    
164    if (-e $log_file ) {    # && -s $log_file > 5 * 1024 * 1024) {
165            $log->info("moved old log with ", -s $log_file, " bytes to '${log_file}.old'");
166            rename $log_file, "${log_file}.old" || $log->logwarn("can't rename $log_file to ${log_file}.old: $!");
167    }
168    
169    my $estcmd_fh;
170    my $estcmd_path = './estcmd-merge.sh';
171    if ($merge) {
172            open($estcmd_fh, '>', $estcmd_path) || $log->logdie("can't open $estcmd_path: $!");
173            print $estcmd_fh 'cd /data/estraier/_node/ || exit 1',$/;
174            print $estcmd_fh 'sudo /etc/init.d/hyperestraier stop',$/;
175            $log->info("created merge batch file $estcmd_path");
176    }
177    
178  my $validate;  my $validate;
179  $validate = new WebPAC::Validate(  $validate = new WebPAC::Validate(
180          path => $validate_path,          delimiters => $config->webpac('delimiters'),
181  ) if ($validate_path);  ) if ($validate_path || $validate_delimiters_path);
182    
183  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  my $use_indexer = $config->use_indexer;
184    $stats ||= $validate;
185  if ($stats) {  if ($stats) {
186          $log->debug("option --stats disables update of indexing engine...");          $log->debug("disabled indexing for stats collection");
187          $use_indexer = undef;          $use_indexer = undef;
188  } else {  } elsif ( $use_indexer ) {
189          $log->info("using $use_indexer indexing engine...");          $log->info("using $use_indexer indexing engine...");
190  }  }
191    
192  # disable indexing when creating marc  # parse normalize files and create source files for lookup and normalization
193  $use_indexer = undef if ($marc_normalize);  
194    my ($only_database,$only_input) = split(m#/#, $only_filter) if $only_filter;
195    
196    my $parser = new WebPAC::Parser(
197            config => $config,
198            only_database => $only_database,
199            only_input => $only_input,
200    );
201    
202  my $total_rows = 0;  my $total_rows = 0;
203  my $start_t = time();  my $start_t = time();
204    
205  my @links;  my @links;
 my $indexer;  
206    
207  if ($parallel) {  if ($parallel) {
208          $log->info("Using $parallel processes for speedup");          $log->info("Using $parallel processes for speedup");
209          Proc::Queue::size($parallel);          Proc::Queue::size($parallel);
210  }  }
211    
212  while (my ($database, $db_config) = each %{ $config->{databases} }) {  sub create_ds_config {
213            my ($db_config, $database, $input, $mfn) = @_;
214            my $c = dclone( $db_config );
215            $c->{_} = $database || $log->logconfess("need database");
216            $c->{_mfn} = $mfn || $log->logconfess("need mfn");
217            $c->{input} = $input || $log->logconfess("need input");
218            return $c;
219    }
220    
221    foreach my $database ( sort keys %{ $config->databases } ) {
222            my $db_config = $config->databases->{$database};
223    
         my ($only_database,$only_input) = split(m#/#, $only_filter) if ($only_filter);  
224          next if ($only_database && $database !~ m/$only_database/i);          next if ($only_database && $database !~ m/$only_database/i);
225    
226          if ($parallel) {          if ($parallel) {
# Line 175  while (my ($database, $db_config) = each Line 232  while (my ($database, $db_config) = each
232                  }                  }
233          }          }
234    
235          if ($use_indexer) {          my $indexer;
236                  my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");          if ($use_indexer && $parser->have_rules( 'search', $database )) {
237    
238                    my $cfg_name = $use_indexer;
239                    $cfg_name =~ s/\-.*$//;
240    
241                    my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
242                  $indexer_config->{database} = $database;                  $indexer_config->{database} = $database;
243                  $indexer_config->{clean} = $clean;                  $indexer_config->{clean} = $clean;
244                  $indexer_config->{label} = $db_config->{name};                  $indexer_config->{label} = $db_config->{name};
245    
246                    # force clean if database has links
247                    $indexer_config->{clean} = 1 if ($db_config->{links});
248    
249                  if ($use_indexer eq 'hyperestraier') {                  if ($use_indexer eq 'hyperestraier') {
250    
251                          # open Hyper Estraier database                          # open Hyper Estraier database
252                          use WebPAC::Output::Estraier '0.10';                          require WebPAC::Output::Estraier;
253                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );                          $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );
254                                    
255                    } elsif ($use_indexer eq 'hyperestraier-native') {
256    
257                            # open Hyper Estraier database
258                            require WebPAC::Output::EstraierNative;
259                            $indexer = new WebPAC::Output::EstraierNative( %{ $indexer_config } );
260    
261                  } elsif ($use_indexer eq 'kinosearch') {                  } elsif ($use_indexer eq 'kinosearch') {
262    
263                          # 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 } );  
264    
265                  } else {                  } else {
266                          $log->logdie("unknown use_indexer: $use_indexer");                          $log->logdie("unknown use_indexer: $use_indexer");
267                  }                  }
268    
269                  $log->logide("can't continue without valid indexer") unless ($indexer);                  $log->logdie("can't continue without valid indexer") unless ($indexer);
270          }          }
271    
272    
273          #          #
274            # store Hyper Estraier links to other databases
275            #
276            if (ref($db_config->{links}) eq 'ARRAY' && $use_indexer) {
277                    foreach my $link (@{ $db_config->{links} }) {
278                            if ($use_indexer eq 'hyperestraier') {
279                                    if ($merge) {
280                                            print $estcmd_fh 'sudo -u www-data estcmd merge ' . $database . ' ' . $link->{to},$/;
281                                    } else {
282                                            $log->info("saving link $database -> $link->{to} [$link->{credit}]");
283                                            push @links, sub {
284                                                    $log->info("adding link $database -> $link->{to} [$link->{credit}]");
285                                                    $indexer->add_link(
286                                                            from => $database,
287                                                            to => $link->{to},
288                                                            credit => $link->{credit},
289                                                    );
290                                            };
291                                    }
292                            } else {
293                                    $log->warn("NOT IMPLEMENTED WITH $use_indexer: adding link $database -> $link->{to} [$link->{credit}]");
294                            }
295                    }
296            }
297            next if ($only_links);
298    
299    
300            #
301          # now WebPAC::Store          # now WebPAC::Store
302          #          #
303          my $abs_path = abs_path($0);          my $store = new WebPAC::Store({
304          $abs_path =~ s#/[^/]*$#/#;                  debug => $debug,
305            });
306    
         my $db_path = $config->{webpac}->{db_path} . '/' . $database;  
307    
308          if ($clean) {          #
309                  $log->info("creating new database '$database' in $db_path");          # prepare output
310                  rmtree( $db_path ) || $log->warn("can't remove $db_path: $!");          #
311          } else {          my @outputs = force_array( $db_config->{output}, sub {
312                  $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?" );
313          }          } );
314    
315          my $db = new WebPAC::Store(          my @output_modules;
316                  path => $db_path,  
317                  database => $database,          foreach my $output ( @outputs ) {
318                  debug => $debug,  
319          );  #warn '## output = ',dump( $output );
320    
321                    my $module = $output->{module} || $log->logdie("need module in output section of $database");
322                    $module = 'WebPAC::Output::' . $module unless $module =~ m/::/;
323            
324                    $log->debug("loading output module $module");
325                    eval "require $module";
326    
327                    # add database to arugemnts for output filter
328                    $output->{database} = $database;
329    
330                    $log->debug("calling $module->new(",dump( $output ),")");
331                    my $out = new $module->new( $output );
332                    $out->init;
333    
334                    push @output_modules, $out;
335            }
336    
337    
338          #          #
339          # now, iterate through input formats          # now, iterate through input formats
340          #          #
341    
         my @inputs;  
         if (ref($db_config->{input}) eq 'ARRAY') {  
                 @inputs = @{ $db_config->{input} };  
         } elsif ($db_config->{input}) {  
                 push @inputs, $db_config->{input};  
         } else {  
                 $log->info("database $database doesn't have inputs defined");  
         }  
342    
343          my @supported_inputs = keys %{ $config->{webpac}->{inputs} };          my @inputs = force_array( $db_config->{input}, sub {
344                    $log->info("database $database doesn't have inputs defined");
345            } );
346    
347          foreach my $input (@inputs) {          foreach my $input (@inputs) {
348    
349                  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));
350    
351                    next if ($only_input && ($input_name !~ m#$only_input#i && $input->{type} !~ m#$only_input#i));
352    
353                  my $type = lc($input->{type});                  my $type = lc($input->{type});
354    
355                  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
356                    my $input_module = $input->{module};
357    
358                  my $lookup;                  if ( ! $input_module ) {
359                  if ($input->{lookup}) {                          if ( grep(/$type/, $config->webpac('inputs')) ) {
360                          $lookup = new WebPAC::Lookup(                                  $input_module = $config->webpac('inputs')->{$type};
361                                  lookup_file => $input->{lookup},                          } else {
362                          );                                  $log->logdie("I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!" );
363                          delete( $input->{lookup} );                          }
364                  }                  }
365    
366                  my $input_module = $config->{webpac}->{inputs}->{$type};                  my @lookups = $parser->have_lookup_create($database, $input);
367    
368                  $log->info("working on input '$input->{name}' in $input->{path} [type: $input->{type}] using $input_module",                  $log->info("working on input '$input_name' in $input->{path} [type: $input->{type}] using $input_module",
369                          $input->{lookup} ? "lookup '$input->{lookup}'" : ""                          @lookups ? " creating lookups: ".join(", ", @lookups) : ""
370                  );                  );
371    
372                    if ($stats) {
373                            # disable modification of records if --stats is in use
374                            delete($input->{modify_records});
375                            delete($input->{modify_file});
376                    }
377    
378                  my $input_db = new WebPAC::Input(                  my $input_db = new WebPAC::Input(
379                          module => $input_module,                          module => $input_module,
380                          encoding => $config->{webpac}->{webpac_encoding},                          encoding => $config->webpac('webpac_encoding'),
381                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
382                          offset => $offset,                          offset => $offset,
                         lookup_coderef => sub {  
                                 my $rec = shift || return;  
                                 $lookup->add( $rec );  
                         },  
383                          recode => $input->{recode},                          recode => $input->{recode},
384                          stats => $stats,                          stats => $stats,
385                          modify_records => $input->{modify_records},                          modify_records => $input->{modify_records},
386                            modify_file => $input->{modify_file},
387                            input_config => $input,
388                  );                  );
389                  $log->logdie("can't create input using $input_module") unless ($input);                  $log->logdie("can't create input using $input_module") unless ($input);
390    
391                    if (defined( $input->{lookup} )) {
392                            $log->warn("$database/$input_name has depriciated lookup definition, removing it...");
393                            delete( $input->{lookup} );
394                    }
395    
396                    my $lookup_coderef;
397    
398                    if (@lookups) {
399    
400                            my $rules = $parser->lookup_create_rules($database, $input) || $log->logdie("no rules found for $database/$input");
401    
402                            $lookup_coderef = sub {
403                                    my $rec = shift || die "need rec!";
404                                    my $mfn = $rec->{'000'}->[0] || die "need mfn in 000";
405    
406                                    WebPAC::Normalize::data_structure(
407                                            row => $rec,
408                                            rules => $rules,
409                                            config => create_ds_config( $db_config, $database, $input, $mfn ),
410                                    );
411    
412                                    #warn "current lookup: ", dump(WebPAC::Normalize::_get_lookup());
413                            };
414    
415                            WebPAC::Normalize::_set_lookup( undef );
416    
417                            $log->debug("created lookup_coderef using:\n$rules");
418    
419                    };
420    
421                    my $lookup_jar;
422    
423                  my $maxmfn = $input_db->open(                  my $maxmfn = $input_db->open(
424                          path => $input->{path},                          path => $input->{path},
425                          code_page => $input->{encoding},        # database encoding                          code_page => $input->{encoding},        # database encoding
426                            lookup_coderef => $lookup_coderef,
427                            lookup => $lookup_jar,
428                          %{ $input },                          %{ $input },
429                            load_row => sub {
430                                    my $a = shift;
431                                    return $store->load_row(
432                                            database => $database,
433                                            input => $input_name,
434                                            id => $a->{id},
435                                    );
436                            },
437                            save_row => sub {
438                                    my $a = shift;
439                                    return $store->save_row(
440                                            database => $database,
441                                            input => $input_name,
442                                            id => $a->{id},
443                                            row => $a->{row},
444                                    );
445                            },
446    
447                  );                  );
448    
449                  my @norm_array = ref($input->{normalize}) eq 'ARRAY' ?                  my $lookup_data = WebPAC::Normalize::_get_lookup();
450                          @{ $input->{normalize} } : ( $input->{normalize} );  
451                    if (defined( $lookup_data->{$database}->{$input_name} )) {
452                            $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
453    
454                  if ($marc_normalize) {                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
455                          @norm_array = ( {                                  $store->save_lookup(
456                                  path => $marc_normalize,                                          database => $database,
457                                  output => $marc_output || 'out/marc/' . $database . '-' . $input->{name} . '.marc',                                          input => $input_name,
458                          } );                                          key => $key,
459                                            data => $lookup_data->{$database}->{$input_name}->{$key},
460                                    );
461                            }
462                  }                  }
463    
464                  foreach my $normalize (@norm_array) {                  my $report_fh;
465                    if ($stats || $validate) {
466                            my $path = "out/report/${database}-${input_name}.txt";
467                            open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
468    
469                            print $report_fh "Report for database '$database' input '$input_name' records ",
470                                    $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
471                            $log->info("Generating report file $path");
472    
473                            if ( $validate ) {
474                                    $validate->read_validate_file( $validate->fill_in( $validate_path, database => $database, input => $input_name ) ) if ( $validate_path );
475                                    $validate->read_validate_delimiters_file( $validate->fill_in( $validate_delimiters_path, database => $database, input => $input_name ) ) if ( $validate_delimiters_path );
476                            }
477                    }
478    
479                          my $normalize_path = $normalize->{path} || $log->logdie("can't find normalize path in config");                  my $marc;
480                    if ($marc_generate && $parser->have_rules( 'marc', $database, $input_name )) {
481                            $marc = new WebPAC::Output::MARC(
482                                    path => "out/marc/${database}-${input_name}.marc",
483                                    lint => $marc_lint,
484                                    dump => $marc_dump,
485                            );
486                    }
487    
488                          $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) || $log->logdie("no normalize rules found for $database/$input_name");
489                    $log->debug("parsed normalize rules:\n$rules");
490    
491                          my $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";                  # reset position in database
492                    $input_db->seek(1);
493    
494                          $log->info("Using $normalize_path for normalization...");                  # generate name of config key for indexer (strip everything after -)
495                    my $indexer_config = $use_indexer;
496                    $indexer_config =~ s/^(\w+)-?.*$/$1/g if ($indexer_config);
497    
498                    my $lookup_hash;
499                    my $depends = $parser->depends($database,$input_name);
500            
501                    if ($depends) {
502                            $log->debug("$database/$input_name depends on: ", dump($depends)) if ($depends);
503                            $log->logdie("parser->depends didn't return HASH") unless (ref($depends) eq 'HASH');
504    
505                            foreach my $db (keys %$depends) {
506                                    foreach my $i (keys %{$depends->{$db}}) {
507                                            foreach my $k (keys %{$depends->{$db}->{$i}}) {
508                                                    my $t = time();
509                                                    $log->debug("loading lookup $db/$i");
510                                                    $lookup_hash->{$db}->{$i}->{$k} = $store->load_lookup(
511                                                            database => $db,
512                                                            input => $i,
513                                                            key => $k,
514                                                    );
515                                                    $log->debug(sprintf("lookup $db/$i took %.2fs", time() - $t));
516                                            }
517                                    }
518                            }
519    
520                          my $marc = new WebPAC::Output::MARC(                          $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
521                                  path => $normalize->{output},                  }
                                 lint => $marc_lint,  
                                 dump => $marc_dump,  
                         ) if ($normalize->{output});  
522    
                         # reset position in database  
                         $input_db->seek(1);  
523    
524                          foreach my $pos ( 0 ... $input_db->size ) {                  # setup input name for all output filters
525                    foreach my $out ( @output_modules ) {
526                            if ( $out->can('input') ) {
527                                    $out->input( $input_name );
528                            } else {
529                                    $log->warn("output filter ",ref($out)," doesn't support input name");
530                            }
531                    }
532    
                                 my $row = $input_db->fetch || next;  
533    
534                                  my $mfn = $row->{'000'}->[0];                  foreach my $pos ( 0 ... $input_db->size ) {
535    
536                                  if (! $mfn || $mfn !~ m#^\d+$#) {                          my $row = $input_db->fetch || next;
                                         $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");  
                                         $mfn = $pos;  
                                         push @{ $row->{'000'} }, $pos;  
                                 }  
537    
538                            $total_rows++;
539    
540                                  if ($validate) {                          my $mfn = $row->{'000'}->[0];
                                         my @errors = $validate->validate_errors( $row );  
                                         $log->error( "MFN $mfn validation errors:\n", join("\n", @errors) ) if (@errors);  
                                 }  
541    
542                                  my $ds_config = dclone($db_config);                          if (! $mfn || $mfn !~ m{^\d+$}) {
543                                    $log->warn("record $pos doesn't have valid MFN but '$mfn', using $pos");
544                                    $mfn = $pos;
545                                    push @{ $row->{'000'} }, $pos;
546                            }
547    
                                 # default values -> database key  
                                 $ds_config->{_} = $database;  
548    
549                                  # current mfn                          if ($validate) {
550                                  $ds_config->{_mfn} = $mfn;                                  if ( my $errors = $validate->validate_rec( $row, $input_db->dump_ascii ) ) {
551                                            $log->error( "MFN $mfn validation error:\n",
552                                                    $validate->report_error( $errors )
553                                            );
554                                    }
555                                    next;   # validation doesn't create any output
556                            }
557    
558                                  # attach current input                          my $ds = WebPAC::Normalize::data_structure(
559                                  $ds_config->{input} = $input;                                  row => $row,
560                                    rules => $rules,
561                                    lookup => $lookup_hash,
562                                    config => create_ds_config( $db_config, $database, $input, $mfn ),
563                                    marc_encoding => 'utf-8',
564                                    load_row_coderef => sub {
565                                            my ($database,$input,$mfn) = @_;
566    #warn "### load_row($database,$input,$mfn) from data_structure\n";
567                                            return $store->load_row(
568                                                    database => $database,
569                                                    input => $input,
570                                                    id => $mfn,
571                                            );
572                                    },
573                            );
574    
575                                  my $ds = WebPAC::Normalize::data_structure(                          $log->debug("ds = ", sub { dump($ds) });
576                                          row => $row,  
577                                          rules => $rules,                          if ( $ds ) {
                                         lookup => $lookup ? $lookup->lookup_hash : undef,  
                                         config => $ds_config,  
                                         marc_encoding => 'utf-8',  
                                 );  
578    
579                                  $db->save_ds(                                  $store->save_ds(
580                                            database => $database,
581                                            input => $input_name,
582                                          id => $mfn,                                          id => $mfn,
583                                          ds => $ds,                                          ds => $ds,
584                                          prefix => $input->{name},                                  ) if !$stats;
                                 ) if ($ds && !$stats);  
585    
586                                  $indexer->add(                                  $indexer->add(
587                                          id => $input->{name} . "/" . $mfn,                                          id => "${input_name}/${mfn}",
588                                          ds => $ds,                                          ds => $ds,
589                                          type => $config->{$use_indexer}->{type},                                          type => $config->get($indexer_config)->{type},
590                                  ) if ($indexer && $ds);                                  ) if $indexer;
591    
592                                  if ($marc) {                                  foreach my $out ( @output_modules ) {
593                                          my $i = 0;                                          $out->add( $mfn, $ds ) if $out->can('add');
594                                    }
595    
596                                          while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {                          } else {
597                                                  $marc->add(                                  $log->warn("record $pos didn't produce any output after normalization rules!") unless $marc;
598                                                          id => $mfn . ( $i ? "/$i" : '' ),                          }
                                                         fields => $fields,  
                                                         leader => WebPAC::Normalize::marc_leader(),  
                                                         row => $row,  
                                                 );  
                                                 $i++;  
                                         }  
599    
600                                          $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);                          if ($marc) {
601                                    my $i = 0;
602    
603                                    while (my $fields = WebPAC::Normalize::_get_marc_fields( fetch_next => 1 ) ) {
604                                            $marc->add(
605                                                    id => $mfn . ( $i ? "/$i" : '' ),
606                                                    fields => $fields,
607                                                    leader => WebPAC::Normalize::_get_marc_leader(),
608                                                    row => $row,
609                                            );
610                                            $i++;
611                                  }                                  }
612    
613                                  $total_rows++;                                  $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
614                          }                          }
615    
616                          $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);                  }
617    
618                          # close MARC file                  if ($validate) {
619                          $marc->finish if ($marc);                          my $errors = $validate->report;
620                            if ($errors) {
621                                    $log->info("validation errors:\n$errors\n" );
622                                    print $report_fh "$errors\n" if ($report_fh);
623                            }
624    
625                            print $report_fh "\nAll possible subfields/delimiter templates:\n", $validate->delimiters_templates( report => 1, current_input => 1 ), "\n\n";
626    
627                            # must be last thing that touches $validate for this input
628                            $validate->reset;
629                    }
630    
631                    if ($stats) {
632                            my $s = $input_db->stats;
633                            $log->info("statistics of fields usage:\n$s");
634                            print $report_fh "Statistics of fields usage:\n$s" if ($report_fh);
635                  }                  }
636    
637                    # close MARC file
638                    $marc->finish if ($marc);
639    
640                    # close report
641                    close($report_fh) if ($report_fh);
642          }          }
643    
644          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));          eval { $indexer->finish } if ($indexer && $indexer->can('finish'));
645    
646            foreach my $out ( @output_modules ) {
647                    $out->finish if $out->can('finish');
648            }
649    
650          my $dt = time() - $start_t;          my $dt = time() - $start_t;
651          $log->info("$total_rows records ", $indexer ? "indexed " : "",          $log->info("$total_rows records ", $indexer ? "indexed " : "",
652                  sprintf("in %.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
# Line 397  while (my ($database, $db_config) = each Line 654  while (my ($database, $db_config) = each
654                  )                  )
655          );          );
656    
         #  
         # 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}]");  
                         }  
                 }  
         }  
657    
658          # end forked process          # end forked process
659          if ($parallel) {          if ($parallel) {
# Line 429  if ($parallel) { Line 669  if ($parallel) {
669          $log->info("all parallel processes finished");          $log->info("all parallel processes finished");
670  }  }
671    
672  foreach my $link (@links) {  # save new delimiters if needed
673          $log->info("adding link $link->{from} -> $link->{to} [$link->{credit}]");  $validate->save_delimiters_templates if ( $validate_delimiters_path );
         $indexer->add_link( %{ $link } );  
 }  
674    
675    #
676    # handle links or merge after indexing
677    #
678    
679    if ($merge) {
680            print $estcmd_fh 'sudo /etc/init.d/hyperestraier start',$/;
681            close($estcmd_fh);
682            chmod 0700, $estcmd_path || $log->warn("can't chmod 0700 $estcmd_path: $!");
683            system $estcmd_path;
684    } else {
685            foreach my $link (@links) {
686                    $log->logdie("coderef in link ", Dumper($link), " is ", ref($link), " and not CODE") unless (ref($link) eq 'CODE');
687                    $link->();
688            }
689    }

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

  ViewVC Help
Powered by ViewVC 1.1.26