Index: /gsdl/trunk/lib/dbclass.cpp
===================================================================
--- /gsdl/trunk/lib/dbclass.cpp	(revision 15654)
+++ /gsdl/trunk/lib/dbclass.cpp	(revision 15655)
@@ -26,4 +26,5 @@
 #include "dbclass.h"
 #include "OIDtools.h"
+#include "unitool.h"
 
 
@@ -36,4 +37,136 @@
   text_t data;
   return getkeydata (key, data);
+}
+
+
+// May be overwritten by subclasses; returns true on success
+bool dbclass::getinfo (const text_t& key, infodbclass &info)
+{
+  text_t data;
+  if (!getkeydata(key, data)) return false;
+
+  // Use getinfoline() to parse the data value into the infodbclass object
+  text_t::iterator data_iterator = data.begin();
+  text_t ikey, ivalue;
+  info.clear();
+  while (getinfoline(data_iterator, data.end(), ikey, ivalue))
+  {
+    info.addinfo(ikey, ivalue);
+  }
+
+  return true;
+}
+
+
+// returns true on success
+bool dbclass::getinfoline (text_t::iterator &here, text_t::iterator end, 
+			   text_t &key, text_t &value)
+{
+  key.clear();
+  value.clear();
+
+  // ignore white space
+  while (here != end && is_unicode_space (*here)) ++here;
+
+  // get the '<'
+  if (here == end || *here != '<') return false;
+  ++here;
+  
+  // get the key
+  while (here != end && *here != '>') {
+    key.push_back(*here);
+    ++here;
+  }
+  
+  // get the '>'
+  if (here == end || *here != '>') return false;
+  ++here;
+  
+  // get the value
+  while (here != end && *here != '\n') {
+    if (*here == '\\') { 
+      // found escape character
+      ++here;
+      if (here != end) {
+	if (*here == 'n') value.push_back ('\n');
+	else if (*here == 'r') value.push_back ('\r');
+	else value.push_back(*here);
+      }
+
+    } else {
+      // a normal character
+      value.push_back(*here);
+    }
+
+    ++here;
+  }
+
+  return true;
+}
+
+
+// returns true on success
+bool dbclass::setinfo (const text_t &key, const infodbclass &info)
+{
+  text_t subkey;
+  text_t data;
+
+  // get all the keys and values
+  infodbclass::const_iterator info_here = info.begin();
+  infodbclass::const_iterator info_end = info.end();
+  while (info_here != info_end) {
+    // add the key
+    subkey.clear();
+    subkey.push_back('<');
+    text_t::const_iterator subkey_here = (*info_here).first.begin();
+    text_t::const_iterator subkey_end = (*info_here).first.end();
+    while (subkey_here != subkey_end) {
+      if (*subkey_here == '>') {
+	subkey.push_back('\\'); subkey.push_back('>');
+      } else if (*subkey_here == '\n') {
+	subkey.push_back('\\'); subkey.push_back('n');
+      } else if (*subkey_here == '\r') {
+	subkey.push_back('\\'); subkey.push_back('r');
+      } else if (*subkey_here == '\\') {
+	subkey.push_back('\\'); subkey.push_back('\\');
+      } else {
+	subkey.push_back (*subkey_here);
+      }
+      ++subkey_here;
+    }
+    subkey.push_back('>');
+
+    // add the values
+    text_tarray::const_iterator subvalue_here = (*info_here).second.begin();
+    text_tarray::const_iterator subvalue_end = (*info_here).second.end();
+    while (subvalue_here != subvalue_end) {
+      data += subkey;
+      
+      text_t::const_iterator thissubvalue_here = (*subvalue_here).begin();
+      text_t::const_iterator thissubvalue_end = (*subvalue_here).end();
+      while (thissubvalue_here != thissubvalue_end) {
+	if (*thissubvalue_here == '>') {
+	  data.push_back('\\'); data.push_back('>');
+	} else if (*thissubvalue_here == '\n') {
+	  data.push_back('\\'); data.push_back('n');
+	} else if (*thissubvalue_here == '\r') {
+	  data.push_back('\\'); data.push_back('r');
+	} else if (*thissubvalue_here == '\\') {
+	  data.push_back('\\'); data.push_back('\\');
+	} else {
+	  data.push_back (*thissubvalue_here);
+	}
+	
+	++thissubvalue_here;
+      }
+      
+      data.push_back('\n');
+      ++subvalue_here;
+    }
+
+    ++info_here;
+  }
+
+  return setkeydata(key, data);
 }
 
