1 /** @file backendmanager_multi.cc
2 * @brief BackendManager subclass for multi databases.
4 /* Copyright (C) 2007,2008,2009,2011,2012,2013,2015 Olly Betts
5 * Copyright (C) 2008 Lemur Consulting Ltd
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.
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.
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
24 #include "backendmanager_multi.h"
26 #include "filetests.h"
27 #include "index_utils.h"
31 #include <cstdio> // For rename().
36 BackendManagerMulti::BackendManagerMulti(const std::string
& subtype_
)
39 #ifdef XAPIAN_HAS_GLASS_BACKEND
40 if (subtype
== "glass") return;
42 throw ("Unknown backend type \"" + subtype
+ "\" specified for multi database subdatabases");
46 BackendManagerMulti::get_dbtype() const
48 return "multi_" + subtype
;
51 #define NUMBER_OF_SUB_DBS 2
54 BackendManagerMulti::createdb_multi(const vector
<string
> & files
)
56 string dbdir
= ".multi" + subtype
;
57 create_dir_if_needed(dbdir
);
60 vector
<string
>::const_iterator i
;
61 for (i
= files
.begin(); i
!= files
.end(); ++i
) {
65 string dbpath
= dbdir
+ "/" + dbname
;
67 if (file_exists(dbpath
)) return dbpath
;
69 string tmpfile
= dbpath
;
71 ofstream
out(tmpfile
.c_str());
73 string msg
= "Couldn't create file '";
76 msg
+= strerror(errno
);
81 // Open NUMBER_OF_SUB_DBS databases and index files to them alternately so
82 // a multi-db combining them contains the documents in the expected order.
83 Xapian::WritableDatabase dbs
;
84 int flags
= Xapian::DB_CREATE_OR_OVERWRITE
;
85 if (subtype
== "glass") {
86 flags
|= Xapian::DB_BACKEND_GLASS
;
88 string msg
= "Unknown multidb subtype: ";
92 string dbbase
= dbdir
;
96 size_t dbbase_len
= dbbase
.size();
97 string line
= subtype
;
101 for (size_t n
= 0; n
< NUMBER_OF_SUB_DBS
; ++n
) {
103 dbs
.add_database(Xapian::WritableDatabase(dbbase
, flags
));
104 dbbase
.resize(dbbase_len
);
105 out
<< line
<< n
<< '\n';
109 FileIndexer(get_datadir(), files
).index_to(dbs
);
111 rename(tmpfile
.c_str(), dbpath
.c_str());
117 BackendManagerMulti::do_get_database_path(const vector
<string
> & files
)
119 return createdb_multi(files
);
122 Xapian::WritableDatabase
123 BackendManagerMulti::get_writable_database(const string
&, const string
&)
125 throw Xapian::UnimplementedError("Multi-databases don't support writing");