Index: /main/trunk/greenstone2/common-src/src/lib/Makefile.in
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/Makefile.in	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/Makefile.in	(revision 22043)
@@ -88,4 +88,5 @@
 	text_t.cpp \
 	unitool.cpp \
+	sqldbclass.cpp \
 	$(SQLITE_SOURCES)
 
@@ -109,4 +110,5 @@
 	text_t.o \
 	unitool.o \
+	sqldbclass.o \
 	$(SQLITE_OBJECTS)
 
Index: /main/trunk/greenstone2/common-src/src/lib/jdbmnaiveclass.cpp
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/jdbmnaiveclass.cpp	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/jdbmnaiveclass.cpp	(revision 22043)
@@ -184,7 +184,10 @@
       fgets(buf,256,PIN);
 
-      cerr << "**## buf = " << buf << endl;
-
-      cerr << "**## buf: ";
+      /* 
+       * debuging code
+
+      cerr << "****## buf = " << buf << endl;
+
+      cerr << "****## buf: ";
 
       int blen = strlen(buf);
@@ -192,5 +195,7 @@
 	cerr << "(" << buf[i] << "," << (int)buf[i] << ") ";
       }
+
       cerr << endl;
+      */ // *****
 
 
@@ -202,5 +207,5 @@
   delete [] key_cstr;
   
-  cerr << "**** data before to_unicode = " << data << endl;
+  // cerr << "**** data before to_unicode = " << data << endl;
 
   data = to_uni(data);  // convert to unicode
Index: /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.cpp
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.cpp	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.cpp	(revision 22043)
@@ -143,6 +143,6 @@
 void mssqldbclass::deletekey (const text_t &key)
 {
-  text_t sql_cmd = "DELETE FROM data_" + tableid + " WHERE one_key=N'" + mssql_safe(key) + "'";
-  dbquery(sql_cmd);
+  text_t sql_cmd = "DELETE FROM data_" + tableid + " WHERE one_key=N'" + sql_safe(key) + "'";
+  sqlexec(sql_cmd);
 }
 
@@ -151,5 +151,5 @@
 bool mssqldbclass::getkeydata (const text_t& key, text_t &data)
 {
-  text_t sql_cmd = "SELECT one_value FROM data_" + tableid + " WHERE one_key=N'" + mssql_safe(key) + "'";
+  text_t sql_cmd = "SELECT one_value FROM data_" + tableid + " WHERE one_key=N'" + sql_safe(key) + "'";
   vector<text_tmap> sql_results;
   if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
@@ -196,11 +196,11 @@
   if (!exists(key))
   {
-    text_t sql_cmd = "INSERT INTO data_" + tableid + " (one_key, one_value) VALUES (N'" + mssql_safe(key) + "', N'" + mssql_safe(data) + "')";
-    return dbquery(sql_cmd);
+    text_t sql_cmd = "INSERT INTO data_" + tableid + " (one_key, one_value) VALUES (N'" + sql_safe(key) + "', N'" + sql_safe(data) + "')";
+    return sqlexec(sql_cmd);
   }
   else
   {
-    text_t sql_cmd = "UPDATE data_" + tableid + " SET one_value='" + mssql_safe(data) + "' WHERE one_key=N'" + mssql_safe(key) + "'";
-    return dbquery(sql_cmd);
+    text_t sql_cmd = "UPDATE data_" + tableid + " SET one_value='" + sql_safe(data) + "' WHERE one_key=N'" + sql_safe(key) + "'";
+    return sqlexec(sql_cmd);
   }
 }
@@ -221,15 +221,15 @@
   
   // Get the entries in the "document_metadata" table where the element and value matches those specified