Index: /gsdl/trunk/lib/dbclass.h
===================================================================
--- /gsdl/trunk/lib/dbclass.h	(revision 15654)
+++ /gsdl/trunk/lib/dbclass.h	(revision 15655)
@@ -54,33 +54,39 @@
   virtual ~dbclass();
 
-  // MUST be implemented by subclasses; returns true if opened
+  void setlogout (ostream *logout_arg) { logout = logout_arg; }
+
+
+  // -----------------------------------------------------------------------------------------------
+  // These functions MUST be implemented by subclasses, as they are database-specific
+
+  // returns true if opened
   virtual bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock) = 0;
 
-  // MUST be implemented by subclasses
   virtual void closedatabase () = 0;
 
-  // MUST be implemented by subclasses
   virtual void deletekey (const text_t &key) = 0;
 
-  // May be overwritten by subclasses; returns true if exists
-  virtual bool exists (const text_t& key);
-
-  // Must be implemented by subclasses; returns true on success
-  virtual bool getinfo (const text_t& key, infodbclass &info) = 0;
-
-  // MUST be implemented by subclasses; returns true on success
+  // returns true on success
   virtual bool getkeydata (const text_t& key, text_t &data) = 0;
 
-  // MUST be implemented by subclasses; returns array of keys
+  // returns array of keys
   virtual text_tarray getkeys () = 0;
 
-  // Must be implemented by subclasses; returns true on success
-  virtual bool setinfo (const text_t &key, const infodbclass &info) = 0;
-
-  // MUST be implemented by subclasses; returns true on success
+  // returns true on success
   virtual bool setkeydata (const text_t &key, const text_t &data) = 0;
 
 
-  void setlogout (ostream *logout_arg) { logout = logout_arg; }
+  // -----------------------------------------------------------------------------------------------
+  // These functions may be overwritten by subclasses, but a default implementation is provided
+
+  // returns true if exists
+  virtual bool exists (const text_t& key);
+
+  // returns true on success
+  virtual bool getinfo (const text_t& key, infodbclass &info);
+
+  // returns true on success
+  virtual bool setinfo (const text_t &key, const infodbclass &info);
+
 
   // replaces the .c, .p, .n, .l syntax (child, parent, next, previous) 
@@ -92,4 +98,7 @@
   ostream *logout;
 
+  // returns true on success
+  bool getinfoline (text_t::iterator &here, text_t::iterator end, text_t &key, text_t &value);
+
   void get_first_child (text_t &OID, infodbclass &info);
   void get_last_child (text_t &OID, infodbclass &info);
Index: /gsdl/trunk/lib/gdbmclass.cpp
===================================================================
--- /gsdl/trunk/lib/gdbmclass.cpp	(revision 15654)
+++ /gsdl/trunk/lib/gdbmclass.cpp	(revision 15655)
@@ -116,23 +116,4 @@
 
 // returns true on success
