Ignore:
Timestamp:
2015-12-10T12:19:20+13:00 (8 years ago)
Author:
jmt12
Message:

Continuing to refactor driver code to move shared code up to parent classes. Have all the basic drivers done...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • gs2-extensions/tdb/trunk/perllib/DBDrivers/JDBM.pm

    r30338 r30347  
    3333use FileUtils;
    3434# - OO inheritence
    35 use parent 'DBDrivers::BaseDBDriver';
     35use parent 'DBDrivers::70HyphenFormat';
    3636
    3737sub BEGIN
     
    4848{
    4949    my $class = shift(@_);
    50     my $self = DBDrivers::BaseDBDriver->new();
     50    my $self = DBDrivers::70HyphenFormat->new(@_);
    5151    $self->{'default_file_extension'} = 'jdb';
     52
     53    # Executables need a little extra work since we are using Java
     54    # - we need to build up the classpath continue the Jar libraries to use
     55    my $jdbmwrap_jar = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'}, 'bin', 'java', 'JDBMWrapper.jar');
     56    my $jdbm_jar = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'}, 'lib', 'java', 'jdbm.jar');
     57    my $classpath = &util::pathname_cat($jdbmwrap_jar,$jdbm_jar);
     58    # Massage paths for Cygwin. Away to run a java program, using a binary that
     59    # is native to Windows, so need Windows directory and path separators
     60    if ($^O eq "cygwin") {
     61    $classpath = `cygpath -wp "$classpath"`;
     62    chomp($classpath);
     63    $classpath =~ s%\\%\\\\%g;
     64    }
     65    $self->{'executable_path'} = '';
     66    $self->{'read_executable'} = 'java -cp "' . $classpath . '" Jdb2Txt';
     67    $self->{'keyread_executable'} = 'java -cp "' . $classpath . '" JdbKeys';
     68    $self->{'write_executable'} = 'java -cp "' . $classpath . '" Txt2Jdb';
     69    # Support
     70    $self->{'supports_set'} = 1;
     71
    5272    bless($self, $class);
    5373    return $self;
     
    6888# sub get_infodb_file_path {}
    6989
    70 
    71 
    72 sub open_infodb_write_handle
    73 {
    74     my $self = shift(@_);
    75     my $infodb_file_path = shift(@_);
    76     my $opt_append = shift(@_);
    77     if (!defined $opt_append) {
    78     $opt_append = '';
    79     }
    80     $self->_debugPrint('("' . $infodb_file_path . '","' . $opt_append . '")');
    81 
    82     my $jdbmwrap_jar = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'},"bin","java", "JDBMWrapper.jar");
    83     my $jdbm_jar = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'},"lib","java", "jdbm.jar");
    84 
    85   my $classpath = &util::pathname_cat($jdbmwrap_jar,$jdbm_jar);
    86 
    87   if ($^O eq "cygwin") {
    88       # Away to run a java program, using a binary that is native to Windows, so need
    89       # Windows directory and path separators
    90 
    91       $classpath = `cygpath -wp "$classpath"`;
    92       chomp($classpath);
    93       $classpath =~ s%\\%\\\\%g;
    94   }
    95 
    96   my $infodb_file_handle = undef;
    97   my $txt2jdb_cmd = "java -cp \"$classpath\" Txt2Jdb";
    98 
    99   if ($opt_append eq "append") {
    100       $txt2jdb_cmd .= " -append";
    101       print STDERR "Append operation to $infodb_file_path\n";
    102   }
    103   else {
    104       print STDERR "Create database $infodb_file_path\n";
    105   }
    106  
    107   # Lop off file extension, as JDBM does not expect this to be present
    108   $infodb_file_path =~ s/\.jdb$//;
    109 
    110   if ($^O eq "cygwin") {
    111       $infodb_file_path = `cygpath -w "$infodb_file_path"`;
    112       chomp($infodb_file_path);
    113       $infodb_file_path =~ s%\\%\\\\%g;
    114   }
    115 
    116   $txt2jdb_cmd .= " \"$infodb_file_path\"";
    117 
    118   if (!open($infodb_file_handle, "| $txt2jdb_cmd"))
    119   {
    120       print STDERR "Error: Failed to open pipe to $txt2jdb_cmd";
    121       print STDERR "       $!\n";
    122       return undef;
    123   }
    124  
    125   binmode($infodb_file_handle,":utf8");
    126   return $infodb_file_handle;
    127 }
    128 
    129 
    130 
    131 sub close_infodb_write_handle
    132 {
    133   my $infodb_handle = shift(@_);
    134 
    135   close($infodb_handle);
    136 }
    137 
    138 
    139 sub read_infodb_file
    140 {
    141   my $infodb_file_path = shift(@_);
    142   my $infodb_map = shift(@_);
    143 
    144   my $jdbmwrap_jar = &util::filename_cat($ENV{'GSDLHOME'},"bin","java", "JDBMWrapper.jar");
    145   my $jdbm_jar = &util::filename_cat($ENV{'GSDLHOME'},"lib","java", "jdbm.jar");
    146 
    147   my $classpath = &util::pathname_cat($jdbmwrap_jar,$jdbm_jar);
    148 
    149   if ($^O eq "cygwin") {
    150       # Away to run a java program, using a binary that is native to Windows, so need
    151       # Windows directory and path separators
    152      
    153       $classpath = `cygpath -wp "$classpath"`;
    154       chomp($classpath);
    155       $classpath =~ s%\\%\\\\%g;
    156 
    157       $infodb_file_path = `cygpath -w "$infodb_file_path"`;
    158       chomp($infodb_file_path);
    159       $infodb_file_path =~ s%\\%\\\\%g;
    160   }
    161 
    162   my $jdb2txt_cmd = "java -cp \"$classpath\" Jdb2Txt";
    163 
    164   open (PIPEIN, "$jdb2txt_cmd \"$infodb_file_path\" |") || die "couldn't open pipe from db2txt \$infodb_file_path\"\n";
    165   binmode(PIPEIN,":utf8");
    166   my $infodb_line = "";
    167   my $infodb_key = "";
    168   my $infodb_value = "";
    169   while (defined ($infodb_line = <PIPEIN>))
    170   {
    171     $infodb_line =~ s/(\r\n)+$//; # more general than chomp
    172 
    173     if ($infodb_line =~ /^\[([^\]]+)\]$/)
    174     {
    175       $infodb_key = $1;
    176     }
    177     elsif ($infodb_line =~ /^-{70}$/)
    178     {
    179       $infodb_map->{$infodb_key} = $infodb_value;
    180       $infodb_key = "";
    181       $infodb_value = "";
    182     }
    183     else
    184     {
    185       $infodb_value .= $infodb_line;
    186     }
    187   }
    188 
    189   close (PIPEIN);
    190 }
    191 
    192 sub read_infodb_keys
    193 {
    194   my $infodb_file_path = shift(@_);
    195   my $infodb_map = shift(@_);
    196 
    197   my $jdbmwrap_jar = &util::filename_cat($ENV{'GSDLHOME'},"bin","java", "JDBMWrapper.jar");
    198   my $jdbm_jar = &util::filename_cat($ENV{'GSDLHOME'},"lib","java", "jdbm.jar");
    199 
    200   my $classpath = &util::pathname_cat($jdbmwrap_jar,$jdbm_jar);
    201 
    202   my $jdbkeys_cmd = "java -cp \"$classpath\" JdbKeys";
    203 
    204   open (PIPEIN, "$jdbkeys_cmd \"$infodb_file_path\" |") || die "couldn't open pipe from jdbmkeys \$infodb_file_path\"\n";
    205   binmode(PIPEIN,":utf8");
    206   my $infodb_line = "";
    207   my $infodb_key = "";
    208   my $infodb_value = "";
    209   while (defined ($infodb_line = <PIPEIN>))
    210   {
    211       # chomp $infodb_line; # remove end of line
    212       $infodb_line =~ s/(\r\n)+$//; # more general than chomp
    213 
    214       $infodb_map->{$infodb_line} = 1;
    215   }
    216 
    217   close (PIPEIN);
    218 }
    219 
    220 
    221    
    222 sub write_infodb_entry
    223 {
    224 
    225   my $infodb_handle = shift(@_);
    226   my $infodb_key = shift(@_);
    227   my $infodb_map = shift(@_);
    228 
    229   print $infodb_handle "[$infodb_key]\n";
    230   foreach my $infodb_value_key (keys(%$infodb_map))
    231   {
    232     foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
    233     {
    234       if ($infodb_value =~ /-{70,}/)
    235       {
    236         # if value contains 70 or more hyphens in a row we need to escape them
    237         # to prevent txt2db from treating them as a separator
    238         $infodb_value =~ s/-/&\#045;/gi;
    239       }
    240       print $infodb_handle "<$infodb_value_key>" . $infodb_value . "\n";
    241     }
    242   }
    243   print $infodb_handle '-' x 70, "\n";
    244 }
    245 
    246 
    247 sub write_infodb_rawentry
    248 {
    249 
    250   my $infodb_handle = shift(@_);
    251   my $infodb_key = shift(@_);
    252   my $infodb_val = shift(@_);
    253  
    254   print $infodb_handle "[$infodb_key]\n";
    255   print $infodb_handle "$infodb_val\n";
    256   print $infodb_handle '-' x 70, "\n";
    257 }
    258 
    259 sub set_infodb_entry
    260 {
    261     my $infodb_file_path = shift(@_);
    262     my $infodb_key = shift(@_);
    263     my $infodb_map = shift(@_);
    264  
    265     # HTML escape anything that is not part of the "contains" metadata value
    266     foreach my $k (keys %$infodb_map) {
    267       my @escaped_v = ();
    268       foreach my $v (@{$infodb_map->{$k}}) {
    269         if ($k eq "contains") {
    270           push(@escaped_v, $v);
    271         }
    272         else {
    273           my $ev = &ghtml::unescape_html($v);
    274           push(@escaped_v, $ev);
    275         }
    276       }
    277       $infodb_map->{$k} = \@escaped_v;
    278     }
    279    
    280     # Generate the record string
    281     my $serialized_infodb_map = &dbutil::convert_infodb_hash_to_string($infodb_map);
    282 ###    print STDERR "**** ser dr\n$serialized_infodb_map\n\n\n";
    283 
    284     # Store it into JDBM using 'Txt2Jdb .... -append' which despite its name
    285     # actually replaces the record if it already exists
    286 
    287     my $jdbmwrap_jar = &util::filename_cat($ENV{'GSDLHOME'},"bin","java", "JDBMWrapper.jar");
    288     my $jdbm_jar = &util::filename_cat($ENV{'GSDLHOME'},"lib","java", "jdbm.jar");
    289    
    290     my $classpath = &util::pathname_cat($jdbmwrap_jar,$jdbm_jar);
    291 
    292     # Lop off file extension, as JDBM does not expect this to be present
    293     $infodb_file_path =~ s/\.jdb$//;
    294 
    295     if ($^O eq "cygwin") {
    296     # Away to run a java program, using a binary that is native to Windows, so need
    297     # Windows directory and path separators
    298    
    299       $classpath = `cygpath -wp "$classpath"`;
    300       chomp($classpath);
    301       $classpath =~ s%\\%\\\\%g;
    302 
    303       $infodb_file_path = `cygpath -w "$infodb_file_path"`;
    304       chomp($infodb_file_path);
    305       $infodb_file_path =~ s%\\%\\\\%g;
    306     }
    307 
    308     my $cmd = "java -cp \"$classpath\" Txt2Jdb -append \"$infodb_file_path\"";
    309 
    310     my $status = undef;
    311     if(!open(GOUT, "| $cmd"))
    312     {
    313     print STDERR "Error: jdbm::set_infodb_entry() failed to open pipe to: $cmd\n";
    314     print STDERR "       $!\n";
    315     $status = -1;
    316     }
    317     else {
    318     binmode(GOUT,":utf8");
    319    
    320     print GOUT "[$infodb_key]\n";
    321     print GOUT "$serialized_infodb_map\n";
    322 
    323     close(GOUT);
    324     $status = 0; # as in exit status of cmd OK
    325     }
    326 
    327     return $status; 
    328 }
    329 
    330 
    331 
    332 
    333 sub delete_infodb_entry
    334 {
    335   my $infodb_handle = shift(@_);
    336   my $infodb_key = shift(@_);
    337  
    338   # A minus at the end of a key (after the ]) signifies 'delete'
    339   print $infodb_handle "[$infodb_key]-\n";
    340 
    341   # The 70 minus signs are also needed, to help make the parsing by db2txt simple
    342   print $infodb_handle '-' x 70, "\n";
    343 }
     90# Handles by 70HyphenFormat
     91# sub open_infodb_write_handle(string, string?) => filehandle
     92# sub close_infodb_write_handle(filehandle) => void
     93# sub read_infodb_file(string, hashmap) => void
     94# sub read_infodb_keys(string, hashmap) => void
     95# sub write_infodb_entry(filehandle, string, hashmap) => void
     96# sub write_infodb_rawentry(filehandle, string, string) => void
     97# sub set_infodb_entry(filehandle, string, string) => void
     98# sub delete_infodb_entry(filehandle, string) => void
    34499
    3451001;
Note: See TracChangeset for help on using the changeset viewer.