Index: gs2-extensions/tdb/trunk/perllib/DBDrivers/BaseDBDriver.pm
===================================================================
--- gs2-extensions/tdb/trunk/perllib/DBDrivers/BaseDBDriver.pm	(revision 30343)
+++ gs2-extensions/tdb/trunk/perllib/DBDrivers/BaseDBDriver.pm	(revision 30347)
@@ -44,8 +44,15 @@
     # Debug messages for this driver
     $self->{'debug'} = $debug; # 1 to enable
+    # Keep track of all opened file handles, but only for drivers that support
+    # persistent connections
+    $self->{'handle_pool'} = {};
     # Default file extension - in this case it is an error to create a DB from
     # BaseDBDriver
     $self->{'default_file_extension'} = 'err';
     # Support
+    $self->{'supports_datestamp'} = 0;
+    $self->{'supports_merge'} = 0;
+    $self->{'supports_persistentconnection'} = 0;
+    $self->{'supports_rss'} = 0;
     $self->{'supports_set'} = 0;
     bless($self, $class);
@@ -68,5 +75,5 @@
     if ($self->{'debug'}) {
 	my ($seconds, $microseconds) = gettimeofday();
-	print STDERR '[DEBUG:' . $seconds . '.' . $microseconds . '] ' . (caller 1)[3] . $message . "\n";
+	print STDERR '[DEBUG:' . $seconds . '.' . $microseconds . '] ' . (caller 1)[3] . '() ' . $message . "\n";
     }
 }
@@ -112,4 +119,130 @@
 ## errorPrint(string, integer) => void ##
 
+
+## @function registerConnectionIfPersistent(filehandle, string, string) => void
+#
+sub registerConnectionIfPersistent
+{
+    my $self = shift(@_);
+    my $conn = shift(@_);
+    my $path = shift(@_);
+    my $append = shift(@_);
+    if ($self->{'supports_persistentconnection'}) {
+	$self->debugPrintFunctionHeader($conn, $path, $append);
+	my $fhid = $path;
+	if (defined $append && $append eq '-append') {
+	    $fhid .= ' [APPEND]';
+	}
+	$self->debugPrint('Registering connection: "' . $fhid . '"');
+	$self->{'handle_pool'}->{$fhid} = $conn;
+    }
+    return;
+}
+## registerConnectionIfPersistent(filehandle, string, string) => void ##
+
+
+## @function removeConnectionIfPersistent(filehandle, string) => integer
+#
+sub removeConnectionIfPersistent
+{
+    my $self = shift(@_);
+    my $handle = shift(@_);
+    my $force_close = shift(@_);
+    my $continue_close = 1;
+    if ($self->{'supports_persistentconnection'}) {
+	$self->debugPrintFunctionHeader($handle, $force_close);
+	if (defined($force_close)) {
+	    # We'll need the file path so we can locate and remove the entry
+	    # in the handle pool (plus possibly the [APPEND] suffix for those
+	    # connections in opened in append mode)
+	    my $fhid = undef;
+	    # Sometimes we can cheat, as the force_close variable will have the
+	    # file_path in it thanks to the DESTROY block above. Doing a regex
+	    # on force_close will treat it like a string no matter what it was,
+	    # and we can search for the appropriate file extension that should
+	    # be there for valid paths.
+	    my $pattern = '\.' . $self->{'default_file_extension'} . '(\s\[APPEND\])?$';
+	    if ($force_close =~ /$pattern/) {
+		$fhid = $force_close;
+	    }
+	    # If we can't cheat then we are stuck finding which connection in
+	    # the handle_pool we are about to close. Need to compare objects
+	    # using refaddr()
+	    else {
+		foreach my $possible_fhid (keys %{$self->{'handle_pool'}}) {
+		    my $possible_handle = $self->{'handle_pool'}->{$possible_fhid};
+		    if (ref($handle) && ref($possible_handle) && refaddr($handle) == refaddr($possible_handle)) {
+			$fhid = $possible_fhid;
+			last;
+		    }
+		}
+	    }
+	    # If we found the fhid we can proceed to close the connection
+	    if (defined($fhid)) {
+		$self->debugPrint('Closing persistent connection: ' . $fhid);
+		delete($self->{'handle_pool'}->{$fhid});
+		$continue_close = 1;
+	    }
+	    else {
+		print STDERR "Warning! About to close persistent database handle, but couldn't locate in open handle pool.\n";
+	    }
+	}
+	# Persistent connection don't close *unless* force close is set
+	else {
+	    $continue_close = 0;
+	}
+    }
+    return $continue_close;
+}
+## removeConnectionIfPersistent(filehandle, string) => integer ##
+
+
+##
+#
+sub retrieveConnectionIfPersistent
+{
+    my $self = shift(@_);
+    my $path = shift(@_);
+    my $append = shift(@_); # -append support
+    my $conn; # This should be populated
+    if ($self->{'supports_persistentconnection'}) {
+	$self->debugPrintFunctionHeader($path, $append);
+	my $fhid = $path;
+	# special case: if the append mode has changed for a persistent
+	# connection, we need to close the old connection first or things
+	# will get wiggy.
+	if (defined $append && $append eq '-append') {
+	    # see if there is a non-append mode connection already open
+	    if (defined $self->{'handle_pool'}->{$path}) {
+		$self->debugPrint("Append mode added - closing existing non-append mode connection");
+		my $old_conn = $self->{'handle_pool'}->{$path};
+		$self->close_infodb_write_handle($old_conn, $path);
+	    }
+	    # Append -append so we know what happened.
+	    $fhid .= ' [APPEND]';
+	}
+	else {
+	    my $fhid_append = $path . ' [APPEND]';
+	    if (defined $self->{'handle_pool'}->{$fhid_append}) {
+		$self->debugPrint("Append mode removed - closing existing append mode connection");
+		my $old_conn = $self->{'handle_pool'}->{$fhid_append};
+		$self->close_infodb_write_handle($old_conn, $fhid_append);
+	    }
+	}
+	if (defined $self->{'handle_pool'}->{$fhid}) {
+	    $self->debugPrint('Retrieving existing connection: ' . $fhid);
+	    $conn = $self->{'handle_pool'}->{$fhid};
+	}
+    }
+    return $conn;
+}
+## ##
+
+
+
+
+
+
+
 ###############################################################################
 ## Public Functions