-bool gdbmclass::getinfo (const text_t& key, infodbclass &info)
-{
-  text_t data;
-  if (!getkeydata(key, data)) return false;
-
-  // Use getinfoline() to parse the data value into the infodbclass object
-  text_t::iterator data_iterator = data.begin();
-  text_t ikey, ivalue;
-  info.clear();
-  while (getinfoline(data_iterator, data.end(), ikey, ivalue))
-  {
-    info.addinfo(ikey, ivalue);
-  }
-
-  return true;
-}
-
-
-// returns true on success
 bool gdbmclass::getkeydata (const text_t& key, text_t &data)
 {
@@ -181,72 +162,4 @@
 
 // returns true on success
-bool gdbmclass::setinfo (const text_t &key, const infodbclass &info)
-{
-  if (gdbmfile == NULL) return false;
-
-  text_t subkey;
-  text_t data;
-
-  // get all the keys and values
-  infodbclass::const_iterator info_here = info.begin();
-  infodbclass::const_iterator info_end = info.end();
-  while (info_here != info_end) {
-    // add the key
-    subkey.clear();
-    subkey.push_back('<');
-    text_t::const_iterator subkey_here = (*info_here).first.begin();
-    text_t::const_iterator subkey_end = (*info_here).first.end();
-    while (subkey_here != subkey_end) {
-      if (*subkey_here == '>') {
-	subkey.push_back('\\'); subkey.push_back('>');
-      } else if (*subkey_here == '\n') {
-	subkey.push_back('\\'); subkey.push_back('n');
-      } else if (*subkey_here == '\r') {
-	subkey.push_back('\\'); subkey.push_back('r');
-      } else if (*subkey_here == '\\') {
-	subkey.push_back('\\'); subkey.push_back('\\');
-      } else {
-	subkey.push_back (*subkey_here);
-      }
-      ++subkey_here;
-    }
-    subkey.push_back('>');
-
-    // add the values
-    text_tarray::const_iterator subvalue_here = (*info_here).second.begin();
-    text_tarray::const_iterator subvalue_end = (*info_here).second.end();
-    while (subvalue_here != subvalue_end) {
-      data += subkey;
-      
-      text_t::const_iterator thissubvalue_here = (*subvalue_here).begin();
-      text_t::const_iterator thissubvalue_end = (*subvalue_here).end();
-      while (thissubvalue_here != thissubvalue_end) {
-	if (*thissubvalue_here == '>') {
-	  data.push_back('\\'); data.push_back('>');
-	} else if (*thissubvalue_here == '\n') {
-	  data.push_back('\\'); data.push_back('n');
-	} else if (*thissubvalue_here == '\r') {
-	  data.push_back('\\'); data.push_back('r');
-	} else if (*thissubvalue_here == '\\') {
-	  data.push_back('\\'); data.push_back('\\');
-	} else {
-	  data.push_back (*thissubvalue_here);
-	}
-	
-	++thissubvalue_here;
-      }
-      
-      data.push_back('\n');
-      ++subvalue_here;
-    }
-
-    ++info_here;
-  }
-
-  return setkeydata(key, data);
-}
-
-
-// returns true on success
 bool gdbmclass::setkeydata (const text_t &key, const text_t &data)
 {
@@ -329,49 +242,2 @@
   return to_uni(nextkey);  // convert to unicode
 }
-
-
-// returns true on success
-bool gdbmclass::getinfoline (text_t::iterator &here, text_t::iterator end, 
-			     text_t &key, text_t &value)
-{
-  key.clear();
-  value.clear();
-
-  // ignore white space
-  while (here != end && is_unicode_space (*here)) ++here;
-
-  // get the '<'
-  if (here == end || *here != '<') return false;
-  ++here;
-  
-  // get the key
-  while (here != end && *here != '>') {
-    key.push_back(*here);
-    ++here;
-  }
-  
-  // get the '>'
-  if (here == end || *here != '>') return false;
-  ++here;
-  
-  // get the value
-  while (here != end && *here != '\n') {
-    if (*here == '\\') { 
-      // found escape character
-      ++here;
-      if (here != end) {
-	if (*here == 'n') value.push_back ('\n');
-	else if (*here == 'r') value.push_back ('\r');
-	else value.push_back(*here);
-      }
-
-    } else {
-      // a normal character
-      value.push_back(*here);
-    }
-
-    ++here;
-  }
-
-  return true;
-}
Index: /gsdl/trunk/lib/gdbmclass.h
===================================================================
--- /gsdl/trunk/lib/gdbmclass.h	(revision 15654)
+++ /gsdl/trunk/lib/gdbmclass.h	(revision 15655)
@@ -63,14 +63,8 @@
 
   // returns true on success
-  bool getinfo (const text_t& key, infodbclass &info);
-
-  // returns true on success
   bool getkeydata (const text_t& key, text_t &data);
 
   // returns array of keys
   text_tarray getkeys ();
-
-  // returns true on success
-  bool setinfo (const text_t &key, const infodbclass &info);
 
   // returns true on success
@@ -87,7 +81,4 @@
   text_t getfirstkey ();
   text_t getnextkey (const text_t &key);
-
-  // returns true on success
-  bool getinfoline (text_t::iterator &here, text_t::iterator end, text_t &key, text_t &value);
 };
 
Index: /gsdl/trunk/lib/sqlitedbclass.cpp
===================================================================
--- /gsdl/trunk/lib/sqlitedbclass.cpp	(revision 15654)
+++ /gsdl/trunk/lib/sqlitedbclass.cpp	(revision 15655)
@@ -90,23 +90,4 @@
 
 // returns true on success
