Index: gs2-extensions/tdb/trunk/perllib/DBDrivers/TDB.pm
===================================================================
--- gs2-extensions/tdb/trunk/perllib/DBDrivers/TDB.pm	(revision 30338)
+++ gs2-extensions/tdb/trunk/perllib/DBDrivers/TDB.pm	(revision 30347)
@@ -53,5 +53,5 @@
     my $class = shift(@_);
 
-    my $self = DBDrivers::GDBM->new();
+    my $self = DBDrivers::GDBM->new(@_);
 
     # Default TDB file extension
@@ -59,8 +59,16 @@
     # Should the TDB used a specific affinity?
     $self->{'forced_affinity'} = -1; # zero upwards indicates the affinity
-    # Keep track of all opened file handles
-    $self->{'handle_pool'} = {};
     # Ask TDB executables to display debugging information?
-    $self->{'tdb_debug'} = 0; # 1 to enable
+    $self->{'tdb_debug'} = 1; # 1 to enable
+
+    # note: file separator agnostic
+    $self->{'executable_path'} = $ENV{GEXTTDBEDIT_INSTALLED} . '/bin/';
+    $self->{'read_executable'} = 'tdb2txt';
+    $self->{'keyread_executable'} = 'tdbkeys';
+    $self->{'write_executable'} = 'txt2tdb';
+
+    # Optional Support
+    $self->{'supports_persistentconnection'} = 1;
+    $self->{'supports_set'} = 1;
 
     bless($self, $class);
@@ -96,32 +104,17 @@
 # -----------------------------------------------------------------------------
 
+# Handled by BaseDBDriver
+# sub debugPrint(string) => void
+# sub debugPrintFunctionHeader(*) => void
+# sub get_infodb_file_path(string, string) => string
 
-## @function _get_tdb_executable(string)
-#
-sub _get_tdb_executable
-{
-    my $self = shift(@_);
-    my $program = shift(@_);
-    if (!defined $ENV{GEXTTDBEDIT_INSTALLED} || !-d $ENV{GEXTTDBEDIT_INSTALLED})
-    {
-	die('Fatal Error! Path to TDB binaries not found. Have you sourced setup.bash?');
-    }
-    my $program_exe = &util::filename_cat($ENV{GEXTTDBEDIT_INSTALLED} . '/bin/' . $program . &util::get_os_exe());
-    if (!-x $program_exe)
-    {
-	die('Fatal Error! File doesn\'t exist or isn\'t executable: ' . $program_exe);
-    }
-    return $program_exe;
-}
-## _get_tdb_executable(string) => string ##
-
-
-# Handled by BaseDBDriver
-# sub get_infodb_file_path(string, string)
-
-# With infodb_handle already set up, these functions work the same as parent version
-# sub delete_infodb_entry {}
-# sub write_infodb_entry {}
-# sub write_infodb_rawentry {}
+# Handled by 70HyphenFormat
+# sub read_infodb_entry(string, string) => hashmap
+# sub read_infodb_file(string, hashmap) => void
+# sub read_infodb_keys(string, hashmap) => void
+# sub read_infodb_rawentry(string, string) => string
+# sub set_infodb_entry(string, string, hashmap) => integer
+# sub write_infodb_entry(filehandle, string, hashmap) => void
+# sub write_infodb_rawentry(filehandle, string, string) => void
 
 
@@ -144,8 +137,8 @@
 sub close_infodb_write_handle {
     my $self = shift(@_);
+    $self->debugPrintFunctionHeader(@_);
     my $infodb_handle = shift(@_);
     my $actually_close = shift(@_); # Undefined most of the time
     if (defined($actually_close)) {
-	$self->_debugPrint('(<infodb_handle>,"' . $actually_close . '")');
 	# We'll need the file path so we can locate and remove the entry in the
 	# handle pool
@@ -156,5 +149,5 @@
 	# we can search for the appropriate file extension that should be there
 	# for valid paths.
-	my $pattern = '\.' . $self->{'default_file_extension'} . '$';
+	my $pattern = '\.' . $self->{'default_file_extension'} . '(\s\[APPEND\])?$';
 	if ($actually_close =~ /$pattern/) {
 	    $infodb_file_path = $actually_close;
@@ -173,4 +166,5 @@
 	}
 	if (defined($infodb_file_path)) {
+            $self->debugPrint('Closing connection: ' . $infodb_file_path);
 	    delete($self->{'handle_pool'}->{$infodb_file_path});
 	}
@@ -181,6 +175,11 @@
 	$self->SUPER::close_infodb_write_handle($infodb_handle);
     }
+    else {
+	$self->debugPrint('Connection persists for later use.');
+    }
 }
 ## close_infodb_write_handle(filehandle) => void ##