@@ -126,4 +259,10 @@
     my $infodb_file_name = &util::get_dirsep_tail($collection_name) . '.' . $self->{'default_file_extension'};
     my $infodb_file_path = &FileUtils::filenameConcatenate($infodb_directory_path, $infodb_file_name);
+    # Correct the path separators to work in Cygwin
+    if ($^O eq "cygwin") {
+	$infodb_file_path = `cygpath -w "$infodb_file_path"`;
+	chomp($infodb_file_path);
+	$infodb_file_path =~ s%\\%\\\\%g;
+    }
     return $infodb_file_path;
 }
@@ -131,12 +270,12 @@
 
 
-## @function supportsDatestamp(void) => boolean
+## @function supportsDatestamp(void) => integer
 #
 sub supportsDatestamp
 {
     my $self = shift(@_);
-    return 0;
-}
-## supportsDatestamp(void) => boolean ##
+    return $self->{'supports_datestamp'};
+}
+## supportsDatestamp(void) => integer ##
 
 
@@ -146,17 +285,27 @@
 {
     my $self = shift(@_);
-    return 0;
-}
-## supportsMerge(void) => boolean ##
-
-
-## @function supportsRSS(void) => boolean
+    return $self->{'supports_merge'};
+}
+## supportsMerge(void) => integer ##
+
+
+## @function supportsPersistentConnection(void) => integer
+#
+sub supportsPersistentConnection
+{
+    my $self = shift(@_);
+    return $self->{'supports_persistentconnection'};
+}
+## supportsPersistentConnection(void) => integer ##
+
+
+## @function supportsRSS(void) => integer
 #
 sub supportsRSS
 {
     my $self = shift(@_);
-    return 0;
-}
-## supportsRSS(void) => boolean ##
+    return $self->{'supports_rss'};
+}
+## supportsRSS(void) => integer ##
 
 
