Index: /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.cpp
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.cpp	(revision 22049)
+++ /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.cpp	(revision 22049)
@@ -0,0 +1,111 @@
+/**********************************************************************
+ *
+ * sqlfilter.cpp -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ * Copyright (C) 2010  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "fileutil.h"
+#include "sqlfilter.h"
+
+
+sqlfilterclass::sqlfilterclass ()
+ : filterclass()
+{}
+
+
+sqlfilterclass::~sqlfilterclass ()
+{}
+
+
+void sqlfilterclass::configure (const text_t &key, const text_tarray &cfgline)
+{
+  filterclass::configure (key, cfgline);
+
+  if (key == "indexstem")
+  {
+    indexstem = cfgline[0];
+  }
+}
+
+bool sqlfilterclass::init (ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  if (!filterclass::init(logout)) return false;
+
+  if (sql_db_ptr == NULL)
+  {
+    // most likely a configuration problem
+    logout << text_t2ascii << "configuration error: sqlfilter contains a null sqldbclass\n\n";
+    return false;
+  }
+
+  if (indexstem.empty())
+  {
+    indexstem = collection;
+  }
+
+  // get the filename for the database and make sure it exists
+  sql_db_filename = resolve_db_filename(indexstem,sql_db_ptr->getfileextension());
+  if (!file_exists(sql_db_filename))
+  {
+    logout << text_t2ascii << "warning: database \"" << sql_db_filename << "\" does not exist\n\n";
+    return false;
+  }
+
+  return true;
+}
+
+
+bool sqlfilterclass::connect_to_sqldb (FilterResponse_t &response,
+				       comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  response.clear();
+  err = noError;
+  
+  if (sql_db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii << "configuration error: sqlbrowsefilter contains a null sqldbclass\n\n";
+    err = configurationError;
+    return false;
+  }
+  
+  // open the database
+  sql_db_ptr->setlogout (&logout);
+  if (!sql_db_ptr->opendatabase (sql_db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii << "system problem: open on database \"" << sql_db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return false;
+  }
+  
+  return true;
+}
+
+
+void sqlfilterclass::disconnect_from_sqldb ()
+{
+  sql_db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+}
Index: /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.h
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.h	(revision 22049)
+++ /main/trunk/greenstone2/runtime-src/src/colservr/sqlfilter.h	(revision 22049)
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * sqlfilter.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ * Copyright (C) 2010  New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SQLFILTER_H
+#define SQLFILTER_H
+
+
+#include "filter.h"
+#include "comtypes.h"
+#include "sqldbclass.h"
+#include "text_t.h"
+
+
+class sqlfilterclass : public filterclass {
+protected:
+  text_t sql_db_filename;
+  text_t indexstem;
+  sqldbclass *sql_db_ptr;
+
+public:
+  sqlfilterclass ();
+  virtual ~sqlfilterclass ();
+
+  text_t get_filter_name () { return "SQLFilter"; }
+
+  // configure should be called once for each configuration line
+  // default configures the default filter options
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // the sql db ptr remains the responsibility of the calling code and
+  // should be destroyed after this sqlfilter is destroyed
+  void set_sql_db_ptr (sqldbclass *sql_db_ptr_arg) { sql_db_ptr = sql_db_ptr_arg; }
+
+  bool init (ostream &logout);
+
+  bool connect_to_sqldb (FilterResponse_t &response,
+			 comerror_t &err, ostream &logout);
+  void disconnect_from_sqldb ();
+
+};
+
+
+#endif
Index: /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.cpp
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.cpp	(revision 22049)
+++ /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.cpp	(revision 22049)
@@ -0,0 +1,185 @@
+/**********************************************************************
+ *
+ * sqlqueryfilter.cpp -- 
+ * Copyright (C) 2010  New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "sqlqueryfilter.h"
+
+sqlqueryfilterclass::sqlqueryfilterclass ()
+  : sqlfilterclass()
+{
+  FilterOption_t filtopt;
+
+  // -- onePerQuery StartResults   integer
+  filtopt.clear();
+  filtopt.name = "StartResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "1";
+  filtopt.validValues.push_back("1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["StartResults"] = filtopt;
+
+  // -- onePerQuery EndResults     integer
+  filtopt.clear();
+  filtopt.name = "EndResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "10";
+  filtopt.validValues.push_back("-1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["EndResults"] = filtopt;
+
+  // -- onePerQuery  Maxdocs  integer
+  filtopt.clear();
+  filtopt.name = "Maxdocs";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "200";
+  filtopt.validValues.push_back("-1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["Maxdocs"] = filtopt;
+
+  // --  IndexFieldDomain, enumerated, used to list available fields (from)
+  filtopt.clear();
+  filtopt.name = "IndexFieldDomain";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["IndexFieldDomain"] = filtopt;
+
+  // --  IndexFieldRange, enumerated, used to list available fields (to)
+  //     Equivalent to IndexField in full text search filter
+  filtopt.clear();
+  filtopt.name = "IndexFieldRange";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["IndexFieldRange"] = filtopt;
+
+}
+
+
+sqlqueryfilterclass::~sqlqueryfilterclass ()
+{}
+
+
+
+
+void sqlqueryfilterclass::configure (const text_t &key, 
+				     const text_tarray &cfgline) 
+{
+  sqlfilterclass::configure(key, cfgline);
+  
+  if (key == "indexfieldmap") {
+    indexfieldmap.importmap (cfgline);
+    
+    // update the list of indexes in the filter information
+    text_tarray from_options;
+    indexfieldmap.getfromarray (from_options);
+    filterOptions["IndexFieldDomain"].validValues = from_options;
+
+    text_tarray to_options;
+    indexfieldmap.gettoarray (to_options);
+    filterOptions["IndexFieldRange"].validValues = to_options;
+
+  } else if (key == "defaultindex") { 
+
+    filterOptions["IndexFieldDomain"].defaultValue = cfgline[0];
+
+    indexfieldmap.from2to (cfgline[0], 
+			   filterOptions["IndexFieldRange"].defaultValue);
+  }
+}
+
+bool sqlqueryfilterclass::init (ostream &logout) 
+{
+  if (!sqlfilterclass::init(logout)) {
+    return false;
+  }
+  
+  if (filterOptions["IndexFieldRange"].defaultValue.empty()) {
+    // use first index in map as default if no default is set explicitly
+
+    text_tarray fromarray;
+    indexfieldmap.getfromarray(fromarray);
+
+    text_tarray toarray;
+    indexfieldmap.gettoarray(fromarray);
+
+    if (fromarray.size()) {
+      filterOptions["IndexFieldDomain"].defaultValue = fromarray[0];
+    }
+
+    if (toarray.size()) {
+      filterOptions["IndexFieldRange"].defaultValue = toarray[0];
+    }
+  }
+
+  return true;
+}
+
+void sqlqueryfilterclass::filter (const FilterRequest_t &request,
+				  FilterResponse_t &response,
+				  comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  if (!connect_to_sqldb(response,err,logout)) {
+    return;
+  }
+  
+  text_t sql_where = "";
+  text_t sort_by_metadata_element_name = "";
+  OptionValue_tarray::const_iterator options_iterator = request.filterOptions.begin();
+  while (options_iterator != request.filterOptions.end())
+    {
+      if ((*options_iterator).name == "SQLWhere") {
+	sql_where = (*options_iterator).value;
+      }
+      if ((*options_iterator).name == "SortField") {
+	sort_by_metadata_element_name = (*options_iterator).value;
+      }
+      options_iterator++;
+    }
+
+  text_tarray document_OIDs = sql_db_ptr->get_documents_where (sql_where, sort_by_metadata_element_name);
+  int numDocs = document_OIDs.size();
+
+  // Fill in response.docInfo with the document OIDs
+  text_tarray::iterator document_OID_iterator = document_OIDs.begin();
+  while (document_OID_iterator != document_OIDs.end())
+    {
+      ResultDocInfo_t document_result_doc;
+      document_result_doc.OID = *document_OID_iterator;
+      response.docInfo.push_back (document_result_doc);
+
+      document_OID_iterator++;
+    }
+
+  disconnect_from_sqldb();
+
+  response.numDocs = numDocs;
+  response.isApprox = Exact;
+
+}
Index: /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.h
===================================================================
--- /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.h	(revision 22049)
+++ /main/trunk/greenstone2/runtime-src/src/colservr/sqlqueryfilter.h	(revision 22049)
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *
+ * sqlqueryfilter.h -- 
+ * Copyright (C) 2010  New Zealand Digital Library Projecct
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SQLQUERYFILTER_H
+#define SQLQUERYFILTER_H
+
+
+#include "maptools.h"
+
+#include "sqlfilter.h"
+
+
+class sqlqueryfilterclass : public sqlfilterclass 
+{
+ protected:
+  stringmap indexfieldmap;
+
+ public:
+  sqlqueryfilterclass ();
+  virtual ~sqlqueryfilterclass ();
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+  bool init (ostream &logout);
+
+  text_t get_filter_name () { return "SQLQueryFilter"; }
+
+  void filter (const FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+};
+
+
+#endif
