Changeset 30337 for gs2-extensions

Show
Ignore:
Timestamp:
03.12.2015 15:43:34 (4 years ago)
Author:
jmt12
Message:

A refined and completed GDBM driver - where most of the heavy lifting is done by the 70HyphenFormat parent

Files:
1 modified

Legend:

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

    r30318 r30337  
    3232use util; 
    3333use FileUtils; 
    34 use DBDrivers::BaseDBDriver; 
     34use parent 'DBDrivers::70HyphenFormat'; 
    3535 
    36 sub BEGIN 
    37 { 
    38     @DBDrivers::GDBM::ISA = ( 'DBDrivers::BaseDBDriver' ); 
    39 } 
    4036 
     37## @function constructor 
     38# 
    4139sub new 
    4240{ 
    4341    my $class = shift(@_); 
    44     return bless ($self, $class); 
     42    my $self = DBDrivers::70HyphenFormat->new(@_); 
     43    $self->{'default_file_extension'} = 'gdb'; 
     44    # note: file separator agnostic 
     45    $self->{'executable_path'} = $ENV{'GSDLHOME'} . '/bin/' . $ENV{'GSDLOS'}; 
     46    $self->{'read_executable'} = 'db2txt'; 
     47    $self->{'keyread_executable'} = 'gdbmkeys'; 
     48    $self->{'write_executable'} = 'txt2db'; 
     49    bless($self, $class); 
     50    return $self; 
    4551} 
     52## new(void) => GDBM ## 
     53 
    4654 
    4755# ----------------------------------------------------------------------------- 
     
    4957# ----------------------------------------------------------------------------- 
    5058 
     59# Handled by BaseDBDriver 
     60# sub get_infodb_file_path(string, string) 
    5161 
    52 ## @function open_infodb_write_handle(string, string) 
     62# Handled by 70HyphenFormat 
     63# sub close_infodb_write_handle(filehandle) => void 
     64# sub delete_infodb_entry(filehandle, string) => void 
     65# sub read_infodb_entry(string, string) => hashmap 
     66# sub read_infodb_file(string, hashmap) => void 
     67# sub read_infodb_keys(string, hashmap) => void 
     68# sub read_infodb_rawentry(string, string) => string 
     69# sub set_infodb_entry(string, string, hashmap) => integer 
     70# sub write_infodb_entry(filehandle, string, hashmap) => void 
     71# sub write_infodb_rawentry(filehandle, string, string) => void 
     72 
     73 
     74## @function open_infodb_write_handle(string, string*) => filehandle 
     75# 
     76#  Handles legacy use of optional 'append' argument where '-append' is required 
    5377# 
    5478sub open_infodb_write_handle 
    5579{ 
     80    my $self = shift(@_); 
    5681    my $infodb_file_path = shift(@_); 
    5782    my $opt_append = shift(@_); 
    58  
    59     my $txt2db_exe = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'},"bin",$ENV{'GSDLOS'}, "txt2db" . &util::get_os_exe()); 
    60     my $infodb_file_handle = undef; 
    61     my $cmd = "\"$txt2db_exe\""; 
    62     if ((defined $opt_append) && ($opt_append eq "append")) { 
    63         $cmd .= " -append"; 
     83    my $infodb_file_handle; 
     84    if (defined $opt_append) { 
     85    if ($opt_append eq 'append') { 
     86        $opt_append = '-append'; 
     87    } 
     88    $infodb_file_handle = $self->SUPER::open_infodb_write_handle($infodb_file_path, $opt_append); 
    6489    } 
    65     $cmd .= " \"$infodb_file_path\""; 
    66  
    67     if (!-e "$txt2db_exe") { 
    68         print STDERR "Error: Unable to find $txt2db_exe\n"; 
    69         return undef; 
     90    else 
     91    { 
     92    $infodb_file_handle = $self->SUPER::open_infodb_write_handle($infodb_file_path); 
    7093    } 
    71  
    72     if(!open($infodb_file_handle, "| $cmd")) { 
    73         print STDERR "Error: Failed to open pipe to $cmd\n"; 
    74         print STDERR "       $!\n"; 
    75         return undef; 
    76     } 
    77  
    78     binmode($infodb_file_handle,":utf8"); 
    79  
    8094    return $infodb_file_handle; 
    8195} 
    82 ## open_infodb_write_handle(string, string) => filehandle ## 
     96## open_infodb_write_handle(string, string*) => filehandle ## 
    8397 
    8498 
    85 ## @function close_infodb_write_handle(filehandle) 
    86 # 
    87 sub close_infodb_write_handle 
    88 { 
    89     my $infodb_handle = shift(@_); 
    90     close($infodb_handle); 
    91 } 
    92 ## close_infodb_write_handle(filehandle) => void ## 
    93  
    94  
    95 ## @function get_infodb_file_path() 
    96 # 
    97 sub get_infodb_file_path 
    98 { 
    99     my $collection_name = shift(@_); 
    100     my $infodb_directory_path = shift(@_); 
    101     my $infodb_file_extension = ".gdb"; 
    102     my $infodb_file_name = &util::get_dirsep_tail($collection_name) . $infodb_file_extension; 
    103     return &FileUtils::filenameConcatenate($infodb_directory_path, $infodb_file_name); 
    104 } 
    105 ## get_infodb_file_path() => string ## 
    106  
    107  
    108 ## @function read_infodb_file(string, hashmap) 
    109 # 
    110 sub read_infodb_file 
    111 { 
    112     my $infodb_file_path = shift(@_); 
    113     my $infodb_map = shift(@_); 
    114  
    115     open (PIPEIN, "db2txt \"$infodb_file_path\" |") || die "couldn't open pipe from db2txt \$infodb_file_path\"\n"; 
    116  
    117     binmode(PIPEIN,":utf8"); 
    118  
    119     my $infodb_line = ""; 
    120     my $infodb_key = ""; 
    121     my $infodb_value = ""; 
    122     while (defined ($infodb_line = <PIPEIN>)) { 
    123         $infodb_line =~ s/(\r\n)+$//; # more general than chomp 
    124  
    125         if ($infodb_line =~ /^\[([^\]]+)\]$/) { 
    126             $infodb_key = $1; 
    127         } 
    128         elsif ($infodb_line =~ /^-{70}$/) { 
    129             $infodb_map->{$infodb_key} = $infodb_value; 
    130             $infodb_key = ""; 
    131             $infodb_value = ""; 
    132         } 
    133         else { 
    134             $infodb_value .= $infodb_line; 
    135         } 
    136     } 
    137   close (PIPEIN); 
    138 } 
    139 ## read_infodb_file(string, hashmap) => void ## 
    140  
    141  
    142 ## @function read_infodb_keys(string, hashmap) 
    143 # 
    144 sub read_infodb_keys 
    145 { 
    146     my $infodb_file_path = shift(@_); 
    147     my $infodb_map = shift(@_); 
    148  
    149     open (PIPEIN, "gdbmkeys \"$infodb_file_path\" |") || die "couldn't open pipe from gdbmkeys \$infodb_file_path\"\n"; 
    150  
    151     binmode(PIPEIN,":utf8"); 
    152  
    153     my $infodb_line = ""; 
    154     my $infodb_key = ""; 
    155     my $infodb_value = ""; 
    156     while (defined ($infodb_line = <PIPEIN>)) { 
    157         # chomp $infodb_line; # remove end of line 
    158         $infodb_line =~ s/(\r\n)+$//; # more general than chomp 
    159  
    160         $infodb_map->{$infodb_line} = 1; 
    161     } 
    162  
    163   close (PIPEIN); 
    164 } 
    165 ## read_infodb_keys(string, hashmap) => void ## 
    166  
    167  
    168 ## @function write_infodb_entry(filehandle, string, hashmap) 
    169 # 
    170 sub write_infodb_entry 
    171 { 
    172     my $infodb_handle = shift(@_); 
    173     my $infodb_key = shift(@_); 
    174     my $infodb_map = shift(@_); 
    175  
    176     print $infodb_handle "[$infodb_key]\n"; 
    177     foreach my $infodb_value_key (sort keys(%$infodb_map)) { 
    178         foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}}) { 
    179             if ($infodb_value =~ /-{70,}/) { 
    180                 # if value contains 70 or more hyphens in a row we need to escape them 
    181                 # to prevent txt2db from treating them as a separator 
    182                 $infodb_value =~ s/-/&\#045;/gi; 
    183             } 
    184             print $infodb_handle "<$infodb_value_key>" . $infodb_value . "\n"; 
    185         } 
    186     } 
    187     print $infodb_handle '-' x 70, "\n"; 
    188 } 
    189 ## write_infodb_entry(filehandle, string, hashmap) => void ## 
    190  
    191  
    192 ## @function write_infodb_rawentry(filehandle, string, string) 
    193 # 
    194 sub write_infodb_rawentry 
    195 { 
    196     my $infodb_handle = shift(@_); 
    197     my $infodb_key = shift(@_); 
    198     my $infodb_val = shift(@_); 
    199  
    200     print $infodb_handle "[$infodb_key]\n"; 
    201     print $infodb_handle "$infodb_val\n"; 
    202     print $infodb_handle '-' x 70, "\n"; 
    203 } 
    204 ## write_infodb_rawentry(filehandle, string, string) ## 
    205  
    206  
    207 ## @function set_infodb_entry(string, string, hashmap) 
    208 # 
    209 sub set_infodb_entry 
    210 { 
    211     my $infodb_file_path = shift(@_); 
    212     my $infodb_key = shift(@_); 
    213     my $infodb_map = shift(@_); 
    214  
    215     # HTML escape anything that is not part of the "contains" metadata value 
    216     foreach my $k (keys %$infodb_map) { 
    217       my @escaped_v = (); 
    218       foreach my $v (@{$infodb_map->{$k}}) { 
    219         if ($k eq "contains") { 
    220           push(@escaped_v, $v); 
    221         } 
    222         else { 
    223           my $ev = &ghtml::unescape_html($v); 
    224           push(@escaped_v, $ev); 
    225         } 
    226       } 
    227       $infodb_map->{$k} = \@escaped_v; 
    228     } 
    229  
    230     # Generate the record string 
    231     my $serialized_infodb_map = &dbutil::convert_infodb_hash_to_string($infodb_map); 
    232  
    233     # Store it into GDBM using 'txt2db -append' which despite its name 
    234     # actually replaces the record if it already exists 
    235     my $cmd = "txt2db -append \"$infodb_file_path\""; 
    236  
    237     my $status = undef; 
    238     if(!open(GOUT, "| $cmd")) { 
    239     print STDERR "Error: gdbm::set_infodb_entry() failed to open pipe to: $cmd\n"; 
    240     print STDERR "       $!\n"; 
    241     $status = -1; 
    242     } 
    243     else { 
    244     binmode(GOUT,":utf8"); 
    245  
    246     print GOUT "[$infodb_key]\n"; 
    247     print GOUT "$serialized_infodb_map\n"; 
    248  
    249     close(GOUT); 
    250     $status = 0; # as in exit status of cmd OK 
    251     } 
    252     return $status; 
    253 } 
    254 ## set_infodb_entry(string, string, hashmap) => integer ## 
    255  
    256  
    257 ## @function delete_infodb_entry(filehandle, string) 
    258 # 
    259 sub delete_infodb_entry 
    260 { 
    261   my $infodb_handle = shift(@_); 
    262   my $infodb_key = shift(@_); 
    263  
    264   # A minus at the end of a key (after the ]) signifies 'delete' 
    265   print $infodb_handle "[$infodb_key]-\n"; 
    266  
    267   # The 70 minus signs are also needed, to help make the parsing by db2txt simple 
    268   print $infodb_handle '-' x 70, "\n"; 
    269 } 
    270 ## delete_infodb_entry(filehandle, string) => void ## 
    271  
    272991;