-  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata_" + tableid + " WHERE element IN (N'" + mssql_safe(metadata_element_names[0]) + "'";
+  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata_" + tableid + " WHERE element IN (N'" + sql_safe(metadata_element_names[0]) + "'";
   for (int i = 1; i < metadata_element_names.size(); i++)
   {
-    sql_cmd += ",'" + mssql_safe(metadata_element_names[i]) + "'";
-  }
-  sql_cmd += ") AND value='" + mssql_safe(metadata_value) + "'";
+    sql_cmd += ",'" + sql_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ") AND value='" + sql_safe(metadata_value) + "'";
   
   // If we're sorting the documents by a certain metadata element, extend the SQL command to do this
   if (sort_by_metadata_element_name != "")
   {
-    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata_" + tableid + " WHERE element=N'" + mssql_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
+    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata_" + tableid + " WHERE element=N'" + sql_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
   }
   
@@ -275,8 +275,8 @@
   
   // Get the entries in the "document_metadata" table where the element matches that specified
-  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata_" + tableid + " WHERE element IN (N'" + mssql_safe(metadata_element_names[0]) + "'";
+  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata_" + tableid + " WHERE element IN (N'" + sql_safe(metadata_element_names[0]) + "'";
   for (int i = 1; i < metadata_element_names.size(); i++)
   {
-    sql_cmd += ",N'" + mssql_safe(metadata_element_names[i]) + "'";
+    sql_cmd += ",N'" + sql_safe(metadata_element_names[i]) + "'";
   }
   sql_cmd += ")";
@@ -285,5 +285,5 @@
   if (metadata_value_filter != "")
   {
-    sql_cmd += " AND value GLOB N'" + mssql_safe(metadata_value_filter) + "'";
+    sql_cmd += " AND value GLOB N'" + sql_safe(metadata_value_filter) + "'";
   }
   
@@ -308,12 +308,8 @@
 
 
-//-------------------------------------------------------------------------------------//
-// MS-SQL Private Utilities [START]
-//-------------------------------------------------------------------------------------//
-
-// dbquery(const text_t &sql)
+// sqlexec(const text_t &sql)
 // Takes a sql statement and executes it
 // Returns false if failed, otherwise true
-bool mssqldbclass::dbquery (const text_t &sql)
+bool mssqldbclass::sqlexec (const text_t &sql)
 {
   char *sql_c = sql.getcstr();
@@ -324,5 +320,5 @@
   if (FAILED(cmd.CreateInstance(__uuidof(Command))))
   {
-    cerr << "mssqldbclass::dbquery: CreateInstance failed" << endl;
+    cerr << "mssqldbclass::sqlexec: CreateInstance failed" << endl;
     return false;
   }
@@ -339,10 +335,10 @@
     text_t error;
     error.setcstr(e.ErrorMessage());
-    cerr << "mssqldbclass::dbquery: _com_error: (" << sql << ") : (" << error << ")" << endl;
+    cerr << "mssqldbclass::sqlexec: _com_error: (" << sql << ") : (" << error << ")" << endl;
     rv = false;
   }
   catch (...)
   {
-    cerr << "mssqldbclass::dbquery: unknown error: (" + sql + ")" << endl;
+    cerr << "mssqldbclass::sqlexec: unknown error: (" + sql + ")" << endl;
     rv = false;
   }
@@ -426,5 +422,24 @@
 
 
-text_t mssqldbclass::mssql_safe (const text_t &value_arg)
+// returns true if exists
+bool sqlitedbclass::sqltableexists(const text_t &table_name)
+{
+  cerr << "**** mssqldbclass::sqltableexists: This implementation is untested!" << endl;
+  cerr << "**** Remove warning message once confirmed/fixed to works as required" << endl;
+
+  text_t sql_cmd = "SELECT name FROM sysobjects WHERE name='" + sql_safe(table_name) 
+    + "' AND OBJECTPROPERTY(id,'IsUserTable')=1";
+
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return false;
+  }
+
+  return true;
+}
+
+
+text_t mssqldbclass::sql_safe (const text_t &value_arg)
 {
   text_t value = value_arg;
@@ -434,7 +449,13 @@
 
 
+//---------------------------------------------------------------------------//
+// MS-SQL Private Utilities [START]
+//---------------------------------------------------------------------------//
+
+
 // read_infodb_file(text_t filename)
-// Unlike the others (sqlite and gdbm), this is a server-client based database.
-// Therefore, instead of store the actual database, we store the infoserver-client based database.
+// Unlike the others (sqlite and gdbm), this is a server-client based
+// database.  Therefore, instead of store the actual database, we store the
+// infoserver-client based database.
 // What we want to do here is to have the 
 text_tmap mssqldbclass::read_infodb_file(text_t filename)
@@ -494,6 +515,6 @@
 }
 
-//-------------------------------------------------------------------------------------//
+//---------------------------------------------------------------------------//
 // MS-SQL Private Utilities [END]
-//-------------------------------------------------------------------------------------//
-
+//---------------------------------------------------------------------------//
+
Index: /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.h
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.h	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/mssqldbclass.h	(revision 22043)
@@ -3,4 +3,5 @@
  * mssqldbclass.h -- 
  * Copyright (C) 2008  DL Consulting Ltd
+ * Copyright (C) 2010  New Zealand Digital Library Project
  *
  * A component of the Greenstone digital library software
@@ -35,30 +36,8 @@
 class mssqldbclass : public sqldbclass
 {
- private:
-
-  _ConnectionPtr dbptr;
-
-  text_t tableid;
-  
-  // To enable the debug string to be output to cerr.
-  bool debug;
-  
-  text_tmap read_infodb_file (text_t filename);
-
-  void debug_output (text_t output_string);
-
-  text_t convert_bstr_to_textt (_variant_t in);
-
-  bool dbquery (const text_t &sql);
-
-  bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
-
-  text_t mssql_safe (const text_t &value_arg);
-  
  public:
 
   mssqldbclass ();
-
-  ~mssqldbclass ();
+  virtual ~mssqldbclass ();
   
   // returns true if opened
@@ -81,12 +60,30 @@
   
   // returns array of document OIDs
-  text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
-                                                 const text_t &metadata_value,
-                                                 const text_t &sort_by_metadata_element_name);
+  virutal text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+							 const text_t &metadata_value,
+							 const text_t &sort_by_metadata_element_name);
   
   // returns array of values
-  text_tarray get_metadata_values (const text_tarray &metadata_element_names,
-                                   const text_t &metadata_value_filter,
-                                   const text_t &metadata_value_grouping_expression);
+  virtual text_tarray get_metadata_values (const text_tarray &metadata_element_names,
+					   const text_t &metadata_value_filter,
+					   const text_t &metadata_value_grouping_expression);
+
+
+ protected:
+  _ConnectionPtr dbptr;
+  text_t tableid;
+  bool debug; // To enable the debug string to be output to cerr.
+
+  virutal text_t sql_safe (const text_t &value_arg);
+
+  virtual bool sqlexec (const text_t &sql);
+  virtual bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
+  virtual bool sqltableexists (const text_t &table_name);
+
+  
+  text_tmap read_infodb_file (text_t filename);
+  void debug_output (text_t output_string);
+  text_t convert_bstr_to_textt (_variant_t in);
+
 };
 
Index: /main/trunk/greenstone2/common-src/src/lib/sqldbclass.h
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/sqldbclass.h	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/sqldbclass.h	(revision 22043)
@@ -3,4 +3,5 @@
  * sqldbclass.h -- 
  * Copyright (C) 2008  DL Consulting Ltd
+ * Copyright (C) 2010  New Zealand Digital Library Project
  *
  * A component of the Greenstone digital library software
@@ -35,10 +36,10 @@
 {
 public:
-  sqldbclass() {}
-  virtual ~sqldbclass() {}
+  sqldbclass();
+  virtual ~sqldbclass();
 
-
-  // -----------------------------------------------------------------------------------------------
-  // These functions MUST be implemented by subclasses, as they are database-specific
+  // returns array of document OIDs
+  virtual text_tarray get_documents_where (const text_t& sql_initial_cmd,
+					   const text_t& sort_by_metadata_element_name);
 
   // returns array of document OIDs
@@ -51,4 +52,13 @@
 					   const text_t &metadata_value_filter,
 					   const text_t &metadata_value_grouping_expression) = 0;
+
+protected:
+  virtual text_t sql_safe (const text_t &value_arg) = 0;
+
+  virtual bool sqlexec(const text_t &sql_cmd) = 0;
+  virtual bool sqlgetarray(const text_t& sql_cmd,
+			   vector<text_tmap>& sql_results) = 0;
+  virtual bool sqltableexists(const text_t &table_name) = 0;
+
 };
 
