Show
Ignore:
Timestamp:
10.12.2015 12:19:20 (4 years ago)
Author:
jmt12
Message:

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

Files:
1 modified

Legend:

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

    r30338 r30347  
    5353    my $class = shift(@_); 
    5454 
    55     my $self = DBDrivers::GDBM->new(); 
     55    my $self = DBDrivers::GDBM->new(@_); 
    5656 
    5757    # Default TDB file extension 
     
    5959    # Should the TDB used a specific affinity? 
    6060    $self->{'forced_affinity'} = -1; # zero upwards indicates the affinity 
    61     # Keep track of all opened file handles 
    62     $self->{'handle_pool'} = {}; 
    6361    # Ask TDB executables to display debugging information? 
    64     $self->{'tdb_debug'} = 0; # 1 to enable 
     62    $self->{'tdb_debug'} = 1; # 1 to enable 
     63 
     64    # note: file separator agnostic 
     65    $self->{'executable_path'} = $ENV{GEXTTDBEDIT_INSTALLED} . '/bin/'; 
     66    $self->{'read_executable'} = 'tdb2txt'; 
     67    $self->{'keyread_executable'} = 'tdbkeys'; 
     68    $self->{'write_executable'} = 'txt2tdb'; 
     69 
     70    # Optional Support 
     71    $self->{'supports_persistentconnection'} = 1; 
     72    $self->{'supports_set'} = 1; 
    6573 
    6674    bless($self, $class); 
     
    96104# ----------------------------------------------------------------------------- 
    97105 
     106# Handled by BaseDBDriver 
     107# sub debugPrint(string) => void 
     108# sub debugPrintFunctionHeader(*) => void 
     109# sub get_infodb_file_path(string, string) => string 
    98110 
    99 ## @function _get_tdb_executable(string) 
    100 # 
    101 sub _get_tdb_executable 
    102 { 
    103     my $self = shift(@_); 
    104     my $program = shift(@_); 
    105     if (!defined $ENV{GEXTTDBEDIT_INSTALLED} || !-d $ENV{GEXTTDBEDIT_INSTALLED}) 
    106     { 
    107     die('Fatal Error! Path to TDB binaries not found. Have you sourced setup.bash?'); 
    108     } 
    109     my $program_exe = &util::filename_cat($ENV{GEXTTDBEDIT_INSTALLED} . '/bin/' . $program . &util::get_os_exe()); 
    110     if (!-x $program_exe) 
    111     { 
    112     die('Fatal Error! File doesn\'t exist or isn\'t executable: ' . $program_exe); 
    113     } 
    114     return $program_exe; 
    115 } 
    116 ## _get_tdb_executable(string) => string ## 
    117  
    118  
    119 # Handled by BaseDBDriver 
    120 # sub get_infodb_file_path(string, string) 
    121  
    122 # With infodb_handle already set up, these functions work the same as parent version 
    123 # sub delete_infodb_entry {} 
    124 # sub write_infodb_entry {} 
    125 # sub write_infodb_rawentry {} 
     111# Handled by 70HyphenFormat 
     112# sub read_infodb_entry(string, string) => hashmap 
     113# sub read_infodb_file(string, hashmap) => void 
     114# sub read_infodb_keys(string, hashmap) => void 
     115# sub read_infodb_rawentry(string, string) => string 
     116# sub set_infodb_entry(string, string, hashmap) => integer 
     117# sub write_infodb_entry(filehandle, string, hashmap) => void 
     118# sub write_infodb_rawentry(filehandle, string, string) => void 
    126119 
    127120 
     
    144137sub close_infodb_write_handle { 
    145138    my $self = shift(@_); 
     139    $self->debugPrintFunctionHeader(@_); 
    146140    my $infodb_handle = shift(@_); 
    147141    my $actually_close = shift(@_); # Undefined most of the time 
    148142    if (defined($actually_close)) { 
    149     $self->_debugPrint('(<infodb_handle>,"' . $actually_close . '")'); 
    150143    # We'll need the file path so we can locate and remove the entry in the 
    151144    # handle pool 
     
    156149    # we can search for the appropriate file extension that should be there 
    157150    # for valid paths. 
    158     my $pattern = '\.' . $self->{'default_file_extension'} . '$'; 
     151    my $pattern = '\.' . $self->{'default_file_extension'} . '(\s\[APPEND\])?$'; 
    159152    if ($actually_close =~ /$pattern/) { 
    160153        $infodb_file_path = $actually_close; 
     
    173166    } 
    174167    if (defined($infodb_file_path)) { 
     168            $self->debugPrint('Closing connection: ' . $infodb_file_path); 
    175169        delete($self->{'handle_pool'}->{$infodb_file_path}); 
    176170    } 
     
    181175    $self->SUPER::close_infodb_write_handle($infodb_handle); 
    182176    } 
     177    else { 
     178    $self->debugPrint('Connection persists for later use.'); 
     179    } 
    183180} 
    184181## close_infodb_write_handle(filehandle) => void ## 
     182 
     183# sub delete_infodb_entry {} 
    185184 
    186185 
     
    190189{ 
    191190    my $self = shift(@_); 
    192     my $infodb_file_path = shift(@_); 
    193     my $opt_append = shift(@_); 
    194  
    195     my $txt2tdb_exe = $self->_get_tdb_executable('txt2tdb'); 
    196  
    197     my $cmd = '"' . $txt2tdb_exe . '"'; 
    198     if ((defined $opt_append) && ($opt_append eq "append")) { 
    199         $cmd .= ' -append'; 
     191    if ($self->{'tdb_debug'}) { 
     192        push(@_, '-debug'); 
    200193    } 
    201     $cmd .= ' "' . $infodb_file_path . '"'; 
    202     # Optional flags 
    203     if ($self->{'forced_affinity'} >= 0) { 
    204         $cmd = 'taskset -c 5 ' . $cmd; 
    205     } 
    206     if ($self->{'debug'}) { 
    207         $cmd .= ' -debug'; 
    208     } 
    209  
    210     # we're going to pipe the key value pairs, in the appropriate format, from 
    211     # within the buildproc, so we create a piped handle here 
    212     my $infodb_file_handle = undef; 
    213     # if the connection is already open, simply return it. 
    214     if (defined $self->{'handle_pool'}->{$infodb_file_path}) { 
    215     $infodb_file_handle = $self->{'handle_pool'}->{$infodb_file_path}; 
    216     } 
    217     else { 
    218     $self->_debugPrint('(' . $infodb_file_path . ')'); 
    219     if(!open($infodb_file_handle, "| $cmd")) { 
    220         print STDERR "Error: Failed to open pipe to $cmd\n"; 
    221         print STDERR "       $!\n"; 
    222         return undef; 
    223     } 
    224     binmode($infodb_file_handle,":utf8"); 
    225     # Remember to store the newly created connection in the pool so we can 
    226     # re-use for subsequent calls. 
    227     $self->{'handle_pool'}->{$infodb_file_path} = $infodb_file_handle; 
    228     } 
    229     return $infodb_file_handle; 
     194    my $handle = $self->SUPER::open_infodb_write_handle(@_); 
     195    return $handle; 
    230196} 
    231197## open_infodb_write_handle(string, string) => filehandle ## 
    232198 
    233  
    234 ## @function read_infodb_file 
    235 # 
    236 sub read_infodb_file 
    237 { 
    238     my $self = shift(@_); 
    239     my $infodb_file_path = shift(@_); 
    240     my $infodb_map = shift(@_); 
    241  
    242     $self->_debugPrint('(' . $infodb_file_path . ', <hashmap>)'); 
    243  
    244     my $tdb2txt_exe = $self->_get_tdb_executable('tdb2txt'); 
    245  
    246     if (!open (PIPEIN, '"' . $tdb2txt_exe . '" "' . $infodb_file_path . '" |')) { 
    247         print STDERR 'Error: Failed to open pipe to ' . $tdb2txt_exe . "\n"; 
    248         print STDERR "       $!\n"; 
    249         return undef; 
    250     } 
    251  
    252     binmode(PIPEIN,":utf8"); 
    253  
    254     my $infodb_line = ""; 
    255     my $infodb_key = ""; 
    256     my $infodb_value = ""; 
    257     while (defined ($infodb_line = <PIPEIN>)) { 
    258         if ($infodb_line =~ /^\[([^\]]+)\]$/) { 
    259             $infodb_key = $1; 
    260         } 
    261         elsif ($infodb_line =~ /^-{70}$/) { 
    262             $infodb_map->{$infodb_key} = $infodb_value; 
    263             $infodb_key = ""; 
    264             $infodb_value = ""; 
    265         } 
    266         else { 
    267             $infodb_value .= $infodb_line; 
    268         } 
    269     } 
    270     close (PIPEIN); 
    271 } 
    272 ## read_infodb_file(string, hashmap) => void ## 
    273  
    274  
    275 ## @function read_infodb_keys(string, hashmap) 
    276 # 
    277 sub read_infodb_keys 
    278 { 
    279     my $self = shift(@_); 
    280     my $infodb_file_path = shift(@_); 
    281     my $infodb_map = shift(@_); 
    282  
    283     $self->_debugPrint('(' . $infodb_file_path . ', <hashmap>)'); 
    284  
    285     my $tdbkeys_exe = $self->_get_tdb_executable('tdbkeys'); 
    286  
    287     if (!open (PIPEIN, '"' . $tdbkeys_exe . '" "' . $infodb_file_path . '" |')) { 
    288         die("Error! Couldn't open pipe from read_infodb_keys: $infodb_file_path\n$!\n"); 
    289     } 
    290  
    291     binmode(PIPEIN,":utf8"); 
    292  
    293     my $infodb_line = ""; 
    294     my $infodb_key = ""; 
    295     my $infodb_value = ""; 
    296     while (defined ($infodb_line = <PIPEIN>)) { 
    297         # remove end of line 
    298         chomp $infodb_line; 
    299         $infodb_map->{$infodb_line} = 1; 
    300     } 
    301  
    302     close (PIPEIN); 
    303 } 
    304 ## read_infodb_keys(string, hashmap) => void ## 
    305  
    306  
    307 ## @function set_infodb_entry(string, string, hashmap) 
    308 # 
    309 sub set_infodb_entry 
    310 { 
    311     my $self = shift(@_); 
    312     my $infodb_file_path = shift(@_); 
    313     my $infodb_key = shift(@_); 
    314     my $infodb_map = shift(@_); 
    315  
    316     $self->_debugPrint('(' . $infodb_file_path . ', ' . $infodb_key . ', <hashmap>)'); 
    317  
    318     # Protect metadata values that go inside quotes for tdbset 
    319     foreach my $k (keys %$infodb_map) { 
    320         my @escaped_v = (); 
    321         foreach my $v (@{$infodb_map->{$k}}) { 
    322             if ($k eq "contains") { 
    323                 # protect quotes in ".2;".3 etc 
    324                 $v =~ s/\"/\\\"/g; 
    325                 push(@escaped_v, $v); 
    326             } 
    327             else { 
    328                 my $ev = &ghtml::unescape_html($v); 
    329                 $ev =~ s/\"/\\\"/g; 
    330                 push(@escaped_v, $ev); 
    331             } 
    332         } 
    333         $infodb_map->{$k} = \@escaped_v; 
    334     } 
    335  
    336     # Generate the record string 
    337     my $serialized_infodb_map = $self->_convert_infodb_hash_to_string($infodb_map); 
    338  
    339     # Store it into GDBM 
    340     my $tdbset_exe = $self->_get_tdb_executable('tdbset'); 
    341     my $cmd = '"' . $tdbset_exe . '" "' . $infodb_file_path . '" "' . $infodb_key . '" "' . $serialized_infodb_map . '"'; 
    342     my $status = system($cmd); 
    343  
    344     return $status; 
    345 } 
    346 ## set_infodb_entry(string, string, hashmap) => integer ## 
    347  
    3481991;