xapian-core  1.4.21
backendmanager.cc
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2002 Ananova Ltd
6  * Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2016,2017,2018 Olly Betts
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23 
24 #include <config.h>
25 
26 #include <xapian.h>
27 
28 #ifdef HAVE_VALGRIND
29 # include <valgrind/memcheck.h>
30 #endif
31 
32 #include <cerrno>
33 #include <cstdio>
34 #include <fstream>
35 #include <string>
36 #include <vector>
37 
38 #include <sys/types.h>
39 #include "safesysstat.h"
40 
41 #include "filetests.h"
42 #include "index_utils.h"
43 #include "backendmanager.h"
44 #include "unixcmds.h"
45 
46 using namespace std;
47 
48 void
50  const vector<string> & files)
51 {
52  FileIndexer(datadir, files).index_to(database);
53 }
54 
59 bool
61 {
62  if (mkdir(dirname.c_str(), 0700) == 0) {
63  return true;
64  }
65 
66  int mkdir_errno = errno;
67  if (mkdir_errno == EEXIST) {
68  // Something exists at dirname, but we need to check if it is a directory.
69  if (dir_exists(dirname)) {
70  return false;
71  }
72  }
73 
74  throw Xapian::DatabaseOpeningError("Failed to create directory",
75  mkdir_errno);
76 }
77 
79 
80 std::string
82 {
83  return "none";
84 }
85 
86 string
87 BackendManager::do_get_database_path(const vector<string> &)
88 {
89  throw Xapian::InvalidArgumentError("Path isn't meaningful for this database type");
90 }
91 
93 BackendManager::do_get_database(const vector<string> & files)
94 {
95  return Xapian::Database(do_get_database_path(files));
96 }
97 
99 BackendManager::get_database(const vector<string> & files)
100 {
101  return do_get_database(files);
102 }
103 
105 BackendManager::get_database(const string & file)
106 {
107  return do_get_database(vector<string>(1, file));
108 }
109 
111 BackendManager::get_database(const std::string &dbname,
112  void (*gen)(Xapian::WritableDatabase&,
113  const std::string &),
114  const std::string &arg)
115 {
116  string dbleaf = "db__";
117  dbleaf += dbname;
118  const string& path = get_generated_database_path(dbleaf);
119  if (path.empty()) {
120  // InMemory doesn't have a path but we want to support generated
121  // databases for it.
123  gen(wdb, arg);
124  return std::move(wdb);
125  }
126 
127  if (path_exists(path)) {
128  try {
129  return get_database_by_path(path);
130  } catch (const Xapian::DatabaseOpeningError &) {
131  }
132  }
133  rm_rf(path);
134 
135  string tmp_dbleaf(dbleaf);
136  tmp_dbleaf += '~';
137  string tmp_path(path);
138  tmp_path += '~';
139 
140  {
141  Xapian::WritableDatabase wdb = get_generated_database(tmp_dbleaf);
142  gen(wdb, arg);
143  }
144  finalise_generated_database(tmp_dbleaf);
145  rename(tmp_path.c_str(), path.c_str());
146  // For multi, the shards will use the temporary name, but that's not really
147  // a problem.
148 
149  return get_database_by_path(path);
150 }
151 
152 std::string
153 BackendManager::get_database_path(const std::string &dbname,
154  void (*gen)(Xapian::WritableDatabase&,
155  const std::string &),
156  const std::string &arg)
157 {
158  string dbleaf = "db__";
159  dbleaf += dbname;
160  const string& path = get_generated_database_path(dbleaf);
161  if (path_exists(path)) {
162  try {
163  (void)Xapian::Database(path);
164  return path;
165  } catch (const Xapian::DatabaseOpeningError &) {
166  }
167  }
168  rm_rf(path);
169 
170  string tmp_dbleaf(dbleaf);
171  tmp_dbleaf += '~';
172  string tmp_path(path);
173  tmp_path += '~';
174 
175  {
176  Xapian::WritableDatabase wdb = get_generated_database(tmp_dbleaf);
177  gen(wdb, arg);
178  }
179  finalise_generated_database(tmp_dbleaf);
180  rename(tmp_path.c_str(), path.c_str());
181 
182  return path;
183 }
184 
187 {
188  return Xapian::Database(path);
189 }
190 
191 string
192 BackendManager::get_database_path(const vector<string> & files)
193 {
194  return do_get_database_path(files);
195 }
196 
197 string
199 {
200  return do_get_database_path(vector<string>(1, file));
201 }
202 
204 BackendManager::get_writable_database(const string &, const string &)
205 {
206  throw Xapian::InvalidArgumentError("Attempted to open a disabled database");
207 }
208 
211 {
212  string msg = "BackendManager::get_remote_writable_database() "
213  "called for non-remote database (type is ";
214  msg += get_dbtype();
215  msg += ')';
217 }
218 
219 string
221 {
222  throw Xapian::InvalidArgumentError("Path isn't meaningful for this database type");
223 }
224 
227 {
228  return get_writable_database(name, string());
229 }
230 
231 string
233 {
234  throw Xapian::InvalidArgumentError("Compaction now supported for this database type");
235 }
236 
237 string
239 {
240  throw Xapian::InvalidArgumentError("Generated databases aren't supported for this database type");
241 }
242 
243 void
245 { }
246 
248 BackendManager::get_remote_database(const vector<string> &, unsigned int)
249 {
250  string msg = "BackendManager::get_remote_database() called for non-remote database (type is ";
251  msg += get_dbtype();
252  msg += ')';
254 }
255 
256 string
258  unsigned int)
259 {
260  string msg = "BackendManager::get_writable_database_args() "
261  "called for non-remote database (type is ";
262  msg += get_dbtype();
263  msg += ')';
265 }
266 
269 {
270  return Xapian::Database(get_writable_database_path_again());
271 }
272 
275 {
276  string msg = "Backend ";
277  msg += get_dbtype();
278  msg += " doesn't support get_writable_database_again()";
280 }
281 
282 string
284 {
285  string msg = "Backend ";
286  msg += get_dbtype();
287  msg += " doesn't support get_writable_database_path_again()";
289 }
290 
291 void
293 {
294 }
295 
296 const char *
298 {
299 #ifdef HAVE_VALGRIND
300  if (RUNNING_ON_VALGRIND) {
301  return "./runsrv " XAPIAN_PROGSRV;
302  }
303 #endif
304  return XAPIAN_PROGSRV;
305 }
static const char * get_xapian_progsrv_command()
Get the command line required to run xapian-progsrv.
virtual Xapian::Database get_remote_database(const std::vector< std::string > &files, unsigned int timeout)
Get a remote database instance with the specified timeout.
This class is used to access a database, or a group of databases.
Definition: database.h:68
Xapian::Database get_database(const std::vector< std::string > &files)
Get a database instance of the current type.
InvalidOperationError indicates the API was used in an invalid way.
Definition: error.h:283
DatabaseOpeningError indicates failure to open a database.
Definition: error.h:581
virtual std::string get_generated_database_path(const std::string &name)
Get the path to use for generating a database, if supported.
Xapian::WritableDatabase get_writable_database(const string &dbname)
Definition: apitest.cc:87
std::string get_database_path(const std::vector< std::string > &files)
Get the path of a database instance, if such a thing exists.
virtual Xapian::WritableDatabase get_generated_database(const std::string &name)
Get a generated writable database instance.
C++ function versions of useful Unix commands.
STL namespace.
#define XAPIAN_PROGSRV
Utility functions for testing files.
virtual std::string get_writable_database_path(const std::string &name)
Get the path of a writable database instance, if such a thing exists.
virtual Xapian::WritableDatabase get_writable_database(const std::string &name, const std::string &file)
Get a writable database instance.
include <sys/stat.h> with portability enhancements
void rm_rf(const string &filename)
Remove a directory and contents, just like the Unix "rm -rf" command.
Definition: unixcmds.cc:111
bool create_dir_if_needed(const std::string &dirname)
Create the directory dirname if needed.
InvalidArgumentError indicates an invalid parameter value was passed to the API.
Definition: error.h:241
virtual Xapian::WritableDatabase get_writable_database_again()
Create a WritableDatabase object for the last opened WritableDatabase.
virtual Xapian::Database get_database_by_path(const std::string &path)
Get a database instance by path.
Base class for backend handling in test harness.
This class provides read/write access to a database.
Definition: database.h:785
Public interfaces for the Xapian library.
virtual Xapian::WritableDatabase get_remote_writable_database(std::string args)
Get a remote Xapian::WritableDatabase instance with specified args.
std::string get_dbtype()
Definition: apitest.cc:42
virtual std::string get_writable_database_path_again()
Get the path of the last opened WritableDatabase.
bool dir_exists(const char *path)
Test if a directory exists.
Definition: filetests.h:136
virtual std::string get_dbtype() const
Get the database type currently in use.
virtual void clean_up()
Called after each test, to perform any necessary cleanup.
virtual ~BackendManager()
We have virtual methods and want to be able to delete derived classes using a pointer to the base cla...
virtual Xapian::Database do_get_database(const std::vector< std::string > &files)
Virtual method implementing get_database().
virtual std::string do_get_database_path(const std::vector< std::string > &files)
Virtual method implementing get_database_path().
void index_to(Xapian::WritableDatabase &db)
Definition: index_utils.cc:52
virtual Xapian::Database get_writable_database_as_database()
Create a Database object for the last opened WritableDatabase.
virtual std::string get_writable_database_args(const std::string &path, unsigned int timeout)
Get the args for opening a writable remote database with the specified timeout.
Definition: header.h:151
utility functions for indexing testcase data
virtual std::string get_compaction_output_path(const std::string &name)
Get a path to compact a database to.
bool path_exists(const char *path)
Test if a path exists.
Definition: filetests.h:158
virtual void finalise_generated_database(const std::string &name)
Finalise the generated database.
void index_files_to_database(Xapian::WritableDatabase &database, const std::vector< std::string > &files)
Index data from zero or more text files into a database.