LCOV - code coverage report
Current view: top level - harness - backendmanager.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core r Lines: 138 166 83.1 %
Date: 2011-08-21 Functions: 23 31 74.2 %
Branches: 21 28 75.0 %

           Branch data     Line data    Source code
       1                 :            : /* backendmanager.cc: manage backends for testsuite
       2                 :            :  *
       3                 :            :  * Copyright 1999,2000,2001 BrightStation PLC
       4                 :            :  * Copyright 2002 Ananova Ltd
       5                 :            :  * Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2010 Olly Betts
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU General Public License as
       9                 :            :  * published by the Free Software Foundation; either version 2 of the
      10                 :            :  * License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      20                 :            :  * USA
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <config.h>
      24                 :            : 
      25                 :            : #include <xapian.h>
      26                 :            : 
      27                 :            : #ifdef HAVE_VALGRIND
      28                 :            : # include <valgrind/memcheck.h>
      29                 :            : #endif
      30                 :            : 
      31                 :            : #include "safeerrno.h"
      32                 :            : 
      33                 :            : #include <fstream>
      34                 :            : #include <string>
      35                 :            : #include <vector>
      36                 :            : 
      37                 :            : #include <sys/types.h>
      38                 :            : #include "safesysstat.h"
      39                 :            : 
      40                 :            : #include "index_utils.h"
      41                 :            : #include "backendmanager.h"
      42                 :            : #include "unixcmds.h"
      43                 :            : #include "utils.h"
      44                 :            : 
      45                 :            : using namespace std;
      46                 :            : 
      47                 :            : void
      48                 :       1053 : BackendManager::index_files_to_database(Xapian::WritableDatabase & database,
      49                 :            :                                         const vector<string> & files)
      50                 :            : {
      51                 :       1053 :     FileIndexer f(datadir, files);
      52         [ +  + ]:      27832 :     while (f) database.add_document(f.next());
      53                 :       1053 : }
      54                 :            : 
      55                 :            : /** Create the directory dirname if needed.  Returns true if the
      56                 :            :  *  directory was created and false if it was already there.  Throws
      57                 :            :  *  an exception if there was an error (eg not a directory).
      58                 :            :  */
      59                 :            : bool
      60                 :       5527 : BackendManager::create_dir_if_needed(const string &dirname)
      61                 :            : {
      62                 :            :     // create a directory if not present
      63                 :            :     struct stat sbuf;
      64                 :       5527 :     int result = stat(dirname, &sbuf);
      65         [ +  + ]:       5527 :     if (result < 0) {
      66         [ -  + ]:        812 :         if (errno != ENOENT)
      67                 :          0 :             throw Xapian::DatabaseOpeningError("Can't stat directory");
      68         [ -  + ]:        812 :         if (mkdir(dirname, 0700) < 0)
      69                 :          0 :             throw Xapian::DatabaseOpeningError("Can't create directory");
      70                 :        812 :         return true; // Successfully created a directory.
      71                 :            :     }
      72         [ -  + ]:       4715 :     if (!S_ISDIR(sbuf.st_mode))
      73                 :          0 :         throw Xapian::DatabaseOpeningError("Is not a directory.");
      74                 :       5527 :     return false; // Already a directory.
      75                 :            : }
      76                 :            : 
      77                 :            : #ifdef XAPIAN_HAS_INMEMORY_BACKEND
      78                 :            : Xapian::WritableDatabase
      79                 :        247 : BackendManager::getwritedb_inmemory(const vector<string> &files)
      80                 :            : {
      81                 :        247 :     Xapian::WritableDatabase db(Xapian::InMemory::open());
      82                 :        247 :     index_files_to_database(db, files);
      83                 :          0 :     return db;
      84                 :            : }
      85                 :            : #endif
      86                 :            : 
      87                 :            : #ifdef XAPIAN_HAS_BRASS_BACKEND
      88                 :            : string
      89                 :        568 : BackendManager::createdb_brass(const vector<string> &files)
      90                 :            : {
      91                 :        568 :     string parent_dir = ".brass";
      92                 :        568 :     create_dir_if_needed(parent_dir);
      93                 :            : 
      94                 :        568 :     string dbdir = parent_dir + "/db";
      95         [ +  + ]:       1157 :     for (vector<string>::const_iterator i = files.begin();
      96                 :            :          i != files.end(); i++) {
      97                 :        589 :         dbdir += '=';
      98                 :        589 :         dbdir += *i;
      99                 :            :     }
     100                 :            :     // If the database is readonly, we can reuse it if it exists.
     101         [ +  + ]:        568 :     if (create_dir_if_needed(dbdir)) {
     102                 :            :         // Directory was created, so do the indexing.
     103                 :         20 :         Xapian::WritableDatabase db(Xapian::Brass::open(dbdir, Xapian::DB_CREATE, 2048));
     104                 :         20 :         index_files_to_database(db, files);
     105                 :         20 :         db.commit();
     106                 :            :     }
     107                 :        568 :     return dbdir;
     108                 :            : }
     109                 :            : 
     110                 :            : Xapian::WritableDatabase
     111                 :        252 : BackendManager::getwritedb_brass(const string & name,
     112                 :            :                                  const vector<string> & files)
     113                 :            : {
     114                 :        252 :     string dbdir = getwritedb_brass_path(name);
     115                 :            : 
     116                 :            :     // For a writable database we need to start afresh each time.
     117                 :        252 :     rm_rf(dbdir);
     118                 :        252 :     (void)create_dir_if_needed(dbdir);
     119                 :            : 
     120                 :            :     // directory was created, so do the indexing.
     121                 :        252 :     Xapian::WritableDatabase db(Xapian::Brass::open(dbdir, Xapian::DB_CREATE, 2048));
     122                 :        252 :     index_files_to_database(db, files);
     123                 :        252 :     return db;
     124                 :            : }
     125                 :            : 
     126                 :            : std::string
     127                 :        280 : BackendManager::getwritedb_brass_path(const string & name)
     128                 :            : {
     129                 :        280 :     string parent_dir = ".brass";
     130                 :        280 :     create_dir_if_needed(parent_dir);
     131                 :            : 
     132                 :        280 :     string dbdir = parent_dir;
     133                 :        280 :     dbdir += '/';
     134                 :        280 :     dbdir += name;
     135                 :        280 :     return dbdir;
     136                 :            : }
     137                 :            : #endif
     138                 :            : 
     139                 :            : #ifdef XAPIAN_HAS_CHERT_BACKEND
     140                 :            : string
     141                 :        612 : BackendManager::createdb_chert(const vector<string> &files)
     142                 :            : {
     143                 :        612 :     string parent_dir = ".chert";
     144                 :        612 :     create_dir_if_needed(parent_dir);
     145                 :            : 
     146                 :        612 :     string dbdir = parent_dir + "/db";
     147         [ +  + ]:       1245 :     for (vector<string>::const_iterator i = files.begin();
     148                 :            :          i != files.end(); i++) {
     149                 :        633 :         dbdir += '=';
     150                 :        633 :         dbdir += *i;
     151                 :            :     }
     152                 :            :     // If the database is readonly, we can reuse it if it exists.
     153         [ +  + ]:        612 :     if (create_dir_if_needed(dbdir)) {
     154                 :            :         // Directory was created, so do the indexing.
     155                 :         20 :         Xapian::WritableDatabase db(Xapian::Chert::open(dbdir, Xapian::DB_CREATE, 2048));
     156                 :         20 :         index_files_to_database(db, files);
     157                 :         20 :         db.commit();
     158                 :            :     }
     159                 :        612 :     return dbdir;
     160                 :            : }
     161                 :            : 
     162                 :            : Xapian::WritableDatabase
     163                 :        252 : BackendManager::getwritedb_chert(const string & name,
     164                 :            :                                  const vector<string> & files)
     165                 :            : {
     166                 :        252 :     string dbdir = getwritedb_chert_path(name);
     167                 :            : 
     168                 :            :     // For a writable database we need to start afresh each time.
     169                 :        252 :     rm_rf(dbdir);
     170                 :        252 :     (void)create_dir_if_needed(dbdir);
     171                 :            : 
     172                 :            :     // directory was created, so do the indexing.
     173                 :        252 :     Xapian::WritableDatabase db(Xapian::Chert::open(dbdir, Xapian::DB_CREATE, 2048));
     174                 :        252 :     index_files_to_database(db, files);
     175                 :        252 :     return db;
     176                 :            : }
     177                 :            : 
     178                 :            : std::string
     179                 :        279 : BackendManager::getwritedb_chert_path(const string & name)
     180                 :            : {
     181                 :        279 :     string parent_dir = ".chert";
     182                 :        279 :     create_dir_if_needed(parent_dir);
     183                 :            : 
     184                 :        279 :     string dbdir = parent_dir;
     185                 :        279 :     dbdir += '/';
     186                 :        279 :     dbdir += name;
     187                 :        279 :     return dbdir;
     188                 :            : }
     189                 :            : 
     190                 :            : #endif
     191                 :            : 
     192                 :            : #ifdef XAPIAN_HAS_FLINT_BACKEND
     193                 :            : string
     194                 :        559 : BackendManager::createdb_flint(const vector<string> &files)
     195                 :            : {
     196                 :        559 :     string parent_dir = ".flint";
     197                 :        559 :     create_dir_if_needed(parent_dir);
     198                 :            : 
     199                 :        559 :     string dbdir = parent_dir + "/db";
     200         [ +  + ]:       1139 :     for (vector<string>::const_iterator i = files.begin();
     201                 :            :          i != files.end(); i++) {
     202                 :        580 :         dbdir += '=';
     203                 :        580 :         dbdir += *i;
     204                 :            :     }
     205                 :            :     // If the database is readonly, we can reuse it if it exists.
     206         [ +  + ]:        559 :     if (create_dir_if_needed(dbdir)) {
     207                 :            :         // Directory was created, so do the indexing.
     208                 :         20 :         Xapian::WritableDatabase db(Xapian::Flint::open(dbdir, Xapian::DB_CREATE, 2048));
     209                 :         20 :         index_files_to_database(db, files);
     210                 :         20 :         db.commit();
     211                 :            :     }
     212                 :        559 :     return dbdir;
     213                 :            : }
     214                 :            : 
     215                 :            : Xapian::WritableDatabase
     216                 :        242 : BackendManager::getwritedb_flint(const string & name,
     217                 :            :                                  const vector<string> & files)
     218                 :            : {
     219                 :        242 :     string dbdir = getwritedb_flint_path(name);
     220                 :            : 
     221                 :            :     // For a writable database we need to start afresh each time.
     222                 :        242 :     rm_rf(dbdir);
     223                 :        242 :     (void)create_dir_if_needed(dbdir);
     224                 :            : 
     225                 :            :     // directory was created, so do the indexing.
     226                 :        242 :     Xapian::WritableDatabase db(Xapian::Flint::open(dbdir, Xapian::DB_CREATE, 2048));
     227                 :        242 :     index_files_to_database(db, files);
     228                 :        242 :     return db;
     229                 :            : }
     230                 :            : 
     231                 :            : std::string
     232                 :        269 : BackendManager::getwritedb_flint_path(const string & name)
     233                 :            : {
     234                 :        269 :     string parent_dir = ".flint";
     235                 :        269 :     create_dir_if_needed(parent_dir);
     236                 :            : 
     237                 :        269 :     string dbdir = parent_dir;
     238                 :        269 :     dbdir += '/';
     239                 :        269 :     dbdir += name;
     240                 :        269 :     return dbdir;
     241                 :            : }
     242                 :            : 
     243                 :            : #endif
     244                 :            : 
     245 [ #  # ][ -  + ]:         40 : BackendManager::~BackendManager() { }
                 [ -  + ]
     246                 :            : 
     247                 :            : std::string
     248                 :          3 : BackendManager::get_dbtype() const
     249                 :            : {
     250                 :          3 :     return "none";
     251                 :            : }
     252                 :            : 
     253                 :            : string
     254                 :          0 : BackendManager::do_get_database_path(const vector<string> &)
     255                 :            : {
     256                 :          0 :     throw Xapian::InvalidArgumentError("Path isn't meaningful for this database type");
     257                 :            : }
     258                 :            : 
     259                 :            : Xapian::Database
     260                 :       1083 : BackendManager::do_get_database(const vector<string> & files)
     261                 :            : {
     262                 :       1083 :     return Xapian::Database(do_get_database_path(files));
     263                 :            : }
     264                 :            : 
     265                 :            : Xapian::Database
     266                 :         79 : BackendManager::get_database(const vector<string> & files)
     267                 :            : {
     268                 :         79 :     return do_get_database(files);
     269                 :            : }
     270                 :            : 
     271                 :            : Xapian::Database
     272                 :       2269 : BackendManager::get_database(const string & file)
     273                 :            : {
     274                 :       2269 :     return do_get_database(vector<string>(1, file));
     275                 :            : }
     276                 :            : 
     277                 :            : Xapian::Database
     278                 :         21 : BackendManager::get_database(const std::string &dbname,
     279                 :            :                              void (*gen)(Xapian::WritableDatabase&,
     280                 :            :                                          const std::string &),
     281                 :            :                              const std::string &arg)
     282                 :            : {
     283                 :         21 :     string dbleaf = "db__";
     284                 :         21 :     dbleaf += dbname;
     285                 :         21 :     const string & path = get_writable_database_path(dbleaf);
     286                 :            :     try {
     287                 :         21 :         return Xapian::Database(path);
     288                 :         18 :     } catch (const Xapian::DatabaseOpeningError &) {
     289                 :            :     }
     290                 :         18 :     rm_rf(path);
     291                 :            : 
     292                 :         18 :     string tmp_dbleaf(dbleaf);
     293                 :         18 :     tmp_dbleaf += '~';
     294                 :         18 :     string tmp_path(path);
     295                 :         18 :     tmp_path += '~';
     296                 :            : 
     297                 :            :     {
     298                 :            :         Xapian::WritableDatabase wdb = get_writable_database(tmp_dbleaf,
     299                 :         18 :                                                              string());
     300                 :         18 :         gen(wdb, arg);
     301                 :            :     }
     302                 :         18 :     rename(tmp_path.c_str(), path.c_str());
     303                 :            : 
     304                 :         21 :     return Xapian::Database(path);
     305                 :            : }
     306                 :            : 
     307                 :            : std::string
     308                 :         21 : BackendManager::get_database_path(const std::string &dbname,
     309                 :            :                                   void (*gen)(Xapian::WritableDatabase&,
     310                 :            :                                               const std::string &),
     311                 :            :                                   const std::string &arg)
     312                 :            : {
     313                 :         21 :     string dbleaf = "db__";
     314                 :         21 :     dbleaf += dbname;
     315                 :         21 :     const string & path = get_writable_database_path(dbleaf);
     316                 :            :     try {
     317                 :         21 :         (void)Xapian::Database(path);
     318                 :          0 :         return path;
     319                 :         21 :     } catch (const Xapian::DatabaseOpeningError &) {
     320                 :            :     }
     321                 :         21 :     rm_rf(path);
     322                 :            : 
     323                 :         21 :     string tmp_dbleaf(dbleaf);
     324                 :         21 :     tmp_dbleaf += '~';
     325                 :         21 :     string tmp_path(path);
     326                 :         21 :     tmp_path += '~';
     327                 :            : 
     328                 :            :     {
     329                 :            :         Xapian::WritableDatabase wdb = get_writable_database(tmp_dbleaf,
     330                 :         21 :                                                              string());
     331                 :         21 :         gen(wdb, arg);
     332                 :            :     }
     333                 :         21 :     rename(tmp_path.c_str(), path.c_str());
     334                 :            : 
     335                 :         21 :     return path;
     336                 :            : }
     337                 :            : 
     338                 :            : string
     339                 :          0 : BackendManager::get_database_path(const vector<string> & files)
     340                 :            : {
     341                 :          0 :     return do_get_database_path(files);
     342                 :            : }
     343                 :            : 
     344                 :            : string
     345                 :         51 : BackendManager::get_database_path(const string & file)
     346                 :            : {
     347                 :         51 :     return do_get_database_path(vector<string>(1, file));
     348                 :            : }
     349                 :            : 
     350                 :            : Xapian::WritableDatabase
     351                 :          0 : BackendManager::get_writable_database(const string &, const string &)
     352                 :            : {
     353                 :          0 :     throw Xapian::InvalidArgumentError("Attempted to open a disabled database");
     354                 :            : }
     355                 :            : 
     356                 :            : string
     357                 :          0 : BackendManager::get_writable_database_path(const std::string &)
     358                 :            : {
     359                 :          0 :     throw Xapian::InvalidArgumentError("Path isn't meaningful for this database type");
     360                 :            : }
     361                 :            : 
     362                 :            : Xapian::Database
     363                 :          0 : BackendManager::get_remote_database(const vector<string> &, unsigned int)
     364                 :            : {
     365                 :          0 :     string msg = "BackendManager::get_remote_database() called for non-remote database (type is ";
     366                 :          0 :     msg += get_dbtype();
     367                 :          0 :     msg += ')';
     368                 :          0 :     throw Xapian::InvalidOperationError(msg);
     369                 :            : }
     370                 :            : 
     371                 :            : Xapian::Database
     372                 :          0 : BackendManager::get_writable_database_as_database()
     373                 :            : {
     374                 :          0 :     string msg = "Backend ";
     375                 :          0 :     msg += get_dbtype();
     376                 :          0 :     msg += " doesn't support get_writable_database_as_database()";
     377                 :          0 :     throw Xapian::InvalidOperationError(msg);
     378                 :            : }
     379                 :            : 
     380                 :            : Xapian::WritableDatabase
     381                 :          0 : BackendManager::get_writable_database_again()
     382                 :            : {
     383                 :          0 :     string msg = "Backend ";
     384                 :          0 :     msg += get_dbtype();
     385                 :          0 :     msg += " doesn't support get_writable_database_again()";
     386                 :          0 :     throw Xapian::InvalidOperationError(msg);
     387                 :            : }
     388                 :            : 
     389                 :            : void
     390                 :       4384 : BackendManager::clean_up()
     391                 :            : {
     392                 :       4384 : }
     393                 :            : 
     394                 :            : const char *
     395                 :          6 : BackendManager::get_xapian_progsrv_command()
     396                 :            : {
     397                 :            : #ifdef HAVE_VALGRIND
     398                 :            :     if (RUNNING_ON_VALGRIND) {
     399                 :            :         return "./runsrv "XAPIAN_PROGSRV;
     400                 :            :     }
     401                 :            : #endif
     402                 :          6 :     return XAPIAN_PROGSRV;
     403                 :            : }

Generated by: LCOV version 1.8