-bool sqlitedbclass::getinfo (const text_t& key, infodbclass &info)
-{
-  text_t data;
-  if (!getkeydata(key, data)) return false;
-
-  // Use getinfoline() to parse the data value into the infodbclass object
-  text_t::iterator data_iterator = data.begin();
-  text_t ikey, ivalue;
-  info.clear();
-  while (getinfoline(data_iterator, data.end(), ikey, ivalue))
-  {
-    info.addinfo(ikey, ivalue);
-  }
-
-  return true;
-}
-
-
-// returns true on success
 bool sqlitedbclass::getkeydata (const text_t& key, text_t &data)
 {
@@ -151,70 +132,4 @@
 
 // returns true on success
-bool sqlitedbclass::setinfo (const text_t &key, const infodbclass &info)
-{
-  text_t subkey;
-  text_t data;
-
-  // get all the keys and values
-  infodbclass::const_iterator info_here = info.begin();
-  infodbclass::const_iterator info_end = info.end();
-  while (info_here != info_end) {
-    // add the key
-    subkey.clear();
-    subkey.push_back('<');
-    text_t::const_iterator subkey_here = (*info_here).first.begin();
-    text_t::const_iterator subkey_end = (*info_here).first.end();
-    while (subkey_here != subkey_end) {
-      if (*subkey_here == '>') {
-	subkey.push_back('\\'); subkey.push_back('>');
-      } else if (*subkey_here == '\n') {
-	subkey.push_back('\\'); subkey.push_back('n');
-      } else if (*subkey_here == '\r') {
-	subkey.push_back('\\'); subkey.push_back('r');
-      } else if (*subkey_here == '\\') {
-	subkey.push_back('\\'); subkey.push_back('\\');
-      } else {
-	subkey.push_back (*subkey_here);
-      }
-      ++subkey_here;
-    }
-    subkey.push_back('>');
-
-    // add the values
-    text_tarray::const_iterator subvalue_here = (*info_here).second.begin();
-    text_tarray::const_iterator subvalue_end = (*info_here).second.end();
-    while (subvalue_here != subvalue_end) {
-      data += subkey;
-      
-      text_t::const_iterator thissubvalue_here = (*subvalue_here).begin();
-      text_t::const_iterator thissubvalue_end = (*subvalue_here).end();
-      while (thissubvalue_here != thissubvalue_end) {
-	if (*thissubvalue_here == '>') {
-	  data.push_back('\\'); data.push_back('>');
-	} else if (*thissubvalue_here == '\n') {
-	  data.push_back('\\'); data.push_back('n');
-	} else if (*thissubvalue_here == '\r') {
-	  data.push_back('\\'); data.push_back('r');
-	} else if (*thissubvalue_here == '\\') {
-	  data.push_back('\\'); data.push_back('\\');
-	} else {
-	  data.push_back (*thissubvalue_here);
-	}
-	
-	++thissubvalue_here;
-      }
-      
-      data.push_back('\n');
-      ++subvalue_here;
-    }
-
-    ++info_here;
-  }
-
-  return setkeydata(key, data);
-}
-
-
-// returns true on success
 bool sqlitedbclass::setkeydata (const text_t &key, const text_t &data)
 {
@@ -233,53 +148,6 @@
 
 
-// returns true on success
-bool sqlitedbclass::getinfoline (text_t::iterator &here, text_t::iterator end, 
-				 text_t &key, text_t &value)
-{
-  key.clear();
-  value.clear();
-
-  // ignore white space
-  while (here != end && is_unicode_space (*here)) ++here;
-
-  // get the '<'
-  if (here == end || *here != '<') return false;
-  ++here;
-  
-  // get the key
-  while (here != end && *here != '>') {
-    key.push_back(*here);
-    ++here;
-  }
-  
-  // get the '>'
-  if (here == end || *here != '>') return false;
-  ++here;
-  
-  // get the value
-  while (here != end && *here != '\n') {
-    if (*here == '\\') { 
-      // found escape character
-      ++here;
-      if (here != end) {
-	if (*here == 'n') value.push_back ('\n');
-	else if (*here == 'r') value.push_back ('\r');
-	else value.push_back(*here);
-      }
-
-    } else {
-      // a normal character
-      value.push_back(*here);
-    }
-
-    ++here;
-  }
-
-  return true;
-}
-
-
 // ----------------------------------------------------------------------------------------
-//   CORE SQL FUNCTIONS
+//   SQLITE-ONLY FUNCTIONS
 // ----------------------------------------------------------------------------------------
 
Index: /gsdl/trunk/lib/sqlitedbclass.h
===================================================================
--- /gsdl/trunk/lib/sqlitedbclass.h	(revision 15654)
+++ /gsdl/trunk/lib/sqlitedbclass.h	(revision 15655)
@@ -46,14 +46,8 @@
 
   // returns true on success
-  bool getinfo (const text_t& key, infodbclass &info);
-
-  // returns true on success
   bool getkeydata (const text_t& key, text_t &data);
 
   // returns array of keys
   text_tarray getkeys ();
-
-  // returns true on success
-  bool setinfo (const text_t &key, const infodbclass &info);
 
   // returns true on success
@@ -64,6 +58,4 @@
   sqlite3* sqlitefile;
 
-  bool getinfoline (text_t::iterator &here, text_t::iterator end, text_t &key, text_t &value);
-
   bool sqlexec (const text_t &sql_cmd);
   bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
