Index: gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.cpp
===================================================================
--- gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.cpp	(revision 24090)
+++ gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.cpp	(revision 24090)
@@ -0,0 +1,311 @@
+/**********************************************************************
+ *
+ * tdbclass.cpp --
+ *
+ * Copyright (C) 2011  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 "tdbclass.h"
+
+#include "gsdltools.h"
+#include "gsdlunicode.h"
+#include "fileutil.h"
+#include "stdlib.h"
+#include <cstring>
+
+
+tdbclass::tdbclass(const text_t& gsdlhome)
+  : dbclass(gsdlhome)
+{
+  tdb = NULL;
+}
+
+tdbclass::~tdbclass()
+{
+  closedatabase();
+}
+
+
+// returns true if opened
+bool
+tdbclass::opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock)
+{
+
+  if (tdb != NULL)
+  {
+    if (openfile == filename)
+    {
+      return true;
+    }
+    else
+    {
+      closedatabase();
+    }
+  }
+
+  // Map the DB mode values into TDB mode values
+  int file_mode = O_RDONLY;
+  if (mode == DB_WRITER)
+  {
+    file_mode = O_RDWR;
+  }
+  else if (mode == DB_WRITER_CREATE)
+  {
+    file_mode = O_RDWR | O_CREAT;
+  }
+
+  char *namebuffer = filename.getcstr();
+  int hash_size = 0;
+  do
+  {
+    tdb = tdb_open(namebuffer, hash_size, TDB_DEFAULT, file_mode, 0664);
+    --num_retrys;
+  } while (num_retrys > 0 && tdb==NULL);
+
+  delete []namebuffer;
+
+  if (tdb == NULL && logout != NULL)
+  {
+    outconvertclass text_t2ascii;
+    (*logout) << text_t2ascii << "database open failed on: " << filename << "\n";
+  }
+
+  openfile = filename;
+
+  return (tdb != NULL);
+}
+/** opendatabase() **/
+
+
+/**
+ */
+void
+tdbclass::closedatabase ()
+{
+  if (tdb == NULL)
+  {
+    return;
+  }
+  tdb_close (tdb);
+  tdb = NULL;
+  openfile.clear();
+}
+/** closedatabase() **/
+
+
+/**
+ */
+void
+tdbclass::deletekey (const text_t &key)
+{
+  if (tdb == NULL)
+  {
+    return;
+  }
+  // get a utf-8 encoded c string of the unicode key
+  TDB_DATA key_data;
+  key_data.dptr = (unsigned char*)(to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL)
+  {
+    return;
+  }
+  key_data.dsize = strlen((const char *)key_data.dptr);
+  // delete the key
+  tdb_delete(tdb, key_data);
+  // free up the key memory
+  delete []key_data.dptr;
+}
+/** deletekey() **/
+
+// returns file extension string
+text_t
+tdbclass::getfileextension ()
+{
+  return ".tdb";
+}
+/** getfileextension() **/
+
+// returns true on success
+bool
+tdbclass::getkeydata (const text_t& key, text_t &data)
+{
+  if (tdb == NULL)
+  {
+    return false;
+  }
+
+  // get a utf-8 encoded c string of the unicode key
+  TDB_DATA key_data;
+  key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL)
+  {
+    if (logout != NULL)
+    {
+      (*logout) << "tdbclass: out of memory" << endl;
+    }
+    return false;
+  }
+  key_data.dsize = strlen((const char *)key_data.dptr);
+
+  // fetch the result
+  TDB_DATA return_data = tdb_fetch(tdb, key_data);
+  delete []key_data.dptr;
+
+  if (return_data.dptr == NULL)
+  {
+    return false;
+  }
+  data.setcarr((char *)return_data.dptr, return_data.dsize);
+  free(return_data.dptr);
+  data = to_uni(data);  // convert to unicode
+
+  return true;
+}
+/** getkeydata() **/
+
+
+// returns array of keys
+text_tarray
+tdbclass::getkeys ()
+{
+  text_tarray keys;
+
+  text_t key = getfirstkey();
+  while (!key.empty())
+  {
+    keys.push_back(key);
+    key = getnextkey(key);
+  }
+
+  return keys;
+}
+/** getkeys() **/
+
+
+// returns true on success
+bool
+tdbclass::setkeydata (const text_t &key, const text_t &data)
+{
+  if (tdb == NULL)
+  {
+    return false;
+  }
+
+  // get a utf-8 encoded c string of the unicode key
+  TDB_DATA key_data;
+  key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL)
+  {
+    if (logout != NULL)
+    {
+      (*logout) << "tdbclass: out of memory" << endl;
+    }
+    return false;
+  }
+  key_data.dsize = strlen((const char *)key_data.dptr);
+
+  TDB_DATA data_data;
+  data_data.dptr = (unsigned char *)(to_utf8(data)).getcstr();
+  if (data_data.dptr == NULL)
+  {
+    if (logout != NULL)
+    {
+      (*logout) << "tdbclass: out of memory" << endl;
+    }
+    delete []key_data.dptr;
+    return false;
+  }
+  data_data.dsize = strlen((const char *)data_data.dptr);
+
+  int ret = tdb_store (tdb, key_data, data_data, TDB_DEFAULT);
+  delete []key_data.dptr;
+  delete []data_data.dptr;
+
+  return (ret == 0);
+}
+/** setkeydata() **/
+
+// ----------------------------------------------------------------------------------------
+//   TDB-ONLY FUNCTIONS
+// ----------------------------------------------------------------------------------------
+
+// getfirstkey and getnextkey are used for traversing the database
+// no insertions or deletions should be carried out while traversing
+// the database. when there are no keys left to visit in the database
+// an empty string is returned.
+text_t
+tdbclass::getfirstkey ()
+{
+  if (tdb == NULL)
+  {
+    return g_EmptyText;
+  }
+  // get the first key
+  TDB_DATA firstkey_data = tdb_firstkey(tdb);
+  if (firstkey_data.dptr == NULL)
+  {
+    return g_EmptyText;
+  }
+  // convert it to text_t
+  text_t firstkey;
+  firstkey.setcarr((char *)firstkey_data.dptr, firstkey_data.dsize);
+  free(firstkey_data.dptr);
+
+  return to_uni(firstkey);  // convert to unicode
+}
+/** getfirstkey() **/
+
+/**
+ */
+text_t
+tdbclass::getnextkey (const text_t &key)
+{
+  if (tdb == NULL || key.empty())
+  {
+    return g_EmptyText;
+  }
+  // get a utf-8 encoded c string of the unicode key
+  TDB_DATA key_data;
+  key_data.dptr = (unsigned char *)(to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL)
+  {
+    return g_EmptyText;
+  }
+  key_data.dsize = strlen((const char *)key_data.dptr);
+
+  // get the next key
+  TDB_DATA nextkey_data = tdb_nextkey(tdb, key_data);
+  if (nextkey_data.dptr == NULL)
+  {
+    delete []key_data.dptr;
+    return g_EmptyText;
+  }
+
+  // convert it to text_t
+  text_t nextkey;
+  nextkey.setcarr((char *)nextkey_data.dptr, nextkey_data.dsize);
+  free(nextkey_data.dptr);
+  delete []key_data.dptr;
+  return to_uni(nextkey);  // convert to unicode
+}
+/** getnextkey() **/
+
Index: gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.h
===================================================================
--- gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.h	(revision 24090)
+++ gs2-extensions/tdb-edit/trunk/src/src/lib/tdbclass.h	(revision 24090)
@@ -0,0 +1,69 @@
+/**********************************************************************
+ *
+ * tdbclass.h --
+ *
+ * Copyright (C) 2011  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.
+ *
+ *********************************************************************/
+
+#ifndef TDBCLASS_H
+#define TDBCLASS_H
+
+#include "gsdlconf.h"
+#include "dbclass.h"
+#include "tdb.h"
+
+class tdbclass : public dbclass
+{
+
+public:
+  tdbclass(const text_t& gsdlhome);
+  ~tdbclass();
+
+  // returns true if opened
+  bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock);
+
+  void closedatabase ();
+
+  void deletekey (const text_t &key);
+
+  // returns file extension string
+  text_t getfileextension ();
+
+  // 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 setkeydata (const text_t &key, const text_t &data);
+
+protected:
+  text_t openfile;
+  TDB_CONTEXT *tdb;
+
+  text_t getfirstkey ();
+  text_t getnextkey (const text_t &key);
+
+};
+
+#endif