Index: /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.cpp
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.cpp	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.cpp	(revision 22043)
@@ -38,4 +38,9 @@
 
 #define SQLITE_MAX_RETRIES 8
+
+sqlitedbclass::sqlitedbclass() 
+{ 
+  sqlitefile = NULL; 
+}
 
 
@@ -95,5 +100,5 @@
 void sqlitedbclass::deletekey (const text_t &key)
 {
-  text_t sql_cmd = "DELETE FROM data WHERE key='" + sqlite_safe(key) + "'";
+  text_t sql_cmd = "DELETE FROM data WHERE key='" + sql_safe(key) + "'";
   sqlexec(sql_cmd);
 }
@@ -114,15 +119,15 @@
 
   // Get the entries in the "document_metadata" table where the element and value matches those specified
-  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata WHERE element IN ('" + sqlite_safe(metadata_element_names[0]) + "'";
+  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata WHERE element IN ('" + sql_safe(metadata_element_names[0]) + "'";
   for (int i = 1; i < metadata_element_names.size(); i++)
   {
-    sql_cmd += ",'" + sqlite_safe(metadata_element_names[i]) + "'";
-  }
-  sql_cmd += ") AND value='" + sqlite_safe(metadata_value) + "'";
+    sql_cmd += ",'" + sql_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ") AND value='" + sql_safe(metadata_value) + "'";
 
   // If we're sorting the documents by a certain metadata element, extend the SQL command to do this
   if (sort_by_metadata_element_name != "")
   {
-    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata WHERE element='" + sqlite_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
+    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata WHERE element='" + sql_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
   }
 
@@ -157,5 +162,5 @@
 bool sqlitedbclass::getkeydata (const text_t& key, text_t &data)
 {
-  text_t sql_cmd = "SELECT value FROM data WHERE key='" + sqlite_safe(key) + "'";
+  text_t sql_cmd = "SELECT value FROM data WHERE key='" + sql_safe(key) + "'";
   vector<text_tmap> sql_results;
   if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
@@ -217,8 +222,8 @@
 
   // Get the entries in the "document_metadata" table where the element matches that specified
-  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata WHERE element IN ('" + sqlite_safe(metadata_element_names[0]) + "'";
+  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata WHERE element IN ('" + sql_safe(metadata_element_names[0]) + "'";
   for (int i = 1; i < metadata_element_names.size(); i++)
   {
-    sql_cmd += ",'" + sqlite_safe(metadata_element_names[i]) + "'";
+    sql_cmd += ",'" + sql_safe(metadata_element_names[i]) + "'";
   }
   sql_cmd += ")";
@@ -227,5 +232,5 @@
   if (metadata_value_filter != "")
   {
-    sql_cmd += " AND value GLOB '" + sqlite_safe(metadata_value_filter) + "'";
+    sql_cmd += " AND value GLOB '" + sql_safe(metadata_value_filter) + "'";
   }
 
@@ -256,10 +261,10 @@
   if (!exists(key))
   {
-    text_t sql_cmd = "INSERT INTO data (key, value) VALUES ('" + sqlite_safe(key) + "', '" + sqlite_safe(data) + "')";
+    text_t sql_cmd = "INSERT INTO data (key, value) VALUES ('" + sql_safe(key) + "', '" + sql_safe(data) + "')";
     return sqlexec(sql_cmd);
   }
   else
   {
-    text_t sql_cmd = "UPDATE data SET value='" + sqlite_safe(data) + "' WHERE key='" + sqlite_safe(key) + "'";
+    text_t sql_cmd = "UPDATE data SET value='" + sql_safe(data) + "' WHERE key='" + sql_safe(key) + "'";
     return sqlexec(sql_cmd);
   }
@@ -282,5 +287,5 @@
 
 
-text_t sqlitedbclass::sqlite_safe (const text_t &value_arg)
+text_t sqlitedbclass::sql_safe (const text_t &value_arg)
 {
   text_t value = value_arg;
@@ -380,5 +385,5 @@
 bool sqlitedbclass::sqltableexists(const text_t &table_name)
 {
-  text_t sql_cmd = "SELECT * FROM sqlite_master WHERE tbl_name='" + sqlite_safe(table_name) + "'";
+  text_t sql_cmd = "SELECT * FROM sqlite_master WHERE tbl_name='" + sql_safe(table_name) + "'";
   vector<text_tmap> sql_results;
   if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
Index: /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.h
===================================================================
--- /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.h	(revision 22042)
+++ /main/trunk/greenstone2/common-src/src/lib/sqlitedbclass.h	(revision 22043)
@@ -3,4 +3,5 @@
  * sqlitedbclass.h -- 
  * Copyright (C) 2008  DL Consulting Ltd
+ * Copyright (C) 2010  New Zealand Digital Library Project
  *
  * A component of the Greenstone digital library software
@@ -35,18 +36,14 @@
 {
 public:
-  sqlitedbclass() { sqlitefile = NULL; }
-  ~sqlitedbclass();
+  sqlitedbclass();
+  virtual ~sqlitedbclass();
 
   // returns true if opened
-  bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock);
+  bool opendatabase (const text_t &filename, int mode, int num_retrys, 
+		     bool need_filelock);
 
   void closedatabase ();
 
   void deletekey (const text_t &key);
-
-  // returns array of document OIDs
-  text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
-						 const text_t &metadata_value,
-						 const text_t &sort_by_metadata_element_name);
 
   // returns file extension string
@@ -59,8 +56,14 @@
   text_tarray getkeys ();
 
+
+  // returns array of document OIDs
+  virtual text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+							 const text_t &metadata_value,
+							 const text_t &sort_by_metadata_element_name);
+
   // returns array of values
-  text_tarray get_metadata_values (const text_tarray &metadata_element_names,
-				   const text_t &metadata_value_filter,
-				   const text_t &metadata_value_grouping_expression);
+  virtual text_tarray get_metadata_values (const text_tarray &metadata_element_names,
+					   const text_t &metadata_value_filter,
+					   const text_t &metadata_value_grouping_expression);
 
   // returns true on success
@@ -71,9 +74,10 @@
   sqlite3* sqlitefile;
 
-  text_t sqlite_safe (const text_t &value_arg);
+  virtual text_t sql_safe (const text_t &value_arg);
 
-  bool sqlexec (const text_t &sql_cmd);
-  bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
-  bool sqltableexists (const text_t &table_name);
+  virtual bool sqlexec (const text_t &sql_cmd);
+  virtual bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
+  virtual bool sqltableexists (const text_t &table_name);
+
 };
 
