LCOV - code coverage report
Current view: top level - tests/harness - backendmanager_multi.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 62 72 86.1 %
Date: 2019-06-30 05:20:33 Functions: 10 10 100.0 %
Branches: 59 124 47.6 %

           Branch data     Line data    Source code
       1                 :            : /** @file backendmanager_multi.cc
       2                 :            :  * @brief BackendManager subclass for multi databases.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009,2011,2012,2013,2015,2017,2018,2019 Olly Betts
       5                 :            :  * Copyright (C) 2008 Lemur Consulting Ltd
       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 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : 
      24                 :            : #include "backendmanager_multi.h"
      25                 :            : 
      26                 :            : #include "errno_to_string.h"
      27                 :            : #include "filetests.h"
      28                 :            : #include "index_utils.h"
      29                 :            : #include "str.h"
      30                 :            : 
      31                 :            : #include <cerrno>
      32                 :            : #include <cstdio> // For rename().
      33                 :            : #include <cstring>
      34                 :            : 
      35                 :            : using namespace std;
      36                 :            : 
      37                 :          1 : BackendManagerMulti::BackendManagerMulti(const std::string& datadir_,
      38                 :            :                                          BackendManager* sub_manager_)
      39                 :            :     : BackendManager(datadir_),
      40                 :            :       sub_manager(sub_manager_),
      41 [ +  - ][ +  - ]:          1 :       cachedir(".multi" + sub_manager_->get_dbtype())
                 [ +  - ]
      42                 :            : {
      43                 :            :     // Ensure the directory we store cached test databases in exists.
      44         [ +  - ]:          1 :     (void)create_dir_if_needed(cachedir);
      45                 :          1 : }
      46                 :            : 
      47                 :            : std::string
      48                 :         38 : BackendManagerMulti::get_dbtype() const
      49                 :            : {
      50         [ +  - ]:         38 :     return "multi_" + sub_manager->get_dbtype();
      51                 :            : }
      52                 :            : 
      53                 :            : #define NUMBER_OF_SUB_DBS 2
      54                 :            : 
      55                 :            : string
      56                 :        378 : BackendManagerMulti::createdb_multi(const string& name,
      57                 :            :                                     const vector<string>& files)
      58                 :            : {
      59         [ +  - ]:        378 :     string dbname;
      60         [ +  + ]:        378 :     if (!name.empty()) {
      61         [ +  - ]:        116 :         dbname = name;
      62                 :            :     } else {
      63         [ +  - ]:        262 :         dbname = "db";
      64         [ +  + ]:        526 :         for (const string& file : files) {
      65         [ +  - ]:        264 :             dbname += "__";
      66         [ +  - ]:        264 :             dbname += file;
      67                 :            :         }
      68                 :            :     }
      69                 :            : 
      70         [ +  - ]:        378 :     string db_path = cachedir;
      71         [ +  - ]:        378 :     db_path += '/';
      72         [ +  - ]:        378 :     db_path += dbname;
      73                 :            : 
      74         [ +  + ]:        378 :     if (!name.empty()) {
      75                 :        116 :         remove(db_path.c_str());
      76                 :            :     } else {
      77         [ +  + ]:        262 :         if (file_exists(db_path)) return db_path;
      78                 :            :     }
      79                 :            : 
      80         [ +  - ]:        274 :     string tmpfile = db_path + ".tmp";
      81         [ +  - ]:        274 :     ofstream out(tmpfile.c_str());
      82 [ +  - ][ -  + ]:        137 :     if (!out.is_open()) {
      83         [ #  # ]:          0 :         string msg = "Couldn't create file '";
      84         [ #  # ]:          0 :         msg += tmpfile;
      85         [ #  # ]:          0 :         msg += "' (";
      86         [ #  # ]:          0 :         errno_to_string(errno, msg);
      87         [ #  # ]:          0 :         msg += ')';
      88                 :          0 :         throw msg;
      89                 :            :     }
      90                 :            : 
      91                 :            :     // Open NUMBER_OF_SUB_DBS databases and index files to them alternately so
      92                 :            :     // a multi-db combining them contains the documents in the expected order.
      93         [ +  - ]:        274 :     Xapian::WritableDatabase dbs;
      94         [ +  - ]:        274 :     const string& subtype = sub_manager->get_dbtype();
      95                 :        137 :     int flags = Xapian::DB_CREATE_OR_OVERWRITE;
      96 [ +  - ][ +  - ]:        137 :     if (subtype == "glass") {
      97                 :        137 :         flags |= Xapian::DB_BACKEND_GLASS;
      98                 :            :     } else {
      99         [ #  # ]:          0 :         string msg = "Unknown multidb subtype: ";
     100         [ #  # ]:          0 :         msg += subtype;
     101                 :          0 :         throw msg;
     102                 :            :     }
     103         [ +  - ]:        274 :     string dbbase = db_path;
     104         [ +  - ]:        137 :     dbbase += "___";
     105                 :        137 :     size_t dbbase_len = dbbase.size();
     106         [ +  - ]:        274 :     string line = subtype;
     107         [ +  - ]:        137 :     line += ' ';
     108         [ +  - ]:        137 :     line += dbname;
     109         [ +  - ]:        137 :     line += "___";
     110         [ +  + ]:        411 :     for (size_t n = 0; n < NUMBER_OF_SUB_DBS; ++n) {
     111 [ +  - ][ +  - ]:        274 :         dbbase += str(n);
     112 [ +  - ][ +  - ]:        274 :         dbs.add_database(Xapian::WritableDatabase(dbbase, flags));
     113         [ +  - ]:        274 :         dbbase.resize(dbbase_len);
     114 [ +  - ][ +  - ]:        274 :         out << line << n << '\n';
                 [ +  - ]
     115                 :            :     }
     116         [ +  - ]:        137 :     out.close();
     117                 :            : 
     118 [ +  - ][ +  - ]:        137 :     FileIndexer(get_datadir(), files).index_to(dbs);
     119         [ +  - ]:        137 :     dbs.close();
     120                 :            : 
     121         [ -  + ]:        137 :     if (rename(tmpfile.c_str(), db_path.c_str()) < 0) {
     122 [ #  # ][ #  # ]:          0 :         throw Xapian::DatabaseError("rename failed", errno);
     123                 :            :     }
     124                 :            : 
     125         [ +  - ]:        137 :     last_wdb_path = db_path;
     126                 :        515 :     return db_path;
     127                 :            : }
     128                 :            : 
     129                 :            : string
     130                 :        262 : BackendManagerMulti::do_get_database_path(const vector<string> & files)
     131                 :            : {
     132         [ +  - ]:        262 :     return createdb_multi(string(), files);
     133                 :            : }
     134                 :            : 
     135                 :            : Xapian::WritableDatabase
     136                 :        116 : BackendManagerMulti::get_writable_database(const string& name, const string& file)
     137                 :            : {
     138                 :        116 :     vector<string> files;
     139 [ +  + ][ +  - ]:        116 :     if (!file.empty()) files.push_back(file);
     140 [ +  - ][ +  - ]:        116 :     return Xapian::WritableDatabase(createdb_multi(name, files));
     141                 :            : }
     142                 :            : 
     143                 :            : string
     144                 :         36 : BackendManagerMulti::get_writable_database_path(const std::string& name)
     145                 :            : {
     146         [ +  - ]:         36 :     return cachedir + "/" + name;
     147                 :            : }
     148                 :            : 
     149                 :            : string
     150                 :         12 : BackendManagerMulti::get_compaction_output_path(const string& name)
     151                 :            : {
     152         [ +  - ]:         12 :     return cachedir + "/" + name;
     153                 :            : }
     154                 :            : 
     155                 :            : string
     156                 :         35 : BackendManagerMulti::get_generated_database_path(const string& name)
     157                 :            : {
     158                 :         35 :     return BackendManagerMulti::get_writable_database_path(name);
     159                 :            : }
     160                 :            : 
     161                 :            : Xapian::WritableDatabase
     162                 :          1 : BackendManagerMulti::get_writable_database_again()
     163                 :            : {
     164                 :          1 :     return Xapian::WritableDatabase(last_wdb_path);
     165                 :            : }
     166                 :            : 
     167                 :            : string
     168                 :          6 : BackendManagerMulti::get_writable_database_path_again()
     169                 :            : {
     170                 :          6 :     return last_wdb_path;
     171                 :            : }

Generated by: LCOV version 1.11