rev 7694 - in kde-extras/strigi: tags tags/0.5.6-1/debian/patches trunk/debian/patches
Fathi Boudra
fboudra-guest at alioth.debian.org
Sun Oct 28 14:05:27 UTC 2007
Author: fboudra-guest
Date: 2007-10-28 14:05:27 +0000 (Sun, 28 Oct 2007)
New Revision: 7694
Added:
kde-extras/strigi/tags/0.5.6-1/
kde-extras/strigi/tags/0.5.6-1/debian/patches/01_strigi_branch_r727526.diff
kde-extras/strigi/trunk/debian/patches/01_strigi_branch_r727526.diff
Log:
* Already uploaded. Tags strigi 0.5.6-1.
Copied: kde-extras/strigi/tags/0.5.6-1 (from rev 7693, kde-extras/strigi/trunk)
Added: kde-extras/strigi/tags/0.5.6-1/debian/patches/01_strigi_branch_r727526.diff
===================================================================
--- kde-extras/strigi/tags/0.5.6-1/debian/patches/01_strigi_branch_r727526.diff (rev 0)
+++ kde-extras/strigi/tags/0.5.6-1/debian/patches/01_strigi_branch_r727526.diff 2007-10-28 14:05:27 UTC (rev 7694)
@@ -0,0 +1,4864 @@
+--- a/cmake/FindCppUnit.cmake
++++ b/cmake/FindCppUnit.cmake
+@@ -7,7 +7,9 @@
+
+ include (MacroEnsureVersion)
+
+-SET(CPPUNIT_MIN_VERSION 1.12.0)
++if(NOT CPPUNIT_MIN_VERSION)
++ SET(CPPUNIT_MIN_VERSION 1.12.0)
++endif(NOT CPPUNIT_MIN_VERSION)
+
+ FIND_PROGRAM(CPPUNIT_CONFIG_EXECUTABLE cppunit-config )
+
+--- a/cmake/FindHyperEstraier.cmake
++++ b/cmake/FindHyperEstraier.cmake
+@@ -8,7 +8,7 @@
+ #
+
+ # find estconfig executable
+-FIND_PROGRAM(ESTCONFIG NAMES estconfig PATHS /bin /usr/bin /usr/local/bin )
++FIND_PROGRAM(ESTCONFIG NAMES estconfig PATHS /bin )
+
+ # get configuration options
+ IF (ESTCONFIG)
+--- a/config.h.cmake
++++ b/config.h.cmake
+@@ -147,7 +147,34 @@
+
+ #define LIBINSTALLDIR "${LIBINSTALLDIR}"
+
++#define SOURCEDIR "${CMAKE_SOURCE_DIR}"
++
++#define BINARYDIR "${CMAKE_BINARY_DIR}"
++
+ #define INSTALLDIR "${CMAKE_INSTALL_PREFIX}"
+
+ #define MIMEINSTALLDIR "${MIMEINSTALLDIR}"
++
++// Definition of types that are used internally
++
++#if !@HAVE_INTPTR_T@
++ typedef int intptr_t;
++ #define HAVE_INTPTR_T 1
++#endif
++
++#if !@HAVE_SOCKLEN_T@
++ typedef int socklen_t;
++ #define HAVE_SOCKLEN_T 1
++#endif
++
++#if !@HAVE_SSIZE_T@
++ #ifndef _SSIZE_T_DEFINED
++ #ifndef HAVE_SSIZE_T
++ typedef signed int ssize_t;
++ #define HAVE_SSIZE_T 1
++ #endif
++ #define _SSIZE_T_DEFINED 1 // kdewin32 define
++ #endif
++#endif
++
+ #endif //CONFIG_H
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -2,7 +2,6 @@
+ # Check copied from kdelibs FindX11.cmake.
+ CHECK_LIBRARY_EXISTS("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT)
+
+-
+ set(DIRS streams streamanalyzer archivereader xsd dummyindexer xmlindexer combinedindexer indexertests strigicmd)
+
+ if (CLucene_FOUND)
+@@ -11,32 +10,31 @@
+
+ if (HyperEstraier_FOUND)
+ set(DIRS ${DIRS} estraierindexer)
+- message("** HyperEstraier support is experimental. **")
++ message("** HyperEstraier support is broken. Do not rely on it. **")
+ endif (HyperEstraier_FOUND)
+
+ if (SQLite_FOUND)
+ set(DIRS ${DIRS} sqliteindexer)
+- message("** SQLite support is experimental. **")
++ message("** SQLite support is broken. Do not rely on it. **")
+ endif (SQLite_FOUND)
+
+-if (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- if(NOT WIN32)
+- set(DIRS ${DIRS} htmlgui)
+- endif(NOT WIN32)
+- # searchclient needs htmlgui which is not compilable on win32
+- if (QT_QTDBUS_FOUND AND NOT WIN32)
+- set(DIRS ${DIRS} searchclient)
+- endif (QT_QTDBUS_FOUND AND NOT WIN32)
+- # make sure we build the daemon on all architectures - not as long as sys/socket.h is used
+- if(NOT WIN32)
+- set(DIRS ${DIRS} daemon)
+- endif(NOT WIN32)
+- message(STATUS "Index libraries were found. strigidaemon will be built.")
+-else (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- message("** No index libraries were found. strigidaemon will not be built.")
++if(NOT WIN32)
++ set(DIRS ${DIRS} htmlgui)
++endif(NOT WIN32)
++# searchclient needs htmlgui which is not compilable on win32
++if (QT_QTDBUS_FOUND AND NOT WIN32)
++ set(DIRS ${DIRS} searchclient)
++endif (QT_QTDBUS_FOUND AND NOT WIN32)
++# make sure we build the daemon on all architectures - not as long as sys/socket.h is used
++if(NOT WIN32)
++ set(DIRS ${DIRS} daemon)
++endif(NOT WIN32)
++
++if (NOT CLucene_FOUND)
++ message("** No CLucene libraries were found, so Strigi cannot use indexes.")
+ message("** It is recommended to install CLucene >= 0.9.16.")
+ message("** You will still be able to use deepfind, deepgrep and xmlindexer.")
+-endif (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
++endif (NOT CLucene_FOUND)
+
+ if (QT4_FOUND)
+ set(DIRS ${DIRS} archiveengine qclient)
+--- a/src/combinedindexer/CMakeLists.txt
++++ b/src/combinedindexer/CMakeLists.txt
+@@ -4,29 +4,7 @@
+ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streams/strigi)
+
+-if (CLucene_FOUND)
+- add_definitions(-DHAVE_CLUCENE)
+- set(combinedindex_LIBS ${combinedindex_LIBS} cluceneindex)
+- include_directories( ../luceneindexer )
+-endif (CLucene_FOUND)
+-
+-if (HyperEstraier_FOUND)
+- add_definitions(-DHAVE_ESTRAIER)
+- set(combinedindex_LIBS ${combinedindex_LIBS} estraierindex)
+- include_directories( ../estraierindexer )
+-endif (HyperEstraier_FOUND)
+-
+-if (SQLite_FOUND)
+- add_definitions(-DHAVE_SQLITE)
+- set(combinedindex_LIBS ${combinedindex_LIBS} sqliteindex)
+- include_directories( ../sqliteindexer )
+-endif (SQLite_FOUND)
+-
+ add_library(combinedindex combinedindexmanager.cpp)
+
+ target_link_libraries(combinedindex streamanalyzer grepindex
+ ${combinedindex_LIBS})
+-
+-#add_executable(combinedindexer combinedindexer.cpp)
+-#target_link_libraries(combinedindexer combinedindex filters)
+-
+--- a/src/combinedindexer/combinedindexmanager.cpp
++++ b/src/combinedindexer/combinedindexmanager.cpp
+@@ -21,6 +21,7 @@
+ #include <strigi/strigiconfig.h>
+ #include "variant.h"
+
++/*
+ #include "grepindexmanager.h"
+ #ifdef HAVE_CLUCENE
+ #include "cluceneindexmanager.h"
+@@ -34,20 +35,26 @@
+ #ifdef HAVE_SQLITE
+ #include "sqliteindexmanager.h"
+ #endif
++*/
+
+ #include "tssptr.h"
+ #include "query.h"
+ #include "indexeddocument.h"
+ #include "indexreader.h"
++#include "indexpluginloader.h"
+ #include <string>
+ #include <set>
+ #include <map>
+ using namespace std;
+ using namespace Strigi;
+
++/*
+ map<string, IndexManager*(*)(const char*)>
+ CombinedIndexManager::factories() {
+ map<string, IndexManager*(*)(const char*)> factories;
++ //IndexPluginLoader pluginloader;
++ //factories = pluginloader.factories();
++
+ #ifdef HAVE_ESTRAIER
+ factories["estraier"] = createEstraierIndexManager;
+ #endif
+@@ -74,7 +81,7 @@
+ }
+ return v;
+ }
+-
++*/
+ class CombinedIndexReader : public IndexReader {
+ private:
+ CombinedIndexManager* m;
+@@ -119,19 +126,21 @@
+ }
+ CombinedIndexManager::Private::~Private() {
+ if (writermanager) {
+- delete writermanager;
++ IndexPluginLoader::deleteIndexManager(writermanager);
+ }
+ }
+ CombinedIndexManager::CombinedIndexManager(const string& type,
+ const string& indexdir) :p(new CombinedIndexManager::Private(this)) {
++ p->writermanager = IndexPluginLoader::createIndexManager(type.c_str(),
++ indexdir.c_str());
+ // determine the right index manager
+- map<string, IndexManager*(*)(const char*)> l_factories = factories();
++/* map<string, IndexManager*(*)(const char*)> l_factories = factories();
+ map<string, IndexManager*(*)(const char*)>::const_iterator f
+ = l_factories.find(type);
+ if (f == l_factories.end()) {
+ f = l_factories.begin();
+ }
+- p->writermanager = f->second(indexdir.c_str());
++ p->writermanager = f->second(indexdir.c_str());*/
+ }
+ CombinedIndexManager::~CombinedIndexManager() {
+ delete p;
+@@ -148,14 +157,12 @@
+ CombinedIndexManager::addReadonlyIndex(const string& indexdir,
+ const string& type) {
+ removeReadonlyIndex(indexdir);
+- // determine the right index manager
+- map<string, IndexManager*(*)(const char*)> l_factories = factories();
+- map<string, IndexManager*(*)(const char*)>::const_iterator f
+- = l_factories.find(type);
+- if (f == l_factories.end()) {
++
++ IndexManager* im = IndexPluginLoader::createIndexManager(type.c_str(),
++ indexdir.c_str());
++ if (im == 0) {
+ return;
+ }
+- IndexManager* im = f->second(indexdir.c_str());
+ p->lock.lock();
+ p->readmanagers[indexdir] = im;
+ p->lock.unlock();
+--- a/src/combinedindexer/combinedindexmanager.h
++++ b/src/combinedindexer/combinedindexmanager.h
+@@ -40,10 +40,6 @@
+
+ void addReadonlyIndex(const std::string& indexdir, const std::string& type);
+ void removeReadonlyIndex(const std::string& indexdir);
+-
+- static std::map<std::string, Strigi::IndexManager*(*)(const char*)>
+- factories();
+- static std::vector<std::string> backEnds();
+ };
+
+ #endif
+--- a/src/combinedindexer/tssptr.h
++++ b/src/combinedindexer/tssptr.h
+@@ -19,6 +19,7 @@
+ */
+
+ #include "strigi_thread.h"
++#include "indexpluginloader.h"
+
+ // thread safe smart pointer
+ template <class T>
+@@ -61,7 +62,7 @@
+ int c = --(p->count);
+ p->lock.unlock();
+ if (c == 0) {
+- delete p->p;
++ Strigi::IndexPluginLoader::deleteIndexManager(p->p);
+ delete p;
+ }
+ p = 0;
+--- a/src/daemon/daemon.cpp
++++ b/src/daemon/daemon.cpp
+@@ -21,6 +21,7 @@
+ #include "interface.h"
+ #include "daemonconfigurator.h"
+ #include "combinedindexmanager.h"
++#include "indexpluginloader.h"
+
+ #include "indexscheduler.h"
+ #include "analyzerconfiguration.h"
+@@ -151,7 +152,7 @@
+ }
+ void
+ printBackendList() {
+- std::vector<std::string> backends = CombinedIndexManager::backEnds();
++ std::vector<std::string> backends = IndexPluginLoader::indexNames();
+ for ( unsigned int i = 0; i < backends.size(); ++i ) {
+ printf( "%s\n", backends[i].c_str() );
+ }
+@@ -194,7 +195,7 @@
+ }
+ void
+ ensureBackend( const std::string& backendName ) {
+- std::vector<std::string> backends = CombinedIndexManager::backEnds();
++ std::vector<std::string> backends = IndexPluginLoader::indexNames();
+ if ( std::find( backends.begin(), backends.end(), backendName ) == backends.end() ) {
+ fprintf( stderr, "Unknown backend type: %s\n", backendName.c_str() );
+ exit( 2 );
+--- a/src/daemon/eventlistener/inotifylistener.cpp
++++ b/src/daemon/eventlistener/inotifylistener.cpp
+@@ -39,6 +39,38 @@
+ using namespace std;
+ using namespace Strigi;
+
++namespace {
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
++
++ char separator = '/';
++
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
++
++ return temp;
++ }
++}
++
+ class MatchString {
+ string m_fixed_val;
+
+@@ -345,59 +377,38 @@
+ m_toWatch.clear();
+ m_toIndex.clear();
+
+- Strigi::FileLister lister (m_pindexerconfiguration);
+-
+ for (set<string>::iterator iter = m_newDirs.begin();
+ iter != m_newDirs.end(); iter++)
+ {
+- string filename;
+- time_t mTime;
+-
+- lister.startListing( *iter);
+-
+- while (lister.nextFile( filename, mTime) != -1)
+- m_toIndex.insert (make_pair (filename, mTime));
+-
+- //TODO: look for a better solution
+- set<string> temp = lister.getListedDirs();
+- for (set<string>::iterator it = temp.begin(); it != temp.end(); it++)
+- m_toWatch.insert(*it);
+- }
+-
+- map <string, time_t> indexedFiles = m_pManager->indexReader()->files(0);
+- map<string,time_t>::iterator mi = indexedFiles.begin();
+-
+- while (mi != indexedFiles.end()) {
+- map<string,time_t>::iterator it = m_toIndex.find(mi->first);
+-
+- if (it == m_toIndex.end()) {
+- // file has been deleted since last run
+- m_events.push_back (new Event (Event::DELETED, mi->first));
++ DirLister lister(m_pindexerconfiguration);
++ string path;
++ vector<pair<string, struct stat> > dirs;
++
++ lister.startListing (*iter);
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
+
+- // no more useful, speedup into dirsRemoved
+- map<string,time_t>::iterator itrm = mi;
+- mi++;
+- indexedFiles.erase(itrm);
+- }
+- else if (mi->second < it->second) {
+- // file has been updated since last run
+- m_events.push_back (new Event (Event::UPDATED, mi->first));
+- m_toIndex.erase (it);
+- mi++;
+- }
+- else {
+- // file has NOT been changed since last run,
+- // we keep our indexed information
+- m_toIndex.erase (it);
+- mi++;
++ if (S_ISDIR(stats.st_mode)) {
++ //dir
++ m_toWatch.insert (iter->first);
++ }
++ else if (S_ISREG(stats.st_mode)) {
++ //file
++ m_events.push_back (new Event (Event::CREATED, iter->first));
++ }
++ }
++ ret = lister.nextDir(path, dirs);
+ }
+ }
+
+- // now m_toIndex contains only files created since the last run
+- for (mi = m_toIndex.begin(); mi != m_toIndex.end(); mi++)
+- m_events.push_back (new Event (Event::CREATED, mi->first));
+-
+ m_nomoreIndexedDirs.clear();
++ set<string> alreadyWatched;
++
+ for (map<int, string>::iterator it = watchedDirs.begin();
+ it != watchedDirs.end(); it++)
+ {
+@@ -405,7 +416,68 @@
+ if (match == m_toWatch.end()) // dir is no longer watched
+ m_nomoreIndexedDirs.insert(it->second);
+ else // dir is already watched
+- m_toWatch.erase (match);
++ alreadyWatched.insert (*match);
++ }
++
++ // look for updated dirs
++ m_toIndex.clear();
++ for (set<string>::iterator iter = alreadyWatched.begin();
++ iter != alreadyWatched.end(); iter++)
++ {
++ // retrieve files contained into the already watched dirs
++
++ Strigi::DirLister lister (m_pindexerconfiguration);
++
++ lister.startListing (*iter);
++
++ string path;
++ vector<pair<string, struct stat> > dirs;
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ cout << "path = " << path << endl;
++
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
++ if (S_ISREG(stats.st_mode))
++ m_toIndex.insert (make_pair (iter->first, stats.st_mtime));
++ }
++ ret = lister.nextDir(path, dirs);
++ }
++
++ map <string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren (*iter, indexedFiles);
++ for (map<string, time_t>::iterator iter = m_toIndex.begin();
++ iter != m_toIndex.end(); iter++)
++ {
++ map<string, time_t>::iterator match;
++ match = indexedFiles.find(iter->first);
++ if (match == indexedFiles.end()) {
++ // new file created
++ m_events.push_back (new Event (Event::CREATED, iter->first));
++ }
++ else if (match->second < iter->second) {
++ // file has been updated
++ m_events.push_back (new Event (Event::UPDATED, iter->first));
++ }
++ }
++ m_toIndex.clear();
++ }
++
++ // remove no more indexed items
++ for (set<string>::iterator iter = m_nomoreIndexedDirs.begin();
++ iter != m_nomoreIndexedDirs.end(); iter++)
++ {
++ map <string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren (*iter, indexedFiles);
++
++ for (map<string,time_t>::iterator mi = indexedFiles.begin();
++ mi != indexedFiles.end(); mi++)
++ {
++ m_events.push_back (new Event (Event::DELETED, mi->first));
++ }
+ }
+
+ if (testInterrupt()) {
+@@ -738,25 +810,35 @@
+ // a new directory has been created or an already watched
+ // directory has been moved into a watched place
+
+- m_toIndex.clear();
+ m_toWatch.clear();
+
+- FileLister lister(m_pindexerconfiguration);
+-
+- string filename;
+- time_t mTime;
+- while (lister.nextFile( filename, mTime) != -1)
+- m_toIndex.insert (make_pair (filename, mTime));
+-
+- m_toWatch = lister.getListedDirs();
+-
+- for (map<string,time_t>::iterator i = m_toIndex.begin();
+- i != m_toIndex.end(); i++)
+- {
+- Event* event = new Event (Event::CREATED, i->first);
+- events.push_back (event);
++ DirLister lister(m_pindexerconfiguration);
++ string path;
++ vector<pair<string, struct stat> > dirs;
++
++ lister.startListing (file);
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
++
++ if (S_ISDIR(stats.st_mode)) {
++ //dir
++ m_toWatch.insert (iter->first);
++ }
++ else if (S_ISREG(stats.st_mode)) {
++ //file
++ Event* event = new Event (Event::CREATED,
++ iter->first);
++ events.push_back (event);
++ }
++ }
++ ret = lister.nextDir(path, dirs);
+ }
+-
++
+ // add new watches
+ addWatches (m_toWatch);
+
+@@ -1066,8 +1148,9 @@
+ // we've to de-index all files contained into the deleted/moved directory
+ if (m_pManager)
+ {
+- // all indexed files
+- map<string, time_t> indexedFiles = m_pManager->indexReader()->files(0);
++ // all indexed files contained into dir
++ map<string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren(dir, indexedFiles);
+
+ // remove all entries that were contained into the removed dir
+ for (map<string, time_t>::iterator it = indexedFiles.begin();
+@@ -1076,12 +1159,8 @@
+ if (enableInterrupt && testInterrupt())
+ break;
+
+- string::size_type pos = (it->first).find (dir);
+- if (pos == 0)
+- {
+- Event* event = new Event (Event::DELETED, it->first);
+- newEvents.push_back (event);
+- }
++ Event* event = new Event (Event::DELETED, it->first);
++ newEvents.push_back (event);
+ }
+ }
+ else
+--- a/src/daemon/eventlistener/pollinglistener.cpp
++++ b/src/daemon/eventlistener/pollinglistener.cpp
+@@ -38,6 +38,38 @@
+ using namespace std;
+ using namespace Strigi;
+
++namespace {
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
++
++ char separator = '/';
++
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
++
++ return temp;
++ }
++}
++
+ PollingListener::PollingListener() :EventListener("PollingListener") {
+ setState(Idling);
+ STRIGI_MUTEX_INIT(&m_mutex);
+@@ -123,35 +155,7 @@
+
+ STRIGI_MUTEX_UNLOCK (&m_mutex);
+ }
+-/*!
+-* @param path string containing path to check
+-* Appends the terminating char to path.
+-* Under Windows that char is '\', '/' under *nix
+-*/
+-string fixPath (string path)
+-{
+- if ( path.c_str() == NULL || path.length() == 0 )
+- return "";
+-
+- string temp(path);
+-
+-#ifdef HAVE_WINDOWS_H
+- size_t l= temp.length();
+- char* t = (char*)temp.c_str();
+- for (size_t i=0;i<l;i++){
+- if ( t[i] == '\\' )
+- t[i] = '/';
+- }
+- temp[0] = tolower(temp.at(0));
+-#endif
+-
+- char separator = '/';
+
+- if (temp[temp.length() - 1 ] != separator)
+- temp += separator;
+-
+- return temp;
+-}
+ void
+ PollingListener::addWatches(const set<string>& watches, bool enableInterrupt) {
+ for (set<string>::iterator iter = watches.begin();
+--- a/src/daemon/interface.cpp
++++ b/src/daemon/interface.cpp
+@@ -18,9 +18,10 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include "interface.h"
+-#include "indexreader.h"
+ #include "combinedindexmanager.h"
++#include "indexreader.h"
+ #include "indexwriter.h"
++#include "indexpluginloader.h"
+ #include "indexscheduler.h"
+ #include "eventlistener.h"
+ #include "streamanalyzer.h"
+@@ -69,7 +70,7 @@
+ }
+ vector<string>
+ Interface::getBackEnds() {
+- return manager.backEnds();
++ return IndexPluginLoader::indexNames();
+ }
+ map<string, string>
+ Interface::getStatus() {
+--- a/src/estraierindexer/CMakeLists.txt
++++ b/src/estraierindexer/CMakeLists.txt
+@@ -3,15 +3,26 @@
+ include_directories( ../streamanalyzer ../streams ${EST_INCLUDE_DIR}
+ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streams/strigi)
++link_directories(${EST_LIBDIR})
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EST_CFLAGS}")
+
+-add_library(estraierindex
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(estraier MODULE
+ estraierindexmanager.cpp
+ estraierindexreader.cpp
+ estraierindexwriter.cpp
+ )
+-
+-target_link_libraries(estraierindex streamanalyzer ${EST_LIBS})
+-
+-add_executable(estraierindexer estraierindexer.cpp)
+-target_link_libraries(estraierindexer estraierindex)
+-
++set_target_properties(estraier PROPERTIES PREFIX ${prefix})
++target_link_libraries(estraier ${EST_LIBS})
++install(TARGETS estraier LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+--- a/src/estraierindexer/estraierindexmanager.cpp
++++ b/src/estraierindexer/estraierindexmanager.cpp
+@@ -22,20 +22,21 @@
+ #include "estraierindexreader.h"
+ #include "estraierindexwriter.h"
+ #include "strigi_thread.h"
++#include "indexplugin.h"
++#include <iostream>
+ #include <assert.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <errno.h>
+ #include "stgdirent.h" //our dirent compatibility header... uses native if available
+ using namespace std;
+ using namespace Strigi;
+
+-pthread_mutex_t EstraierIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(EstraierIndexManager)
+
+-Strigi::IndexManager*
+-createEstraierIndexManager(const char* path) {
+- return new EstraierIndexManager(path);
+-}
++pthread_mutex_t EstraierIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
+
+ EstraierIndexManager::EstraierIndexManager(const char* dbd)
+ : dblock(lock), dbdir(dbd) {
+--- a/src/estraierindexer/estraierindexmanager.h
++++ b/src/estraierindexer/estraierindexmanager.h
+@@ -56,7 +56,4 @@
+ void deleteIndex();
+ };
+
+-Strigi::IndexManager*
+-createEstraierIndexManager(const char* path);
+-
+ #endif
+--- a/src/estraierindexer/estraierindexreader.cpp
++++ b/src/estraierindexer/estraierindexreader.cpp
+@@ -37,7 +37,7 @@
+ // build the phrase string
+
+ // write the part of the query that matches the document context
+- string inphrase, exphrase;
++/* string inphrase, exphrase;
+ set<string> terms;
+ const map<string, set<string> >& includes = query.includes();
+ map<string, set<string> >::const_iterator i = includes.find("");
+@@ -60,9 +60,9 @@
+ phrase += " ANDNOT ";
+ }
+ phrase += *j;
+- }
++ } */
+ ESTCOND* cond = est_cond_new();
+- printf("%s", phrase.c_str());
++/* printf("%s", phrase.c_str());
+ if (phrase.length() > 0) {
+ est_cond_set_phrase(cond, phrase.c_str());
+ }
+@@ -93,7 +93,7 @@
+ est_cond_add_attr(cond, att.c_str());
+ }
+ }
+- printf("\n");
++ printf("\n");*/
+
+ return cond;
+ }
+@@ -136,7 +136,7 @@
+ return n;
+ }
+ vector<IndexedDocument>
+-EstraierIndexReader::query(const Query& query) {
++EstraierIndexReader::query(const Query& query, int off, int max) {
+ ESTCOND* cond = createCondition(query);
+ est_cond_set_max(cond, 10);
+ int n;
+@@ -182,9 +182,17 @@
+ free(ids);
+ return results;
+ }
+-map<string, time_t>
+-EstraierIndexReader::files(char depth) {
+- map<string, time_t> files;
++void
++EstraierIndexReader::getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max) {
++}
++void
++EstraierIndexReader::getChildren(const std::string& parent,
++ std::map<std::string, time_t>& children) {
++/* map<string, time_t> files;
+ ESTCOND* cond = est_cond_new();
+ string q = "depth NUMEQ 0";
+ est_cond_add_attr(cond, q.c_str());
+@@ -208,7 +216,7 @@
+ // clean up
+ est_cond_delete(cond);
+ free(ids);
+- return files;
++ return files;*/
+ }
+ int32_t
+ EstraierIndexReader::countDocuments() {
+@@ -231,16 +239,10 @@
+ manager->deref();
+ return count;
+ }
+-int64_t
+-EstraierIndexReader::documentId(const string& uri) {
+- ESTDB* db = manager->ref();
+- int64_t id = est_db_uri_to_id(db, uri.c_str());
+- manager->deref();
+- return id;
+-}
+ time_t
+-EstraierIndexReader::mTime(int64_t docid) {
++EstraierIndexReader::mTime(const std::string& uri) {
+ ESTDB* db = manager->ref();
++ int64_t docid = est_db_uri_to_id(db, uri.c_str());
+ time_t mtime = -1;
+ char *cstr = est_db_get_doc_attr(db, docid, "@mdate");
+ if (cstr) {
+@@ -248,12 +250,7 @@
+ free(cstr);
+ }
+ manager->deref();
+- return mtime;
+-
+-}
+-time_t
+-EstraierIndexReader::mTime(const std::string& uri) {
+- return mTime(documentId(uri));
++ return docid;
+ }
+ vector<string>
+ EstraierIndexReader::fieldNames() {
+@@ -264,3 +261,14 @@
+ const string& labeltype) {
+ return vector<pair<string,uint32_t> >();
+ }
++int32_t
++EstraierIndexReader::countKeywords(const std::string& keywordprefix,
++ const std::vector<std::string>& fieldnames) {
++ return -1;
++}
++vector<string>
++EstraierIndexReader::keywords(const std::string& keywordmatch,
++ const std::vector<std::string>& fieldnames,
++ uint32_t max, uint32_t offset) {
++ return vector<string>();
++}
+--- a/src/estraierindexer/estraierindexreader.h
++++ b/src/estraierindexer/estraierindexreader.h
+@@ -36,14 +36,14 @@
+ static ESTCOND* createCondition(const Strigi::Query&);
+ static const char* mapId(const std::string& id);
+ public:
++ std::vector<Strigi::IndexedDocument> query(const Strigi::Query&,
++ int off, int max);
++ void getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max);
+ int32_t countHits(const Strigi::Query&);
+- std::vector<Strigi::IndexedDocument> query(const Strigi::Query&);
+- std::map<std::string, time_t> files(char depth);
+- int countDocuments();
+- int32_t countWords();
+- int64_t indexSize();
+- int64_t documentId(const std::string& uri);
+- time_t mTime(int64_t docid);
+ time_t mTime(const std::string& uri);
+ std::vector<std::string> fieldNames();
+ std::vector<std::pair<std::string,uint32_t> > histogram(
+@@ -54,6 +54,11 @@
+ std::vector<std::string> keywords(const std::string& keywordmatch,
+ const std::vector<std::string>& fieldnames,
+ uint32_t max, uint32_t offset);
++ void getChildren(const std::string& parent,
++ std::map<std::string, time_t>& children);
++ int countDocuments();
++ int32_t countWords();
++ int64_t indexSize();
+ };
+
+ #endif
+--- a/src/estraierindexer/estraierindexwriter.cpp
++++ b/src/estraierindexer/estraierindexwriter.cpp
+@@ -49,16 +49,16 @@
+ EstraierIndexWriter::addValue(const AnalysisResult* idx,
+ const RegisteredField* field, const string& value) {
+ ESTDOC* doc = static_cast<ESTDOC*>(idx->writerData());
+- if (field->getKey() == "size") {
++ if (field->key() == "size") {
+ est_doc_add_attr(doc, "@size", value.c_str());
+- } else if (field->getKey() == "title") {
++ } else if (field->key() == "title") {
+ est_doc_add_attr(doc, "@title", value.c_str());
+ } else {
+- est_doc_add_attr(doc, field->getKey().c_str(), value.c_str());
++ est_doc_add_attr(doc, field->key().c_str(), value.c_str());
+ }
+ }
+ void
+-EstraierIndexWriter::startAnalysis(AnalysisResult* idx) {
++EstraierIndexWriter::startAnalysis(const AnalysisResult* idx) {
+ // allocate a new estraier document
+ ESTDOC* doc = est_doc_new();
+ idx->setWriterData(doc);
+--- a/src/estraierindexer/estraierindexwriter.h
++++ b/src/estraierindexer/estraierindexwriter.h
+@@ -31,7 +31,7 @@
+ const std::string indexpath;
+
+ protected:
+- void startAnalysis(Strigi::AnalysisResult*);
++ void startAnalysis(const Strigi::AnalysisResult*);
+ void addValue(const Strigi::AnalysisResult*, const Strigi::RegisteredField* field,
+ const std::string& value);
+ void addValue(const Strigi::AnalysisResult*, const Strigi::RegisteredField* field,
+--- a/src/estraierindexer/tests/CMakeLists.txt
++++ b/src/estraierindexer/tests/CMakeLists.txt
+@@ -1,9 +1,10 @@
+ include_directories(.. ../../indexertests)
++link_directories(${EST_LIBDIR})
+
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp EstraierTest.cpp)
+
+ ADD_EXECUTABLE(testrunner ${Tests} )
+-target_link_libraries(testrunner streams estraierindex indexertests)
++target_link_libraries(testrunner streams indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/estraierindexer/tests/EstraierTest.cpp
++++ b/src/estraierindexer/tests/EstraierTest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "estraierindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -15,7 +16,8 @@
+
+ // initialize a directory for writing and an indexmanager
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+- EstraierIndexManager* manager = new EstraierIndexManager(path);
++ Strigi::IndexManager *manager
++ = Strigi::IndexPluginLoader::createIndexManager("estraier", path);
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+--- a/src/htmlgui/strigihtmlgui.cpp
++++ b/src/htmlgui/strigihtmlgui.cpp
+@@ -27,6 +27,7 @@
+ #include <dirent.h>
+ #include <sstream>
+ #include <fstream>
++#include <iostream>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -56,7 +57,9 @@
+ }
+ void
+ StrigiHtmlGui::printHtmlHeader(ostream& out) {
+- out << "<?xml version='1.0' encoding='utf-8'?>\n"
++ // FIXME: extra spaces added at the beginning as a wordaround because
++ // KIO discards several first chars for unknown reason
++ out << " <?xml version='1.0' encoding='utf-8'?>\n"
+ "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+@@ -190,12 +193,15 @@
+ if (i != params.end()) {
+ max = atoi(i->second.c_str());
+ }
+- if (max == 0) max = 10;
++ if (max <= 0 || max > 1000) max = 10;
+ int off = 0;
+ i = params.find("o");
+ if (i != params.end()) {
+ off = atoi(i->second.c_str());
+ }
++ if (off < 0) {
++ off = 0;
++ }
+ string selectedtab;
+ i = params.find("t");
+ if (i != params.end()) {
+@@ -215,20 +221,23 @@
+ bool doother = true;
+ tabs = readTabQueries();
+ if (tabs.size() == 0) {
+- tabs["Images"] = "content.mime_type:image*";
+- tabs["Mail"] = "content.mime_type:message/*";
+- tabs["Web"] = "content.mime_type:text/html";
+- tabs["Text"] = "content.mime_type:text/*";
++ tabs["Images"] = "mimeType:image*";
++ tabs["Mail"] = "mimeType:message/*";
++ tabs["Web"] = "mimeType:text/html";
++ tabs["Text"] = "mimeType:text/*";
+ }
+ map<string, string>::const_iterator j;
+ string otherq = query;
+ for (j = tabs.begin(); j != tabs.end(); ++j) {
+- string q = query+' '+j->second;
++ string q = query;
++ if (q != j->second) {
++ q += ' ' + j->second;
++ }
+ int c = p->strigi.countHits(q);
+ if (c > 0) {
+ hitcounts[j->first] = c;
+ doother &= c < count;
+- otherq += " -" + j->second;
++ otherq += " -" + j->second;
+ if (j->first == selectedtab || activetab.size() == 0) {
+ activetab = j->first;
+ activequery = q;
+@@ -424,9 +433,9 @@
+ icon = "<div class='iconbox'><img class='icon' src='"+icon;
+ icon += "'/></div>\n";
+ }
+- t = doc.properties.find("audio.title");
++ t = doc.properties.find("title");
+ if (t == doc.properties.end()) {
+- t = doc.properties.find("email.subject");
++ t = doc.properties.find("subject");
+ }
+ size_t l = doc.uri.rfind('/');
+ if (t != doc.properties.end()) {
+--- a/src/luceneindexer/cluceneindexmanager.cpp
++++ b/src/luceneindexer/cluceneindexmanager.cpp
+@@ -27,12 +27,17 @@
+ #include <CLucene.h>
+ #include "cluceneindexwriter.h"
+ #include "cluceneindexreader.h"
++#include "indexplugin.h"
+ #include <iostream>
+ #include <sys/types.h>
+ #include <time.h>
+ #include "timeofday.h"
+ #include "stgdirent.h" //our dirent compatibility header... uses native if available
+
++
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(CLuceneIndexManager)
++
+ using namespace lucene::index;
+ using lucene::analysis::standard::StandardAnalyzer;
+ using lucene::store::FSDirectory;
+@@ -51,6 +56,11 @@
+ indexwriter = 0;
+ writer = new CLuceneIndexWriter(this);
+ analyzer = new StandardAnalyzer();
++ if (path == ":memory:") {
++ ramdirectory = new lucene::store::RAMDirectory();
++ } else {
++ ramdirectory = 0;
++ }
+ mtime = 0;
+
+ //remove any old segments lying around from crashes, etc
+@@ -67,6 +77,7 @@
+ r->second = 0;
+ }
+ closeWriter();
++ delete ramdirectory;
+ delete analyzer;
+ if (--numberOfManagers == 0) {
+ // temporarily commented out because of problem with clucene
+@@ -116,16 +127,22 @@
+ void
+ CLuceneIndexManager::openWriter(bool truncate) {
+ try {
+- if (!truncate && IndexReader::indexExists(dbdir.c_str())) {
++ if (ramdirectory) {
++ indexwriter = new IndexWriter(ramdirectory, analyzer, true);
++ } else if (!truncate && IndexReader::indexExists(dbdir.c_str())) {
+ if (IndexReader::isLocked(dbdir.c_str())) {
+ IndexReader::unlock(dbdir.c_str());
+ }
+ indexwriter = new IndexWriter(dbdir.c_str(), analyzer, false);
+ } else {
+- indexwriter = new IndexWriter(dbdir.c_str(), analyzer, true, true);
++ indexwriter = new IndexWriter(dbdir.c_str(), analyzer, true);
+ }
+ } catch (CLuceneError& err) {
+- printf("could not create writer: %s\n", err.what());
++ fprintf(stderr, "could not create writer: %s\n", err.what());
++ indexwriter = 0;
++ } catch (...) {
++ fprintf(stderr, "Unknown exception was thrown.");
++ indexwriter = 0;
+ }
+ }
+ void
+@@ -201,3 +218,4 @@
+ mtime = t.tv_sec;
+ lock.unlock();
+ }
++
+--- a/src/luceneindexer/cluceneindexmanager.h
++++ b/src/luceneindexer/cluceneindexmanager.h
+@@ -22,7 +22,6 @@
+
+ #include <strigi/strigiconfig.h>
+ #include "indexmanager.h"
+-//#include "querybitset.h"
+ #include <strigi_thread.h>
+ #include <string>
+ #include <map>
+@@ -38,6 +37,9 @@
+ class IndexWriter;
+ class IndexReader;
+ }
++ namespace store {
++ class RAMDirectory;
++ }
+ }
+
+ class CLuceneIndexReader;
+@@ -50,13 +52,14 @@
+ std::map<STRIGI_THREAD_TYPE, CLuceneIndexReader*> readers;
+ CLuceneIndexWriter* writer;
+ lucene::index::IndexWriter* indexwriter;
+- //Strigi::QueryBitsetCache bitsets;
+ lucene::analysis::Analyzer* analyzer;
+ time_t mtime;
+ static int numberOfManagers;
+
+ void openWriter(bool truncate=false);
+ public:
++ lucene::store::RAMDirectory* ramdirectory;
++
+ explicit CLuceneIndexManager(const std::string& path);
+ ~CLuceneIndexManager();
+
+@@ -65,7 +68,6 @@
+ Strigi::IndexReader* indexReader();
+ Strigi::IndexWriter* indexWriter();
+ CLuceneIndexReader* luceneReader();
+-// Strigi::QueryBitsetCache* bitSets();
+ int32_t docCount();
+ int64_t indexSize();
+ void deleteIndex();
+@@ -74,7 +76,4 @@
+ void setIndexMTime();
+ };
+
+-CLUCENEINDEXER_EXPORT Strigi::IndexManager*
+-createCLuceneIndexManager(const char* path);
+-
+ #endif
+--- a/src/luceneindexer/cluceneindexreader.cpp
++++ b/src/luceneindexer/cluceneindexreader.cpp
+@@ -137,7 +137,11 @@
+ doccount = -1;
+ wordcount = -1;
+ try {
+- reader = lucene::index::IndexReader::open(dbdir.c_str());
++ if (manager->ramdirectory) {
++ reader = lucene::index::IndexReader::open(manager->ramdirectory);
++ } else {
++ reader = lucene::index::IndexReader::open(dbdir.c_str());
++ }
+ //fprintf(stderr,
+ //"reader at %s: %i\n", dbdir.c_str(), reader->numDocs());
+ } catch (CLuceneError& err) {
+@@ -585,14 +589,14 @@
+ vector<int32_t>::const_iterator i;
+ struct tm t;
+ for (i = v.begin(); i < v.end(); ++i) {
+- time_t ti = *i;
++ time_t ti = *i;
+ #ifdef _WIN32
+ t = *localtime( &ti ); // is thread-safe on win32
+ #else
+- localtime_r(&ti, &t);
++ localtime_r(&ti, &t);
+ #endif
+- int32_t c = 10000*t.tm_year + 100*t.tm_mon + t.tm_mday;
+- m[c]++;
++ int32_t c = 10000*t.tm_year + 100*t.tm_mon + t.tm_mday;
++ m[c]++;
+ }
+ vector<pair<string,uint32_t> > h;
+ h.reserve(m.size());
+--- a/src/luceneindexer/cluceneindexwriter.cpp
++++ b/src/luceneindexer/cluceneindexwriter.cpp
+@@ -240,8 +240,11 @@
+ if (t && _tcsncmp(t, prefixText, prefixLen) == 0) {
+ try {
+ reader->deleteDocument(i);
++ } catch (CLuceneError& err) {
++ cerr << "Could not delete document '" << entry
++ << "' from the index: " << err.what() << endl;
+ } catch (...) {
+- fprintf(stderr, "could not delete document");
++ cerr << "This should not happen." << endl;
+ }
+ }
+ _CLDELETE(d);
+--- a/src/luceneindexer/CMakeLists.txt
++++ b/src/luceneindexer/CMakeLists.txt
+@@ -19,42 +19,44 @@
+ ADD_DEFINITIONS(-DUNICODE)
+ ENDIF(WIN32)
+
+-# CLucene requires exception support and has no support for visibility=hidden
+-# so we must use the default (i.e. public) value for -fvisibility
++# CLucene requires exception support
+ IF(NOT WIN32)
+ IF (CMAKE_COMPILER_IS_GNUCXX)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
+ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ ENDIF(NOT WIN32)
+-IF(__STRIGI_HAVE_GCC_VISIBILITY)
+- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
+-ENDIF(__STRIGI_HAVE_GCC_VISIBILITY)
++# In the past, we though we needed to use -fvisibility=default for compiling
++# this library. This appears not to be the case anymore.
++#IF(__STRIGI_HAVE_GCC_VISIBILITY)
++# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
++#ENDIF(__STRIGI_HAVE_GCC_VISIBILITY)
+
+ set(cluceneindex_SRCS
+-# PrefixFilter.cpp
+- cluceneindexmanager.cpp
+- cluceneindexreader.cpp
+- cluceneindexwriter.cpp
+- jsgzipcompressstream.cpp
+- tcharutils.cpp
++ cluceneindexmanager.cpp
++ cluceneindexreader.cpp
++ cluceneindexwriter.cpp
++ jsgzipcompressstream.cpp
++ tcharutils.cpp
+ )
+
+-add_library(cluceneindex SHARED ${cluceneindex_SRCS})
+-
+-set_target_properties(cluceneindex
+- PROPERTIES VERSION ${STRIGI_VERSION}
+- SOVERSION ${STRIGI_VERSION_MAJOR}
+- DEFINE_SYMBOL MAKE_CLUCENEINDEXER_LIB
+-)
+-
+-target_link_libraries(cluceneindex streamanalyzer ${CLUCENE_LIBRARY})
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(clucene MODULE ${cluceneindex_SRCS})
++set_target_properties(clucene PROPERTIES PREFIX ${prefix})
++target_link_libraries(clucene ${CLUCENE_LIBRARY})
++install(TARGETS clucene LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+
+ add_executable(luceneindexer luceneindexer.cpp)
+-target_link_libraries(luceneindexer cluceneindex)
++target_link_libraries(luceneindexer streamanalyzer)
+
+ install(TARGETS luceneindexer RUNTIME DESTINATION bin)
+-install(TARGETS cluceneindex
+- LIBRARY DESTINATION ${LIB_DESTINATION}
+- RUNTIME DESTINATION bin
+- ARCHIVE DESTINATION ${LIB_DESTINATION}
+-)
+--- a/src/luceneindexer/indexdump/CMakeLists.txt
++++ b/src/luceneindexer/indexdump/CMakeLists.txt
+@@ -1,4 +1,4 @@
+ include_directories(${CLUCENE_LIBRARY_DIR} ${CLUCENE_INCLUDE_DIR}
+ ${ICONV_INCLUDE_DIR} ..)
+-add_executable(indexdump indexdump.cpp)
+-target_link_libraries(indexdump ${CLUCENE_LIBRARY} cluceneindex)
++add_executable(indexdump indexdump.cpp ../tcharutils.cpp)
++target_link_libraries(indexdump streamanalyzer ${CLUCENE_LIBRARY})
+--- a/src/luceneindexer/luceneindexer.cpp
++++ b/src/luceneindexer/luceneindexer.cpp
+@@ -18,9 +18,8 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include <strigi/strigiconfig.h>
+-#include <CLucene.h>
+ #include "diranalyzer.h"
+-#include "cluceneindexmanager.h"
++#include "indexpluginloader.h"
+ #include "analyzerconfiguration.h"
+ #include <iostream>
+ #include <sys/types.h>
+@@ -65,10 +64,13 @@
+ Strigi::AnalyzerConfiguration ic;
+ ic.setFilters(filters);
+ try {
+- Strigi::IndexManager *manager = createCLuceneIndexManager(argv[1]);
+- Strigi::DirAnalyzer analyzer(*manager, ic);
+- analyzer.analyzeDir(argv[2]);
+- delete manager;
++ Strigi::IndexManager *manager
++ = Strigi::IndexPluginLoader::createIndexManager("clucene", argv[1]);
++ if (manager) {
++ Strigi::DirAnalyzer analyzer(*manager, ic);
++ analyzer.analyzeDir(argv[2]);
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
++ }
+ } catch (...) {
+ cerr << "error while creating index" << endl;
+ }
+--- a/src/luceneindexer/tcharutils.h
++++ b/src/luceneindexer/tcharutils.h
+@@ -25,9 +25,9 @@
+ #include <string>
+ #include <strigi/strigiconfig.h>
+
+-std::string CLUCENEINDEXER_EXPORT wchartoutf8(const wchar_t*);
+-std::wstring CLUCENEINDEXER_EXPORT utf8toucs2(const char*);
+-std::string CLUCENEINDEXER_EXPORT wchartoutf8(const std::wstring&);
+-std::wstring CLUCENEINDEXER_EXPORT utf8toucs2(const std::string&);
++std::string wchartoutf8(const wchar_t*);
++std::wstring utf8toucs2(const char*);
++std::string wchartoutf8(const std::wstring&);
++std::wstring utf8toucs2(const std::string&);
+
+ #endif
+--- a/src/luceneindexer/tests/CLuceneTest.cpp
++++ b/src/luceneindexer/tests/CLuceneTest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "cluceneindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -23,7 +24,12 @@
+ #else
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ #endif
+- Strigi::IndexManager* manager = createCLuceneIndexManager(path);
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("clucene", path);
++ if (manager == 0) {
++ founderrors++;
++ return founderrors;
++ }
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+@@ -39,7 +45,7 @@
+ rtests.testAll();
+
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ std::string cmd = "rm -r ";
+--- a/src/luceneindexer/tests/CMakeLists.txt
++++ b/src/luceneindexer/tests/CMakeLists.txt
+@@ -3,7 +3,7 @@
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp CLuceneTest.cpp)
+
+ ADD_EXECUTABLE(testrunner-lucene ${Tests} )
+-target_link_libraries(testrunner-lucene streams cluceneindex indexertests)
++target_link_libraries(testrunner-lucene streamanalyzer indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/sqliteindexer/CMakeLists.txt
++++ b/src/sqliteindexer/CMakeLists.txt
+@@ -4,14 +4,23 @@
+ ${SQLITE_LIBRARY_DIR} ${SQLITE_INCLUDE_DIR}
+ ${strigi_BINARY_DIR}/src/streams)
+
+-add_library(sqliteindex
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(sqlite MODULE
+ sqliteindexmanager.cpp
+ sqliteindexreader.cpp
+ sqliteindexwriter.cpp
+ )
+-
+-target_link_libraries(sqliteindex streamanalyzer ${SQLITE_LIBRARIES})
+-
+-add_executable(sqliteindexer sqliteindexer.cpp)
+-target_link_libraries(sqliteindexer sqliteindex sqlite3)
+-
++set_target_properties(sqlite PROPERTIES PREFIX ${prefix})
++target_link_libraries(sqlite ${SQLITE_LIBRARIES})
++install(TARGETS sqlite LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+--- a/src/sqliteindexer/sqliteindexmanager.cpp
++++ b/src/sqliteindexer/sqliteindexmanager.cpp
+@@ -21,15 +21,15 @@
+ #include "sqliteindexreader.h"
+ #include "sqliteindexwriter.h"
+ #include "strigi_thread.h"
++#include "indexplugin.h"
++#include <iostream>
+ using namespace std;
+ using namespace Strigi;
+
+-pthread_mutex_t SqliteIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(SqliteIndexManager)
+
+-Strigi::IndexManager*
+-createSqliteIndexManager(const char* path) {
+- return new SqliteIndexManager(path);
+-}
++pthread_mutex_t SqliteIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
+
+ SqliteIndexManager::SqliteIndexManager(const char* dbfile) {
+ dblock = lock;
+@@ -51,6 +51,7 @@
+ }
+ sqlite3*
+ SqliteIndexManager::opendb(const char* path) {
++ // check if the database already exists
+ sqlite3* db;
+ int r = sqlite3_open(path, &db);
+ // any value other than SQLITE_OK is an error
+@@ -85,9 +86,8 @@
+ ;
+ r = sqlite3_exec(db, sql, 0, 0, 0);
+ if (r != SQLITE_OK) {
+- fprintf(stderr, "could not create table %i %s\n", r,
+- sqlite3_errmsg(db));
+- exit(1);
++ //fprintf(stderr, "could not create table %i %s.\n", r,
++ // sqlite3_errmsg(db));
+ }
+
+ // create temporary tables
+--- a/src/sqliteindexer/sqliteindexmanager.h
++++ b/src/sqliteindexer/sqliteindexmanager.h
+@@ -54,7 +54,5 @@
+ static std::string escapeSqlValue(const std::string& value);
+ static sqlite3* opendb(const char*);
+ };
+-Strigi::IndexManager*
+-createSqliteIndexManager(const char* path);
+
+ #endif
+--- a/src/sqliteindexer/sqliteindexreader.cpp
++++ b/src/sqliteindexer/sqliteindexreader.cpp
+@@ -20,6 +20,7 @@
+ #include "sqliteindexreader.h"
+ #include "sqliteindexmanager.h"
+ #include <set>
++#include <iostream>
+ #include <sstream>
+ using namespace std;
+ using namespace Strigi;
+@@ -61,7 +62,7 @@
+ q << "f"<<a<<".count*1.0/w"<<a<<".count";
+ }
+ if (n > 0) {
+- q <<") p ";
++ q <<") p ";
+ }
+ q <<" from ";
+ for (int i=0; i<n; ++i) {
+@@ -93,16 +94,55 @@
+
+ return q.str();
+ }
++string
++createQuery(const Query& query, int off, int max) {
++ // TODO: makeing a query with wildcards slows things down, so we must
++ // think about reordering them
++ // although we'll never be able to manage queries like 'a% b% c%'
++ ostringstream q;
++ q << "select path from ";
++ //
++ for (int i=0; i<n; ++i) {
++ q << "words w" << i << ",";
++ }
++ for (int i=0; i<n; ++i) {
++ q << "filewords f" << i << ",";
++ }
++ q <<"files where ";
++ for (int i=0; i<n; ++i) {
++ q << "w" << i << ".word like ? and w" << i << ".wordid = f" << i
++ << ".wordid and ";
++ }
++ for (int i=1; i<n; ++i) {
++ q << "f0.fileid = f" << i << ".fileid and ";
++ }
++ if (n > 0) {
++ q <<"f0.fileid = files.fileid ";
++ }
++ if (filterpath) {
++ if (n > 0) q <<"and ";
++ q <<"files.path like ? ";
++ }
++ if (n > 0) q <<"group by fa.fileid order by p ";
++ q << "limit " << max << " offset " << off;
++
++ return q.str();
++}
+ int
+ SqliteIndexReader::countHits(const Strigi::Query& q) {
+ // very inefficient: needs refactoring
+ vector<IndexedDocument> r = query(q, 0, 1000000);
+ return r.size();
+ }
++string
++createQuery(const Query& query) {
++ return "select path from files;";
++}
+ vector<IndexedDocument>
+ SqliteIndexReader::query(const Strigi::Query& query, int off, int max) {
+- string q;
+- // replace * by %
++ string sql(createQuery(query, off, max));
++ vector<IndexedDocument> results;
++/* // replace * by %
+ size_t p = q.find('*');
+ while (p != string::npos) {
+ q.replace(p, 1, "%");
+@@ -116,7 +156,6 @@
+ }
+ // split up in terms
+ set<string> terms = split(q);
+- vector<IndexedDocument> results;
+ if (terms.size() == 0) return results;
+ string pathfilter;
+ set<string>::iterator i = terms.begin();
+@@ -132,17 +171,17 @@
+ if (terms.size() == 0 && pathfilter.length() == 0) return results;
+
+ string sql = createQuery(terms.size(), pathfilter.length() > 0);
+-
++*/
+ sqlite3* db = manager->ref();
+ sqlite3_stmt* stmt;
+ int r = sqlite3_prepare(db, sql.c_str(), -1, &stmt, 0);
+ if (r != SQLITE_OK) {
+- printf("could not prepare query '%s': %s\n", sql.c_str(),
++ fprintf(stderr, "could not prepare query '%s': %s\n", sql.c_str(),
+ sqlite3_errmsg(db));
+ manager->deref();
+ return results;
+ }
+- int j = 1;
++/* int j = 1;
+ for (i=terms.begin(); i!=terms.end(); ++i) {
+ sqlite3_bind_text(stmt, j++, i->c_str(), i->length(),
+ SQLITE_STATIC);
+@@ -150,7 +189,7 @@
+ if (pathfilter.length() > 0) {
+ sqlite3_bind_text(stmt, j, pathfilter.c_str(), pathfilter.length(),
+ SQLITE_STATIC);
+- }
++ }*/
+ r = sqlite3_step(stmt);
+ while (r == SQLITE_ROW) {
+ IndexedDocument doc;
+@@ -245,3 +284,10 @@
+ vector<string> k;
+ return k;
+ }
++void
++SqliteIndexReader::getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max) {
++}
+--- a/src/sqliteindexer/sqliteindexreader.h
++++ b/src/sqliteindexer/sqliteindexreader.h
+@@ -48,6 +48,11 @@
+ std::vector<std::string> keywords(const std::string& keywordmatch,
+ const std::vector<std::string>& fieldnames,
+ uint32_t max, uint32_t offset);
++ void getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max);
+ };
+
+ #endif
+--- a/src/sqliteindexer/sqliteindexwriter.cpp
++++ b/src/sqliteindexer/sqliteindexwriter.cpp
+@@ -183,6 +183,7 @@
+ = content.find(wdata->id);
+
+ if (m == content.end()) {
++ delete wdata;
+ return;
+ }
+
+@@ -199,6 +200,7 @@
+ sqlite3_errmsg(db));
+ content.erase(m->first);
+ manager->deref();
++ delete wdata;
+ return;
+ }
+ map<string, int>::const_iterator i = m->second.begin();
+@@ -209,7 +211,7 @@
+ SQLITE_STATIC);
+ sqlite3_bind_int(stmt, 3, i->second);
+ r = sqlite3_step(stmt);
+- if (r != 21) { // what is 21?
++ if (r != SQLITE_DONE) { // what is 21?
+ fprintf(stderr, "could not write content into database: %i %s\n", r,
+ sqlite3_errmsg(db));
+ }
+--- a/src/sqliteindexer/tests/CMakeLists.txt
++++ b/src/sqliteindexer/tests/CMakeLists.txt
+@@ -3,7 +3,7 @@
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp SqliteTest.cpp simpletest.cpp)
+
+ ADD_EXECUTABLE(sqlitetest ${Tests} )
+-target_link_libraries(sqlitetest streams sqliteindex indexertests)
++target_link_libraries(sqlitetest streams indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/sqliteindexer/tests/simpletest.cpp
++++ b/src/sqliteindexer/tests/simpletest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "sqliteindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "analyzerconfiguration.h"
+@@ -38,13 +39,14 @@
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ string p(path);
+ p += "/test.db";
+- IndexManager* manager = createSqliteIndexManager(p.c_str());
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("sqlite", p.c_str());
+ IndexWriter* writer = manager->indexWriter();
+ IndexReader* reader = manager->indexReader();
+ addAndCount(writer, reader, 1);
+
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ /* std::string cmd = "rm -r ";
+--- a/src/sqliteindexer/tests/SqliteTest.cpp
++++ b/src/sqliteindexer/tests/SqliteTest.cpp
+@@ -1,5 +1,5 @@
+ #include <strigi/strigiconfig.h>
+-#include "sqliteindexmanager.h"
++#include "indexpluginloader.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -18,7 +18,8 @@
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ string p(path);
+ p += "/test.db";
+- Strigi::IndexManager* manager = createSqliteIndexManager(p.c_str());
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("sqlite", p.c_str());
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+@@ -34,7 +35,7 @@
+ rtests.testAll();
+ */
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ std::string cmd = "rm -r ";
+--- a/src/streamanalyzer/classproperties.cpp
++++ b/src/streamanalyzer/classproperties.cpp
+@@ -25,7 +25,6 @@
+ using namespace Strigi;
+ using namespace std;
+
+-const string ClassProperties::Private::empty;
+ ClassProperties::ClassProperties() :p(new Private()) {
+ }
+ ClassProperties::ClassProperties(const Private& pr) :p(new Private(pr)) {}
+@@ -70,12 +69,12 @@
+ const string&
+ ClassProperties::localizedName(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.name;
++ return (i == p->localized.end()) ?empty() :i->second.name;
+ }
+ const string&
+ ClassProperties::localizedDescription(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.description;
++ return (i == p->localized.end()) ?empty() :i->second.description;
+ }
+ const vector<string>&
+ ClassProperties::parentUris() const {
+--- a/src/streamanalyzer/CMakeLists.txt
++++ b/src/streamanalyzer/CMakeLists.txt
+@@ -26,6 +26,7 @@
+ htmlsaxanalyzer.cpp
+ id3v2throughanalyzer.cpp
+ indexreader.cpp
++ indexpluginloader.cpp
+ lineeventanalyzer.cpp
+ m3ustreamanalyzer.cpp
+ mimeeventanalyzer.cpp
+@@ -97,6 +98,9 @@
+ fieldproperties.h
+ fieldtypes.h
+ indexeddocument.h
++ indexreader.h
++ indexmanager.h
++ indexplugin.h
+ indexwriter.h
+ streamanalyzer.h
+ streamanalyzerfactory.h
+--- a/src/streamanalyzer/fieldproperties.cpp
++++ b/src/streamanalyzer/fieldproperties.cpp
+@@ -25,7 +25,6 @@
+ using namespace Strigi;
+ using namespace std;
+
+-const string FieldProperties::Private::empty;
+ FieldProperties::FieldProperties() :p(new Private()) {
+ }
+ FieldProperties::FieldProperties(const Private& pr) :p(new Private(pr)) {}
+@@ -102,12 +101,12 @@
+ const string&
+ FieldProperties::localizedName(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.name;
++ return (i == p->localized.end()) ?empty() :i->second.name;
+ }
+ const string&
+ FieldProperties::localizedDescription(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.description;
++ return (i == p->localized.end()) ?empty() :i->second.description;
+ }
+ const vector<string>&
+ FieldProperties::parentUris() const {
+--- a/src/streamanalyzer/fieldpropertiesdb.cpp
++++ b/src/streamanalyzer/fieldpropertiesdb.cpp
+@@ -39,7 +39,8 @@
+ #include <map>
+ #include <iostream>
+ #include <list>
+-#include <string>
++#include <set>
++
+ using namespace Strigi;
+ using namespace std;
+
+@@ -47,8 +48,8 @@
+ public:
+ map<string, FieldProperties> properties;
+ map<string, ClassProperties> classes;
+- static FieldProperties emptyField;
+- static ClassProperties emptyClass;
++ static const FieldProperties& emptyField();
++ static const ClassProperties& emptyClass();
+
+ Private();
+ static vector<string> getdirs(const string&);
+@@ -94,8 +95,16 @@
+
+ };
+
+-FieldProperties FieldPropertiesDb::Private::emptyField;
+-ClassProperties FieldPropertiesDb::Private::emptyClass;
++const FieldProperties&
++FieldPropertiesDb::Private::emptyField() {
++ static const FieldProperties e;
++ return e;
++}
++const ClassProperties&
++FieldPropertiesDb::Private::emptyClass() {
++ static const ClassProperties f;
++ return f;
++}
+
+ FieldPropertiesDb&
+ FieldPropertiesDb::db() {
+@@ -112,7 +121,7 @@
+ map<std::string, FieldProperties>::const_iterator j
+ = p->properties.find(uri);
+ if (j == p->properties.end()) {
+- return FieldPropertiesDb::Private::emptyField;
++ return FieldPropertiesDb::Private::emptyField();
+ } else {
+ return j->second;
+ }
+@@ -126,7 +135,7 @@
+ FieldPropertiesDb::classes(const std::string& uri) const {
+ map<std::string, ClassProperties>::const_iterator j = p->classes.find(uri);
+ if (j == p->classes.end()) {
+- return FieldPropertiesDb::Private::emptyClass;
++ return FieldPropertiesDb::Private::emptyClass();
+ } else {
+ return j->second;
+ }
+@@ -178,8 +187,12 @@
+
+ vector<string> dirs = getXdgDirs();
+ vector<string>::const_iterator i;
++ set<string> done;
+ for (i=dirs.begin(); i!=dirs.end(); i++) {
+- loadProperties(*i);
++ if (done.find(*i) == done.end()) {
++ done.insert(*i);
++ loadProperties(*i);
++ }
+ }
+
+ // Generate childUris, applicable* and locales values.
+@@ -255,6 +268,9 @@
+ props.uri = FieldRegister::filenameFieldName;
+ properties[FieldRegister::filenameFieldName] = props;
+
++ props.uri = FieldRegister::mimetypeFieldName;
++ properties[FieldRegister::mimetypeFieldName] = props;
++
+ props.uri = FieldRegister::parentLocationFieldName;
+ props.tokenized = false;
+ properties[FieldRegister::parentLocationFieldName] = props;
+@@ -263,13 +279,23 @@
+ FieldPropertiesDb::Private::loadProperties(const string& dir) {
+ string pdir = dir + "/strigi/fieldproperties/";
+ DIR* d = opendir(pdir.c_str());
+- if (!d) return;
++ if (!d) {
++ pdir = dir;
++ d = opendir(pdir.c_str());
++ }
++ if (!d) {
++ return;
++ }
++ if (pdir[pdir.length()-1] != '/') {
++ pdir.append("/");
++ }
+ struct dirent* de = readdir(d);
+ struct stat s;
+ char* data = 0;
+ while (de) {
+ string path(pdir+de->d_name);
+- if (!stat(path.c_str(), &s) && S_ISREG(s.st_mode)) {
++ if (path.length() >= 5 && path.substr(path.length()-5) == ".rdfs" &&
++ !stat(path.c_str(), &s) && S_ISREG(s.st_mode)) {
+ FILE* f = fopen(path.c_str(), "r");
+ if (f) {
+ // read the entire file at once
+--- a/src/streamanalyzer/fieldproperties_private.h
++++ b/src/streamanalyzer/fieldproperties_private.h
+@@ -24,12 +24,18 @@
+ #include "fieldproperties.h"
+ #include "fieldtypes.h"
+
++namespace {
++ const std::string& empty() {
++ static std::string e;
++ return e;
++ }
++}
++
+ namespace Strigi {
+
+ class FieldProperties::Private {
+ friend class FieldPropertiesDb;
+ public:
+- static const std::string empty;
+ std::string uri;
+ std::string name;
+ std::string typeuri;
+@@ -69,7 +75,6 @@
+ class ClassProperties::Private {
+ friend class FieldPropertiesDb;
+ public:
+- static const std::string empty;
+ std::string uri;
+ std::string name;
+ std::string description;
+--- a/src/streamanalyzer/fieldtypes.cpp
++++ b/src/streamanalyzer/fieldtypes.cpp
+@@ -103,7 +103,7 @@
+ = FieldPropertiesDb::db().properties(fieldname);
+ if (!props.valid()) {
+ cerr << "WARNING: field '" << fieldname << "' is not defined in "
+- ".fieldproperties ontology database." << endl;
++ "any rdfs ontology database." << endl;
+ // creates a field with defaults (stringType and no parents)
+ FieldPropertiesDb::db().addField(fieldname);
+ }
+--- a/src/streamanalyzer/filelister.cpp
++++ b/src/streamanalyzer/filelister.cpp
+@@ -47,34 +47,37 @@
+ using namespace std;
+ using namespace Strigi;
+
+-/*!
+-* @param path string containing path to check
+-* Appends the terminating char to path.
+-* Under Windows that char is '\', '/' under *nix
+-*/
+-string fixPath (string path)
++namespace
+ {
+- if ( path.c_str() == NULL || path.length() == 0 )
+- return "";
+-
+- string temp(path);
+-
+-#ifdef HAVE_WINDOWS_H
+- size_t l= temp.length();
+- char* t = (char*)temp.c_str();
+- for (size_t i=0;i<l;i++){
+- if ( t[i] == '\\' )
+- t[i] = '/';
+- }
+- temp[0] = tolower(temp.at(0));
+-#endif
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
+
+- char separator = '/';
++ char separator = '/';
+
+- if (temp[temp.length() - 1 ] != separator)
+- temp += separator;
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
+
+- return temp;
++ return temp;
++ }
+ }
+
+ class FileLister::Private {
+--- a/src/streamanalyzer/filelister.h
++++ b/src/streamanalyzer/filelister.h
+@@ -45,7 +45,6 @@
+
+ namespace Strigi {
+
+-
+ class FileLister {
+ private:
+ class Private;
+@@ -72,7 +71,7 @@
+ void skipTillAfter(const std::string& lastToSkip);
+ };
+
+-class DirLister {
++class STRIGI_EXPORT DirLister {
+ private:
+ class Private;
+ Private* p;
+--- a/src/streamanalyzer/indexmanager.h
++++ b/src/streamanalyzer/indexmanager.h
+@@ -24,6 +24,9 @@
+ class IndexReader;
+ class IndexWriter;
+
++class IndexManager;
++void deleteIndexManager(Strigi::IndexManager* m);
++
+ /**
+ * Abstract interface that manages access to the IndexReader and IndexWriter
+ * instances provided by a particular index backend.
+@@ -38,6 +41,7 @@
+ * be used in the active thread.
+ **/
+ class IndexManager {
++friend void deleteIndexManager(Strigi::IndexManager* m);
+ public:
+ virtual ~IndexManager() {}
+ /**
+--- /dev/null
++++ b/src/streamanalyzer/indexplugin.h
+@@ -0,0 +1,40 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#ifndef STRIGI_INDEXPLUGIN_H
++#define STRIGI_INDEXPLUGIN_H
++#include <strigi/strigiconfig.h>
++
++/**
++ * @brief Macro to register functions for creating and deleting an indexmanager
++ * in a plugin
++ *
++ * @param CLASS the name of the subclass of Strigi::IndexManager
++ */
++#define REGISTER_STRIGI_INDEXMANAGER(CLASS) extern "C" { \
++ STRIGI_EXPORT Strigi::IndexManager* createIndexManager(const char* dir) { \
++ return new CLASS(dir); \
++ } \
++ STRIGI_EXPORT void deleteIndexManager(Strigi::IndexManager* m) { \
++ delete m; \
++ } \
++}
++#endif
++
+--- /dev/null
++++ b/src/streamanalyzer/indexpluginloader.cpp
+@@ -0,0 +1,245 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include "indexpluginloader.h"
++#include "indexmanager.h"
++#include <iostream>
++#include <stgdirent.h>
++#include <sys/stat.h>
++using namespace std;
++using namespace Strigi;
++
++#ifndef _WIN32
++#include <dlfcn.h>
++#define DLSYM dlsym
++#define DLCLOSE dlclose
++#else
++#define DLSYM GetProcAddress
++#define DLCLOSE FreeLibrary
++#endif
++
++#ifndef _WIN32
++typedef void* StgModuleType;
++#else
++#include <windows.h>
++typedef HMODULE StgModuleType;
++#endif
++
++// anonymous namespace for static variables
++namespace {
++ class Module {
++ private:
++ const StgModuleType mod;
++ Module(const Module&);
++ void operator=(const Module&);
++ public:
++ Strigi::IndexManager* (*create)(const char*);
++ void (*destroy)(Strigi::IndexManager*);
++ Module(StgModuleType m)
++ :mod(m) {}
++ ~Module() {
++// TODO: figure out why we get segfaults when cleaning up nicely
++ DLCLOSE(mod);
++ }
++ };
++ vector<string>
++ getdirs(const string& direnv) {
++ vector<string> dirs;
++ string::size_type lastp = 0;
++ string::size_type p = direnv.find(':');
++ while (p != string::npos) {
++ dirs.push_back(direnv.substr(lastp, p-lastp));
++ lastp = p+1;
++ p = direnv.find(':', lastp);
++ }
++ dirs.push_back(direnv.substr(lastp));
++ return dirs;
++ }
++ class ModuleList {
++ private:
++ map<std::string, Module*> modules;
++ public:
++ map<std::string, Module*>& mods() {
++ if (!initialized) initialize();
++ return modules;
++ };
++ map<void*, Module*> indexmanagers;
++ bool initialized;
++
++ ModuleList() {
++ initialized = false;
++ }
++ void initialize() {
++ initialized = true;
++ // load the plugins from the environment setting
++ string strigipluginpath;
++ if (getenv("STRIGI_PLUGIN_PATH")) {
++ strigipluginpath = getenv("STRIGI_PLUGIN_PATH");
++ }
++ vector<string> strigipluginpaths = getdirs(strigipluginpath);
++ if (strigipluginpath.size()) {
++ for (uint i=0; i<strigipluginpaths.size(); ++i) {
++ IndexPluginLoader::loadPlugins(strigipluginpaths[i].c_str());
++ }
++ } else {
++ IndexPluginLoader::loadPlugins( LIBINSTALLDIR "/strigi");
++ }
++ }
++ ~ModuleList() {
++ // delete all leftover indexmanagers
++ // if code deletes the indexmanager on it's own, the error will
++ // appear here
++ map<void*, Module*>::iterator j;
++ for (j = indexmanagers.begin(); j != indexmanagers.end(); ++j) {
++ j->second->destroy(static_cast<IndexManager*>(j->first));
++ }
++ // unload all the modules
++ map<string, Module*>::iterator i;
++ for (i = modules.begin(); i != modules.end(); ++i) {
++ delete i->second;
++ }
++ }
++ void loadModule(const string& name, const string& dir);
++ };
++ void
++ ModuleList::loadModule(const string& name, const string& lib) {
++ // check if this module was already loaded
++ map<string, Module*>::iterator i = modules.find(name);
++ if (i != modules.end()) {
++ return;
++ }
++ StgModuleType handle;
++#ifdef HAVE_DLFCN_H
++ // do not use RTLD_GLOBAL here
++ // note: If neither RTLD_GLOBAL nor RTLD_LOCAL are specified,
++ // the default is RTLD_LOCAL.
++ handle = dlopen(lib.c_str(), RTLD_LAZY);
++#else
++ handle = LoadLibrary(lib.c_str());
++#endif
++ if (!handle) {
++#ifdef HAVE_DLFCN_H
++ cerr << "Could not load '" << lib << "':" << dlerror() << endl;
++#else
++ cerr << "Could not load '" << lib << "': GetLastError(): "
++ << GetLastError() << endl;
++#endif
++ return;
++ }
++ IndexManager*(*create)(const char*) = (IndexManager*(*)(const char*))
++ DLSYM(handle, "createIndexManager");
++ if (!create) {
++#ifndef WIN32
++ fprintf(stderr, "%s\n", dlerror());
++#else
++ fprintf(stderr, "GetLastError: %d\n", GetLastError());
++#endif
++ DLCLOSE(handle);
++ return;
++ }
++ void(*destroy)(IndexManager*) = (void(*)(IndexManager*))
++ DLSYM(handle, "deleteIndexManager");
++ if (!destroy) {
++#ifndef WIN32
++ fprintf(stderr, "%s\n", dlerror());
++#else
++ fprintf(stderr, "GetLastError: %d\n", GetLastError());
++#endif
++ DLCLOSE(handle);
++ return;
++ }
++ Module* module = new Module(handle);
++ module->create = create;
++ module->destroy = destroy;
++ modules[name] = module;
++ }
++ static ModuleList modules;
++}
++void
++IndexPluginLoader::loadPlugins(const char* d) {
++ DIR *dir = opendir(d);
++ if (dir == 0) {
++ return;
++ }
++ struct dirent* ent = readdir(dir);
++ string prefix("strigiindex_");
++#ifdef WIN32
++ string suffix(".dll");
++#else
++ string suffix(".so");
++#endif
++ while(ent) {
++ size_t len = strlen(ent->d_name);
++ const char* prepos = strstr(ent->d_name, prefix.c_str());
++ const char* sufpos = strstr(ent->d_name, suffix.c_str());
++ if (prepos && sufpos + suffix.length() == ent->d_name + len) {
++ len -= (prepos - ent->d_name) + prefix.length() + suffix.length();
++ string name(prepos + prefix.length(), len);
++ string pluginpath = d;
++ if (pluginpath[pluginpath.length()-1] != '/') {
++ pluginpath.append("/");
++ }
++ pluginpath.append(ent->d_name);
++ // check that the file is a regular file
++ struct stat s;
++ if (stat(pluginpath.c_str(), &s) == 0 && (S_IFREG & s.st_mode)) {
++ modules.loadModule(name, pluginpath);
++ }
++ }
++ ent = readdir(dir);
++ }
++ closedir(dir);
++}
++vector<string>
++IndexPluginLoader::indexNames() {
++ vector<string> names;
++ map<string, Module*>::const_iterator i = modules.mods().begin();
++ for (; i != modules.mods().end(); ++i) {
++ names.push_back(i->first);
++ }
++ return names;
++}
++IndexManager*
++IndexPluginLoader::createIndexManager(const char* name, const char* dir) {
++ // find the right plugin
++ map<string, Module*>::iterator i = modules.mods().find(name);
++ if (i == modules.mods().end()) {
++ return 0;
++ }
++ // create the indexmanager
++ IndexManager* im = i->second->create(dir);
++ if (im) {
++ // map the indexmanager to the module that created it, so we can delete
++ // it later
++ modules.indexmanagers[im] = i->second;
++ }
++ return im;
++}
++void
++IndexPluginLoader::deleteIndexManager(IndexManager* im) {
++ // find the right module
++ map<void*, Module*>::iterator i = modules.indexmanagers.find(im);
++ if (i == modules.indexmanagers.end()) {
++ return;
++ }
++ // let the module delete the indexmanager
++ i->second->destroy(im);
++ // remove the mapping from the map
++ modules.indexmanagers.erase(i);
++}
+--- /dev/null
++++ b/src/streamanalyzer/indexpluginloader.h
+@@ -0,0 +1,34 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include <strigi/strigiconfig.h>
++#include <vector>
++#include <map>
++#include <string>
++
++namespace Strigi {
++ class IndexManager;
++ namespace IndexPluginLoader {
++ STRIGI_EXPORT void loadPlugins(const char* dir);
++ STRIGI_EXPORT std::vector<std::string> indexNames();
++ STRIGI_EXPORT Strigi::IndexManager* createIndexManager(const char* name,
++ const char* dir);
++ STRIGI_EXPORT void deleteIndexManager(Strigi::IndexManager* manager);
++ }
++}
+--- a/src/streamanalyzer/indexreader.h
++++ b/src/streamanalyzer/indexreader.h
+@@ -79,7 +79,7 @@
+ * @p parent will be placed.
+ **/
+ virtual void getChildren(const std::string& parent,
+- std::map<std::string, time_t>& children) {}
++ std::map<std::string, time_t>& children) {};
+ /**
+ * Count the number of documents indexed in the index.
+ *
+--- a/src/streamanalyzer/queryparser.cpp
++++ b/src/streamanalyzer/queryparser.cpp
+@@ -120,7 +120,19 @@
+ }
+ return space+1;
+ }
+-
++void
++prependXesamNamespace(Query& query) {
++ // prepend the field names with the xesam namespace
++ // this will be elaborated once the xesam spec continues
++ vector<string>::iterator end(query.fields().end());
++ for (vector<string>::iterator i = query.fields().begin(); i != end; ++i) {
++ *i = "http://freedesktop.org/standards/xesam/1.0/core#" + *i;
++ }
++ std::vector<Query>::iterator qend(query.subQueries().end());
++ for (vector<Query>::iterator i = query.subQueries().begin(); i!=qend; ++i) {
++ prependXesamNamespace(*i);
++ }
++}
+ Query
+ QueryParser::buildQuery(const std::string& q) {
+ Query query;
+@@ -140,14 +152,7 @@
+ Query q = query.subQueries()[0];
+ query = q;
+ }
++ prependXesamNamespace(query);
+
+- // prepend the field names with the xesam namespace
+- // this will be elaborated once the xesam spec continues
+- vector<string>::iterator end(query.fields().end());
+- for (vector<string>::iterator i = query.fields().begin(); i != end; ++i) {
+- *i = "http://freedesktop.org/standards/xesam/1.0/core#" + *i;
+- }
+- //cerr << "query: '" << q << "' : " << query.subQueries().size() << "'"
+- // << query.term().string() << "'" << endl;
+ return query;
+ }
+--- a/src/streams/base64inputstream.cpp
++++ b/src/streams/base64inputstream.cpp
+@@ -71,6 +71,7 @@
+ Base64InputStream::Base64InputStream(InputStream* i) :p(new Private(this, i)) {
+ }
+ Base64InputStream::~Base64InputStream() {
++ delete p;
+ }
+ Base64InputStream::Private::Private(Base64InputStream* bi, InputStream* i)
+ :p(bi), input(i) {
+--- a/src/streams/CMakeLists.txt
++++ b/src/streams/CMakeLists.txt
+@@ -73,7 +73,6 @@
+ stringterminatedsubstream.h
+ subinputstream.h
+ textutils.h
+- strigi/jstreamsconfig.h
+ DESTINATION include/strigi
+ )
+ install(TARGETS streams
+--- a/src/streams/rpminputstream.cpp
++++ b/src/streams/rpminputstream.cpp
+@@ -141,15 +141,9 @@
+ m_status = cpio->status();
+ }
+ RpmInputStream::~RpmInputStream() {
+- if (uncompressionStream) {
+- delete uncompressionStream;
+- }
+- if (cpio) {
+- delete cpio;
+- }
+- if (headerinfo) {
+- delete headerinfo;
+- }
++ delete uncompressionStream;
++ delete cpio;
++ delete headerinfo;
+ }
+ InputStream*
+ RpmInputStream::nextEntry() {
+--- a/src/streams/strigi/strigiconfig.h.cmake
++++ b/src/streams/strigi/strigiconfig.h.cmake
+@@ -47,7 +47,7 @@
+ // our needed types
+ #if !@HAVE_INT8_T@
+ #define HAVE_INT8_T 1
+- #if ${SIZEOF_CHAR}==1 //is char 1bit?
++ #if ${SIZEOF_CHAR}==1 //is char one byte?
+ typedef char int8_t;
+ #else
+ #error Could not determine type for int8_t!
+@@ -56,7 +56,7 @@
+
+ #if !@HAVE_UINT8_T@
+ #define HAVE_UINT8_T 1
+- #if ${SIZEOF_CHAR}==1 //is char 1bit?
++ #if ${SIZEOF_CHAR}==1 //is char one byte?
+ typedef unsigned char uint8_t;
+ #else
+ #error Could not determine type for uint8_t!
+@@ -65,7 +65,7 @@
+
+ #if !@HAVE_INT16_T@
+ #define HAVE_INT16_T 1
+- #if ${SIZEOF_SHORT}==2 //is short 2bits?
++ #if ${SIZEOF_SHORT}==2 //is short two bytes?
+ typedef short int16_t;
+ #else
+ #error Could not determine type for int16_t!
+@@ -74,7 +74,7 @@
+
+ #if !@HAVE_UINT16_T@
+ #define HAVE_UINT16_T 1
+- #if ${SIZEOF_SHORT}==2 //is short 2bits?
++ #if ${SIZEOF_SHORT}==2 //is short two bytes?
+ typedef unsigned short uint16_t;
+ #else
+ #error Could not determine type for uint16_t!
+@@ -83,9 +83,9 @@
+
+ #if !@HAVE_INT32_T@
+ #define HAVE_INT32_T 1
+- #if ${SIZEOF_INT}==4 //is int 4bits?
++ #if ${SIZEOF_INT}==4 //is int four bytes?
+ typedef int int32_t;
+- #elif ${SIZEOF_LONG}==4 //is long 4bits?
++ #elif ${SIZEOF_LONG}==4 //is long four bytes?
+ typedef long int32_t;
+ #else
+ #error Could not determine type for int32_t!
+@@ -94,9 +94,9 @@
+
+ #if !@HAVE_UINT32_T@
+ #define HAVE_UINT32_T 1
+- #if ${SIZEOF_INT}==4 //is int 4bits?
++ #if ${SIZEOF_INT}==4 //is int four bytes?
+ typedef unsigned int uint32_t;
+- #elif ${SIZEOF_LONG}==4 //is long 4bits?
++ #elif ${SIZEOF_LONG}==4 //is long four bytes?
+ typedef unsigned long uint32_t;
+ #else
+ #error Could not determine type for uint32_t!
+@@ -132,16 +132,6 @@
+ #define HAVE_UINT 1
+ #endif
+
+-#if !@HAVE_INTPTR_T@
+- typedef int intptr_t;
+- #define HAVE_INTPTR_T 1
+-#endif
+-
+-#if !@HAVE_SOCKLEN_T@
+- typedef int socklen_t;
+- #define HAVE_SOCKLEN_T 1
+-#endif
+-
+ #if !@HAVE_SIZE_T@
+ #ifndef _SIZE_T_DEFINED
+ #ifndef HAVE_SIZE_T
+@@ -152,16 +142,6 @@
+ #endif
+ #endif
+
+-#if !@HAVE_SSIZE_T@
+- #ifndef _SSIZE_T_DEFINED
+- #ifndef HAVE_SSIZE_T
+- typedef signed int ssize_t;
+- #define HAVE_SSIZE_T 1
+- #endif
+- #define _SSIZE_T_DEFINED 1 // kdewin32 define
+- #endif
+-#endif
+-
+ #cmakedefine __STRIGI_HAVE_GCC_VISIBILITY
+
+ #cmakedefine ENABLE_NEWXESAM
+@@ -175,7 +155,7 @@
+ */
+ #ifdef __STRIGI_HAVE_GCC_VISIBILITY
+ #define STRIGI_EXPORT __attribute__ ((visibility("default")))
+-#define STRIGI_IMPORT STRIGI_EXPORT
++#define STRIGI_IMPORT
+ #elif defined(_WIN32) || defined(_WIN64)
+ #define STRIGI_EXPORT __declspec(dllexport)
+ #define STRIGI_IMPORT __declspec(dllimport)
+@@ -200,14 +180,6 @@
+ # endif
+ #endif
+
+-#ifndef CLUCENEINDEXER_EXPORT
+-# ifdef MAKE_CLUCENEINDEXER_LIB
+-# define CLUCENEINDEXER_EXPORT STRIGI_EXPORT
+-# else
+-# define CLUCENEINDEXER_EXPORT STRIGI_IMPORT
+-# endif
+-#endif
+-
+ #ifndef STRIGI_QTDBUSCLIENT_EXPORT
+ # ifdef MAKE_STRIGI_QTDBUSCLIENT_LIB
+ # define STRIGI_QTDBUSCLIENT_EXPORT STRIGI_EXPORT
+--- a/src/strigicmd/strigicmd.cpp
++++ b/src/strigicmd/strigicmd.cpp
+@@ -18,7 +18,8 @@
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+-#include "combinedindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexreader.h"
+ #include "indexwriter.h"
+ #include "indexeddocument.h"
+@@ -154,6 +155,10 @@
+ }
+ void
+ printBackends(const string& msg, const vector<string> backends) {
++ if (backends.size() == 0) {
++ pe(" No backends are available.\n");
++ return;
++ }
+ pe(msg.c_str());
+ pe(" Choose one from ");
+ for (uint j=0; j<backends.size()-1; ++j) {
+@@ -218,7 +223,7 @@
+ IndexManager*
+ getIndexManager(string& backend, const string& indexdir) {
+ // check arguments: backend
+- const vector<string>& backends = CombinedIndexManager::backEnds();
++ const vector<string>& backends = IndexPluginLoader::indexNames();
+ // if there is only one backend, the backend does not have to be specified
+ if (backend.size() == 0) {
+ if (backends.size() == 1) {
+@@ -230,11 +235,13 @@
+ }
+ vector<string>::const_iterator b
+ = find(backends.begin(), backends.end(), backend);
++cerr << "n backends: " << backends.size() << endl;
+ if (b == backends.end()) {
+ printBackends("Invalid index type.", backends);
+ return 0;
+ }
+- return CombinedIndexManager::factories()[backend](indexdir.c_str());
++ return IndexPluginLoader::createIndexManager(backend.c_str(),
++ indexdir.c_str());
+ }
+ int
+ create(int argc, char** argv) {
+@@ -286,7 +293,7 @@
+ analyzer->analyzeDir(j->c_str(), nthreads);
+ }
+ delete analyzer;
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+
+ return 0;
+ }
+@@ -329,7 +336,7 @@
+ DirAnalyzer* analyzer = new DirAnalyzer(*manager, config);
+ analyzer->updateDirs(arguments, nthreads);
+ delete analyzer;
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+
+ return 0;
+ }
+@@ -363,7 +370,7 @@
+ }
+ IndexReader* reader = manager->indexReader();
+ listFiles(reader, "");
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -411,7 +418,7 @@
+ }
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -478,7 +485,7 @@
+ }
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -572,7 +579,7 @@
+ if (results != 0)
+ printf ("Query returned %i results\n", results);
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -645,7 +652,7 @@
+ writer->optimize();
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -672,7 +679,7 @@
+ for (i=fields.begin(); i!=fields.end(); ++i) {
+ printf("%s\n", i->c_str());
+ }
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -1,28 +1,21 @@
+-set (TESTINGDIRS ${TESTINGDIRS} utils indextesters streamanalyzer)
++set (TESTINGDIRS utils indextesters streamanalyzer daemon)
++subdirs (${TESTINGDIRS})
++
++# setting for using CPPUNIT
+
+-if (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- set(TESTINGDIRS ${TESTINGDIRS} daemon)
+-endif (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
++include_directories (. ${CPPUNIT_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/daemon
++ ${CMAKE_BINARY_DIR}/src/streams)
+
+ # cppunit requires exception support
+ IF(NOT WIN32)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
+ ENDIF(NOT WIN32)
+
+-# disable, needs some testing
+-#if (HyperEstraier_FOUND)
+-# set (TESTINGDIRS ${TESTINGDIRS} estraierindexer)
+-#endif (HyperEstraier_FOUND)
+-
+-if (CLucene_FOUND)
+- set(TESTINGDIRS ${TESTINGDIRS} luceneindexer)
+-endif (CLucene_FOUND)
+-
+-include_directories (. ${CPPUNIT_INCLUDE_DIR} ${strigi_SOURCE_DIR}/src/daemon)
+-
++# a convenience library that adds a unified way of build a test executable
++# for testing
++# simply link this into any unit test executable
+ add_library(test_runner test_runner.cpp)
+ target_link_libraries(test_runner ${CPPUNIT_LIBRARIES})
+
+- ENABLE_TESTING()
++ENABLE_TESTING()
+
+-subdirs (${TESTINGDIRS})
+--- a/tests/daemon/CMakeLists.txt
++++ b/tests/daemon/CMakeLists.txt
+@@ -1,8 +1,5 @@
+ # add a test for the daemon configuration loading classes
+
+-# fancy way of saying set(INC_DIR test/daemon)
+-string(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+ # if we use log4cxx, include it
+ # ideally this should be abstracted away in something like STRIGILOG( ... )
+ if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+--- a/tests/estraierindexer/CMakeLists.txt
++++ /dev/null
+@@ -1,26 +0,0 @@
+-STRING(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+-if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(estraiertest_LIBS ${estraiertest_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
+- add_definitions(-DHAVE_LOG4CXX)
+-endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+-
+-include_directories (. .. ${INC_DIR}
+- ../indextests
+- ${strigi_SOURCE_DIR}/src/streamanalyzer
+- ${strigi_SOURCE_DIR}/src/streams
+- ${strigi_BINARY_DIR}/src/streams
+- ${strigi_SOURCE_DIR}/src/streams/strigi
+- ${EST_INCLUDE_DIR}
+-)
+-
+-add_library(estraiertest SHARED estraierindexmanagertest.cpp
+- ../indextests/indexmanagertester.cpp
+- estraierindexreadertest.cpp
+- ../indextests/indexreadertester.cpp
+- estraierindexwritertest.cpp
+- ../indextests/indexwritertester.cpp )
+-
+-target_link_libraries (estraiertest estraierindex ${estraiertest_LIBS})
+-add_test (estraiertest estraiertest)
+--- a/tests/estraierindexer/estraierindexmanagertest.cpp
++++ /dev/null
+@@ -1,72 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexmanagertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexManagerTest );
+-
+-void EstraierIndexManagerTest::setUp()
+-{
+- IndexManagerTester::setUp();
+-
+- path = "testestraierindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- writer = manager->getIndexWriter();
+- reader = manager->getIndexReader();
+- ic = new Strigi::AnalyzerConfiguration ();
+- si = new Strigi::StreamAnalyzer (*ic);
+-}
+-
+-void EstraierIndexManagerTest::tearDown()
+-{
+- IndexManagerTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexmanagertest.h
++++ /dev/null
+@@ -1,43 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_MANAGER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_MANAGER_TEST_H
+-
+-#include "indexmanagertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexManagerTest : public IndexManagerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexManagerTest, IndexManagerTester);
+- CPPUNIT_TEST( testVariables );
+- //CPPUNIT_TEST( runUnthreadedTests );
+- //CPPUNIT_TEST( runThreadedTests );
+- CPPUNIT_TEST( addAndCount );
+- CPPUNIT_TEST( testNumberQuery );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/estraierindexer/estraierindexreadertest.cpp
++++ /dev/null
+@@ -1,69 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexreadertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexReaderTest );
+-
+-void EstraierIndexReaderTest::setUp()
+-{
+- IndexReaderTester::setUp();
+-
+- path = "testestraier";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- reader = manager->getIndexReader();
+-}
+-
+-void EstraierIndexReaderTest::tearDown()
+-{
+- IndexReaderTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexreadertest.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_READER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_READER_TEST_H
+-
+-#include "indexreadertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexReaderTest : public IndexReaderTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexReaderTest, IndexReaderTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( getFiles );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/estraierindexer/estraierindexwritertest.cpp
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexwritertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexWriterTest );
+-
+-void EstraierIndexWriterTest::setUp()
+-{
+- IndexWriterTester::setUp();
+-
+- path = "testestraierindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- writer = manager->getIndexWriter();
+- ic = new Strigi::AnalyzerConfiguration ();
+- si = new Strigi::StreamAnalyzer (*ic);
+-}
+-
+-void EstraierIndexWriterTest::tearDown()
+-{
+- IndexWriterTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexwritertest.h
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_WRITER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_WRITER_TEST_H
+-
+-#include "indexwritertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexWriterTest : public IndexWriterTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexWriterTest, IndexWriterTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( add );
+- CPPUNIT_TEST( optimize );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- /dev/null
++++ b/tests/indextesters/clucenetests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++
++class CLuceneIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexReaderTest() :IndexReaderTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexReaderTest );
++
++class CLuceneIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexWriterTest() :IndexWriterTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexWriterTest );
++
++class CLuceneIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexSearchTest() :IndexSearchTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexSearchTest );
++
+--- a/tests/indextesters/CMakeLists.txt
++++ b/tests/indextesters/CMakeLists.txt
+@@ -1,6 +1,6 @@
+ if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(indextesters_LIBS ${indextesters_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
++ set(indextesters_LIBS ${LOG4CXX_LIBRARIES})
++ set(INC_DIR ${LOG4CXX_INCLUDE_DIR})
+ add_definitions(-DHAVE_LOG4CXX)
+ endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+
+@@ -12,10 +12,26 @@
+ ../utils
+ )
+
+-add_library(indextesters indexmanagertester.cpp
+- indexreadertester.cpp
+- indexwritertester.cpp
+- indexsearchtester.cpp
+-)
++set(indextester_SRCS indextest.cpp indexreadertester.cpp indexwritertester.cpp
++ indexsearchtester.cpp)
++if (CLucene_FOUND)
++ set(indextester_SRCS ${indextester_SRCS} clucenetests.cpp)
++ set (indextester_DEPS ${indextester_DEPS} clucene)
++endif (CLucene_FOUND)
++if (ENABLE_SQLITE AND SQLite_FOUND)
++ set (indextester_SRCS ${indextester_SRCS} sqlitetests.cpp)
++ set (indextester_DEPS sqlite)
++endif (ENABLE_SQLITE AND SQLite_FOUND)
++if (HyperEstraier_FOUND)
++ set (indextester_SRCS ${indextester_SRCS} estraiertests.cpp)
++ set (indextester_DEPS estraier)
++endif (HyperEstraier_FOUND)
++
++add_executable(indextester ${indextester_SRCS})
++if (indextester_DEPS)
++ ADD_DEPENDENCIES(indextester ${indextester_DEPS})
++endif (indextester_DEPS)
++target_link_libraries(indextester
++ test_runner unittestfunctions ${indextesters_LIBS})
+
+-target_link_libraries (indextesters unittestfunctions ${indextesters_LIBS})
++add_test(indextester indextester)
+--- /dev/null
++++ b/tests/indextesters/estraiertests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++
++class EstraierIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexReaderTest() :IndexReaderTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexReaderTest );
++
++class EstraierIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexWriterTest() :IndexWriterTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexWriterTest );
++
++
++class EstraierIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexSearchTest() :IndexSearchTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexSearchTest );
+--- a/tests/indextesters/indexmanagertester.cpp
++++ b/tests/indextesters/indexmanagertester.cpp
+@@ -18,53 +18,41 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include "indexmanagertester.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+ #include "indexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "fieldtypes.h"
+-#include "query.h"
+-#include "queryparser.h"
+-
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
++#include "indexpluginloader.h"
+
+ using namespace std;
+ using namespace Strigi;
+ using namespace strigiunittest;
+
+-void IndexManagerTester::setUp()
+-{
+- m_manager = createManager();
+-}
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexManagerTest );
+
+-void IndexManagerTester::tearDown()
+-{
+- deleteManager( m_manager );
++IndexManagerTest::IndexManagerTest(const std::string& backendname)
++ :m_backendname(backendname), m_indexpath(":memory:"), m_manager(0) {
+ }
+
+-
+-void IndexManagerTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++void
++IndexManagerTest::setUp() {
++ m_manager = Strigi::IndexPluginLoader::createIndexManager(
++ m_backendname.c_str(), m_indexpath.c_str());
+ }
+
++void
++IndexManagerTest::tearDown() {
++ Strigi::IndexPluginLoader::deleteIndexManager(m_manager);
++ // clean up data (if any)
++ string cmd("rm -rf '" + m_indexpath + "'");
++ system(cmd.c_str());
++}
+
+-void IndexManagerTester::testIndexReader()
+-{
++void
++IndexManagerTest::testIndexReader() {
+ Strigi::IndexReader* reader = m_manager->indexReader();
+ CPPUNIT_ASSERT_MESSAGE("reader creation failed", reader);
+ }
+
+-void IndexManagerTester::testIndexWriter()
+-{
++void
++IndexManagerTest::testIndexWriter() {
+ Strigi::IndexWriter* writer = m_manager->indexWriter();
+ CPPUNIT_ASSERT_MESSAGE("writer creation failed", writer);
+ }
+--- a/tests/indextesters/indexmanagertester.h
++++ b/tests/indextesters/indexmanagertester.h
+@@ -30,34 +30,37 @@
+ class IndexReader;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexManagerTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexManagerTester );
+- CPPUNIT_TEST( testIndexReader );
+- CPPUNIT_TEST( testIndexWriter );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+-
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void testIndexReader();
+- virtual void testIndexWriter();
+- };
+-}
++namespace strigiunittest {
++
++class IndexManagerTest : public CppUnit::TestFixture {
++private:
++ CPPUNIT_TEST_SUITE( IndexManagerTest );
++ CPPUNIT_TEST( testIndexReader );
++ CPPUNIT_TEST( testIndexWriter );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ const std::string m_backendname;
++ const std::string m_indexpath;
++ Strigi::IndexManager* m_manager;
++
++protected:
++ IndexManagerTest(const std::string& backendname);
+
++public:
++ void setUp();
++ void tearDown();
++
++ void testIndexReader();
++ void testIndexWriter();
++};
++
++class CLuceneIndexManagerTest : public IndexManagerTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexManagerTest, IndexManagerTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexManagerTest() :IndexManagerTest("clucene") {}
++};
++
++}
+ #endif
+--- a/tests/indextesters/indexreadertester.cpp
++++ b/tests/indextesters/indexreadertester.cpp
+@@ -20,61 +20,38 @@
+ #include "indexreadertester.h"
+
+ #include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "fieldtypes.h"
+-#include "analyzerconfiguration.h"
+ #include "query.h"
+ #include "queryparser.h"
+
+-#include <string>
+ #include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+ #include <ostream>
+
+ using namespace std;
+ using namespace strigiunittest;
+ using namespace Strigi;
+
+-void IndexReaderTester::setUp()
+-{
+- m_manager = createManager();
+- m_writer = m_manager->indexWriter();
+- m_reader = m_manager->indexReader();
+-
+- CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
+- CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
+-
++void
++IndexReaderTest::setUp() {
++ IndexTest::setUp();
+ m_streamAnalyzer = new Strigi::StreamAnalyzer( m_analyzerConfiguration );
+ }
+
+-void IndexReaderTester::tearDown()
+-{
++void
++IndexReaderTest::tearDown() {
+ delete m_streamAnalyzer;
+- deleteManager( m_manager );
+-}
+-
+-
+-void IndexReaderTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++ IndexTest::tearDown();
+ }
+
+ void
+-IndexReaderTester::testChildrenRetrieval() {
++IndexReaderTest::testChildrenRetrieval() {
+ // FIXME
+ }
+
+-void IndexReaderTester::addAndCount()
+-{
++void
++IndexReaderTest::addAndCount() {
+ static const int m = 20;
+
+ m_writer->deleteAllEntries();
+@@ -93,8 +70,8 @@
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(str.str(), m, n);
+ }
+
+-void IndexReaderTester::testNumberQuery()
+-{
++void
++IndexReaderTest::testNumberQuery() {
+ m_writer->deleteAllEntries();
+ // add numbers to the database
+ int m = 200;
+--- a/tests/indextesters/indexreadertester.h
++++ b/tests/indextesters/indexreadertester.h
+@@ -20,55 +20,37 @@
+ #ifndef UNIT_TEST_INDEX_READER_TESTER_H
+ #define UNIT_TEST_INDEX_READER_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
+-#include <string>
+-
++#include "indextest.h"
+ #include "analyzerconfiguration.h"
+-#include "fieldtypes.h"
+
+ namespace Strigi {
+- class IndexManager;
+- class IndexReader;
+- class IndexWriter;
+ class StreamAnalyzer;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexReaderTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexReaderTester );
+- CPPUNIT_TEST( testChildrenRetrieval );
+- CPPUNIT_TEST( addAndCount );
+- CPPUNIT_TEST( testNumberQuery );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- Strigi::IndexWriter* m_writer;
+- Strigi::IndexReader* m_reader;
+- Strigi::StreamAnalyzer* m_streamAnalyzer;
+- Strigi::AnalyzerConfiguration m_analyzerConfiguration;
+- Strigi::FieldRegister m_fieldRegister;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void addAndCount();
+- virtual void testChildrenRetrieval();
+- virtual void testNumberQuery();
+- };
++namespace strigiunittest {
++
++class IndexReaderTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexReaderTest );
++ CPPUNIT_TEST( testChildrenRetrieval );
++ CPPUNIT_TEST( addAndCount );
++ CPPUNIT_TEST( testNumberQuery );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ Strigi::StreamAnalyzer* m_streamAnalyzer;
++ Strigi::AnalyzerConfiguration m_analyzerConfiguration;
++ Strigi::FieldRegister m_fieldRegister;
++
++ void addAndCount();
++ void testChildrenRetrieval();
++ void testNumberQuery();
++public:
++ IndexReaderTest(const std::string& backendname) :IndexTest(backendname),
++ m_streamAnalyzer(0) {}
++ void setUp();
++ void tearDown();
++};
++
+ }
+
+ #endif
+--- a/tests/indextesters/indexsearchtester.cpp
++++ b/tests/indextesters/indexsearchtester.cpp
+@@ -27,6 +27,7 @@
+ #include "query.h"
+ #include "queryparser.h"
+ #include "unittestfunctions.h"
++#include "indexpluginloader.h"
+
+ #include <errno.h>
+ #include <fstream>
+@@ -39,23 +40,12 @@
+ using namespace strigiunittest;
+
+ void
+-IndexSearchTester::setUp() {
++IndexSearchTest::setUp() {
++ IndexTest::setUp();
++
+ char buff[13];
+ char* dirname;
+ string separator;
+-
+- // generate index dir name
+- strcpy(buff, "strigiXXXXXX");
+- dirname = mkdtemp(buff);
+-
+- if (dirname) {
+- cout << "created index dir: " << dirname << endl;
+- indexdir.assign(dirname);
+- } else {
+- cerr << "Error creating temporary directory for index because of: "
+- << strerror(errno) << endl;
+- return;
+- }
+
+ // generate indexed docs name
+ strcpy(buff, "strigiXXXXXX");
+@@ -68,7 +58,7 @@
+ << strerror(errno) << endl;
+ return;
+ }
+-
++
+ #ifdef _WIN32
+ separator = "\\";
+ #else
+@@ -78,15 +68,15 @@
+ // prepare files to be indexed
+ string filename;
+ string filecontents;
+-
++
+ filename = "testfile01";
+ filecontents = "this is a simple test file";
+ indexedFiles.insert(make_pair<string, string> (filename, filecontents));
+-
++
+ filename = "testfile02";
+ filecontents = "unit testing example";
+ indexedFiles.insert(make_pair<string, string> (filename, filecontents));
+-
++
+ // create files on file system
+ for (map<string,string>::iterator iter = indexedFiles.begin();
+ iter != indexedFiles.end(); iter++) {
+@@ -100,48 +90,37 @@
+ cerr << "error during creation of file " << fullpath << endl;
+ }
+ }
+-
+- manager = getIndexManager(backend, indexdir);
+
+- CPPUNIT_ASSERT_MESSAGE ("manager == null", manager);
+-
+ Strigi::AnalyzerConfiguration config;
+ Strigi::StreamAnalyzer* streamindexer = new Strigi::StreamAnalyzer(config);
+- Strigi::IndexWriter* writer = manager->indexWriter();
+- streamindexer->setIndexWriter(*writer);
+-
++ streamindexer->setIndexWriter(*m_writer);
++
+ for (map<string,string>::iterator iter = indexedFiles.begin();
+ iter != indexedFiles.end(); iter++) {
+ string temp = filedir + separator + iter->first;
+ fprintf (stderr, "going to index %s\n", temp.c_str());
+ streamindexer->indexFile(temp);
+ }
+-
++
+ delete streamindexer;
+-
+- writer->commit();
+-
++
++ m_writer->commit();
+ }
+
+ void
+-IndexSearchTester::tearDown() {
+- if (manager)
+- delete manager;
+- manager = NULL;
+-
++IndexSearchTest::tearDown() {
+ // clean up data (does not work on windows)
+- string cmd = "rm -r " + indexdir + " " + filedir;
++ string cmd = "rm -r '" + filedir + "'";
+ system(cmd.c_str());
++
++ IndexTest::tearDown();
+ }
+
+ void
+-IndexSearchTester::testVariables() {
+- CPPUNIT_ASSERT_MESSAGE ("manager == NULL", manager);
+- CPPUNIT_ASSERT_MESSAGE ("backend empty", !backend.empty());
+- CPPUNIT_ASSERT_MESSAGE ("indexdir empty", !indexdir.empty());
++IndexSearchTest::testVariables() {
+ CPPUNIT_ASSERT_MESSAGE ("filedir empty", !filedir.empty());
+-
+- unsigned int indexedFilesSize = manager->indexReader()->countDocuments();
++
++ unsigned int indexedFilesSize = m_reader->countDocuments();
+ if (indexedFilesSize != indexedFiles.size()) {
+ ostringstream msg;
+ msg << "There are " << indexedFilesSize << " indexed files instead of "
+@@ -151,30 +130,24 @@
+ }
+
+ void
+-IndexSearchTester::testSystemLocationSearchIndexedFile() {
+- Strigi::IndexReader* reader = manager->indexReader();
+- CPPUNIT_ASSERT_MESSAGE("reader == NULL", reader);
+-
++IndexSearchTest::testSystemLocationSearchIndexedFile() {
+ Strigi::QueryParser parser;
+
+ Strigi::Query query = parser.buildQuery("name:'testfile01'");
+- vector<Strigi::IndexedDocument> matches = reader->query(query, 0, 10);
++ vector<Strigi::IndexedDocument> matches = m_reader->query(query, 0, 10);
+
+ int nhits = matches.size();
+- CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", nhits, 1);
++ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", 1, nhits);
+ }
+
+ void
+-IndexSearchTester::testSystemLocationSearchUnindexedFile() {
+- Strigi::IndexReader* reader = manager->indexReader();
+- CPPUNIT_ASSERT_MESSAGE("reader == NULL", reader);
+-
++IndexSearchTest::testSystemLocationSearchUnindexedFile() {
+ Strigi::QueryParser parser;
+
+ Strigi::Query query = parser.buildQuery(
+ Strigi::FieldRegister::pathFieldName+":'unindexed'");
+- vector<Strigi::IndexedDocument> matches = reader->query(query, 0, 10);
++ vector<Strigi::IndexedDocument> matches = m_reader->query(query, 0, 10);
+ int nhits = matches.size();
+- CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", nhits, 0);
++ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", 0, nhits);
+ }
+
+--- a/tests/indextesters/indexsearchtester.h
++++ b/tests/indextesters/indexsearchtester.h
+@@ -20,42 +20,33 @@
+ #ifndef UNIT_TEST_INDEX_SEARCH_TESTER_H
+ #define UNIT_TEST_INDEX_SEARCH_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
++#include "indextest.h"
+
+ #include <map>
+-#include <string>
+
+-namespace Strigi
+-{
+- class IndexManager;
+-}
++namespace strigiunittest {
++
++class IndexSearchTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexSearchTest );
++ CPPUNIT_TEST( testVariables );
++ CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
++ CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ std::string filedir;
++ std::map<std::string,std::string> indexedFiles; //!< map with key = file name, and value = file contents
++
++ void testSystemLocationSearchIndexedFile();
++ void testSystemLocationSearchUnindexedFile();
++ void testVariables();
++
++public:
++ IndexSearchTest(const std::string& backendname) :IndexTest(backendname){}
++ void setUp();
++ void tearDown();
++};
+
+-namespace strigiunittest
+-{
+- class IndexSearchTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexSearchTester );
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
+- CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- protected:
+- Strigi::IndexManager* manager;
+- std::string backend;
+- std::string indexdir;
+- std::string filedir;
+- std::map<std::string,std::string> indexedFiles; //!< map with key = file name, and value = file contents
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void testSystemLocationSearchIndexedFile();
+- virtual void testSystemLocationSearchUnindexedFile();
+- virtual void testVariables();
+- };
+ }
+
+ #endif
+--- /dev/null
++++ b/tests/indextesters/indextest.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include "indextest.h"
++#include "indexmanager.h"
++#include "indexpluginloader.h"
++
++using namespace std;
++using namespace Strigi;
++using namespace strigiunittest;
++
++IndexTest::IndexTest(const string& backendname, const string& indexpath)
++ :m_backendname(backendname), m_indexpath(":memory:"), m_manager(0) {
++}
++
++void
++IndexTest::setUp() {
++ m_manager = IndexPluginLoader::createIndexManager(
++ m_backendname.c_str(), m_indexpath.c_str());
++ CPPUNIT_ASSERT_MESSAGE("manager creation failed", m_manager);
++ if (!m_manager) return;
++
++ m_writer = m_manager->indexWriter();
++ CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
++
++ m_reader = m_manager->indexReader();
++ CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
++}
++
++void
++IndexTest::tearDown() {
++ IndexPluginLoader::deleteIndexManager(m_manager);
++ // clean up data (if any)
++ string cmd("rm -rf '" + m_indexpath + "'");
++ system(cmd.c_str());
++}
+--- /dev/null
++++ b/tests/indextesters/indextest.h
+@@ -0,0 +1,51 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#ifndef UNIT_TEST_INDEX_TEST_H
++#define UNIT_TEST_INDEX_TEST_H
++
++#include <cppunit/TestFixture.h>
++#include <cppunit/extensions/HelperMacros.h>
++#include <string>
++
++namespace Strigi {
++ class IndexManager;
++ class IndexWriter;
++ class IndexReader;
++}
++
++namespace strigiunittest {
++
++class IndexTest : public CppUnit::TestFixture {
++protected:
++ const std::string m_backendname;
++ const std::string m_indexpath;
++ Strigi::IndexManager* m_manager;
++ Strigi::IndexReader* m_reader;
++ Strigi::IndexWriter* m_writer;
++
++ IndexTest(const std::string& backendname,
++ const std::string& indexpath = ":memory:");
++ void setUp();
++ void tearDown();
++};
++
++}
++
++#endif
+--- a/tests/indextesters/indexwritertester.cpp
++++ b/tests/indextesters/indexwritertester.cpp
+@@ -20,55 +20,32 @@
+ #include "indexwritertester.h"
+
+ #include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "fieldtypes.h"
+-#include "analyzerconfiguration.h"
+ #include "query.h"
+ #include "queryparser.h"
+
+-#include <string>
+ #include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+
+ using namespace std;
+ using namespace strigiunittest;
+ using namespace Strigi;
+
+-void IndexWriterTester::setUp()
+-{
+- m_manager = createManager();
+- m_writer = m_manager->indexWriter();
+- m_reader = m_manager->indexReader();
+-
+- CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
+- CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
+-
+- m_streamAnalyzer = new Strigi::StreamAnalyzer( m_analyzerConfiguration );
++void
++IndexWriterTest::setUp() {
++ IndexTest::setUp();
++ m_streamAnalyzer = new StreamAnalyzer( m_analyzerConfiguration );
+ }
+
+-void IndexWriterTester::tearDown()
+-{
++void
++IndexWriterTest::tearDown() {
+ delete m_streamAnalyzer;
+- deleteManager( m_manager );
+-}
+-
+-
+-void IndexWriterTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++ IndexTest::tearDown();
+ }
+
+-
+-void IndexWriterTester::testAddText()
+-{
++void
++IndexWriterTest::testAddText() {
+ // test adding very simple text
+ string path( "/tmp/dummy.txt" );
+ {
+@@ -78,9 +55,12 @@
+ }
+ m_writer->commit();
+
+- std::vector<IndexedDocument> results = m_reader->query( QueryParser::buildQuery("dummy"), 0, 100 );
+- CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid number of results", 1, ( int )results.size() );
+- CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid path result", path, results[0].uri );
++ std::vector<IndexedDocument> results = m_reader->query(
++ QueryParser::buildQuery("dummy"), 0, 100 );
++ CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid number of results", 1,
++ (int)results.size() );
++ CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid path result", path,
++ results[0].uri );
+
+ m_writer->deleteAllEntries();
+
+@@ -88,9 +68,8 @@
+
+ }
+
+-
+-void IndexWriterTester::testDeleteAllEntries()
+-{
++void
++IndexWriterTest::testDeleteAllEntries() {
+ // add some random data
+ string path( "/tmp/dummy.txt" );
+ {
+@@ -107,18 +86,23 @@
+ // now make sure nothing is left
+ std::map<std::string, time_t> children;
+ m_reader->getChildren( std::string(), children );
+- CPPUNIT_ASSERT_MESSAGE( "Still files left after calling deleteAllEntries.", children.empty() );
++ CPPUNIT_ASSERT_MESSAGE( "Still files left after calling deleteAllEntries.",
++ children.empty() );
+
+- std::vector<IndexedDocument> results = m_reader->query( QueryParser::buildQuery( FieldRegister::pathFieldName + "=\"" + path + "\"" ), 0, 100 );
+- CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries", results.empty() );
+-
+- results = m_reader->query( QueryParser::buildQuery( FieldRegister::filenameFieldName + "=\"dummy.txt\"" ), 0, 100 );
+- CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries", results.empty() );
++ std::vector<IndexedDocument> results = m_reader->query(
++ QueryParser::buildQuery(
++ FieldRegister::pathFieldName + "=\"" + path + "\"" ), 0, 100 );
++ CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries",
++ results.empty() );
++
++ results = m_reader->query( QueryParser::buildQuery(
++ FieldRegister::filenameFieldName + "=\"dummy.txt\"" ), 0, 100 );
++ CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries",
++ results.empty() );
+ }
+
+-
+-void IndexWriterTester::testDeleteEntries()
+-{
++void
++IndexWriterTest::testDeleteEntries() {
+ // add some random data
+ string path1( "/tmp/dummy1.txt" );
+ string path2( "/tmp/dummy2.txt" );
+@@ -128,11 +112,11 @@
+ AnalysisResult anaRes1( path1, 1, *m_writer, *m_streamAnalyzer );
+ AnalysisResult anaRes2( path2, 1, *m_writer, *m_streamAnalyzer );
+
+- m_writer->addValue( &anaRes1, m_fieldRegister.pathField, anaRes1.path() );
+- m_writer->addValue( &anaRes1, m_fieldRegister.filenameField, filename1 );
++ m_writer->addValue(&anaRes1, m_fieldRegister.pathField, anaRes1.path());
++ m_writer->addValue(&anaRes1, m_fieldRegister.filenameField, filename1);
+
+- m_writer->addValue( &anaRes2, m_fieldRegister.pathField, anaRes2.path() );
+- m_writer->addValue( &anaRes2, m_fieldRegister.filenameField, filename2 );
++ m_writer->addValue(&anaRes2, m_fieldRegister.pathField, anaRes2.path());
++ m_writer->addValue(&anaRes2, m_fieldRegister.filenameField, filename2 );
+ }
+ m_writer->commit();
+
+--- a/tests/indextesters/indexwritertester.h
++++ b/tests/indextesters/indexwritertester.h
+@@ -20,56 +20,40 @@
+ #ifndef UNIT_TEST_INDEX_WRITER_TESTER_H
+ #define UNIT_TEST_INDEX_WRITER_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
+-#include <string>
++#include "indextest.h"
+
+ #include "analyzerconfiguration.h"
+ #include "fieldtypes.h"
+
+ namespace Strigi {
+- class IndexManager;
+- class IndexWriter;
+- class IndexReader;
+ class StreamAnalyzer;
+ class AnalysisResult;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexWriterTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexWriterTester );
+- CPPUNIT_TEST( testAddText );
+- CPPUNIT_TEST( testDeleteAllEntries );
+-
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- Strigi::IndexWriter* m_writer;
+- Strigi::IndexReader* m_reader;
+- Strigi::StreamAnalyzer* m_streamAnalyzer;
+- Strigi::AnalyzerConfiguration m_analyzerConfiguration;
+- Strigi::FieldRegister m_fieldRegister;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- void testAddText();
+- void testDeleteAllEntries();
+- void testDeleteEntries();
+- };
++namespace strigiunittest {
++
++class IndexWriterTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexWriterTest );
++ CPPUNIT_TEST( testAddText );
++ CPPUNIT_TEST( testDeleteAllEntries );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ Strigi::StreamAnalyzer* m_streamAnalyzer;
++ Strigi::AnalyzerConfiguration m_analyzerConfiguration;
++ Strigi::FieldRegister m_fieldRegister;
++
++ void testAddText();
++ void testDeleteAllEntries();
++ void testDeleteEntries();
++
++public:
++ IndexWriterTest(const std::string& backendname) :IndexTest(backendname),
++ m_streamAnalyzer(0) {}
++ void setUp();
++ void tearDown();
++};
++
+ }
+
+ #endif
+--- /dev/null
++++ b/tests/indextesters/sqlitetests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++/*
++class SQLiteIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexReaderTest() :IndexReaderTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexReaderTest );
++*/
++class SQLiteIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexWriterTest() :IndexWriterTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexWriterTest );
++/*
++
++class SQLiteIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexSearchTest() :IndexSearchTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexSearchTest );*/
+--- a/tests/luceneindexer/CMakeLists.txt
++++ /dev/null
+@@ -1,33 +0,0 @@
+-STRING(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+-if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(lucenetest_LIBS ${lucenetest_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
+- add_definitions(-DHAVE_LOG4CXX)
+-endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+-
+-include_directories (. .. ${INC_DIR}
+- ../indextesters
+- ../streamanalyzer
+- ${strigi_SOURCE_DIR}/src/streamanalyzer
+- ${strigi_SOURCE_DIR}/src/luceneindexer
+- ${strigi_SOURCE_DIR}/src/streams
+- ${strigi_BINARY_DIR}/src/streams
+- ${strigi_SOURCE_DIR}/src/streams/strigi
+- ${CLUCENE_INCLUDE_DIR}
+-)
+-
+-add_executable (lucenetest luceneindexmanagertest.cpp
+- luceneindexreadertest.cpp
+- luceneindexwritertest.cpp
+- luceneindexsearchtest.cpp
+- lucenediranalyzertest.cpp
+-)
+-
+-target_link_libraries (lucenetest test_runner
+- streamanalyzertesters
+- indextesters
+- cluceneindex
+- ${lucenetest_LIBS})
+-
+-add_test (lucenetests lucenetest)
+--- a/tests/luceneindexer/lucenediranalyzertest.cpp
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "lucenediranalyzertest.h"
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneDirAnalyzerTest );
+-
+-void LuceneDirAnalyzerTest::setUp()
+-{
+- backend = "clucene";
+- DirAnalyzerTester::setUp();
+-}
+-
+-void LuceneDirAnalyzerTest::tearDown()
+-{
+- DirAnalyzerTester::tearDown();
+-}
+--- a/tests/luceneindexer/lucenediranalyzertest.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_SEARCH_TEST_H
+-#define UNIT_TEST_LUCENE_SEARCH_TEST_H
+-
+-#include "diranalyzertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneDirAnalyzerTest : public DirAnalyzerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneDirAnalyzerTest, DirAnalyzerTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testCreateIndex );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexmanagertest.cpp
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexmanagertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexManagerTest );
+-
+-Strigi::IndexManager* LuceneIndexManagerTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexManagerTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexmanagertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_MANAGER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_MANAGER_TEST_H
+-
+-#include "indexmanagertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexManagerTest : public IndexManagerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexManagerTest, IndexManagerTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexreadertest.cpp
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexreadertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexReaderTest );
+-
+-Strigi::IndexManager* LuceneIndexReaderTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexReaderTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexreadertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_READER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_READER_TEST_H
+-
+-#include "indexreadertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexReaderTest : public IndexReaderTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexReaderTest, IndexReaderTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexsearchtest.cpp
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexsearchtest.h"
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexSearchTest );
+-
+-void LuceneIndexSearchTest::setUp()
+-{
+- backend = "clucene";
+- IndexSearchTester::setUp();
+-}
+-
+-void LuceneIndexSearchTest::tearDown()
+-{
+- IndexSearchTester::tearDown();
+-}
+--- a/tests/luceneindexer/luceneindexsearchtest.h
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_SEARCH_TEST_H
+-#define UNIT_TEST_LUCENE_SEARCH_TEST_H
+-
+-#include "indexsearchtester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexSearchTest : public IndexSearchTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexSearchTest, IndexSearchTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
+- CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexwritertest.cpp
++++ /dev/null
+@@ -1,63 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexwritertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexWriterTest );
+-
+-Strigi::IndexManager* LuceneIndexWriterTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexWriterTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexwritertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_WRITER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_WRITER_TEST_H
+-
+-#include "indexwritertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexWriterTest : public IndexWriterTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexWriterTest, IndexWriterTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/streamanalyzer/diranalyzertester.cpp
++++ b/tests/streamanalyzer/diranalyzertester.cpp
+@@ -23,6 +23,7 @@
+ #include "diranalyzer.h"
+ #include "indexmanager.h"
+ #include "indexreader.h"
++#include "indexpluginloader.h"
+ #include "unittestfunctions.h"
+
+ #include <errno.h>
+@@ -105,8 +106,9 @@
+
+ void DirAnalyzerTester::tearDown()
+ {
+- if (manager)
+- delete manager;
++ if (manager) {
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
++ }
+ manager = NULL;
+
+ // clean up data
+--- a/tests/test_runner.cpp
++++ b/tests/test_runner.cpp
+@@ -24,11 +24,27 @@
+ #include <cppunit/TextTestRunner.h>
+
+ #include "strigilogging.h"
++#include "config.h"
++
++#include <iostream>
++using namespace std;
++
++int main() {
++ // set some environment variables so that the system can find the desired
++ // files
++ setenv("XDG_DATA_HOME",
++ SOURCEDIR"/src/streamanalyzer/fieldproperties", 1);
++ setenv("XDG_DATA_DIRS",
++ SOURCEDIR"/src/streamanalyzer/fieldproperties", 1);
++ setenv("STRIGI_PLUGIN_PATH",
++ BINARYDIR"/src/luceneindexer/:"
++ BINARYDIR"/src/estraierindexer:"
++ BINARYDIR"/src/sqliteindexer", 1);
++
++cerr << BINARYDIR << endl;
+
+-int main()
+-{
+ STRIGI_LOG_INIT_BASIC()
+-
++
+ // Get the top level suite from the registry
+ CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+@@ -46,18 +62,3 @@
+ return wasSucessful ? 0 : 1;
+ }
+
+-// using namespace CppUnit;
+-//
+-// int main (int argc, char* argv[]) {
+-// TextTestRunner runner;
+-// TestFactoryRegistry& registry = TestFactoryRegistry::getRegistry();
+-//
+-// // run all tests if none specified on command line
+-// Test* test_to_run = registry.makeTest();
+-// if (argc>1)
+-// test_to_run = test_to_run->findTest(argv[1]);
+-//
+-// runner.addTest( test_to_run );
+-// bool failed = runner.run("", false);
+-// return !failed;
+-// }
+--- a/tests/utils/CMakeLists.txt
++++ b/tests/utils/CMakeLists.txt
+@@ -1,8 +1,9 @@
+ include_directories ( .
++ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streamanalyzer
+ ${strigi_SOURCE_DIR}/src/combinedindexer
+ )
+
+ add_library(unittestfunctions unittestfunctions.cpp)
+
+-target_link_libraries (unittestfunctions combinedindex)
+\ No newline at end of file
++target_link_libraries (unittestfunctions combinedindex)
+--- a/tests/utils/unittestfunctions.cpp
++++ b/tests/utils/unittestfunctions.cpp
+@@ -21,22 +21,14 @@
+ #include "unittestfunctions.h"
+
+ #include "indexmanager.h"
+-#include "combinedindexmanager.h"
++#include "indexpluginloader.h"
+ #include <vector>
+ #include <algorithm>
+
+ using namespace std;
+
+ Strigi::IndexManager* strigiunittest::getIndexManager(string& backend,
+- const string& indexdir)
+-{
+- // check arguments: backend
+- const vector<string>& backends = CombinedIndexManager::backEnds();
+-
+- vector<string>::const_iterator b
+- = find(backends.begin(), backends.end(), backend);
+- if (b == backends.end())
+- return 0;
+-
+- return CombinedIndexManager::factories()[backend](indexdir.c_str());
++ const string& indexdir) {
++ return Strigi::IndexPluginLoader::createIndexManager(backend.c_str(),
++ indexdir.c_str());
+ }
Added: kde-extras/strigi/trunk/debian/patches/01_strigi_branch_r727526.diff
===================================================================
--- kde-extras/strigi/trunk/debian/patches/01_strigi_branch_r727526.diff (rev 0)
+++ kde-extras/strigi/trunk/debian/patches/01_strigi_branch_r727526.diff 2007-10-28 14:05:27 UTC (rev 7694)
@@ -0,0 +1,4864 @@
+--- a/cmake/FindCppUnit.cmake
++++ b/cmake/FindCppUnit.cmake
+@@ -7,7 +7,9 @@
+
+ include (MacroEnsureVersion)
+
+-SET(CPPUNIT_MIN_VERSION 1.12.0)
++if(NOT CPPUNIT_MIN_VERSION)
++ SET(CPPUNIT_MIN_VERSION 1.12.0)
++endif(NOT CPPUNIT_MIN_VERSION)
+
+ FIND_PROGRAM(CPPUNIT_CONFIG_EXECUTABLE cppunit-config )
+
+--- a/cmake/FindHyperEstraier.cmake
++++ b/cmake/FindHyperEstraier.cmake
+@@ -8,7 +8,7 @@
+ #
+
+ # find estconfig executable
+-FIND_PROGRAM(ESTCONFIG NAMES estconfig PATHS /bin /usr/bin /usr/local/bin )
++FIND_PROGRAM(ESTCONFIG NAMES estconfig PATHS /bin )
+
+ # get configuration options
+ IF (ESTCONFIG)
+--- a/config.h.cmake
++++ b/config.h.cmake
+@@ -147,7 +147,34 @@
+
+ #define LIBINSTALLDIR "${LIBINSTALLDIR}"
+
++#define SOURCEDIR "${CMAKE_SOURCE_DIR}"
++
++#define BINARYDIR "${CMAKE_BINARY_DIR}"
++
+ #define INSTALLDIR "${CMAKE_INSTALL_PREFIX}"
+
+ #define MIMEINSTALLDIR "${MIMEINSTALLDIR}"
++
++// Definition of types that are used internally
++
++#if !@HAVE_INTPTR_T@
++ typedef int intptr_t;
++ #define HAVE_INTPTR_T 1
++#endif
++
++#if !@HAVE_SOCKLEN_T@
++ typedef int socklen_t;
++ #define HAVE_SOCKLEN_T 1
++#endif
++
++#if !@HAVE_SSIZE_T@
++ #ifndef _SSIZE_T_DEFINED
++ #ifndef HAVE_SSIZE_T
++ typedef signed int ssize_t;
++ #define HAVE_SSIZE_T 1
++ #endif
++ #define _SSIZE_T_DEFINED 1 // kdewin32 define
++ #endif
++#endif
++
+ #endif //CONFIG_H
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -2,7 +2,6 @@
+ # Check copied from kdelibs FindX11.cmake.
+ CHECK_LIBRARY_EXISTS("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT)
+
+-
+ set(DIRS streams streamanalyzer archivereader xsd dummyindexer xmlindexer combinedindexer indexertests strigicmd)
+
+ if (CLucene_FOUND)
+@@ -11,32 +10,31 @@
+
+ if (HyperEstraier_FOUND)
+ set(DIRS ${DIRS} estraierindexer)
+- message("** HyperEstraier support is experimental. **")
++ message("** HyperEstraier support is broken. Do not rely on it. **")
+ endif (HyperEstraier_FOUND)
+
+ if (SQLite_FOUND)
+ set(DIRS ${DIRS} sqliteindexer)
+- message("** SQLite support is experimental. **")
++ message("** SQLite support is broken. Do not rely on it. **")
+ endif (SQLite_FOUND)
+
+-if (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- if(NOT WIN32)
+- set(DIRS ${DIRS} htmlgui)
+- endif(NOT WIN32)
+- # searchclient needs htmlgui which is not compilable on win32
+- if (QT_QTDBUS_FOUND AND NOT WIN32)
+- set(DIRS ${DIRS} searchclient)
+- endif (QT_QTDBUS_FOUND AND NOT WIN32)
+- # make sure we build the daemon on all architectures - not as long as sys/socket.h is used
+- if(NOT WIN32)
+- set(DIRS ${DIRS} daemon)
+- endif(NOT WIN32)
+- message(STATUS "Index libraries were found. strigidaemon will be built.")
+-else (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- message("** No index libraries were found. strigidaemon will not be built.")
++if(NOT WIN32)
++ set(DIRS ${DIRS} htmlgui)
++endif(NOT WIN32)
++# searchclient needs htmlgui which is not compilable on win32
++if (QT_QTDBUS_FOUND AND NOT WIN32)
++ set(DIRS ${DIRS} searchclient)
++endif (QT_QTDBUS_FOUND AND NOT WIN32)
++# make sure we build the daemon on all architectures - not as long as sys/socket.h is used
++if(NOT WIN32)
++ set(DIRS ${DIRS} daemon)
++endif(NOT WIN32)
++
++if (NOT CLucene_FOUND)
++ message("** No CLucene libraries were found, so Strigi cannot use indexes.")
+ message("** It is recommended to install CLucene >= 0.9.16.")
+ message("** You will still be able to use deepfind, deepgrep and xmlindexer.")
+-endif (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
++endif (NOT CLucene_FOUND)
+
+ if (QT4_FOUND)
+ set(DIRS ${DIRS} archiveengine qclient)
+--- a/src/combinedindexer/CMakeLists.txt
++++ b/src/combinedindexer/CMakeLists.txt
+@@ -4,29 +4,7 @@
+ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streams/strigi)
+
+-if (CLucene_FOUND)
+- add_definitions(-DHAVE_CLUCENE)
+- set(combinedindex_LIBS ${combinedindex_LIBS} cluceneindex)
+- include_directories( ../luceneindexer )
+-endif (CLucene_FOUND)
+-
+-if (HyperEstraier_FOUND)
+- add_definitions(-DHAVE_ESTRAIER)
+- set(combinedindex_LIBS ${combinedindex_LIBS} estraierindex)
+- include_directories( ../estraierindexer )
+-endif (HyperEstraier_FOUND)
+-
+-if (SQLite_FOUND)
+- add_definitions(-DHAVE_SQLITE)
+- set(combinedindex_LIBS ${combinedindex_LIBS} sqliteindex)
+- include_directories( ../sqliteindexer )
+-endif (SQLite_FOUND)
+-
+ add_library(combinedindex combinedindexmanager.cpp)
+
+ target_link_libraries(combinedindex streamanalyzer grepindex
+ ${combinedindex_LIBS})
+-
+-#add_executable(combinedindexer combinedindexer.cpp)
+-#target_link_libraries(combinedindexer combinedindex filters)
+-
+--- a/src/combinedindexer/combinedindexmanager.cpp
++++ b/src/combinedindexer/combinedindexmanager.cpp
+@@ -21,6 +21,7 @@
+ #include <strigi/strigiconfig.h>
+ #include "variant.h"
+
++/*
+ #include "grepindexmanager.h"
+ #ifdef HAVE_CLUCENE
+ #include "cluceneindexmanager.h"
+@@ -34,20 +35,26 @@
+ #ifdef HAVE_SQLITE
+ #include "sqliteindexmanager.h"
+ #endif
++*/
+
+ #include "tssptr.h"
+ #include "query.h"
+ #include "indexeddocument.h"
+ #include "indexreader.h"
++#include "indexpluginloader.h"
+ #include <string>
+ #include <set>
+ #include <map>
+ using namespace std;
+ using namespace Strigi;
+
++/*
+ map<string, IndexManager*(*)(const char*)>
+ CombinedIndexManager::factories() {
+ map<string, IndexManager*(*)(const char*)> factories;
++ //IndexPluginLoader pluginloader;
++ //factories = pluginloader.factories();
++
+ #ifdef HAVE_ESTRAIER
+ factories["estraier"] = createEstraierIndexManager;
+ #endif
+@@ -74,7 +81,7 @@
+ }
+ return v;
+ }
+-
++*/
+ class CombinedIndexReader : public IndexReader {
+ private:
+ CombinedIndexManager* m;
+@@ -119,19 +126,21 @@
+ }
+ CombinedIndexManager::Private::~Private() {
+ if (writermanager) {
+- delete writermanager;
++ IndexPluginLoader::deleteIndexManager(writermanager);
+ }
+ }
+ CombinedIndexManager::CombinedIndexManager(const string& type,
+ const string& indexdir) :p(new CombinedIndexManager::Private(this)) {
++ p->writermanager = IndexPluginLoader::createIndexManager(type.c_str(),
++ indexdir.c_str());
+ // determine the right index manager
+- map<string, IndexManager*(*)(const char*)> l_factories = factories();
++/* map<string, IndexManager*(*)(const char*)> l_factories = factories();
+ map<string, IndexManager*(*)(const char*)>::const_iterator f
+ = l_factories.find(type);
+ if (f == l_factories.end()) {
+ f = l_factories.begin();
+ }
+- p->writermanager = f->second(indexdir.c_str());
++ p->writermanager = f->second(indexdir.c_str());*/
+ }
+ CombinedIndexManager::~CombinedIndexManager() {
+ delete p;
+@@ -148,14 +157,12 @@
+ CombinedIndexManager::addReadonlyIndex(const string& indexdir,
+ const string& type) {
+ removeReadonlyIndex(indexdir);
+- // determine the right index manager
+- map<string, IndexManager*(*)(const char*)> l_factories = factories();
+- map<string, IndexManager*(*)(const char*)>::const_iterator f
+- = l_factories.find(type);
+- if (f == l_factories.end()) {
++
++ IndexManager* im = IndexPluginLoader::createIndexManager(type.c_str(),
++ indexdir.c_str());
++ if (im == 0) {
+ return;
+ }
+- IndexManager* im = f->second(indexdir.c_str());
+ p->lock.lock();
+ p->readmanagers[indexdir] = im;
+ p->lock.unlock();
+--- a/src/combinedindexer/combinedindexmanager.h
++++ b/src/combinedindexer/combinedindexmanager.h
+@@ -40,10 +40,6 @@
+
+ void addReadonlyIndex(const std::string& indexdir, const std::string& type);
+ void removeReadonlyIndex(const std::string& indexdir);
+-
+- static std::map<std::string, Strigi::IndexManager*(*)(const char*)>
+- factories();
+- static std::vector<std::string> backEnds();
+ };
+
+ #endif
+--- a/src/combinedindexer/tssptr.h
++++ b/src/combinedindexer/tssptr.h
+@@ -19,6 +19,7 @@
+ */
+
+ #include "strigi_thread.h"
++#include "indexpluginloader.h"
+
+ // thread safe smart pointer
+ template <class T>
+@@ -61,7 +62,7 @@
+ int c = --(p->count);
+ p->lock.unlock();
+ if (c == 0) {
+- delete p->p;
++ Strigi::IndexPluginLoader::deleteIndexManager(p->p);
+ delete p;
+ }
+ p = 0;
+--- a/src/daemon/daemon.cpp
++++ b/src/daemon/daemon.cpp
+@@ -21,6 +21,7 @@
+ #include "interface.h"
+ #include "daemonconfigurator.h"
+ #include "combinedindexmanager.h"
++#include "indexpluginloader.h"
+
+ #include "indexscheduler.h"
+ #include "analyzerconfiguration.h"
+@@ -151,7 +152,7 @@
+ }
+ void
+ printBackendList() {
+- std::vector<std::string> backends = CombinedIndexManager::backEnds();
++ std::vector<std::string> backends = IndexPluginLoader::indexNames();
+ for ( unsigned int i = 0; i < backends.size(); ++i ) {
+ printf( "%s\n", backends[i].c_str() );
+ }
+@@ -194,7 +195,7 @@
+ }
+ void
+ ensureBackend( const std::string& backendName ) {
+- std::vector<std::string> backends = CombinedIndexManager::backEnds();
++ std::vector<std::string> backends = IndexPluginLoader::indexNames();
+ if ( std::find( backends.begin(), backends.end(), backendName ) == backends.end() ) {
+ fprintf( stderr, "Unknown backend type: %s\n", backendName.c_str() );
+ exit( 2 );
+--- a/src/daemon/eventlistener/inotifylistener.cpp
++++ b/src/daemon/eventlistener/inotifylistener.cpp
+@@ -39,6 +39,38 @@
+ using namespace std;
+ using namespace Strigi;
+
++namespace {
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
++
++ char separator = '/';
++
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
++
++ return temp;
++ }
++}
++
+ class MatchString {
+ string m_fixed_val;
+
+@@ -345,59 +377,38 @@
+ m_toWatch.clear();
+ m_toIndex.clear();
+
+- Strigi::FileLister lister (m_pindexerconfiguration);
+-
+ for (set<string>::iterator iter = m_newDirs.begin();
+ iter != m_newDirs.end(); iter++)
+ {
+- string filename;
+- time_t mTime;
+-
+- lister.startListing( *iter);
+-
+- while (lister.nextFile( filename, mTime) != -1)
+- m_toIndex.insert (make_pair (filename, mTime));
+-
+- //TODO: look for a better solution
+- set<string> temp = lister.getListedDirs();
+- for (set<string>::iterator it = temp.begin(); it != temp.end(); it++)
+- m_toWatch.insert(*it);
+- }
+-
+- map <string, time_t> indexedFiles = m_pManager->indexReader()->files(0);
+- map<string,time_t>::iterator mi = indexedFiles.begin();
+-
+- while (mi != indexedFiles.end()) {
+- map<string,time_t>::iterator it = m_toIndex.find(mi->first);
+-
+- if (it == m_toIndex.end()) {
+- // file has been deleted since last run
+- m_events.push_back (new Event (Event::DELETED, mi->first));
++ DirLister lister(m_pindexerconfiguration);
++ string path;
++ vector<pair<string, struct stat> > dirs;
++
++ lister.startListing (*iter);
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
+
+- // no more useful, speedup into dirsRemoved
+- map<string,time_t>::iterator itrm = mi;
+- mi++;
+- indexedFiles.erase(itrm);
+- }
+- else if (mi->second < it->second) {
+- // file has been updated since last run
+- m_events.push_back (new Event (Event::UPDATED, mi->first));
+- m_toIndex.erase (it);
+- mi++;
+- }
+- else {
+- // file has NOT been changed since last run,
+- // we keep our indexed information
+- m_toIndex.erase (it);
+- mi++;
++ if (S_ISDIR(stats.st_mode)) {
++ //dir
++ m_toWatch.insert (iter->first);
++ }
++ else if (S_ISREG(stats.st_mode)) {
++ //file
++ m_events.push_back (new Event (Event::CREATED, iter->first));
++ }
++ }
++ ret = lister.nextDir(path, dirs);
+ }
+ }
+
+- // now m_toIndex contains only files created since the last run
+- for (mi = m_toIndex.begin(); mi != m_toIndex.end(); mi++)
+- m_events.push_back (new Event (Event::CREATED, mi->first));
+-
+ m_nomoreIndexedDirs.clear();
++ set<string> alreadyWatched;
++
+ for (map<int, string>::iterator it = watchedDirs.begin();
+ it != watchedDirs.end(); it++)
+ {
+@@ -405,7 +416,68 @@
+ if (match == m_toWatch.end()) // dir is no longer watched
+ m_nomoreIndexedDirs.insert(it->second);
+ else // dir is already watched
+- m_toWatch.erase (match);
++ alreadyWatched.insert (*match);
++ }
++
++ // look for updated dirs
++ m_toIndex.clear();
++ for (set<string>::iterator iter = alreadyWatched.begin();
++ iter != alreadyWatched.end(); iter++)
++ {
++ // retrieve files contained into the already watched dirs
++
++ Strigi::DirLister lister (m_pindexerconfiguration);
++
++ lister.startListing (*iter);
++
++ string path;
++ vector<pair<string, struct stat> > dirs;
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ cout << "path = " << path << endl;
++
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
++ if (S_ISREG(stats.st_mode))
++ m_toIndex.insert (make_pair (iter->first, stats.st_mtime));
++ }
++ ret = lister.nextDir(path, dirs);
++ }
++
++ map <string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren (*iter, indexedFiles);
++ for (map<string, time_t>::iterator iter = m_toIndex.begin();
++ iter != m_toIndex.end(); iter++)
++ {
++ map<string, time_t>::iterator match;
++ match = indexedFiles.find(iter->first);
++ if (match == indexedFiles.end()) {
++ // new file created
++ m_events.push_back (new Event (Event::CREATED, iter->first));
++ }
++ else if (match->second < iter->second) {
++ // file has been updated
++ m_events.push_back (new Event (Event::UPDATED, iter->first));
++ }
++ }
++ m_toIndex.clear();
++ }
++
++ // remove no more indexed items
++ for (set<string>::iterator iter = m_nomoreIndexedDirs.begin();
++ iter != m_nomoreIndexedDirs.end(); iter++)
++ {
++ map <string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren (*iter, indexedFiles);
++
++ for (map<string,time_t>::iterator mi = indexedFiles.begin();
++ mi != indexedFiles.end(); mi++)
++ {
++ m_events.push_back (new Event (Event::DELETED, mi->first));
++ }
+ }
+
+ if (testInterrupt()) {
+@@ -738,25 +810,35 @@
+ // a new directory has been created or an already watched
+ // directory has been moved into a watched place
+
+- m_toIndex.clear();
+ m_toWatch.clear();
+
+- FileLister lister(m_pindexerconfiguration);
+-
+- string filename;
+- time_t mTime;
+- while (lister.nextFile( filename, mTime) != -1)
+- m_toIndex.insert (make_pair (filename, mTime));
+-
+- m_toWatch = lister.getListedDirs();
+-
+- for (map<string,time_t>::iterator i = m_toIndex.begin();
+- i != m_toIndex.end(); i++)
+- {
+- Event* event = new Event (Event::CREATED, i->first);
+- events.push_back (event);
++ DirLister lister(m_pindexerconfiguration);
++ string path;
++ vector<pair<string, struct stat> > dirs;
++
++ lister.startListing (file);
++ int ret = lister.nextDir(path, dirs);
++
++ while (ret != -1) {
++ for (vector<pair<string, struct stat> >::iterator iter = dirs.begin();
++ iter != dirs.end(); iter++)
++ {
++ struct stat stats = iter->second;
++
++ if (S_ISDIR(stats.st_mode)) {
++ //dir
++ m_toWatch.insert (iter->first);
++ }
++ else if (S_ISREG(stats.st_mode)) {
++ //file
++ Event* event = new Event (Event::CREATED,
++ iter->first);
++ events.push_back (event);
++ }
++ }
++ ret = lister.nextDir(path, dirs);
+ }
+-
++
+ // add new watches
+ addWatches (m_toWatch);
+
+@@ -1066,8 +1148,9 @@
+ // we've to de-index all files contained into the deleted/moved directory
+ if (m_pManager)
+ {
+- // all indexed files
+- map<string, time_t> indexedFiles = m_pManager->indexReader()->files(0);
++ // all indexed files contained into dir
++ map<string, time_t> indexedFiles;
++ m_pManager->indexReader()->getChildren(dir, indexedFiles);
+
+ // remove all entries that were contained into the removed dir
+ for (map<string, time_t>::iterator it = indexedFiles.begin();
+@@ -1076,12 +1159,8 @@
+ if (enableInterrupt && testInterrupt())
+ break;
+
+- string::size_type pos = (it->first).find (dir);
+- if (pos == 0)
+- {
+- Event* event = new Event (Event::DELETED, it->first);
+- newEvents.push_back (event);
+- }
++ Event* event = new Event (Event::DELETED, it->first);
++ newEvents.push_back (event);
+ }
+ }
+ else
+--- a/src/daemon/eventlistener/pollinglistener.cpp
++++ b/src/daemon/eventlistener/pollinglistener.cpp
+@@ -38,6 +38,38 @@
+ using namespace std;
+ using namespace Strigi;
+
++namespace {
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
++
++ char separator = '/';
++
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
++
++ return temp;
++ }
++}
++
+ PollingListener::PollingListener() :EventListener("PollingListener") {
+ setState(Idling);
+ STRIGI_MUTEX_INIT(&m_mutex);
+@@ -123,35 +155,7 @@
+
+ STRIGI_MUTEX_UNLOCK (&m_mutex);
+ }
+-/*!
+-* @param path string containing path to check
+-* Appends the terminating char to path.
+-* Under Windows that char is '\', '/' under *nix
+-*/
+-string fixPath (string path)
+-{
+- if ( path.c_str() == NULL || path.length() == 0 )
+- return "";
+-
+- string temp(path);
+-
+-#ifdef HAVE_WINDOWS_H
+- size_t l= temp.length();
+- char* t = (char*)temp.c_str();
+- for (size_t i=0;i<l;i++){
+- if ( t[i] == '\\' )
+- t[i] = '/';
+- }
+- temp[0] = tolower(temp.at(0));
+-#endif
+-
+- char separator = '/';
+
+- if (temp[temp.length() - 1 ] != separator)
+- temp += separator;
+-
+- return temp;
+-}
+ void
+ PollingListener::addWatches(const set<string>& watches, bool enableInterrupt) {
+ for (set<string>::iterator iter = watches.begin();
+--- a/src/daemon/interface.cpp
++++ b/src/daemon/interface.cpp
+@@ -18,9 +18,10 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include "interface.h"
+-#include "indexreader.h"
+ #include "combinedindexmanager.h"
++#include "indexreader.h"
+ #include "indexwriter.h"
++#include "indexpluginloader.h"
+ #include "indexscheduler.h"
+ #include "eventlistener.h"
+ #include "streamanalyzer.h"
+@@ -69,7 +70,7 @@
+ }
+ vector<string>
+ Interface::getBackEnds() {
+- return manager.backEnds();
++ return IndexPluginLoader::indexNames();
+ }
+ map<string, string>
+ Interface::getStatus() {
+--- a/src/estraierindexer/CMakeLists.txt
++++ b/src/estraierindexer/CMakeLists.txt
+@@ -3,15 +3,26 @@
+ include_directories( ../streamanalyzer ../streams ${EST_INCLUDE_DIR}
+ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streams/strigi)
++link_directories(${EST_LIBDIR})
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EST_CFLAGS}")
+
+-add_library(estraierindex
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(estraier MODULE
+ estraierindexmanager.cpp
+ estraierindexreader.cpp
+ estraierindexwriter.cpp
+ )
+-
+-target_link_libraries(estraierindex streamanalyzer ${EST_LIBS})
+-
+-add_executable(estraierindexer estraierindexer.cpp)
+-target_link_libraries(estraierindexer estraierindex)
+-
++set_target_properties(estraier PROPERTIES PREFIX ${prefix})
++target_link_libraries(estraier ${EST_LIBS})
++install(TARGETS estraier LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+--- a/src/estraierindexer/estraierindexmanager.cpp
++++ b/src/estraierindexer/estraierindexmanager.cpp
+@@ -22,20 +22,21 @@
+ #include "estraierindexreader.h"
+ #include "estraierindexwriter.h"
+ #include "strigi_thread.h"
++#include "indexplugin.h"
++#include <iostream>
+ #include <assert.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
++#include <errno.h>
+ #include "stgdirent.h" //our dirent compatibility header... uses native if available
+ using namespace std;
+ using namespace Strigi;
+
+-pthread_mutex_t EstraierIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(EstraierIndexManager)
+
+-Strigi::IndexManager*
+-createEstraierIndexManager(const char* path) {
+- return new EstraierIndexManager(path);
+-}
++pthread_mutex_t EstraierIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
+
+ EstraierIndexManager::EstraierIndexManager(const char* dbd)
+ : dblock(lock), dbdir(dbd) {
+--- a/src/estraierindexer/estraierindexmanager.h
++++ b/src/estraierindexer/estraierindexmanager.h
+@@ -56,7 +56,4 @@
+ void deleteIndex();
+ };
+
+-Strigi::IndexManager*
+-createEstraierIndexManager(const char* path);
+-
+ #endif
+--- a/src/estraierindexer/estraierindexreader.cpp
++++ b/src/estraierindexer/estraierindexreader.cpp
+@@ -37,7 +37,7 @@
+ // build the phrase string
+
+ // write the part of the query that matches the document context
+- string inphrase, exphrase;
++/* string inphrase, exphrase;
+ set<string> terms;
+ const map<string, set<string> >& includes = query.includes();
+ map<string, set<string> >::const_iterator i = includes.find("");
+@@ -60,9 +60,9 @@
+ phrase += " ANDNOT ";
+ }
+ phrase += *j;
+- }
++ } */
+ ESTCOND* cond = est_cond_new();
+- printf("%s", phrase.c_str());
++/* printf("%s", phrase.c_str());
+ if (phrase.length() > 0) {
+ est_cond_set_phrase(cond, phrase.c_str());
+ }
+@@ -93,7 +93,7 @@
+ est_cond_add_attr(cond, att.c_str());
+ }
+ }
+- printf("\n");
++ printf("\n");*/
+
+ return cond;
+ }
+@@ -136,7 +136,7 @@
+ return n;
+ }
+ vector<IndexedDocument>
+-EstraierIndexReader::query(const Query& query) {
++EstraierIndexReader::query(const Query& query, int off, int max) {
+ ESTCOND* cond = createCondition(query);
+ est_cond_set_max(cond, 10);
+ int n;
+@@ -182,9 +182,17 @@
+ free(ids);
+ return results;
+ }
+-map<string, time_t>
+-EstraierIndexReader::files(char depth) {
+- map<string, time_t> files;
++void
++EstraierIndexReader::getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max) {
++}
++void
++EstraierIndexReader::getChildren(const std::string& parent,
++ std::map<std::string, time_t>& children) {
++/* map<string, time_t> files;
+ ESTCOND* cond = est_cond_new();
+ string q = "depth NUMEQ 0";
+ est_cond_add_attr(cond, q.c_str());
+@@ -208,7 +216,7 @@
+ // clean up
+ est_cond_delete(cond);
+ free(ids);
+- return files;
++ return files;*/
+ }
+ int32_t
+ EstraierIndexReader::countDocuments() {
+@@ -231,16 +239,10 @@
+ manager->deref();
+ return count;
+ }
+-int64_t
+-EstraierIndexReader::documentId(const string& uri) {
+- ESTDB* db = manager->ref();
+- int64_t id = est_db_uri_to_id(db, uri.c_str());
+- manager->deref();
+- return id;
+-}
+ time_t
+-EstraierIndexReader::mTime(int64_t docid) {
++EstraierIndexReader::mTime(const std::string& uri) {
+ ESTDB* db = manager->ref();
++ int64_t docid = est_db_uri_to_id(db, uri.c_str());
+ time_t mtime = -1;
+ char *cstr = est_db_get_doc_attr(db, docid, "@mdate");
+ if (cstr) {
+@@ -248,12 +250,7 @@
+ free(cstr);
+ }
+ manager->deref();
+- return mtime;
+-
+-}
+-time_t
+-EstraierIndexReader::mTime(const std::string& uri) {
+- return mTime(documentId(uri));
++ return docid;
+ }
+ vector<string>
+ EstraierIndexReader::fieldNames() {
+@@ -264,3 +261,14 @@
+ const string& labeltype) {
+ return vector<pair<string,uint32_t> >();
+ }
++int32_t
++EstraierIndexReader::countKeywords(const std::string& keywordprefix,
++ const std::vector<std::string>& fieldnames) {
++ return -1;
++}
++vector<string>
++EstraierIndexReader::keywords(const std::string& keywordmatch,
++ const std::vector<std::string>& fieldnames,
++ uint32_t max, uint32_t offset) {
++ return vector<string>();
++}
+--- a/src/estraierindexer/estraierindexreader.h
++++ b/src/estraierindexer/estraierindexreader.h
+@@ -36,14 +36,14 @@
+ static ESTCOND* createCondition(const Strigi::Query&);
+ static const char* mapId(const std::string& id);
+ public:
++ std::vector<Strigi::IndexedDocument> query(const Strigi::Query&,
++ int off, int max);
++ void getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max);
+ int32_t countHits(const Strigi::Query&);
+- std::vector<Strigi::IndexedDocument> query(const Strigi::Query&);
+- std::map<std::string, time_t> files(char depth);
+- int countDocuments();
+- int32_t countWords();
+- int64_t indexSize();
+- int64_t documentId(const std::string& uri);
+- time_t mTime(int64_t docid);
+ time_t mTime(const std::string& uri);
+ std::vector<std::string> fieldNames();
+ std::vector<std::pair<std::string,uint32_t> > histogram(
+@@ -54,6 +54,11 @@
+ std::vector<std::string> keywords(const std::string& keywordmatch,
+ const std::vector<std::string>& fieldnames,
+ uint32_t max, uint32_t offset);
++ void getChildren(const std::string& parent,
++ std::map<std::string, time_t>& children);
++ int countDocuments();
++ int32_t countWords();
++ int64_t indexSize();
+ };
+
+ #endif
+--- a/src/estraierindexer/estraierindexwriter.cpp
++++ b/src/estraierindexer/estraierindexwriter.cpp
+@@ -49,16 +49,16 @@
+ EstraierIndexWriter::addValue(const AnalysisResult* idx,
+ const RegisteredField* field, const string& value) {
+ ESTDOC* doc = static_cast<ESTDOC*>(idx->writerData());
+- if (field->getKey() == "size") {
++ if (field->key() == "size") {
+ est_doc_add_attr(doc, "@size", value.c_str());
+- } else if (field->getKey() == "title") {
++ } else if (field->key() == "title") {
+ est_doc_add_attr(doc, "@title", value.c_str());
+ } else {
+- est_doc_add_attr(doc, field->getKey().c_str(), value.c_str());
++ est_doc_add_attr(doc, field->key().c_str(), value.c_str());
+ }
+ }
+ void
+-EstraierIndexWriter::startAnalysis(AnalysisResult* idx) {
++EstraierIndexWriter::startAnalysis(const AnalysisResult* idx) {
+ // allocate a new estraier document
+ ESTDOC* doc = est_doc_new();
+ idx->setWriterData(doc);
+--- a/src/estraierindexer/estraierindexwriter.h
++++ b/src/estraierindexer/estraierindexwriter.h
+@@ -31,7 +31,7 @@
+ const std::string indexpath;
+
+ protected:
+- void startAnalysis(Strigi::AnalysisResult*);
++ void startAnalysis(const Strigi::AnalysisResult*);
+ void addValue(const Strigi::AnalysisResult*, const Strigi::RegisteredField* field,
+ const std::string& value);
+ void addValue(const Strigi::AnalysisResult*, const Strigi::RegisteredField* field,
+--- a/src/estraierindexer/tests/CMakeLists.txt
++++ b/src/estraierindexer/tests/CMakeLists.txt
+@@ -1,9 +1,10 @@
+ include_directories(.. ../../indexertests)
++link_directories(${EST_LIBDIR})
+
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp EstraierTest.cpp)
+
+ ADD_EXECUTABLE(testrunner ${Tests} )
+-target_link_libraries(testrunner streams estraierindex indexertests)
++target_link_libraries(testrunner streams indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/estraierindexer/tests/EstraierTest.cpp
++++ b/src/estraierindexer/tests/EstraierTest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "estraierindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -15,7 +16,8 @@
+
+ // initialize a directory for writing and an indexmanager
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+- EstraierIndexManager* manager = new EstraierIndexManager(path);
++ Strigi::IndexManager *manager
++ = Strigi::IndexPluginLoader::createIndexManager("estraier", path);
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+--- a/src/htmlgui/strigihtmlgui.cpp
++++ b/src/htmlgui/strigihtmlgui.cpp
+@@ -27,6 +27,7 @@
+ #include <dirent.h>
+ #include <sstream>
+ #include <fstream>
++#include <iostream>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -56,7 +57,9 @@
+ }
+ void
+ StrigiHtmlGui::printHtmlHeader(ostream& out) {
+- out << "<?xml version='1.0' encoding='utf-8'?>\n"
++ // FIXME: extra spaces added at the beginning as a wordaround because
++ // KIO discards several first chars for unknown reason
++ out << " <?xml version='1.0' encoding='utf-8'?>\n"
+ "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' "
+ "'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n"
+ "<html xmlns='http://www.w3.org/1999/xhtml'>"
+@@ -190,12 +193,15 @@
+ if (i != params.end()) {
+ max = atoi(i->second.c_str());
+ }
+- if (max == 0) max = 10;
++ if (max <= 0 || max > 1000) max = 10;
+ int off = 0;
+ i = params.find("o");
+ if (i != params.end()) {
+ off = atoi(i->second.c_str());
+ }
++ if (off < 0) {
++ off = 0;
++ }
+ string selectedtab;
+ i = params.find("t");
+ if (i != params.end()) {
+@@ -215,20 +221,23 @@
+ bool doother = true;
+ tabs = readTabQueries();
+ if (tabs.size() == 0) {
+- tabs["Images"] = "content.mime_type:image*";
+- tabs["Mail"] = "content.mime_type:message/*";
+- tabs["Web"] = "content.mime_type:text/html";
+- tabs["Text"] = "content.mime_type:text/*";
++ tabs["Images"] = "mimeType:image*";
++ tabs["Mail"] = "mimeType:message/*";
++ tabs["Web"] = "mimeType:text/html";
++ tabs["Text"] = "mimeType:text/*";
+ }
+ map<string, string>::const_iterator j;
+ string otherq = query;
+ for (j = tabs.begin(); j != tabs.end(); ++j) {
+- string q = query+' '+j->second;
++ string q = query;
++ if (q != j->second) {
++ q += ' ' + j->second;
++ }
+ int c = p->strigi.countHits(q);
+ if (c > 0) {
+ hitcounts[j->first] = c;
+ doother &= c < count;
+- otherq += " -" + j->second;
++ otherq += " -" + j->second;
+ if (j->first == selectedtab || activetab.size() == 0) {
+ activetab = j->first;
+ activequery = q;
+@@ -424,9 +433,9 @@
+ icon = "<div class='iconbox'><img class='icon' src='"+icon;
+ icon += "'/></div>\n";
+ }
+- t = doc.properties.find("audio.title");
++ t = doc.properties.find("title");
+ if (t == doc.properties.end()) {
+- t = doc.properties.find("email.subject");
++ t = doc.properties.find("subject");
+ }
+ size_t l = doc.uri.rfind('/');
+ if (t != doc.properties.end()) {
+--- a/src/luceneindexer/cluceneindexmanager.cpp
++++ b/src/luceneindexer/cluceneindexmanager.cpp
+@@ -27,12 +27,17 @@
+ #include <CLucene.h>
+ #include "cluceneindexwriter.h"
+ #include "cluceneindexreader.h"
++#include "indexplugin.h"
+ #include <iostream>
+ #include <sys/types.h>
+ #include <time.h>
+ #include "timeofday.h"
+ #include "stgdirent.h" //our dirent compatibility header... uses native if available
+
++
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(CLuceneIndexManager)
++
+ using namespace lucene::index;
+ using lucene::analysis::standard::StandardAnalyzer;
+ using lucene::store::FSDirectory;
+@@ -51,6 +56,11 @@
+ indexwriter = 0;
+ writer = new CLuceneIndexWriter(this);
+ analyzer = new StandardAnalyzer();
++ if (path == ":memory:") {
++ ramdirectory = new lucene::store::RAMDirectory();
++ } else {
++ ramdirectory = 0;
++ }
+ mtime = 0;
+
+ //remove any old segments lying around from crashes, etc
+@@ -67,6 +77,7 @@
+ r->second = 0;
+ }
+ closeWriter();
++ delete ramdirectory;
+ delete analyzer;
+ if (--numberOfManagers == 0) {
+ // temporarily commented out because of problem with clucene
+@@ -116,16 +127,22 @@
+ void
+ CLuceneIndexManager::openWriter(bool truncate) {
+ try {
+- if (!truncate && IndexReader::indexExists(dbdir.c_str())) {
++ if (ramdirectory) {
++ indexwriter = new IndexWriter(ramdirectory, analyzer, true);
++ } else if (!truncate && IndexReader::indexExists(dbdir.c_str())) {
+ if (IndexReader::isLocked(dbdir.c_str())) {
+ IndexReader::unlock(dbdir.c_str());
+ }
+ indexwriter = new IndexWriter(dbdir.c_str(), analyzer, false);
+ } else {
+- indexwriter = new IndexWriter(dbdir.c_str(), analyzer, true, true);
++ indexwriter = new IndexWriter(dbdir.c_str(), analyzer, true);
+ }
+ } catch (CLuceneError& err) {
+- printf("could not create writer: %s\n", err.what());
++ fprintf(stderr, "could not create writer: %s\n", err.what());
++ indexwriter = 0;
++ } catch (...) {
++ fprintf(stderr, "Unknown exception was thrown.");
++ indexwriter = 0;
+ }
+ }
+ void
+@@ -201,3 +218,4 @@
+ mtime = t.tv_sec;
+ lock.unlock();
+ }
++
+--- a/src/luceneindexer/cluceneindexmanager.h
++++ b/src/luceneindexer/cluceneindexmanager.h
+@@ -22,7 +22,6 @@
+
+ #include <strigi/strigiconfig.h>
+ #include "indexmanager.h"
+-//#include "querybitset.h"
+ #include <strigi_thread.h>
+ #include <string>
+ #include <map>
+@@ -38,6 +37,9 @@
+ class IndexWriter;
+ class IndexReader;
+ }
++ namespace store {
++ class RAMDirectory;
++ }
+ }
+
+ class CLuceneIndexReader;
+@@ -50,13 +52,14 @@
+ std::map<STRIGI_THREAD_TYPE, CLuceneIndexReader*> readers;
+ CLuceneIndexWriter* writer;
+ lucene::index::IndexWriter* indexwriter;
+- //Strigi::QueryBitsetCache bitsets;
+ lucene::analysis::Analyzer* analyzer;
+ time_t mtime;
+ static int numberOfManagers;
+
+ void openWriter(bool truncate=false);
+ public:
++ lucene::store::RAMDirectory* ramdirectory;
++
+ explicit CLuceneIndexManager(const std::string& path);
+ ~CLuceneIndexManager();
+
+@@ -65,7 +68,6 @@
+ Strigi::IndexReader* indexReader();
+ Strigi::IndexWriter* indexWriter();
+ CLuceneIndexReader* luceneReader();
+-// Strigi::QueryBitsetCache* bitSets();
+ int32_t docCount();
+ int64_t indexSize();
+ void deleteIndex();
+@@ -74,7 +76,4 @@
+ void setIndexMTime();
+ };
+
+-CLUCENEINDEXER_EXPORT Strigi::IndexManager*
+-createCLuceneIndexManager(const char* path);
+-
+ #endif
+--- a/src/luceneindexer/cluceneindexreader.cpp
++++ b/src/luceneindexer/cluceneindexreader.cpp
+@@ -137,7 +137,11 @@
+ doccount = -1;
+ wordcount = -1;
+ try {
+- reader = lucene::index::IndexReader::open(dbdir.c_str());
++ if (manager->ramdirectory) {
++ reader = lucene::index::IndexReader::open(manager->ramdirectory);
++ } else {
++ reader = lucene::index::IndexReader::open(dbdir.c_str());
++ }
+ //fprintf(stderr,
+ //"reader at %s: %i\n", dbdir.c_str(), reader->numDocs());
+ } catch (CLuceneError& err) {
+@@ -585,14 +589,14 @@
+ vector<int32_t>::const_iterator i;
+ struct tm t;
+ for (i = v.begin(); i < v.end(); ++i) {
+- time_t ti = *i;
++ time_t ti = *i;
+ #ifdef _WIN32
+ t = *localtime( &ti ); // is thread-safe on win32
+ #else
+- localtime_r(&ti, &t);
++ localtime_r(&ti, &t);
+ #endif
+- int32_t c = 10000*t.tm_year + 100*t.tm_mon + t.tm_mday;
+- m[c]++;
++ int32_t c = 10000*t.tm_year + 100*t.tm_mon + t.tm_mday;
++ m[c]++;
+ }
+ vector<pair<string,uint32_t> > h;
+ h.reserve(m.size());
+--- a/src/luceneindexer/cluceneindexwriter.cpp
++++ b/src/luceneindexer/cluceneindexwriter.cpp
+@@ -240,8 +240,11 @@
+ if (t && _tcsncmp(t, prefixText, prefixLen) == 0) {
+ try {
+ reader->deleteDocument(i);
++ } catch (CLuceneError& err) {
++ cerr << "Could not delete document '" << entry
++ << "' from the index: " << err.what() << endl;
+ } catch (...) {
+- fprintf(stderr, "could not delete document");
++ cerr << "This should not happen." << endl;
+ }
+ }
+ _CLDELETE(d);
+--- a/src/luceneindexer/CMakeLists.txt
++++ b/src/luceneindexer/CMakeLists.txt
+@@ -19,42 +19,44 @@
+ ADD_DEFINITIONS(-DUNICODE)
+ ENDIF(WIN32)
+
+-# CLucene requires exception support and has no support for visibility=hidden
+-# so we must use the default (i.e. public) value for -fvisibility
++# CLucene requires exception support
+ IF(NOT WIN32)
+ IF (CMAKE_COMPILER_IS_GNUCXX)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
+ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ ENDIF(NOT WIN32)
+-IF(__STRIGI_HAVE_GCC_VISIBILITY)
+- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
+-ENDIF(__STRIGI_HAVE_GCC_VISIBILITY)
++# In the past, we though we needed to use -fvisibility=default for compiling
++# this library. This appears not to be the case anymore.
++#IF(__STRIGI_HAVE_GCC_VISIBILITY)
++# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
++#ENDIF(__STRIGI_HAVE_GCC_VISIBILITY)
+
+ set(cluceneindex_SRCS
+-# PrefixFilter.cpp
+- cluceneindexmanager.cpp
+- cluceneindexreader.cpp
+- cluceneindexwriter.cpp
+- jsgzipcompressstream.cpp
+- tcharutils.cpp
++ cluceneindexmanager.cpp
++ cluceneindexreader.cpp
++ cluceneindexwriter.cpp
++ jsgzipcompressstream.cpp
++ tcharutils.cpp
+ )
+
+-add_library(cluceneindex SHARED ${cluceneindex_SRCS})
+-
+-set_target_properties(cluceneindex
+- PROPERTIES VERSION ${STRIGI_VERSION}
+- SOVERSION ${STRIGI_VERSION_MAJOR}
+- DEFINE_SYMBOL MAKE_CLUCENEINDEXER_LIB
+-)
+-
+-target_link_libraries(cluceneindex streamanalyzer ${CLUCENE_LIBRARY})
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(clucene MODULE ${cluceneindex_SRCS})
++set_target_properties(clucene PROPERTIES PREFIX ${prefix})
++target_link_libraries(clucene ${CLUCENE_LIBRARY})
++install(TARGETS clucene LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+
+ add_executable(luceneindexer luceneindexer.cpp)
+-target_link_libraries(luceneindexer cluceneindex)
++target_link_libraries(luceneindexer streamanalyzer)
+
+ install(TARGETS luceneindexer RUNTIME DESTINATION bin)
+-install(TARGETS cluceneindex
+- LIBRARY DESTINATION ${LIB_DESTINATION}
+- RUNTIME DESTINATION bin
+- ARCHIVE DESTINATION ${LIB_DESTINATION}
+-)
+--- a/src/luceneindexer/indexdump/CMakeLists.txt
++++ b/src/luceneindexer/indexdump/CMakeLists.txt
+@@ -1,4 +1,4 @@
+ include_directories(${CLUCENE_LIBRARY_DIR} ${CLUCENE_INCLUDE_DIR}
+ ${ICONV_INCLUDE_DIR} ..)
+-add_executable(indexdump indexdump.cpp)
+-target_link_libraries(indexdump ${CLUCENE_LIBRARY} cluceneindex)
++add_executable(indexdump indexdump.cpp ../tcharutils.cpp)
++target_link_libraries(indexdump streamanalyzer ${CLUCENE_LIBRARY})
+--- a/src/luceneindexer/luceneindexer.cpp
++++ b/src/luceneindexer/luceneindexer.cpp
+@@ -18,9 +18,8 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include <strigi/strigiconfig.h>
+-#include <CLucene.h>
+ #include "diranalyzer.h"
+-#include "cluceneindexmanager.h"
++#include "indexpluginloader.h"
+ #include "analyzerconfiguration.h"
+ #include <iostream>
+ #include <sys/types.h>
+@@ -65,10 +64,13 @@
+ Strigi::AnalyzerConfiguration ic;
+ ic.setFilters(filters);
+ try {
+- Strigi::IndexManager *manager = createCLuceneIndexManager(argv[1]);
+- Strigi::DirAnalyzer analyzer(*manager, ic);
+- analyzer.analyzeDir(argv[2]);
+- delete manager;
++ Strigi::IndexManager *manager
++ = Strigi::IndexPluginLoader::createIndexManager("clucene", argv[1]);
++ if (manager) {
++ Strigi::DirAnalyzer analyzer(*manager, ic);
++ analyzer.analyzeDir(argv[2]);
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
++ }
+ } catch (...) {
+ cerr << "error while creating index" << endl;
+ }
+--- a/src/luceneindexer/tcharutils.h
++++ b/src/luceneindexer/tcharutils.h
+@@ -25,9 +25,9 @@
+ #include <string>
+ #include <strigi/strigiconfig.h>
+
+-std::string CLUCENEINDEXER_EXPORT wchartoutf8(const wchar_t*);
+-std::wstring CLUCENEINDEXER_EXPORT utf8toucs2(const char*);
+-std::string CLUCENEINDEXER_EXPORT wchartoutf8(const std::wstring&);
+-std::wstring CLUCENEINDEXER_EXPORT utf8toucs2(const std::string&);
++std::string wchartoutf8(const wchar_t*);
++std::wstring utf8toucs2(const char*);
++std::string wchartoutf8(const std::wstring&);
++std::wstring utf8toucs2(const std::string&);
+
+ #endif
+--- a/src/luceneindexer/tests/CLuceneTest.cpp
++++ b/src/luceneindexer/tests/CLuceneTest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "cluceneindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -23,7 +24,12 @@
+ #else
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ #endif
+- Strigi::IndexManager* manager = createCLuceneIndexManager(path);
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("clucene", path);
++ if (manager == 0) {
++ founderrors++;
++ return founderrors;
++ }
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+@@ -39,7 +45,7 @@
+ rtests.testAll();
+
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ std::string cmd = "rm -r ";
+--- a/src/luceneindexer/tests/CMakeLists.txt
++++ b/src/luceneindexer/tests/CMakeLists.txt
+@@ -3,7 +3,7 @@
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp CLuceneTest.cpp)
+
+ ADD_EXECUTABLE(testrunner-lucene ${Tests} )
+-target_link_libraries(testrunner-lucene streams cluceneindex indexertests)
++target_link_libraries(testrunner-lucene streamanalyzer indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/sqliteindexer/CMakeLists.txt
++++ b/src/sqliteindexer/CMakeLists.txt
+@@ -4,14 +4,23 @@
+ ${SQLITE_LIBRARY_DIR} ${SQLITE_INCLUDE_DIR}
+ ${strigi_BINARY_DIR}/src/streams)
+
+-add_library(sqliteindex
++if(WIN32)
++ # this is needed to have mingw, cygwin and msvc libs installed in one directory
++ if(MSVC)
++ set(prefix msvc_strigiindex_)
++ elseif(CYGWIN)
++ set(prefix cyg_strigiindex_)
++ elseif(MINGW)
++ set(prefix mingw_strigiindex_)
++ endif(MSVC)
++else(WIN32)
++ set(prefix strigiindex_)
++endif(WIN32)
++add_library(sqlite MODULE
+ sqliteindexmanager.cpp
+ sqliteindexreader.cpp
+ sqliteindexwriter.cpp
+ )
+-
+-target_link_libraries(sqliteindex streamanalyzer ${SQLITE_LIBRARIES})
+-
+-add_executable(sqliteindexer sqliteindexer.cpp)
+-target_link_libraries(sqliteindexer sqliteindex sqlite3)
+-
++set_target_properties(sqlite PROPERTIES PREFIX ${prefix})
++target_link_libraries(sqlite ${SQLITE_LIBRARIES})
++install(TARGETS sqlite LIBRARY DESTINATION ${LIB_DESTINATION}/strigi)
+--- a/src/sqliteindexer/sqliteindexmanager.cpp
++++ b/src/sqliteindexer/sqliteindexmanager.cpp
+@@ -21,15 +21,15 @@
+ #include "sqliteindexreader.h"
+ #include "sqliteindexwriter.h"
+ #include "strigi_thread.h"
++#include "indexplugin.h"
++#include <iostream>
+ using namespace std;
+ using namespace Strigi;
+
+-pthread_mutex_t SqliteIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
++/* define and export the index factory */
++REGISTER_STRIGI_INDEXMANAGER(SqliteIndexManager)
+
+-Strigi::IndexManager*
+-createSqliteIndexManager(const char* path) {
+- return new SqliteIndexManager(path);
+-}
++pthread_mutex_t SqliteIndexManager::lock = PTHREAD_MUTEX_INITIALIZER;
+
+ SqliteIndexManager::SqliteIndexManager(const char* dbfile) {
+ dblock = lock;
+@@ -51,6 +51,7 @@
+ }
+ sqlite3*
+ SqliteIndexManager::opendb(const char* path) {
++ // check if the database already exists
+ sqlite3* db;
+ int r = sqlite3_open(path, &db);
+ // any value other than SQLITE_OK is an error
+@@ -85,9 +86,8 @@
+ ;
+ r = sqlite3_exec(db, sql, 0, 0, 0);
+ if (r != SQLITE_OK) {
+- fprintf(stderr, "could not create table %i %s\n", r,
+- sqlite3_errmsg(db));
+- exit(1);
++ //fprintf(stderr, "could not create table %i %s.\n", r,
++ // sqlite3_errmsg(db));
+ }
+
+ // create temporary tables
+--- a/src/sqliteindexer/sqliteindexmanager.h
++++ b/src/sqliteindexer/sqliteindexmanager.h
+@@ -54,7 +54,5 @@
+ static std::string escapeSqlValue(const std::string& value);
+ static sqlite3* opendb(const char*);
+ };
+-Strigi::IndexManager*
+-createSqliteIndexManager(const char* path);
+
+ #endif
+--- a/src/sqliteindexer/sqliteindexreader.cpp
++++ b/src/sqliteindexer/sqliteindexreader.cpp
+@@ -20,6 +20,7 @@
+ #include "sqliteindexreader.h"
+ #include "sqliteindexmanager.h"
+ #include <set>
++#include <iostream>
+ #include <sstream>
+ using namespace std;
+ using namespace Strigi;
+@@ -61,7 +62,7 @@
+ q << "f"<<a<<".count*1.0/w"<<a<<".count";
+ }
+ if (n > 0) {
+- q <<") p ";
++ q <<") p ";
+ }
+ q <<" from ";
+ for (int i=0; i<n; ++i) {
+@@ -93,16 +94,55 @@
+
+ return q.str();
+ }
++string
++createQuery(const Query& query, int off, int max) {
++ // TODO: makeing a query with wildcards slows things down, so we must
++ // think about reordering them
++ // although we'll never be able to manage queries like 'a% b% c%'
++ ostringstream q;
++ q << "select path from ";
++ //
++ for (int i=0; i<n; ++i) {
++ q << "words w" << i << ",";
++ }
++ for (int i=0; i<n; ++i) {
++ q << "filewords f" << i << ",";
++ }
++ q <<"files where ";
++ for (int i=0; i<n; ++i) {
++ q << "w" << i << ".word like ? and w" << i << ".wordid = f" << i
++ << ".wordid and ";
++ }
++ for (int i=1; i<n; ++i) {
++ q << "f0.fileid = f" << i << ".fileid and ";
++ }
++ if (n > 0) {
++ q <<"f0.fileid = files.fileid ";
++ }
++ if (filterpath) {
++ if (n > 0) q <<"and ";
++ q <<"files.path like ? ";
++ }
++ if (n > 0) q <<"group by fa.fileid order by p ";
++ q << "limit " << max << " offset " << off;
++
++ return q.str();
++}
+ int
+ SqliteIndexReader::countHits(const Strigi::Query& q) {
+ // very inefficient: needs refactoring
+ vector<IndexedDocument> r = query(q, 0, 1000000);
+ return r.size();
+ }
++string
++createQuery(const Query& query) {
++ return "select path from files;";
++}
+ vector<IndexedDocument>
+ SqliteIndexReader::query(const Strigi::Query& query, int off, int max) {
+- string q;
+- // replace * by %
++ string sql(createQuery(query, off, max));
++ vector<IndexedDocument> results;
++/* // replace * by %
+ size_t p = q.find('*');
+ while (p != string::npos) {
+ q.replace(p, 1, "%");
+@@ -116,7 +156,6 @@
+ }
+ // split up in terms
+ set<string> terms = split(q);
+- vector<IndexedDocument> results;
+ if (terms.size() == 0) return results;
+ string pathfilter;
+ set<string>::iterator i = terms.begin();
+@@ -132,17 +171,17 @@
+ if (terms.size() == 0 && pathfilter.length() == 0) return results;
+
+ string sql = createQuery(terms.size(), pathfilter.length() > 0);
+-
++*/
+ sqlite3* db = manager->ref();
+ sqlite3_stmt* stmt;
+ int r = sqlite3_prepare(db, sql.c_str(), -1, &stmt, 0);
+ if (r != SQLITE_OK) {
+- printf("could not prepare query '%s': %s\n", sql.c_str(),
++ fprintf(stderr, "could not prepare query '%s': %s\n", sql.c_str(),
+ sqlite3_errmsg(db));
+ manager->deref();
+ return results;
+ }
+- int j = 1;
++/* int j = 1;
+ for (i=terms.begin(); i!=terms.end(); ++i) {
+ sqlite3_bind_text(stmt, j++, i->c_str(), i->length(),
+ SQLITE_STATIC);
+@@ -150,7 +189,7 @@
+ if (pathfilter.length() > 0) {
+ sqlite3_bind_text(stmt, j, pathfilter.c_str(), pathfilter.length(),
+ SQLITE_STATIC);
+- }
++ }*/
+ r = sqlite3_step(stmt);
+ while (r == SQLITE_ROW) {
+ IndexedDocument doc;
+@@ -245,3 +284,10 @@
+ vector<string> k;
+ return k;
+ }
++void
++SqliteIndexReader::getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max) {
++}
+--- a/src/sqliteindexer/sqliteindexreader.h
++++ b/src/sqliteindexer/sqliteindexreader.h
+@@ -48,6 +48,11 @@
+ std::vector<std::string> keywords(const std::string& keywordmatch,
+ const std::vector<std::string>& fieldnames,
+ uint32_t max, uint32_t offset);
++ void getHits(const Strigi::Query& query,
++ const std::vector<std::string>& fields,
++ const std::vector<Strigi::Variant::Type>& types,
++ std::vector<std::vector<Strigi::Variant> >& result,
++ int off, int max);
+ };
+
+ #endif
+--- a/src/sqliteindexer/sqliteindexwriter.cpp
++++ b/src/sqliteindexer/sqliteindexwriter.cpp
+@@ -183,6 +183,7 @@
+ = content.find(wdata->id);
+
+ if (m == content.end()) {
++ delete wdata;
+ return;
+ }
+
+@@ -199,6 +200,7 @@
+ sqlite3_errmsg(db));
+ content.erase(m->first);
+ manager->deref();
++ delete wdata;
+ return;
+ }
+ map<string, int>::const_iterator i = m->second.begin();
+@@ -209,7 +211,7 @@
+ SQLITE_STATIC);
+ sqlite3_bind_int(stmt, 3, i->second);
+ r = sqlite3_step(stmt);
+- if (r != 21) { // what is 21?
++ if (r != SQLITE_DONE) { // what is 21?
+ fprintf(stderr, "could not write content into database: %i %s\n", r,
+ sqlite3_errmsg(db));
+ }
+--- a/src/sqliteindexer/tests/CMakeLists.txt
++++ b/src/sqliteindexer/tests/CMakeLists.txt
+@@ -3,7 +3,7 @@
+ CREATE_TEST_SOURCELIST(Tests testrunner.cpp SqliteTest.cpp simpletest.cpp)
+
+ ADD_EXECUTABLE(sqlitetest ${Tests} )
+-target_link_libraries(sqlitetest streams sqliteindex indexertests)
++target_link_libraries(sqlitetest streams indexertests)
+
+ SET (TestsToRun ${Tests})
+ REMOVE (TestsToRun testrunner.cpp)
+--- a/src/sqliteindexer/tests/simpletest.cpp
++++ b/src/sqliteindexer/tests/simpletest.cpp
+@@ -1,5 +1,6 @@
+ #include <strigi/strigiconfig.h>
+-#include "sqliteindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "analyzerconfiguration.h"
+@@ -38,13 +39,14 @@
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ string p(path);
+ p += "/test.db";
+- IndexManager* manager = createSqliteIndexManager(p.c_str());
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("sqlite", p.c_str());
+ IndexWriter* writer = manager->indexWriter();
+ IndexReader* reader = manager->indexReader();
+ addAndCount(writer, reader, 1);
+
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ /* std::string cmd = "rm -r ";
+--- a/src/sqliteindexer/tests/SqliteTest.cpp
++++ b/src/sqliteindexer/tests/SqliteTest.cpp
+@@ -1,5 +1,5 @@
+ #include <strigi/strigiconfig.h>
+-#include "sqliteindexmanager.h"
++#include "indexpluginloader.h"
+ #include "indexmanagertests.h"
+ #include "indexwritertests.h"
+ #include "indexreadertests.h"
+@@ -18,7 +18,8 @@
+ mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+ string p(path);
+ p += "/test.db";
+- Strigi::IndexManager* manager = createSqliteIndexManager(p.c_str());
++ Strigi::IndexManager* manager
++ = Strigi::IndexPluginLoader::createIndexManager("sqlite", p.c_str());
+
+ Strigi::AnalyzerConfiguration ic;
+ IndexManagerTests tests(manager, ic);
+@@ -34,7 +35,7 @@
+ rtests.testAll();
+ */
+ // close and clean up the manager
+- delete manager;
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
+
+ // clean up data
+ std::string cmd = "rm -r ";
+--- a/src/streamanalyzer/classproperties.cpp
++++ b/src/streamanalyzer/classproperties.cpp
+@@ -25,7 +25,6 @@
+ using namespace Strigi;
+ using namespace std;
+
+-const string ClassProperties::Private::empty;
+ ClassProperties::ClassProperties() :p(new Private()) {
+ }
+ ClassProperties::ClassProperties(const Private& pr) :p(new Private(pr)) {}
+@@ -70,12 +69,12 @@
+ const string&
+ ClassProperties::localizedName(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.name;
++ return (i == p->localized.end()) ?empty() :i->second.name;
+ }
+ const string&
+ ClassProperties::localizedDescription(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.description;
++ return (i == p->localized.end()) ?empty() :i->second.description;
+ }
+ const vector<string>&
+ ClassProperties::parentUris() const {
+--- a/src/streamanalyzer/CMakeLists.txt
++++ b/src/streamanalyzer/CMakeLists.txt
+@@ -26,6 +26,7 @@
+ htmlsaxanalyzer.cpp
+ id3v2throughanalyzer.cpp
+ indexreader.cpp
++ indexpluginloader.cpp
+ lineeventanalyzer.cpp
+ m3ustreamanalyzer.cpp
+ mimeeventanalyzer.cpp
+@@ -97,6 +98,9 @@
+ fieldproperties.h
+ fieldtypes.h
+ indexeddocument.h
++ indexreader.h
++ indexmanager.h
++ indexplugin.h
+ indexwriter.h
+ streamanalyzer.h
+ streamanalyzerfactory.h
+--- a/src/streamanalyzer/fieldproperties.cpp
++++ b/src/streamanalyzer/fieldproperties.cpp
+@@ -25,7 +25,6 @@
+ using namespace Strigi;
+ using namespace std;
+
+-const string FieldProperties::Private::empty;
+ FieldProperties::FieldProperties() :p(new Private()) {
+ }
+ FieldProperties::FieldProperties(const Private& pr) :p(new Private(pr)) {}
+@@ -102,12 +101,12 @@
+ const string&
+ FieldProperties::localizedName(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.name;
++ return (i == p->localized.end()) ?empty() :i->second.name;
+ }
+ const string&
+ FieldProperties::localizedDescription(const string& locale) const {
+ map<string,Localized>::iterator i = p->localized.find(locale);
+- return (i == p->localized.end()) ?Private::empty :i->second.description;
++ return (i == p->localized.end()) ?empty() :i->second.description;
+ }
+ const vector<string>&
+ FieldProperties::parentUris() const {
+--- a/src/streamanalyzer/fieldpropertiesdb.cpp
++++ b/src/streamanalyzer/fieldpropertiesdb.cpp
+@@ -39,7 +39,8 @@
+ #include <map>
+ #include <iostream>
+ #include <list>
+-#include <string>
++#include <set>
++
+ using namespace Strigi;
+ using namespace std;
+
+@@ -47,8 +48,8 @@
+ public:
+ map<string, FieldProperties> properties;
+ map<string, ClassProperties> classes;
+- static FieldProperties emptyField;
+- static ClassProperties emptyClass;
++ static const FieldProperties& emptyField();
++ static const ClassProperties& emptyClass();
+
+ Private();
+ static vector<string> getdirs(const string&);
+@@ -94,8 +95,16 @@
+
+ };
+
+-FieldProperties FieldPropertiesDb::Private::emptyField;
+-ClassProperties FieldPropertiesDb::Private::emptyClass;
++const FieldProperties&
++FieldPropertiesDb::Private::emptyField() {
++ static const FieldProperties e;
++ return e;
++}
++const ClassProperties&
++FieldPropertiesDb::Private::emptyClass() {
++ static const ClassProperties f;
++ return f;
++}
+
+ FieldPropertiesDb&
+ FieldPropertiesDb::db() {
+@@ -112,7 +121,7 @@
+ map<std::string, FieldProperties>::const_iterator j
+ = p->properties.find(uri);
+ if (j == p->properties.end()) {
+- return FieldPropertiesDb::Private::emptyField;
++ return FieldPropertiesDb::Private::emptyField();
+ } else {
+ return j->second;
+ }
+@@ -126,7 +135,7 @@
+ FieldPropertiesDb::classes(const std::string& uri) const {
+ map<std::string, ClassProperties>::const_iterator j = p->classes.find(uri);
+ if (j == p->classes.end()) {
+- return FieldPropertiesDb::Private::emptyClass;
++ return FieldPropertiesDb::Private::emptyClass();
+ } else {
+ return j->second;
+ }
+@@ -178,8 +187,12 @@
+
+ vector<string> dirs = getXdgDirs();
+ vector<string>::const_iterator i;
++ set<string> done;
+ for (i=dirs.begin(); i!=dirs.end(); i++) {
+- loadProperties(*i);
++ if (done.find(*i) == done.end()) {
++ done.insert(*i);
++ loadProperties(*i);
++ }
+ }
+
+ // Generate childUris, applicable* and locales values.
+@@ -255,6 +268,9 @@
+ props.uri = FieldRegister::filenameFieldName;
+ properties[FieldRegister::filenameFieldName] = props;
+
++ props.uri = FieldRegister::mimetypeFieldName;
++ properties[FieldRegister::mimetypeFieldName] = props;
++
+ props.uri = FieldRegister::parentLocationFieldName;
+ props.tokenized = false;
+ properties[FieldRegister::parentLocationFieldName] = props;
+@@ -263,13 +279,23 @@
+ FieldPropertiesDb::Private::loadProperties(const string& dir) {
+ string pdir = dir + "/strigi/fieldproperties/";
+ DIR* d = opendir(pdir.c_str());
+- if (!d) return;
++ if (!d) {
++ pdir = dir;
++ d = opendir(pdir.c_str());
++ }
++ if (!d) {
++ return;
++ }
++ if (pdir[pdir.length()-1] != '/') {
++ pdir.append("/");
++ }
+ struct dirent* de = readdir(d);
+ struct stat s;
+ char* data = 0;
+ while (de) {
+ string path(pdir+de->d_name);
+- if (!stat(path.c_str(), &s) && S_ISREG(s.st_mode)) {
++ if (path.length() >= 5 && path.substr(path.length()-5) == ".rdfs" &&
++ !stat(path.c_str(), &s) && S_ISREG(s.st_mode)) {
+ FILE* f = fopen(path.c_str(), "r");
+ if (f) {
+ // read the entire file at once
+--- a/src/streamanalyzer/fieldproperties_private.h
++++ b/src/streamanalyzer/fieldproperties_private.h
+@@ -24,12 +24,18 @@
+ #include "fieldproperties.h"
+ #include "fieldtypes.h"
+
++namespace {
++ const std::string& empty() {
++ static std::string e;
++ return e;
++ }
++}
++
+ namespace Strigi {
+
+ class FieldProperties::Private {
+ friend class FieldPropertiesDb;
+ public:
+- static const std::string empty;
+ std::string uri;
+ std::string name;
+ std::string typeuri;
+@@ -69,7 +75,6 @@
+ class ClassProperties::Private {
+ friend class FieldPropertiesDb;
+ public:
+- static const std::string empty;
+ std::string uri;
+ std::string name;
+ std::string description;
+--- a/src/streamanalyzer/fieldtypes.cpp
++++ b/src/streamanalyzer/fieldtypes.cpp
+@@ -103,7 +103,7 @@
+ = FieldPropertiesDb::db().properties(fieldname);
+ if (!props.valid()) {
+ cerr << "WARNING: field '" << fieldname << "' is not defined in "
+- ".fieldproperties ontology database." << endl;
++ "any rdfs ontology database." << endl;
+ // creates a field with defaults (stringType and no parents)
+ FieldPropertiesDb::db().addField(fieldname);
+ }
+--- a/src/streamanalyzer/filelister.cpp
++++ b/src/streamanalyzer/filelister.cpp
+@@ -47,34 +47,37 @@
+ using namespace std;
+ using namespace Strigi;
+
+-/*!
+-* @param path string containing path to check
+-* Appends the terminating char to path.
+-* Under Windows that char is '\', '/' under *nix
+-*/
+-string fixPath (string path)
++namespace
+ {
+- if ( path.c_str() == NULL || path.length() == 0 )
+- return "";
+-
+- string temp(path);
+-
+-#ifdef HAVE_WINDOWS_H
+- size_t l= temp.length();
+- char* t = (char*)temp.c_str();
+- for (size_t i=0;i<l;i++){
+- if ( t[i] == '\\' )
+- t[i] = '/';
+- }
+- temp[0] = tolower(temp.at(0));
+-#endif
++ /*!
++ * @param path string containing path to check
++ * Appends the terminating char to path.
++ * Under Windows that char is '\', '/' under *nix
++ */
++ string fixPath (string path)
++ {
++ if ( path.c_str() == NULL || path.length() == 0 )
++ return "";
++
++ string temp(path);
++
++ #ifdef HAVE_WINDOWS_H
++ size_t l= temp.length();
++ char* t = (char*)temp.c_str();
++ for (size_t i=0;i<l;i++){
++ if ( t[i] == '\\' )
++ t[i] = '/';
++ }
++ temp[0] = tolower(temp.at(0));
++ #endif
+
+- char separator = '/';
++ char separator = '/';
+
+- if (temp[temp.length() - 1 ] != separator)
+- temp += separator;
++ if (temp[temp.length() - 1 ] != separator)
++ temp += separator;
+
+- return temp;
++ return temp;
++ }
+ }
+
+ class FileLister::Private {
+--- a/src/streamanalyzer/filelister.h
++++ b/src/streamanalyzer/filelister.h
+@@ -45,7 +45,6 @@
+
+ namespace Strigi {
+
+-
+ class FileLister {
+ private:
+ class Private;
+@@ -72,7 +71,7 @@
+ void skipTillAfter(const std::string& lastToSkip);
+ };
+
+-class DirLister {
++class STRIGI_EXPORT DirLister {
+ private:
+ class Private;
+ Private* p;
+--- a/src/streamanalyzer/indexmanager.h
++++ b/src/streamanalyzer/indexmanager.h
+@@ -24,6 +24,9 @@
+ class IndexReader;
+ class IndexWriter;
+
++class IndexManager;
++void deleteIndexManager(Strigi::IndexManager* m);
++
+ /**
+ * Abstract interface that manages access to the IndexReader and IndexWriter
+ * instances provided by a particular index backend.
+@@ -38,6 +41,7 @@
+ * be used in the active thread.
+ **/
+ class IndexManager {
++friend void deleteIndexManager(Strigi::IndexManager* m);
+ public:
+ virtual ~IndexManager() {}
+ /**
+--- /dev/null
++++ b/src/streamanalyzer/indexplugin.h
+@@ -0,0 +1,40 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#ifndef STRIGI_INDEXPLUGIN_H
++#define STRIGI_INDEXPLUGIN_H
++#include <strigi/strigiconfig.h>
++
++/**
++ * @brief Macro to register functions for creating and deleting an indexmanager
++ * in a plugin
++ *
++ * @param CLASS the name of the subclass of Strigi::IndexManager
++ */
++#define REGISTER_STRIGI_INDEXMANAGER(CLASS) extern "C" { \
++ STRIGI_EXPORT Strigi::IndexManager* createIndexManager(const char* dir) { \
++ return new CLASS(dir); \
++ } \
++ STRIGI_EXPORT void deleteIndexManager(Strigi::IndexManager* m) { \
++ delete m; \
++ } \
++}
++#endif
++
+--- /dev/null
++++ b/src/streamanalyzer/indexpluginloader.cpp
+@@ -0,0 +1,245 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include "indexpluginloader.h"
++#include "indexmanager.h"
++#include <iostream>
++#include <stgdirent.h>
++#include <sys/stat.h>
++using namespace std;
++using namespace Strigi;
++
++#ifndef _WIN32
++#include <dlfcn.h>
++#define DLSYM dlsym
++#define DLCLOSE dlclose
++#else
++#define DLSYM GetProcAddress
++#define DLCLOSE FreeLibrary
++#endif
++
++#ifndef _WIN32
++typedef void* StgModuleType;
++#else
++#include <windows.h>
++typedef HMODULE StgModuleType;
++#endif
++
++// anonymous namespace for static variables
++namespace {
++ class Module {
++ private:
++ const StgModuleType mod;
++ Module(const Module&);
++ void operator=(const Module&);
++ public:
++ Strigi::IndexManager* (*create)(const char*);
++ void (*destroy)(Strigi::IndexManager*);
++ Module(StgModuleType m)
++ :mod(m) {}
++ ~Module() {
++// TODO: figure out why we get segfaults when cleaning up nicely
++ DLCLOSE(mod);
++ }
++ };
++ vector<string>
++ getdirs(const string& direnv) {
++ vector<string> dirs;
++ string::size_type lastp = 0;
++ string::size_type p = direnv.find(':');
++ while (p != string::npos) {
++ dirs.push_back(direnv.substr(lastp, p-lastp));
++ lastp = p+1;
++ p = direnv.find(':', lastp);
++ }
++ dirs.push_back(direnv.substr(lastp));
++ return dirs;
++ }
++ class ModuleList {
++ private:
++ map<std::string, Module*> modules;
++ public:
++ map<std::string, Module*>& mods() {
++ if (!initialized) initialize();
++ return modules;
++ };
++ map<void*, Module*> indexmanagers;
++ bool initialized;
++
++ ModuleList() {
++ initialized = false;
++ }
++ void initialize() {
++ initialized = true;
++ // load the plugins from the environment setting
++ string strigipluginpath;
++ if (getenv("STRIGI_PLUGIN_PATH")) {
++ strigipluginpath = getenv("STRIGI_PLUGIN_PATH");
++ }
++ vector<string> strigipluginpaths = getdirs(strigipluginpath);
++ if (strigipluginpath.size()) {
++ for (uint i=0; i<strigipluginpaths.size(); ++i) {
++ IndexPluginLoader::loadPlugins(strigipluginpaths[i].c_str());
++ }
++ } else {
++ IndexPluginLoader::loadPlugins( LIBINSTALLDIR "/strigi");
++ }
++ }
++ ~ModuleList() {
++ // delete all leftover indexmanagers
++ // if code deletes the indexmanager on it's own, the error will
++ // appear here
++ map<void*, Module*>::iterator j;
++ for (j = indexmanagers.begin(); j != indexmanagers.end(); ++j) {
++ j->second->destroy(static_cast<IndexManager*>(j->first));
++ }
++ // unload all the modules
++ map<string, Module*>::iterator i;
++ for (i = modules.begin(); i != modules.end(); ++i) {
++ delete i->second;
++ }
++ }
++ void loadModule(const string& name, const string& dir);
++ };
++ void
++ ModuleList::loadModule(const string& name, const string& lib) {
++ // check if this module was already loaded
++ map<string, Module*>::iterator i = modules.find(name);
++ if (i != modules.end()) {
++ return;
++ }
++ StgModuleType handle;
++#ifdef HAVE_DLFCN_H
++ // do not use RTLD_GLOBAL here
++ // note: If neither RTLD_GLOBAL nor RTLD_LOCAL are specified,
++ // the default is RTLD_LOCAL.
++ handle = dlopen(lib.c_str(), RTLD_LAZY);
++#else
++ handle = LoadLibrary(lib.c_str());
++#endif
++ if (!handle) {
++#ifdef HAVE_DLFCN_H
++ cerr << "Could not load '" << lib << "':" << dlerror() << endl;
++#else
++ cerr << "Could not load '" << lib << "': GetLastError(): "
++ << GetLastError() << endl;
++#endif
++ return;
++ }
++ IndexManager*(*create)(const char*) = (IndexManager*(*)(const char*))
++ DLSYM(handle, "createIndexManager");
++ if (!create) {
++#ifndef WIN32
++ fprintf(stderr, "%s\n", dlerror());
++#else
++ fprintf(stderr, "GetLastError: %d\n", GetLastError());
++#endif
++ DLCLOSE(handle);
++ return;
++ }
++ void(*destroy)(IndexManager*) = (void(*)(IndexManager*))
++ DLSYM(handle, "deleteIndexManager");
++ if (!destroy) {
++#ifndef WIN32
++ fprintf(stderr, "%s\n", dlerror());
++#else
++ fprintf(stderr, "GetLastError: %d\n", GetLastError());
++#endif
++ DLCLOSE(handle);
++ return;
++ }
++ Module* module = new Module(handle);
++ module->create = create;
++ module->destroy = destroy;
++ modules[name] = module;
++ }
++ static ModuleList modules;
++}
++void
++IndexPluginLoader::loadPlugins(const char* d) {
++ DIR *dir = opendir(d);
++ if (dir == 0) {
++ return;
++ }
++ struct dirent* ent = readdir(dir);
++ string prefix("strigiindex_");
++#ifdef WIN32
++ string suffix(".dll");
++#else
++ string suffix(".so");
++#endif
++ while(ent) {
++ size_t len = strlen(ent->d_name);
++ const char* prepos = strstr(ent->d_name, prefix.c_str());
++ const char* sufpos = strstr(ent->d_name, suffix.c_str());
++ if (prepos && sufpos + suffix.length() == ent->d_name + len) {
++ len -= (prepos - ent->d_name) + prefix.length() + suffix.length();
++ string name(prepos + prefix.length(), len);
++ string pluginpath = d;
++ if (pluginpath[pluginpath.length()-1] != '/') {
++ pluginpath.append("/");
++ }
++ pluginpath.append(ent->d_name);
++ // check that the file is a regular file
++ struct stat s;
++ if (stat(pluginpath.c_str(), &s) == 0 && (S_IFREG & s.st_mode)) {
++ modules.loadModule(name, pluginpath);
++ }
++ }
++ ent = readdir(dir);
++ }
++ closedir(dir);
++}
++vector<string>
++IndexPluginLoader::indexNames() {
++ vector<string> names;
++ map<string, Module*>::const_iterator i = modules.mods().begin();
++ for (; i != modules.mods().end(); ++i) {
++ names.push_back(i->first);
++ }
++ return names;
++}
++IndexManager*
++IndexPluginLoader::createIndexManager(const char* name, const char* dir) {
++ // find the right plugin
++ map<string, Module*>::iterator i = modules.mods().find(name);
++ if (i == modules.mods().end()) {
++ return 0;
++ }
++ // create the indexmanager
++ IndexManager* im = i->second->create(dir);
++ if (im) {
++ // map the indexmanager to the module that created it, so we can delete
++ // it later
++ modules.indexmanagers[im] = i->second;
++ }
++ return im;
++}
++void
++IndexPluginLoader::deleteIndexManager(IndexManager* im) {
++ // find the right module
++ map<void*, Module*>::iterator i = modules.indexmanagers.find(im);
++ if (i == modules.indexmanagers.end()) {
++ return;
++ }
++ // let the module delete the indexmanager
++ i->second->destroy(im);
++ // remove the mapping from the map
++ modules.indexmanagers.erase(i);
++}
+--- /dev/null
++++ b/src/streamanalyzer/indexpluginloader.h
+@@ -0,0 +1,34 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include <strigi/strigiconfig.h>
++#include <vector>
++#include <map>
++#include <string>
++
++namespace Strigi {
++ class IndexManager;
++ namespace IndexPluginLoader {
++ STRIGI_EXPORT void loadPlugins(const char* dir);
++ STRIGI_EXPORT std::vector<std::string> indexNames();
++ STRIGI_EXPORT Strigi::IndexManager* createIndexManager(const char* name,
++ const char* dir);
++ STRIGI_EXPORT void deleteIndexManager(Strigi::IndexManager* manager);
++ }
++}
+--- a/src/streamanalyzer/indexreader.h
++++ b/src/streamanalyzer/indexreader.h
+@@ -79,7 +79,7 @@
+ * @p parent will be placed.
+ **/
+ virtual void getChildren(const std::string& parent,
+- std::map<std::string, time_t>& children) {}
++ std::map<std::string, time_t>& children) {};
+ /**
+ * Count the number of documents indexed in the index.
+ *
+--- a/src/streamanalyzer/queryparser.cpp
++++ b/src/streamanalyzer/queryparser.cpp
+@@ -120,7 +120,19 @@
+ }
+ return space+1;
+ }
+-
++void
++prependXesamNamespace(Query& query) {
++ // prepend the field names with the xesam namespace
++ // this will be elaborated once the xesam spec continues
++ vector<string>::iterator end(query.fields().end());
++ for (vector<string>::iterator i = query.fields().begin(); i != end; ++i) {
++ *i = "http://freedesktop.org/standards/xesam/1.0/core#" + *i;
++ }
++ std::vector<Query>::iterator qend(query.subQueries().end());
++ for (vector<Query>::iterator i = query.subQueries().begin(); i!=qend; ++i) {
++ prependXesamNamespace(*i);
++ }
++}
+ Query
+ QueryParser::buildQuery(const std::string& q) {
+ Query query;
+@@ -140,14 +152,7 @@
+ Query q = query.subQueries()[0];
+ query = q;
+ }
++ prependXesamNamespace(query);
+
+- // prepend the field names with the xesam namespace
+- // this will be elaborated once the xesam spec continues
+- vector<string>::iterator end(query.fields().end());
+- for (vector<string>::iterator i = query.fields().begin(); i != end; ++i) {
+- *i = "http://freedesktop.org/standards/xesam/1.0/core#" + *i;
+- }
+- //cerr << "query: '" << q << "' : " << query.subQueries().size() << "'"
+- // << query.term().string() << "'" << endl;
+ return query;
+ }
+--- a/src/streams/base64inputstream.cpp
++++ b/src/streams/base64inputstream.cpp
+@@ -71,6 +71,7 @@
+ Base64InputStream::Base64InputStream(InputStream* i) :p(new Private(this, i)) {
+ }
+ Base64InputStream::~Base64InputStream() {
++ delete p;
+ }
+ Base64InputStream::Private::Private(Base64InputStream* bi, InputStream* i)
+ :p(bi), input(i) {
+--- a/src/streams/CMakeLists.txt
++++ b/src/streams/CMakeLists.txt
+@@ -73,7 +73,6 @@
+ stringterminatedsubstream.h
+ subinputstream.h
+ textutils.h
+- strigi/jstreamsconfig.h
+ DESTINATION include/strigi
+ )
+ install(TARGETS streams
+--- a/src/streams/rpminputstream.cpp
++++ b/src/streams/rpminputstream.cpp
+@@ -141,15 +141,9 @@
+ m_status = cpio->status();
+ }
+ RpmInputStream::~RpmInputStream() {
+- if (uncompressionStream) {
+- delete uncompressionStream;
+- }
+- if (cpio) {
+- delete cpio;
+- }
+- if (headerinfo) {
+- delete headerinfo;
+- }
++ delete uncompressionStream;
++ delete cpio;
++ delete headerinfo;
+ }
+ InputStream*
+ RpmInputStream::nextEntry() {
+--- a/src/streams/strigi/strigiconfig.h.cmake
++++ b/src/streams/strigi/strigiconfig.h.cmake
+@@ -47,7 +47,7 @@
+ // our needed types
+ #if !@HAVE_INT8_T@
+ #define HAVE_INT8_T 1
+- #if ${SIZEOF_CHAR}==1 //is char 1bit?
++ #if ${SIZEOF_CHAR}==1 //is char one byte?
+ typedef char int8_t;
+ #else
+ #error Could not determine type for int8_t!
+@@ -56,7 +56,7 @@
+
+ #if !@HAVE_UINT8_T@
+ #define HAVE_UINT8_T 1
+- #if ${SIZEOF_CHAR}==1 //is char 1bit?
++ #if ${SIZEOF_CHAR}==1 //is char one byte?
+ typedef unsigned char uint8_t;
+ #else
+ #error Could not determine type for uint8_t!
+@@ -65,7 +65,7 @@
+
+ #if !@HAVE_INT16_T@
+ #define HAVE_INT16_T 1
+- #if ${SIZEOF_SHORT}==2 //is short 2bits?
++ #if ${SIZEOF_SHORT}==2 //is short two bytes?
+ typedef short int16_t;
+ #else
+ #error Could not determine type for int16_t!
+@@ -74,7 +74,7 @@
+
+ #if !@HAVE_UINT16_T@
+ #define HAVE_UINT16_T 1
+- #if ${SIZEOF_SHORT}==2 //is short 2bits?
++ #if ${SIZEOF_SHORT}==2 //is short two bytes?
+ typedef unsigned short uint16_t;
+ #else
+ #error Could not determine type for uint16_t!
+@@ -83,9 +83,9 @@
+
+ #if !@HAVE_INT32_T@
+ #define HAVE_INT32_T 1
+- #if ${SIZEOF_INT}==4 //is int 4bits?
++ #if ${SIZEOF_INT}==4 //is int four bytes?
+ typedef int int32_t;
+- #elif ${SIZEOF_LONG}==4 //is long 4bits?
++ #elif ${SIZEOF_LONG}==4 //is long four bytes?
+ typedef long int32_t;
+ #else
+ #error Could not determine type for int32_t!
+@@ -94,9 +94,9 @@
+
+ #if !@HAVE_UINT32_T@
+ #define HAVE_UINT32_T 1
+- #if ${SIZEOF_INT}==4 //is int 4bits?
++ #if ${SIZEOF_INT}==4 //is int four bytes?
+ typedef unsigned int uint32_t;
+- #elif ${SIZEOF_LONG}==4 //is long 4bits?
++ #elif ${SIZEOF_LONG}==4 //is long four bytes?
+ typedef unsigned long uint32_t;
+ #else
+ #error Could not determine type for uint32_t!
+@@ -132,16 +132,6 @@
+ #define HAVE_UINT 1
+ #endif
+
+-#if !@HAVE_INTPTR_T@
+- typedef int intptr_t;
+- #define HAVE_INTPTR_T 1
+-#endif
+-
+-#if !@HAVE_SOCKLEN_T@
+- typedef int socklen_t;
+- #define HAVE_SOCKLEN_T 1
+-#endif
+-
+ #if !@HAVE_SIZE_T@
+ #ifndef _SIZE_T_DEFINED
+ #ifndef HAVE_SIZE_T
+@@ -152,16 +142,6 @@
+ #endif
+ #endif
+
+-#if !@HAVE_SSIZE_T@
+- #ifndef _SSIZE_T_DEFINED
+- #ifndef HAVE_SSIZE_T
+- typedef signed int ssize_t;
+- #define HAVE_SSIZE_T 1
+- #endif
+- #define _SSIZE_T_DEFINED 1 // kdewin32 define
+- #endif
+-#endif
+-
+ #cmakedefine __STRIGI_HAVE_GCC_VISIBILITY
+
+ #cmakedefine ENABLE_NEWXESAM
+@@ -175,7 +155,7 @@
+ */
+ #ifdef __STRIGI_HAVE_GCC_VISIBILITY
+ #define STRIGI_EXPORT __attribute__ ((visibility("default")))
+-#define STRIGI_IMPORT STRIGI_EXPORT
++#define STRIGI_IMPORT
+ #elif defined(_WIN32) || defined(_WIN64)
+ #define STRIGI_EXPORT __declspec(dllexport)
+ #define STRIGI_IMPORT __declspec(dllimport)
+@@ -200,14 +180,6 @@
+ # endif
+ #endif
+
+-#ifndef CLUCENEINDEXER_EXPORT
+-# ifdef MAKE_CLUCENEINDEXER_LIB
+-# define CLUCENEINDEXER_EXPORT STRIGI_EXPORT
+-# else
+-# define CLUCENEINDEXER_EXPORT STRIGI_IMPORT
+-# endif
+-#endif
+-
+ #ifndef STRIGI_QTDBUSCLIENT_EXPORT
+ # ifdef MAKE_STRIGI_QTDBUSCLIENT_LIB
+ # define STRIGI_QTDBUSCLIENT_EXPORT STRIGI_EXPORT
+--- a/src/strigicmd/strigicmd.cpp
++++ b/src/strigicmd/strigicmd.cpp
+@@ -18,7 +18,8 @@
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+-#include "combinedindexmanager.h"
++#include "indexpluginloader.h"
++#include "indexmanager.h"
+ #include "indexreader.h"
+ #include "indexwriter.h"
+ #include "indexeddocument.h"
+@@ -154,6 +155,10 @@
+ }
+ void
+ printBackends(const string& msg, const vector<string> backends) {
++ if (backends.size() == 0) {
++ pe(" No backends are available.\n");
++ return;
++ }
+ pe(msg.c_str());
+ pe(" Choose one from ");
+ for (uint j=0; j<backends.size()-1; ++j) {
+@@ -218,7 +223,7 @@
+ IndexManager*
+ getIndexManager(string& backend, const string& indexdir) {
+ // check arguments: backend
+- const vector<string>& backends = CombinedIndexManager::backEnds();
++ const vector<string>& backends = IndexPluginLoader::indexNames();
+ // if there is only one backend, the backend does not have to be specified
+ if (backend.size() == 0) {
+ if (backends.size() == 1) {
+@@ -230,11 +235,13 @@
+ }
+ vector<string>::const_iterator b
+ = find(backends.begin(), backends.end(), backend);
++cerr << "n backends: " << backends.size() << endl;
+ if (b == backends.end()) {
+ printBackends("Invalid index type.", backends);
+ return 0;
+ }
+- return CombinedIndexManager::factories()[backend](indexdir.c_str());
++ return IndexPluginLoader::createIndexManager(backend.c_str(),
++ indexdir.c_str());
+ }
+ int
+ create(int argc, char** argv) {
+@@ -286,7 +293,7 @@
+ analyzer->analyzeDir(j->c_str(), nthreads);
+ }
+ delete analyzer;
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+
+ return 0;
+ }
+@@ -329,7 +336,7 @@
+ DirAnalyzer* analyzer = new DirAnalyzer(*manager, config);
+ analyzer->updateDirs(arguments, nthreads);
+ delete analyzer;
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+
+ return 0;
+ }
+@@ -363,7 +370,7 @@
+ }
+ IndexReader* reader = manager->indexReader();
+ listFiles(reader, "");
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -411,7 +418,7 @@
+ }
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -478,7 +485,7 @@
+ }
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -572,7 +579,7 @@
+ if (results != 0)
+ printf ("Query returned %i results\n", results);
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -645,7 +652,7 @@
+ writer->optimize();
+ }
+
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+@@ -672,7 +679,7 @@
+ for (i=fields.begin(); i!=fields.end(); ++i) {
+ printf("%s\n", i->c_str());
+ }
+- delete manager;
++ IndexPluginLoader::deleteIndexManager(manager);
+ return 0;
+ }
+ int
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -1,28 +1,21 @@
+-set (TESTINGDIRS ${TESTINGDIRS} utils indextesters streamanalyzer)
++set (TESTINGDIRS utils indextesters streamanalyzer daemon)
++subdirs (${TESTINGDIRS})
++
++# setting for using CPPUNIT
+
+-if (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
+- set(TESTINGDIRS ${TESTINGDIRS} daemon)
+-endif (CLucene_FOUND OR HyperEstraier_FOUND OR SQLite_FOUND)
++include_directories (. ${CPPUNIT_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/daemon
++ ${CMAKE_BINARY_DIR}/src/streams)
+
+ # cppunit requires exception support
+ IF(NOT WIN32)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
+ ENDIF(NOT WIN32)
+
+-# disable, needs some testing
+-#if (HyperEstraier_FOUND)
+-# set (TESTINGDIRS ${TESTINGDIRS} estraierindexer)
+-#endif (HyperEstraier_FOUND)
+-
+-if (CLucene_FOUND)
+- set(TESTINGDIRS ${TESTINGDIRS} luceneindexer)
+-endif (CLucene_FOUND)
+-
+-include_directories (. ${CPPUNIT_INCLUDE_DIR} ${strigi_SOURCE_DIR}/src/daemon)
+-
++# a convenience library that adds a unified way of build a test executable
++# for testing
++# simply link this into any unit test executable
+ add_library(test_runner test_runner.cpp)
+ target_link_libraries(test_runner ${CPPUNIT_LIBRARIES})
+
+- ENABLE_TESTING()
++ENABLE_TESTING()
+
+-subdirs (${TESTINGDIRS})
+--- a/tests/daemon/CMakeLists.txt
++++ b/tests/daemon/CMakeLists.txt
+@@ -1,8 +1,5 @@
+ # add a test for the daemon configuration loading classes
+
+-# fancy way of saying set(INC_DIR test/daemon)
+-string(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+ # if we use log4cxx, include it
+ # ideally this should be abstracted away in something like STRIGILOG( ... )
+ if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+--- a/tests/estraierindexer/CMakeLists.txt
++++ /dev/null
+@@ -1,26 +0,0 @@
+-STRING(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+-if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(estraiertest_LIBS ${estraiertest_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
+- add_definitions(-DHAVE_LOG4CXX)
+-endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+-
+-include_directories (. .. ${INC_DIR}
+- ../indextests
+- ${strigi_SOURCE_DIR}/src/streamanalyzer
+- ${strigi_SOURCE_DIR}/src/streams
+- ${strigi_BINARY_DIR}/src/streams
+- ${strigi_SOURCE_DIR}/src/streams/strigi
+- ${EST_INCLUDE_DIR}
+-)
+-
+-add_library(estraiertest SHARED estraierindexmanagertest.cpp
+- ../indextests/indexmanagertester.cpp
+- estraierindexreadertest.cpp
+- ../indextests/indexreadertester.cpp
+- estraierindexwritertest.cpp
+- ../indextests/indexwritertester.cpp )
+-
+-target_link_libraries (estraiertest estraierindex ${estraiertest_LIBS})
+-add_test (estraiertest estraiertest)
+--- a/tests/estraierindexer/estraierindexmanagertest.cpp
++++ /dev/null
+@@ -1,72 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexmanagertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexManagerTest );
+-
+-void EstraierIndexManagerTest::setUp()
+-{
+- IndexManagerTester::setUp();
+-
+- path = "testestraierindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- writer = manager->getIndexWriter();
+- reader = manager->getIndexReader();
+- ic = new Strigi::AnalyzerConfiguration ();
+- si = new Strigi::StreamAnalyzer (*ic);
+-}
+-
+-void EstraierIndexManagerTest::tearDown()
+-{
+- IndexManagerTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexmanagertest.h
++++ /dev/null
+@@ -1,43 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_MANAGER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_MANAGER_TEST_H
+-
+-#include "indexmanagertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexManagerTest : public IndexManagerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexManagerTest, IndexManagerTester);
+- CPPUNIT_TEST( testVariables );
+- //CPPUNIT_TEST( runUnthreadedTests );
+- //CPPUNIT_TEST( runThreadedTests );
+- CPPUNIT_TEST( addAndCount );
+- CPPUNIT_TEST( testNumberQuery );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/estraierindexer/estraierindexreadertest.cpp
++++ /dev/null
+@@ -1,69 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexreadertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexReaderTest );
+-
+-void EstraierIndexReaderTest::setUp()
+-{
+- IndexReaderTester::setUp();
+-
+- path = "testestraier";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- reader = manager->getIndexReader();
+-}
+-
+-void EstraierIndexReaderTest::tearDown()
+-{
+- IndexReaderTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexreadertest.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_READER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_READER_TEST_H
+-
+-#include "indexreadertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexReaderTest : public IndexReaderTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexReaderTest, IndexReaderTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( getFiles );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/estraierindexer/estraierindexwritertest.cpp
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "estraierindexwritertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "estraierindexmanager.h"
+-#include "indexwriter.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexWriterTest );
+-
+-void EstraierIndexWriterTest::setUp()
+-{
+- IndexWriterTester::setUp();
+-
+- path = "testestraierindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- manager = new EstraierIndexManager(path.c_str());
+- writer = manager->getIndexWriter();
+- ic = new Strigi::AnalyzerConfiguration ();
+- si = new Strigi::StreamAnalyzer (*ic);
+-}
+-
+-void EstraierIndexWriterTest::tearDown()
+-{
+- IndexWriterTester::tearDown();
+-
+- // clean up data
+- string cmd = "rm -r ";
+- cmd += path;
+- system(cmd.c_str());
+-}
+--- a/tests/estraierindexer/estraierindexwritertest.h
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_ESTRAIER_INDEX_WRITER_TEST_H
+-#define UNIT_TEST_ESTRAIER_INDEX_WRITER_TEST_H
+-
+-#include "indexwritertester.h"
+-
+-namespace strigiunittest
+-{
+- class EstraierIndexWriterTest : public IndexWriterTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( EstraierIndexWriterTest, IndexWriterTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( add );
+- CPPUNIT_TEST( optimize );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- /dev/null
++++ b/tests/indextesters/clucenetests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++
++class CLuceneIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexReaderTest() :IndexReaderTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexReaderTest );
++
++class CLuceneIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexWriterTest() :IndexWriterTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexWriterTest );
++
++class CLuceneIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexSearchTest() :IndexSearchTest("clucene") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexSearchTest );
++
+--- a/tests/indextesters/CMakeLists.txt
++++ b/tests/indextesters/CMakeLists.txt
+@@ -1,6 +1,6 @@
+ if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(indextesters_LIBS ${indextesters_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
++ set(indextesters_LIBS ${LOG4CXX_LIBRARIES})
++ set(INC_DIR ${LOG4CXX_INCLUDE_DIR})
+ add_definitions(-DHAVE_LOG4CXX)
+ endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+
+@@ -12,10 +12,26 @@
+ ../utils
+ )
+
+-add_library(indextesters indexmanagertester.cpp
+- indexreadertester.cpp
+- indexwritertester.cpp
+- indexsearchtester.cpp
+-)
++set(indextester_SRCS indextest.cpp indexreadertester.cpp indexwritertester.cpp
++ indexsearchtester.cpp)
++if (CLucene_FOUND)
++ set(indextester_SRCS ${indextester_SRCS} clucenetests.cpp)
++ set (indextester_DEPS ${indextester_DEPS} clucene)
++endif (CLucene_FOUND)
++if (ENABLE_SQLITE AND SQLite_FOUND)
++ set (indextester_SRCS ${indextester_SRCS} sqlitetests.cpp)
++ set (indextester_DEPS sqlite)
++endif (ENABLE_SQLITE AND SQLite_FOUND)
++if (HyperEstraier_FOUND)
++ set (indextester_SRCS ${indextester_SRCS} estraiertests.cpp)
++ set (indextester_DEPS estraier)
++endif (HyperEstraier_FOUND)
++
++add_executable(indextester ${indextester_SRCS})
++if (indextester_DEPS)
++ ADD_DEPENDENCIES(indextester ${indextester_DEPS})
++endif (indextester_DEPS)
++target_link_libraries(indextester
++ test_runner unittestfunctions ${indextesters_LIBS})
+
+-target_link_libraries (indextesters unittestfunctions ${indextesters_LIBS})
++add_test(indextester indextester)
+--- /dev/null
++++ b/tests/indextesters/estraiertests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++
++class EstraierIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexReaderTest() :IndexReaderTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexReaderTest );
++
++class EstraierIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexWriterTest() :IndexWriterTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexWriterTest );
++
++
++class EstraierIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( EstraierIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ EstraierIndexSearchTest() :IndexSearchTest("estraier") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( EstraierIndexSearchTest );
+--- a/tests/indextesters/indexmanagertester.cpp
++++ b/tests/indextesters/indexmanagertester.cpp
+@@ -18,53 +18,41 @@
+ * Boston, MA 02110-1301, USA.
+ */
+ #include "indexmanagertester.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+ #include "indexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "fieldtypes.h"
+-#include "query.h"
+-#include "queryparser.h"
+-
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
++#include "indexpluginloader.h"
+
+ using namespace std;
+ using namespace Strigi;
+ using namespace strigiunittest;
+
+-void IndexManagerTester::setUp()
+-{
+- m_manager = createManager();
+-}
++CPPUNIT_TEST_SUITE_REGISTRATION( CLuceneIndexManagerTest );
+
+-void IndexManagerTester::tearDown()
+-{
+- deleteManager( m_manager );
++IndexManagerTest::IndexManagerTest(const std::string& backendname)
++ :m_backendname(backendname), m_indexpath(":memory:"), m_manager(0) {
+ }
+
+-
+-void IndexManagerTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++void
++IndexManagerTest::setUp() {
++ m_manager = Strigi::IndexPluginLoader::createIndexManager(
++ m_backendname.c_str(), m_indexpath.c_str());
+ }
+
++void
++IndexManagerTest::tearDown() {
++ Strigi::IndexPluginLoader::deleteIndexManager(m_manager);
++ // clean up data (if any)
++ string cmd("rm -rf '" + m_indexpath + "'");
++ system(cmd.c_str());
++}
+
+-void IndexManagerTester::testIndexReader()
+-{
++void
++IndexManagerTest::testIndexReader() {
+ Strigi::IndexReader* reader = m_manager->indexReader();
+ CPPUNIT_ASSERT_MESSAGE("reader creation failed", reader);
+ }
+
+-void IndexManagerTester::testIndexWriter()
+-{
++void
++IndexManagerTest::testIndexWriter() {
+ Strigi::IndexWriter* writer = m_manager->indexWriter();
+ CPPUNIT_ASSERT_MESSAGE("writer creation failed", writer);
+ }
+--- a/tests/indextesters/indexmanagertester.h
++++ b/tests/indextesters/indexmanagertester.h
+@@ -30,34 +30,37 @@
+ class IndexReader;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexManagerTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexManagerTester );
+- CPPUNIT_TEST( testIndexReader );
+- CPPUNIT_TEST( testIndexWriter );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+-
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void testIndexReader();
+- virtual void testIndexWriter();
+- };
+-}
++namespace strigiunittest {
++
++class IndexManagerTest : public CppUnit::TestFixture {
++private:
++ CPPUNIT_TEST_SUITE( IndexManagerTest );
++ CPPUNIT_TEST( testIndexReader );
++ CPPUNIT_TEST( testIndexWriter );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ const std::string m_backendname;
++ const std::string m_indexpath;
++ Strigi::IndexManager* m_manager;
++
++protected:
++ IndexManagerTest(const std::string& backendname);
+
++public:
++ void setUp();
++ void tearDown();
++
++ void testIndexReader();
++ void testIndexWriter();
++};
++
++class CLuceneIndexManagerTest : public IndexManagerTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( CLuceneIndexManagerTest, IndexManagerTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ CLuceneIndexManagerTest() :IndexManagerTest("clucene") {}
++};
++
++}
+ #endif
+--- a/tests/indextesters/indexreadertester.cpp
++++ b/tests/indextesters/indexreadertester.cpp
+@@ -20,61 +20,38 @@
+ #include "indexreadertester.h"
+
+ #include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "fieldtypes.h"
+-#include "analyzerconfiguration.h"
+ #include "query.h"
+ #include "queryparser.h"
+
+-#include <string>
+ #include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+ #include <ostream>
+
+ using namespace std;
+ using namespace strigiunittest;
+ using namespace Strigi;
+
+-void IndexReaderTester::setUp()
+-{
+- m_manager = createManager();
+- m_writer = m_manager->indexWriter();
+- m_reader = m_manager->indexReader();
+-
+- CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
+- CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
+-
++void
++IndexReaderTest::setUp() {
++ IndexTest::setUp();
+ m_streamAnalyzer = new Strigi::StreamAnalyzer( m_analyzerConfiguration );
+ }
+
+-void IndexReaderTester::tearDown()
+-{
++void
++IndexReaderTest::tearDown() {
+ delete m_streamAnalyzer;
+- deleteManager( m_manager );
+-}
+-
+-
+-void IndexReaderTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++ IndexTest::tearDown();
+ }
+
+ void
+-IndexReaderTester::testChildrenRetrieval() {
++IndexReaderTest::testChildrenRetrieval() {
+ // FIXME
+ }
+
+-void IndexReaderTester::addAndCount()
+-{
++void
++IndexReaderTest::addAndCount() {
+ static const int m = 20;
+
+ m_writer->deleteAllEntries();
+@@ -93,8 +70,8 @@
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(str.str(), m, n);
+ }
+
+-void IndexReaderTester::testNumberQuery()
+-{
++void
++IndexReaderTest::testNumberQuery() {
+ m_writer->deleteAllEntries();
+ // add numbers to the database
+ int m = 200;
+--- a/tests/indextesters/indexreadertester.h
++++ b/tests/indextesters/indexreadertester.h
+@@ -20,55 +20,37 @@
+ #ifndef UNIT_TEST_INDEX_READER_TESTER_H
+ #define UNIT_TEST_INDEX_READER_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
+-#include <string>
+-
++#include "indextest.h"
+ #include "analyzerconfiguration.h"
+-#include "fieldtypes.h"
+
+ namespace Strigi {
+- class IndexManager;
+- class IndexReader;
+- class IndexWriter;
+ class StreamAnalyzer;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexReaderTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexReaderTester );
+- CPPUNIT_TEST( testChildrenRetrieval );
+- CPPUNIT_TEST( addAndCount );
+- CPPUNIT_TEST( testNumberQuery );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- Strigi::IndexWriter* m_writer;
+- Strigi::IndexReader* m_reader;
+- Strigi::StreamAnalyzer* m_streamAnalyzer;
+- Strigi::AnalyzerConfiguration m_analyzerConfiguration;
+- Strigi::FieldRegister m_fieldRegister;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void addAndCount();
+- virtual void testChildrenRetrieval();
+- virtual void testNumberQuery();
+- };
++namespace strigiunittest {
++
++class IndexReaderTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexReaderTest );
++ CPPUNIT_TEST( testChildrenRetrieval );
++ CPPUNIT_TEST( addAndCount );
++ CPPUNIT_TEST( testNumberQuery );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ Strigi::StreamAnalyzer* m_streamAnalyzer;
++ Strigi::AnalyzerConfiguration m_analyzerConfiguration;
++ Strigi::FieldRegister m_fieldRegister;
++
++ void addAndCount();
++ void testChildrenRetrieval();
++ void testNumberQuery();
++public:
++ IndexReaderTest(const std::string& backendname) :IndexTest(backendname),
++ m_streamAnalyzer(0) {}
++ void setUp();
++ void tearDown();
++};
++
+ }
+
+ #endif
+--- a/tests/indextesters/indexsearchtester.cpp
++++ b/tests/indextesters/indexsearchtester.cpp
+@@ -27,6 +27,7 @@
+ #include "query.h"
+ #include "queryparser.h"
+ #include "unittestfunctions.h"
++#include "indexpluginloader.h"
+
+ #include <errno.h>
+ #include <fstream>
+@@ -39,23 +40,12 @@
+ using namespace strigiunittest;
+
+ void
+-IndexSearchTester::setUp() {
++IndexSearchTest::setUp() {
++ IndexTest::setUp();
++
+ char buff[13];
+ char* dirname;
+ string separator;
+-
+- // generate index dir name
+- strcpy(buff, "strigiXXXXXX");
+- dirname = mkdtemp(buff);
+-
+- if (dirname) {
+- cout << "created index dir: " << dirname << endl;
+- indexdir.assign(dirname);
+- } else {
+- cerr << "Error creating temporary directory for index because of: "
+- << strerror(errno) << endl;
+- return;
+- }
+
+ // generate indexed docs name
+ strcpy(buff, "strigiXXXXXX");
+@@ -68,7 +58,7 @@
+ << strerror(errno) << endl;
+ return;
+ }
+-
++
+ #ifdef _WIN32
+ separator = "\\";
+ #else
+@@ -78,15 +68,15 @@
+ // prepare files to be indexed
+ string filename;
+ string filecontents;
+-
++
+ filename = "testfile01";
+ filecontents = "this is a simple test file";
+ indexedFiles.insert(make_pair<string, string> (filename, filecontents));
+-
++
+ filename = "testfile02";
+ filecontents = "unit testing example";
+ indexedFiles.insert(make_pair<string, string> (filename, filecontents));
+-
++
+ // create files on file system
+ for (map<string,string>::iterator iter = indexedFiles.begin();
+ iter != indexedFiles.end(); iter++) {
+@@ -100,48 +90,37 @@
+ cerr << "error during creation of file " << fullpath << endl;
+ }
+ }
+-
+- manager = getIndexManager(backend, indexdir);
+
+- CPPUNIT_ASSERT_MESSAGE ("manager == null", manager);
+-
+ Strigi::AnalyzerConfiguration config;
+ Strigi::StreamAnalyzer* streamindexer = new Strigi::StreamAnalyzer(config);
+- Strigi::IndexWriter* writer = manager->indexWriter();
+- streamindexer->setIndexWriter(*writer);
+-
++ streamindexer->setIndexWriter(*m_writer);
++
+ for (map<string,string>::iterator iter = indexedFiles.begin();
+ iter != indexedFiles.end(); iter++) {
+ string temp = filedir + separator + iter->first;
+ fprintf (stderr, "going to index %s\n", temp.c_str());
+ streamindexer->indexFile(temp);
+ }
+-
++
+ delete streamindexer;
+-
+- writer->commit();
+-
++
++ m_writer->commit();
+ }
+
+ void
+-IndexSearchTester::tearDown() {
+- if (manager)
+- delete manager;
+- manager = NULL;
+-
++IndexSearchTest::tearDown() {
+ // clean up data (does not work on windows)
+- string cmd = "rm -r " + indexdir + " " + filedir;
++ string cmd = "rm -r '" + filedir + "'";
+ system(cmd.c_str());
++
++ IndexTest::tearDown();
+ }
+
+ void
+-IndexSearchTester::testVariables() {
+- CPPUNIT_ASSERT_MESSAGE ("manager == NULL", manager);
+- CPPUNIT_ASSERT_MESSAGE ("backend empty", !backend.empty());
+- CPPUNIT_ASSERT_MESSAGE ("indexdir empty", !indexdir.empty());
++IndexSearchTest::testVariables() {
+ CPPUNIT_ASSERT_MESSAGE ("filedir empty", !filedir.empty());
+-
+- unsigned int indexedFilesSize = manager->indexReader()->countDocuments();
++
++ unsigned int indexedFilesSize = m_reader->countDocuments();
+ if (indexedFilesSize != indexedFiles.size()) {
+ ostringstream msg;
+ msg << "There are " << indexedFilesSize << " indexed files instead of "
+@@ -151,30 +130,24 @@
+ }
+
+ void
+-IndexSearchTester::testSystemLocationSearchIndexedFile() {
+- Strigi::IndexReader* reader = manager->indexReader();
+- CPPUNIT_ASSERT_MESSAGE("reader == NULL", reader);
+-
++IndexSearchTest::testSystemLocationSearchIndexedFile() {
+ Strigi::QueryParser parser;
+
+ Strigi::Query query = parser.buildQuery("name:'testfile01'");
+- vector<Strigi::IndexedDocument> matches = reader->query(query, 0, 10);
++ vector<Strigi::IndexedDocument> matches = m_reader->query(query, 0, 10);
+
+ int nhits = matches.size();
+- CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", nhits, 1);
++ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", 1, nhits);
+ }
+
+ void
+-IndexSearchTester::testSystemLocationSearchUnindexedFile() {
+- Strigi::IndexReader* reader = manager->indexReader();
+- CPPUNIT_ASSERT_MESSAGE("reader == NULL", reader);
+-
++IndexSearchTest::testSystemLocationSearchUnindexedFile() {
+ Strigi::QueryParser parser;
+
+ Strigi::Query query = parser.buildQuery(
+ Strigi::FieldRegister::pathFieldName+":'unindexed'");
+- vector<Strigi::IndexedDocument> matches = reader->query(query, 0, 10);
++ vector<Strigi::IndexedDocument> matches = m_reader->query(query, 0, 10);
+ int nhits = matches.size();
+- CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", nhits, 0);
++ CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of hits is wrong.", 0, nhits);
+ }
+
+--- a/tests/indextesters/indexsearchtester.h
++++ b/tests/indextesters/indexsearchtester.h
+@@ -20,42 +20,33 @@
+ #ifndef UNIT_TEST_INDEX_SEARCH_TESTER_H
+ #define UNIT_TEST_INDEX_SEARCH_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
++#include "indextest.h"
+
+ #include <map>
+-#include <string>
+
+-namespace Strigi
+-{
+- class IndexManager;
+-}
++namespace strigiunittest {
++
++class IndexSearchTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexSearchTest );
++ CPPUNIT_TEST( testVariables );
++ CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
++ CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ std::string filedir;
++ std::map<std::string,std::string> indexedFiles; //!< map with key = file name, and value = file contents
++
++ void testSystemLocationSearchIndexedFile();
++ void testSystemLocationSearchUnindexedFile();
++ void testVariables();
++
++public:
++ IndexSearchTest(const std::string& backendname) :IndexTest(backendname){}
++ void setUp();
++ void tearDown();
++};
+
+-namespace strigiunittest
+-{
+- class IndexSearchTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexSearchTester );
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
+- CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- protected:
+- Strigi::IndexManager* manager;
+- std::string backend;
+- std::string indexdir;
+- std::string filedir;
+- std::map<std::string,std::string> indexedFiles; //!< map with key = file name, and value = file contents
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- virtual void testSystemLocationSearchIndexedFile();
+- virtual void testSystemLocationSearchUnindexedFile();
+- virtual void testVariables();
+- };
+ }
+
+ #endif
+--- /dev/null
++++ b/tests/indextesters/indextest.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#include "indextest.h"
++#include "indexmanager.h"
++#include "indexpluginloader.h"
++
++using namespace std;
++using namespace Strigi;
++using namespace strigiunittest;
++
++IndexTest::IndexTest(const string& backendname, const string& indexpath)
++ :m_backendname(backendname), m_indexpath(":memory:"), m_manager(0) {
++}
++
++void
++IndexTest::setUp() {
++ m_manager = IndexPluginLoader::createIndexManager(
++ m_backendname.c_str(), m_indexpath.c_str());
++ CPPUNIT_ASSERT_MESSAGE("manager creation failed", m_manager);
++ if (!m_manager) return;
++
++ m_writer = m_manager->indexWriter();
++ CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
++
++ m_reader = m_manager->indexReader();
++ CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
++}
++
++void
++IndexTest::tearDown() {
++ IndexPluginLoader::deleteIndexManager(m_manager);
++ // clean up data (if any)
++ string cmd("rm -rf '" + m_indexpath + "'");
++ system(cmd.c_str());
++}
+--- /dev/null
++++ b/tests/indextesters/indextest.h
+@@ -0,0 +1,51 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++#ifndef UNIT_TEST_INDEX_TEST_H
++#define UNIT_TEST_INDEX_TEST_H
++
++#include <cppunit/TestFixture.h>
++#include <cppunit/extensions/HelperMacros.h>
++#include <string>
++
++namespace Strigi {
++ class IndexManager;
++ class IndexWriter;
++ class IndexReader;
++}
++
++namespace strigiunittest {
++
++class IndexTest : public CppUnit::TestFixture {
++protected:
++ const std::string m_backendname;
++ const std::string m_indexpath;
++ Strigi::IndexManager* m_manager;
++ Strigi::IndexReader* m_reader;
++ Strigi::IndexWriter* m_writer;
++
++ IndexTest(const std::string& backendname,
++ const std::string& indexpath = ":memory:");
++ void setUp();
++ void tearDown();
++};
++
++}
++
++#endif
+--- a/tests/indextesters/indexwritertester.cpp
++++ b/tests/indextesters/indexwritertester.cpp
+@@ -20,55 +20,32 @@
+ #include "indexwritertester.h"
+
+ #include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "indexmanager.h"
+ #include "indexwriter.h"
+ #include "indexreader.h"
+ #include "fieldtypes.h"
+-#include "analyzerconfiguration.h"
+ #include "query.h"
+ #include "queryparser.h"
+
+-#include <string>
+ #include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+
+ using namespace std;
+ using namespace strigiunittest;
+ using namespace Strigi;
+
+-void IndexWriterTester::setUp()
+-{
+- m_manager = createManager();
+- m_writer = m_manager->indexWriter();
+- m_reader = m_manager->indexReader();
+-
+- CPPUNIT_ASSERT_MESSAGE("writer creation failed", m_writer);
+- CPPUNIT_ASSERT_MESSAGE("reader creation failed", m_reader);
+-
+- m_streamAnalyzer = new Strigi::StreamAnalyzer( m_analyzerConfiguration );
++void
++IndexWriterTest::setUp() {
++ IndexTest::setUp();
++ m_streamAnalyzer = new StreamAnalyzer( m_analyzerConfiguration );
+ }
+
+-void IndexWriterTester::tearDown()
+-{
++void
++IndexWriterTest::tearDown() {
+ delete m_streamAnalyzer;
+- deleteManager( m_manager );
+-}
+-
+-
+-void IndexWriterTester::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
++ IndexTest::tearDown();
+ }
+
+-
+-void IndexWriterTester::testAddText()
+-{
++void
++IndexWriterTest::testAddText() {
+ // test adding very simple text
+ string path( "/tmp/dummy.txt" );
+ {
+@@ -78,9 +55,12 @@
+ }
+ m_writer->commit();
+
+- std::vector<IndexedDocument> results = m_reader->query( QueryParser::buildQuery("dummy"), 0, 100 );
+- CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid number of results", 1, ( int )results.size() );
+- CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid path result", path, results[0].uri );
++ std::vector<IndexedDocument> results = m_reader->query(
++ QueryParser::buildQuery("dummy"), 0, 100 );
++ CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid number of results", 1,
++ (int)results.size() );
++ CPPUNIT_ASSERT_EQUAL_MESSAGE( "got invalid path result", path,
++ results[0].uri );
+
+ m_writer->deleteAllEntries();
+
+@@ -88,9 +68,8 @@
+
+ }
+
+-
+-void IndexWriterTester::testDeleteAllEntries()
+-{
++void
++IndexWriterTest::testDeleteAllEntries() {
+ // add some random data
+ string path( "/tmp/dummy.txt" );
+ {
+@@ -107,18 +86,23 @@
+ // now make sure nothing is left
+ std::map<std::string, time_t> children;
+ m_reader->getChildren( std::string(), children );
+- CPPUNIT_ASSERT_MESSAGE( "Still files left after calling deleteAllEntries.", children.empty() );
++ CPPUNIT_ASSERT_MESSAGE( "Still files left after calling deleteAllEntries.",
++ children.empty() );
+
+- std::vector<IndexedDocument> results = m_reader->query( QueryParser::buildQuery( FieldRegister::pathFieldName + "=\"" + path + "\"" ), 0, 100 );
+- CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries", results.empty() );
+-
+- results = m_reader->query( QueryParser::buildQuery( FieldRegister::filenameFieldName + "=\"dummy.txt\"" ), 0, 100 );
+- CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries", results.empty() );
++ std::vector<IndexedDocument> results = m_reader->query(
++ QueryParser::buildQuery(
++ FieldRegister::pathFieldName + "=\"" + path + "\"" ), 0, 100 );
++ CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries",
++ results.empty() );
++
++ results = m_reader->query( QueryParser::buildQuery(
++ FieldRegister::filenameFieldName + "=\"dummy.txt\"" ), 0, 100 );
++ CPPUNIT_ASSERT_MESSAGE( "Query results not empty after deleteAllEntries",
++ results.empty() );
+ }
+
+-
+-void IndexWriterTester::testDeleteEntries()
+-{
++void
++IndexWriterTest::testDeleteEntries() {
+ // add some random data
+ string path1( "/tmp/dummy1.txt" );
+ string path2( "/tmp/dummy2.txt" );
+@@ -128,11 +112,11 @@
+ AnalysisResult anaRes1( path1, 1, *m_writer, *m_streamAnalyzer );
+ AnalysisResult anaRes2( path2, 1, *m_writer, *m_streamAnalyzer );
+
+- m_writer->addValue( &anaRes1, m_fieldRegister.pathField, anaRes1.path() );
+- m_writer->addValue( &anaRes1, m_fieldRegister.filenameField, filename1 );
++ m_writer->addValue(&anaRes1, m_fieldRegister.pathField, anaRes1.path());
++ m_writer->addValue(&anaRes1, m_fieldRegister.filenameField, filename1);
+
+- m_writer->addValue( &anaRes2, m_fieldRegister.pathField, anaRes2.path() );
+- m_writer->addValue( &anaRes2, m_fieldRegister.filenameField, filename2 );
++ m_writer->addValue(&anaRes2, m_fieldRegister.pathField, anaRes2.path());
++ m_writer->addValue(&anaRes2, m_fieldRegister.filenameField, filename2 );
+ }
+ m_writer->commit();
+
+--- a/tests/indextesters/indexwritertester.h
++++ b/tests/indextesters/indexwritertester.h
+@@ -20,56 +20,40 @@
+ #ifndef UNIT_TEST_INDEX_WRITER_TESTER_H
+ #define UNIT_TEST_INDEX_WRITER_TESTER_H
+
+-#include <cppunit/TestFixture.h>
+-#include <cppunit/extensions/HelperMacros.h>
+-#include <string>
++#include "indextest.h"
+
+ #include "analyzerconfiguration.h"
+ #include "fieldtypes.h"
+
+ namespace Strigi {
+- class IndexManager;
+- class IndexWriter;
+- class IndexReader;
+ class StreamAnalyzer;
+ class AnalysisResult;
+ }
+
+-namespace strigiunittest
+-{
+- class IndexWriterTester : public CppUnit::TestFixture
+- {
+- CPPUNIT_TEST_SUITE( IndexWriterTester );
+- CPPUNIT_TEST( testAddText );
+- CPPUNIT_TEST( testDeleteAllEntries );
+-
+- CPPUNIT_TEST_SUITE_END_ABSTRACT();
+-
+- private:
+- Strigi::IndexManager* m_manager;
+-
+- Strigi::IndexWriter* m_writer;
+- Strigi::IndexReader* m_reader;
+- Strigi::StreamAnalyzer* m_streamAnalyzer;
+- Strigi::AnalyzerConfiguration m_analyzerConfiguration;
+- Strigi::FieldRegister m_fieldRegister;
+-
+- protected:
+- virtual Strigi::IndexManager* createManager() = 0;
+- /**
+- * delete the manager. The default implementation simply
+- * calls delete.
+- */
+- virtual void deleteManager( Strigi::IndexManager* );
+-
+- public:
+- virtual void setUp();
+- virtual void tearDown();
+-
+- void testAddText();
+- void testDeleteAllEntries();
+- void testDeleteEntries();
+- };
++namespace strigiunittest {
++
++class IndexWriterTest : public IndexTest {
++private:
++ CPPUNIT_TEST_SUITE( IndexWriterTest );
++ CPPUNIT_TEST( testAddText );
++ CPPUNIT_TEST( testDeleteAllEntries );
++ CPPUNIT_TEST_SUITE_END_ABSTRACT();
++
++ Strigi::StreamAnalyzer* m_streamAnalyzer;
++ Strigi::AnalyzerConfiguration m_analyzerConfiguration;
++ Strigi::FieldRegister m_fieldRegister;
++
++ void testAddText();
++ void testDeleteAllEntries();
++ void testDeleteEntries();
++
++public:
++ IndexWriterTest(const std::string& backendname) :IndexTest(backendname),
++ m_streamAnalyzer(0) {}
++ void setUp();
++ void tearDown();
++};
++
+ }
+
+ #endif
+--- /dev/null
++++ b/tests/indextesters/sqlitetests.cpp
+@@ -0,0 +1,52 @@
++/* This file is part of Strigi Desktop Search
++ *
++ * Copyright (C) 2007 Jos van den Oever <jos at vandenoever.info>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this library; see the file COPYING.LIB. If not, write to
++ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++#include "indexreadertester.h"
++#include "indexwritertester.h"
++#include "indexsearchtester.h"
++using namespace strigiunittest;
++/*
++class SQLiteIndexReaderTest : public IndexReaderTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexReaderTest, IndexReaderTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexReaderTest() :IndexReaderTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexReaderTest );
++*/
++class SQLiteIndexWriterTest : public IndexWriterTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexWriterTest, IndexWriterTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexWriterTest() :IndexWriterTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexWriterTest );
++/*
++
++class SQLiteIndexSearchTest : public IndexSearchTest {
++private:
++ CPPUNIT_TEST_SUB_SUITE( SQLiteIndexSearchTest, IndexSearchTest);
++ CPPUNIT_TEST_SUITE_END();
++public:
++ SQLiteIndexSearchTest() :IndexSearchTest("sqlite") {}
++};
++CPPUNIT_TEST_SUITE_REGISTRATION( SQLiteIndexSearchTest );*/
+--- a/tests/luceneindexer/CMakeLists.txt
++++ /dev/null
+@@ -1,33 +0,0 @@
+-STRING(REGEX REPLACE /test /src INC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+-
+-if (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+- set(lucenetest_LIBS ${lucenetest_LIBS} ${LOG4CXX_LIBRARIES})
+- set (INC_DIR ${INC_DIR} ${LOG4CXX_INCLUDE_DIR})
+- add_definitions(-DHAVE_LOG4CXX)
+-endif (ENABLE_LOG4CXX AND Log4cxx_FOUND)
+-
+-include_directories (. .. ${INC_DIR}
+- ../indextesters
+- ../streamanalyzer
+- ${strigi_SOURCE_DIR}/src/streamanalyzer
+- ${strigi_SOURCE_DIR}/src/luceneindexer
+- ${strigi_SOURCE_DIR}/src/streams
+- ${strigi_BINARY_DIR}/src/streams
+- ${strigi_SOURCE_DIR}/src/streams/strigi
+- ${CLUCENE_INCLUDE_DIR}
+-)
+-
+-add_executable (lucenetest luceneindexmanagertest.cpp
+- luceneindexreadertest.cpp
+- luceneindexwritertest.cpp
+- luceneindexsearchtest.cpp
+- lucenediranalyzertest.cpp
+-)
+-
+-target_link_libraries (lucenetest test_runner
+- streamanalyzertesters
+- indextesters
+- cluceneindex
+- ${lucenetest_LIBS})
+-
+-add_test (lucenetests lucenetest)
+--- a/tests/luceneindexer/lucenediranalyzertest.cpp
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "lucenediranalyzertest.h"
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneDirAnalyzerTest );
+-
+-void LuceneDirAnalyzerTest::setUp()
+-{
+- backend = "clucene";
+- DirAnalyzerTester::setUp();
+-}
+-
+-void LuceneDirAnalyzerTest::tearDown()
+-{
+- DirAnalyzerTester::tearDown();
+-}
+--- a/tests/luceneindexer/lucenediranalyzertest.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_SEARCH_TEST_H
+-#define UNIT_TEST_LUCENE_SEARCH_TEST_H
+-
+-#include "diranalyzertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneDirAnalyzerTest : public DirAnalyzerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneDirAnalyzerTest, DirAnalyzerTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testCreateIndex );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexmanagertest.cpp
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexmanagertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexManagerTest );
+-
+-Strigi::IndexManager* LuceneIndexManagerTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexManagerTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexmanagertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_MANAGER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_MANAGER_TEST_H
+-
+-#include "indexmanagertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexManagerTest : public IndexManagerTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexManagerTest, IndexManagerTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexreadertest.cpp
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexreadertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "indexreader.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexReaderTest );
+-
+-Strigi::IndexManager* LuceneIndexReaderTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexReaderTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexreadertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_READER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_READER_TEST_H
+-
+-#include "indexreadertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexReaderTest : public IndexReaderTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexReaderTest, IndexReaderTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexsearchtest.cpp
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexsearchtest.h"
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexSearchTest );
+-
+-void LuceneIndexSearchTest::setUp()
+-{
+- backend = "clucene";
+- IndexSearchTester::setUp();
+-}
+-
+-void LuceneIndexSearchTest::tearDown()
+-{
+- IndexSearchTester::tearDown();
+-}
+--- a/tests/luceneindexer/luceneindexsearchtest.h
++++ /dev/null
+@@ -1,41 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_SEARCH_TEST_H
+-#define UNIT_TEST_LUCENE_SEARCH_TEST_H
+-
+-#include "indexsearchtester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexSearchTest : public IndexSearchTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexSearchTest, IndexSearchTester);
+- CPPUNIT_TEST( testVariables );
+- CPPUNIT_TEST( testSystemLocationSearchIndexedFile );
+- CPPUNIT_TEST( testSystemLocationSearchUnindexedFile );
+- CPPUNIT_TEST_SUITE_END();
+-
+- public:
+- void setUp();
+- void tearDown();
+- };
+-}
+-
+-#endif
+--- a/tests/luceneindexer/luceneindexwritertest.cpp
++++ /dev/null
+@@ -1,63 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#include "luceneindexwritertest.h"
+-
+-#include "analysisresult.h"
+-#include "analyzerconfiguration.h"
+-#include "cluceneindexmanager.h"
+-#include "indexwriter.h"
+-#include "query.h"
+-
+-#include <string>
+-#include <sstream>
+-#include <sys/stat.h>
+-#include <sys/types.h>
+-#include <stdlib.h>
+-#ifdef _WIN32
+-#include <direct.h>
+-#endif
+-
+-using namespace std;
+-using namespace strigiunittest;
+-
+-// Registers the fixture into the 'registry'
+-CPPUNIT_TEST_SUITE_REGISTRATION( LuceneIndexWriterTest );
+-
+-Strigi::IndexManager* LuceneIndexWriterTest::createManager()
+-{
+- string path = "testcluceneindex";
+-
+- // initialize a directory for writing and an indexmanager
+-#ifdef _WIN32
+- mkdir(path.c_str());
+-#else
+- mkdir(path.c_str(), S_IRUSR|S_IWUSR|S_IXUSR);
+-#endif
+-
+- return createCLuceneIndexManager(path.c_str());
+-}
+-
+-void LuceneIndexWriterTest::deleteManager( Strigi::IndexManager* m )
+-{
+- delete m;
+-
+- // clean up data
+- system("rm -r testcluceneindex");
+-}
+--- a/tests/luceneindexer/luceneindexwritertest.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/* This file is part of Strigi Desktop Search
+- *
+- * Copyright (C) 2007 Flavio Castelli <flavio.castelli at gmail.com>
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public License
+- * along with this library; see the file COPYING.LIB. If not, write to
+- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+- * Boston, MA 02110-1301, USA.
+- */
+-#ifndef UNIT_TEST_LUCENE_INDEX_WRITER_TEST_H
+-#define UNIT_TEST_LUCENE_INDEX_WRITER_TEST_H
+-
+-#include "indexwritertester.h"
+-
+-namespace strigiunittest
+-{
+- class LuceneIndexWriterTest : public IndexWriterTester
+- {
+- CPPUNIT_TEST_SUB_SUITE( LuceneIndexWriterTest, IndexWriterTester);
+- CPPUNIT_TEST_SUITE_END();
+-
+- private:
+- Strigi::IndexManager* createManager();
+- void deleteManager( Strigi::IndexManager* );
+- };
+-}
+-
+-#endif
+--- a/tests/streamanalyzer/diranalyzertester.cpp
++++ b/tests/streamanalyzer/diranalyzertester.cpp
+@@ -23,6 +23,7 @@
+ #include "diranalyzer.h"
+ #include "indexmanager.h"
+ #include "indexreader.h"
++#include "indexpluginloader.h"
+ #include "unittestfunctions.h"
+
+ #include <errno.h>
+@@ -105,8 +106,9 @@
+
+ void DirAnalyzerTester::tearDown()
+ {
+- if (manager)
+- delete manager;
++ if (manager) {
++ Strigi::IndexPluginLoader::deleteIndexManager(manager);
++ }
+ manager = NULL;
+
+ // clean up data
+--- a/tests/test_runner.cpp
++++ b/tests/test_runner.cpp
+@@ -24,11 +24,27 @@
+ #include <cppunit/TextTestRunner.h>
+
+ #include "strigilogging.h"
++#include "config.h"
++
++#include <iostream>
++using namespace std;
++
++int main() {
++ // set some environment variables so that the system can find the desired
++ // files
++ setenv("XDG_DATA_HOME",
++ SOURCEDIR"/src/streamanalyzer/fieldproperties", 1);
++ setenv("XDG_DATA_DIRS",
++ SOURCEDIR"/src/streamanalyzer/fieldproperties", 1);
++ setenv("STRIGI_PLUGIN_PATH",
++ BINARYDIR"/src/luceneindexer/:"
++ BINARYDIR"/src/estraierindexer:"
++ BINARYDIR"/src/sqliteindexer", 1);
++
++cerr << BINARYDIR << endl;
+
+-int main()
+-{
+ STRIGI_LOG_INIT_BASIC()
+-
++
+ // Get the top level suite from the registry
+ CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+@@ -46,18 +62,3 @@
+ return wasSucessful ? 0 : 1;
+ }
+
+-// using namespace CppUnit;
+-//
+-// int main (int argc, char* argv[]) {
+-// TextTestRunner runner;
+-// TestFactoryRegistry& registry = TestFactoryRegistry::getRegistry();
+-//
+-// // run all tests if none specified on command line
+-// Test* test_to_run = registry.makeTest();
+-// if (argc>1)
+-// test_to_run = test_to_run->findTest(argv[1]);
+-//
+-// runner.addTest( test_to_run );
+-// bool failed = runner.run("", false);
+-// return !failed;
+-// }
+--- a/tests/utils/CMakeLists.txt
++++ b/tests/utils/CMakeLists.txt
+@@ -1,8 +1,9 @@
+ include_directories ( .
++ ${strigi_BINARY_DIR}/src/streams
+ ${strigi_SOURCE_DIR}/src/streamanalyzer
+ ${strigi_SOURCE_DIR}/src/combinedindexer
+ )
+
+ add_library(unittestfunctions unittestfunctions.cpp)
+
+-target_link_libraries (unittestfunctions combinedindex)
+\ No newline at end of file
++target_link_libraries (unittestfunctions combinedindex)
+--- a/tests/utils/unittestfunctions.cpp
++++ b/tests/utils/unittestfunctions.cpp
+@@ -21,22 +21,14 @@
+ #include "unittestfunctions.h"
+
+ #include "indexmanager.h"
+-#include "combinedindexmanager.h"
++#include "indexpluginloader.h"
+ #include <vector>
+ #include <algorithm>
+
+ using namespace std;
+
+ Strigi::IndexManager* strigiunittest::getIndexManager(string& backend,
+- const string& indexdir)
+-{
+- // check arguments: backend
+- const vector<string>& backends = CombinedIndexManager::backEnds();
+-
+- vector<string>::const_iterator b
+- = find(backends.begin(), backends.end(), backend);
+- if (b == backends.end())
+- return 0;
+-
+- return CombinedIndexManager::factories()[backend](indexdir.c_str());
++ const string& indexdir) {
++ return Strigi::IndexPluginLoader::createIndexManager(backend.c_str(),
++ indexdir.c_str());
+ }
More information about the pkg-kde-commits
mailing list