+
+# sub delete_infodb_entry {}
 
 
@@ -190,159 +189,11 @@
 {
     my $self = shift(@_);
-    my $infodb_file_path = shift(@_);
-    my $opt_append = shift(@_);
-
-    my $txt2tdb_exe = $self->_get_tdb_executable('txt2tdb');
-
-    my $cmd = '"' . $txt2tdb_exe . '"';
-    if ((defined $opt_append) && ($opt_append eq "append")) {
-        $cmd .= ' -append';
+    if ($self->{'tdb_debug'}) {
+        push(@_, '-debug');
     }
-    $cmd .= ' "' . $infodb_file_path . '"';
-    # Optional flags
-    if ($self->{'forced_affinity'} >= 0) {
-        $cmd = 'taskset -c 5 ' . $cmd;
-    }
-    if ($self->{'debug'}) {
-        $cmd .= ' -debug';
-    }
-
-    # we're going to pipe the key value pairs, in the appropriate format, from
-    # within the buildproc, so we create a piped handle here
-    my $infodb_file_handle = undef;
-    # if the connection is already open, simply return it.
-    if (defined $self->{'handle_pool'}->{$infodb_file_path}) {
-	$infodb_file_handle = $self->{'handle_pool'}->{$infodb_file_path};
-    }
-    else {
-	$self->_debugPrint('(' . $infodb_file_path . ')');
-	if(!open($infodb_file_handle, "| $cmd")) {
-	    print STDERR "Error: Failed to open pipe to $cmd\n";
-	    print STDERR "       $!\n";
-	    return undef;
-	}
-	binmode($infodb_file_handle,":utf8");
-	# Remember to store the newly created connection in the pool so we can
-	# re-use for subsequent calls.
-	$self->{'handle_pool'}->{$infodb_file_path} = $infodb_file_handle;
-    }
-    return $infodb_file_handle;
+    my $handle = $self->SUPER::open_infodb_write_handle(@_);
+    return $handle;
 }
 ## open_infodb_write_handle(string, string) => filehandle ##
 
-
-## @function read_infodb_file
-#
-sub read_infodb_file
-{
-    my $self = shift(@_);
-    my $infodb_file_path = shift(@_);
-    my $infodb_map = shift(@_);
-
-    $self->_debugPrint('(' . $infodb_file_path . ', <hashmap>)');
-
-    my $tdb2txt_exe = $self->_get_tdb_executable('tdb2txt');
-
-    if (!open (PIPEIN, '"' . $tdb2txt_exe . '" "' . $infodb_file_path . '" |')) {
-        print STDERR 'Error: Failed to open pipe to ' . $tdb2txt_exe . "\n";
-        print STDERR "       $!\n";
-        return undef;
-    }
-
-    binmode(PIPEIN,":utf8");
-
-    my $infodb_line = "";
-    my $infodb_key = "";
-    my $infodb_value = "";
-    while (defined ($infodb_line = <PIPEIN>)) {
-        if ($infodb_line =~ /^\[([^\]]+)\]$/) {
-            $infodb_key = $1;
-        }
-        elsif ($infodb_line =~ /^-{70}$/) {
-            $infodb_map->{$infodb_key} = $infodb_value;
-            $infodb_key = "";
-            $infodb_value = "";
-        }
-        else {
-            $infodb_value .= $infodb_line;
-        }
-    }
-    close (PIPEIN);
-}
-## read_infodb_file(string, hashmap) => void ##
-
-
-## @function read_infodb_keys(string, hashmap)
-#
-sub read_infodb_keys
-{
-    my $self = shift(@_);
-    my $infodb_file_path = shift(@_);
-    my $infodb_map = shift(@_);
-
-    $self->_debugPrint('(' . $infodb_file_path . ', <hashmap>)');
-
-    my $tdbkeys_exe = $self->_get_tdb_executable('tdbkeys');
-
-    if (!open (PIPEIN, '"' . $tdbkeys_exe . '" "' . $infodb_file_path . '" |')) {
-        die("Error! Couldn't open pipe from read_infodb_keys: $infodb_file_path\n$!\n");
-    }
-
-    binmode(PIPEIN,":utf8");
-
-    my $infodb_line = "";
-    my $infodb_key = "";
-    my $infodb_value = "";
-    while (defined ($infodb_line = <PIPEIN>)) {
-        # remove end of line
-        chomp $infodb_line;
-        $infodb_map->{$infodb_line} = 1;
-    }
-
-    close (PIPEIN);
-}
-## read_infodb_keys(string, hashmap) => void ##
-
-
-## @function set_infodb_entry(string, string, hashmap)
-#
-sub set_infodb_entry
-{
-    my $self = shift(@_);
-    my $infodb_file_path = shift(@_);
-    my $infodb_key = shift(@_);
-    my $infodb_map = shift(@_);
-
-    $self->_debugPrint('(' . $infodb_file_path . ', ' . $infodb_key . ', <hashmap>)');
-
-    # Protect metadata values that go inside quotes for tdbset
-    foreach my $k (keys %$infodb_map) {
-        my @escaped_v = ();
-        foreach my $v (@{$infodb_map->{$k}}) {
-            if ($k eq "contains") {
-                # protect quotes in ".2;".3 etc
-                $v =~ s/\"/\\\"/g;
-                push(@escaped_v, $v);
-            }
-            else {
-                my $ev = &ghtml::unescape_html($v);
-                $ev =~ s/\"/\\\"/g;
-                push(@escaped_v, $ev);
-            }
-        }
-        $infodb_map->{$k} = \@escaped_v;
-    }
-
-    # Generate the record string
-    my $serialized_infodb_map = $self->_convert_infodb_hash_to_string($infodb_map);
-
-    # Store it into GDBM
-    my $tdbset_exe = $self->_get_tdb_executable('tdbset');
-    my $cmd = '"' . $tdbset_exe . '" "' . $infodb_file_path . '" "' . $infodb_key . '" "' . $serialized_infodb_map . '"';
-    my $status = system($cmd);
-
-    return $status;
-}
-## set_infodb_entry(string, string, hashmap) => integer ##
-
 1;
