/[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 508 by dpavlin, Mon May 15 13:32:18 2006 UTC revision 1041 by dpavlin, Mon Nov 12 12:22:08 2007 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;
 use WebPAC::Normalize::Set;  
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;  use File::Slurp;
22    use Data::Dump qw/dump/;
23    use Storable qw/dclone/;
24    use Pod::Usage qw/pod2usage/;
25    
26    use Proc::Queue size => 1;
27    use POSIX ":sys_wait_h"; # imports WNOHANG
28    
29  =head1 NAME  =head1 NAME
30    
# Line 26  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 42  limit loading to 100 records Line 48  limit loading to 100 records
48    
49  remove database and Hyper Estraier index before indexing  remove database and Hyper Estraier index before indexing
50    
51  =item --only=database_name  =item --only=database_name/input_filter
52    
53  reindex just single database (legacy name is --one)  reindex just single database (legacy name is --one)
54    
55    C</input_filter> is optional part which can be C<name>
56    or C<type> from input
57    
58  =item --config conf/config.yml  =item --config conf/config.yml
59    
60  path to YAML configuration file  path to YAML configuration file
61    
62  =item --force-set  =item --stats
63    
64    disable indexing, modify_* in configuration and dump statistics about field
65    and subfield usage for each input
66    
67  force conversion C<< normalize->path >> in C<config.yml> from  =item --validate path/to/validation_file
 C<.xml> to C<.pl>  
68    
69  =item --stats  turn on extra validation of imput records, see L<WebPAC::Validation>
70    
71    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    =item --validate-delimiters path/to/validate_delimiters_file
75    
76    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    =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
85    
86  dump statistics about used fields and subfields in each input  By default turned on if normalisation file has C<marc*> directives. You can disable lint
87    messages with C<--no-marc-lint>.
88    
89    =item --marc-dump
90    
91    Force dump or input and marc record for debugging.
92    
93    =item --parallel 4
94    
95    Run databases in parallel (aproximatly same as number of processors in
96    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    
# Line 67  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_db_name;  my $only_filter;
 my $force_set = 0;  
117  my $stats = 0;  my $stats = 0;
118    my $validate_path;
119    my $validate_delimiters_path;
120    my $marc_generate = 1;
121    my $marc_lint = 1;
122    my $marc_dump = 0;
123    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,
132          "offset=i" => \$offset,          "offset=i" => \$offset,
133          "clean" => \$clean,          "clean" => \$clean,
134          "one=s" => \$only_db_name,          "one=s" => \$only_filter,
135          "only=s" => \$only_db_name,          "only=s" => \$only_filter,
136          "config" => \$config,          "config=s" => \$config_path,
137          "debug" => \$debug,          "debug+" => \$debug,
         "force-set" => \$force_set,  
138          "stats" => \$stats,          "stats" => \$stats,
139            "validate=s" => \$validate_path,
140            "validate-delimiters=s" => \$validate_delimiters_path,
141            "marc-generate!" => \$marc_generate,
142            "marc-lint!" => \$marc_lint,
143            "marc-dump!" => \$marc_dump,
144            "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 = ",Dumper($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  my $log = _new WebPAC::Common()->_get_logger();  #print "config = ",dump($config) if ($debug);
157    
158  my $use_indexer = $config->{use_indexer} || 'hyperestraier';  die "no databases in config file!\n" unless ($config->databases);
159  $log->info("using $use_indexer indexing engine...");  
160    $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;
179    $validate = new WebPAC::Validate(
180            delimiters => $config->webpac('delimiters'),
181    ) if ($validate_path || $validate_delimiters_path);
182    
183    my $use_indexer = $config->use_indexer;
184    $stats ||= $validate;
185    if ($stats) {
186            $log->debug("disabled indexing for stats collection");
187            $use_indexer = undef;
188    } elsif ( $use_indexer ) {
189            $log->info("using $use_indexer indexing engine...");
190    }
191    
192    # parse normalize files and create source files for lookup and normalization
193    
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  while (my ($database, $db_config) = each %{ $config->{databases} }) {  my @links;
206    
207    if ($parallel) {
208            $log->info("Using $parallel processes for speedup");
209            Proc::Queue::size($parallel);
210    }
211    
212    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    
224          next if ($only_db_name && $database !~ m/$only_db_name/i);          next if ($only_database && $database !~ m/$only_database/i);
225    
226            if ($parallel) {
227                    my $f=fork;
228                    if(defined ($f) and $f==0) {
229                            $log->info("Created processes $$ for speedup");
230                    } else {
231                            next;
232                    }
233            }
234    
235          my $indexer;          my $indexer;
236            if ($use_indexer && $parser->have_rules( 'search', $database )) {
237    
238          my $indexer_config = $config->{$use_indexer} || $log->logdie("can't find '$use_indexer' part in confguration");                  my $cfg_name = $use_indexer;
239          $indexer_config->{database} = $database;                  $cfg_name =~ s/\-.*$//;
         $indexer_config->{clean} = $clean;  
         $indexer_config->{label} = $db_config->{name};  
   
         if ($use_indexer eq 'hyperestraier') {  
   
                 # open Hyper Estraier database  
                 use WebPAC::Output::Estraier '0.10';  
                 $indexer = new WebPAC::Output::Estraier( %{ $indexer_config } );  
           
         } elsif ($use_indexer eq 'kinosearch') {  
240    
241                  # open KinoSearch                  my $indexer_config = $config->get( $cfg_name ) || $log->logdie("can't find '$cfg_name' part in confguration");
242                  use WebPAC::Output::KinoSearch;                  $indexer_config->{database} = $database;
243                  $indexer_config->{clean} = 1 unless (-e $indexer_config->{index_path});                  $indexer_config->{clean} = $clean;
244                  $indexer = new WebPAC::Output::KinoSearch( %{ $indexer_config } );                  $indexer_config->{label} = $db_config->{name};
245    
246          } else {                  # force clean if database has links
247                  $log->logdie("unknown use_indexer: $use_indexer");                  $indexer_config->{clean} = 1 if ($db_config->{links});
248    
249                    if ($use_indexer eq 'hyperestraier') {
250    
251                            # open Hyper Estraier database
252                            require WebPAC::Output::Estraier;
253                            $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') {
262    
263                            die "no longer supported";
264    
265                    } else {
266                            $log->logdie("unknown use_indexer: $use_indexer");
267                    }
268    
269                    $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    
         $log->logide("can't continue without valid indexer") unless ($indexer);  
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->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?" );
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                    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 = new WebPAC::Lookup(                  if ( ! $input_module ) {
359                          lookup_file => $input->{lookup},                          if ( grep(/$type/, $config->webpac('inputs')) ) {
360                  );                                  $input_module = $config->webpac('inputs')->{$type};
361                            } else {
362                                    $log->logdie("I know only how to handle input types ", join(",", $config->webpac('inputs') ), " not '$type'!" );
363                            }
364                    }
365    
366                    my @lookups = $parser->have_lookup_create($database, $input);
367    
368                  my $input_module = $config->{webpac}->{inputs}->{$type};                  $log->info("working on input '$input_name' in $input->{path} [type: $input->{type}] using $input_module",
369                            @lookups ? " creating lookups: ".join(", ", @lookups) : ""
370                    );
371    
372                  $log->info("working on input '$input->{path}' [$input->{type}] using $input_module lookup '$input->{lookup}'");                  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                          code_page => $config->{webpac}->{webpac_encoding},                          encoding => $config->webpac('webpac_encoding'),
381                          limit => $limit || $input->{limit},                          limit => $limit || $input->{limit},
382                          offset => $offset,                          offset => $offset,
                         lookup => $lookup,  
383                          recode => $input->{recode},                          recode => $input->{recode},
384                          stats => $stats,                          stats => $stats,
385                            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 },
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    
                 my $n = new WebPAC::Normalize::XML(  
                 #       filter => { 'foo' => sub { shift } },  
                         db => $db,  
                         lookup_regex => $lookup->regex,  
                         lookup => $lookup,  
                         prefix => $input->{name},  
447                  );                  );
448    
449                  my $rules;                  my $lookup_data = WebPAC::Normalize::_get_lookup();
                 my $normalize_path = $input->{normalize}->{path};  
450    
451                  if ($force_set) {                  if (defined( $lookup_data->{$database}->{$input_name} )) {
452                          my $new_norm_path = $normalize_path;                          $log->debug("created following lookups: ", sub { dump( $lookup_data ) } );
453                          $new_norm_path =~ s/\.xml$/.pl/;  
454                          if (-e $new_norm_path) {                          foreach my $key (keys %{ $lookup_data->{$database}->{$input_name} }) {
455                                  $log->debug("--force-set replaced $normalize_path with $new_norm_path");                                  $store->save_lookup(
456                                  $normalize_path = $new_norm_path;                                          database => $database,
457                          } else {                                          input => $input_name,
458                                  $log->debug("--force-set failed on $new_norm_path, fallback to $normalize_path");                                          key => $key,
459                                            data => $lookup_data->{$database}->{$input_name}->{$key},
460                                    );
461                          }                          }
462                  }                  }
463    
464                  if ($normalize_path =~ m/\.xml$/i) {                  my $report_fh;
465                          $n->open(                  if ($stats || $validate) {
466                                  tag => $input->{normalize}->{tag},                          my $path = "out/report/${database}-${input_name}.txt";
467                                  xml_file => $normalize_path,                          open($report_fh, '>', $path) || $log->logdie("can't open $path: $!");
468                          );  
469                  } elsif ($normalize_path =~ m/\.(?:yml|yaml)$/i) {                          print $report_fh "Report for database '$database' input '$input_name' records ",
470                          $n->open_yaml(                                  $offset || 1, "-", $limit || $input->{limit} || $maxmfn, "\n\n";
471                                  path => $normalize_path,                          $log->info("Generating report file $path");
472                                  tag => $input->{normalize}->{tag},  
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 $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                          );                          );
                 } elsif ($normalize_path =~ m/\.(?:pl)$/i) {  
                         $n = undef;  
                         $log->info("using WebPAC::Normalize::Set to process $normalize_path");  
                         $rules = read_file( $normalize_path ) or die "can't open $normalize_path: $!";  
486                  }                  }
487    
488                    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                    # reset position in database
492                    $input_db->seek(1);
493    
494                    # 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                            $log->debug("lookup_hash = ", sub { dump( $lookup_hash ) });
521                    }
522    
523    
524                    # 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    
533    
534                  foreach my $pos ( 0 ... $input_db->size ) {                  foreach my $pos ( 0 ... $input_db->size ) {
535    
536                          my $row = $input_db->fetch || next;                          my $row = $input_db->fetch || next;
537    
538                            $total_rows++;
539    
540                          my $mfn = $row->{'000'}->[0];                          my $mfn = $row->{'000'}->[0];
541    
542                          if (! $mfn || $mfn !~ m#^\d+$#) {                          if (! $mfn || $mfn !~ m{^\d+$}) {
543                                  $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");
544                                  $mfn = $pos;                                  $mfn = $pos;
545                                  push @{ $row->{'000'} }, $pos;                                  push @{ $row->{'000'} }, $pos;
546                          }                          }
547    
                                   
                         my $ds;  
                         if ($n) {  
                                 $ds = $n->data_structure($row);  
                         } else {  
                                 $ds = WebPAC::Normalize::Set::data_structure(  
                                         row => $row,  
                                         rules => $rules,  
                                         lookup => $lookup->lookup_hash,  
                                 );  
548    
549                                  $db->save_ds(                          if ($validate) {
550                                    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                            my $ds = WebPAC::Normalize::data_structure(
559                                    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                            $log->debug("ds = ", sub { dump($ds) });
576    
577                            if ( $ds ) {
578    
579                                    $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;
585                                  ) if ($ds);  
586                                    $indexer->add(
587                                            id => "${input_name}/${mfn}",
588                                            ds => $ds,
589                                            type => $config->get($indexer_config)->{type},
590                                    ) if $indexer;
591    
592                                    foreach my $out ( @output_modules ) {
593                                            $out->add( $mfn, $ds ) if $out->can('add');
594                                    }
595    
596                            } else {
597                                    $log->warn("record $pos didn't produce any output after normalization rules!") unless $marc;
598                          }                          }
599    
600                          $indexer->add(                          if ($marc) {
601                                  id => $input->{name} . "/" . $mfn,                                  my $i = 0;
602                                  ds => $ds,  
603                                  type => $config->{$use_indexer}->{type},                                  while (my $fields = WebPAC::Normalize::MARC::_get_marc_fields( fetch_next => 1 ) ) {
604                          );                                          $marc->add(
605                                                    id => $mfn . ( $i ? "/$i" : '' ),
606                                                    fields => $fields,
607                                                    leader => WebPAC::Normalize::MARC::_get_marc_leader(),
608                                                    row => $row,
609                                            );
610                                            $i++;
611                                    }
612    
613                                    $log->info("Created $i instances of MFN $mfn\n") if ($i > 1);
614                            }
615    
                         $total_rows++;  
616                  }                  }
617    
618                  $log->info("statistics of fields usage:\n", $input_db->stats) if ($stats);                  if ($validate) {
619                            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          eval { $indexer->finish } if ($indexer->can('finish'));                          # 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'));
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 indexed in " .          $log->info("$total_rows records ", $indexer ? "indexed " : "",
652                  sprintf("%.2f sec [%.2f rec/sec]",                  sprintf("in %.2f sec [%.2f rec/sec]",
653                          $dt, ($total_rows / $dt)                          $dt, ($total_rows / $dt)
654                  )                  )
655          );          );
656    
657          #  
658          # add Hyper Estraier links to other databases          # end forked process
659          #          if ($parallel) {
660          if (ref($db_config->{links}) eq 'ARRAY') {                  $log->info("parallel process $$ finished");
661                  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}]");  
                         }  
                 }  
662          }          }
663    
664  }  }
665    
666    if ($parallel) {
667            # wait all children to finish
668            sleep(1) while wait != -1;
669            $log->info("all parallel processes finished");
670    }
671    
672    # save new delimiters if needed
673    $validate->save_delimiters_templates if ( $validate_delimiters_path );
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.508  
changed lines
  Added in v.1041

  ViewVC Help
Powered by ViewVC 1.1.26