1
0
Fork 0

simplification: FileResult does only support ok, no additional result

header only, added FileResultString class for Result that return a string
This commit is contained in:
Frank Celler 2017-03-06 17:25:35 +01:00
parent fd7ad33a0c
commit 7eefdf547b
13 changed files with 441 additions and 307 deletions

View File

@ -67,14 +67,14 @@ DumpFeature::DumpFeature(application_features::ApplicationServer* server,
_result(result),
_batchId(0),
_clusterMode(false),
_stats{ 0, 0, 0 } {
_stats{0, 0, 0} {
requiresElevatedPrivileges(false);
setOptional(false);
startsAfter("Client");
startsAfter("Logger");
_outputDirectory =
FileUtils::buildFilename(FileUtils::currentDirectory(), "dump");
FileUtils::buildFilename(FileUtils::currentDirectory().result(), "dump");
}
void DumpFeature::collectOptions(
@ -117,8 +117,9 @@ void DumpFeature::collectOptions(
options->addOption("--tick-end", "last tick to be included in data dump",
new UInt64Parameter(&_tickEnd));
options->addOption("--compat28", "produce a dump compatible with ArangoDB 2.8",
options->addOption("--compat28",
"produce a dump compatible with ArangoDB 2.8",
new BooleanParameter(&_compat28));
}
@ -130,8 +131,9 @@ void DumpFeature::validateOptions(
if (1 == n) {
_outputDirectory = positionals[0];
} else if (1 < n) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
FATAL_ERROR_EXIT();
}
@ -144,7 +146,8 @@ void DumpFeature::validateOptions(
}
if (_tickStart < _tickEnd) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "invalid values for --tick-start or --tick-end";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "invalid values for --tick-start or --tick-end";
FATAL_ERROR_EXIT();
}
@ -165,23 +168,28 @@ void DumpFeature::prepare() {
isDirectory = TRI_IsDirectory(_outputDirectory.c_str());
if (isDirectory) {
std::vector<std::string> files(TRI_FullTreeDirectory(_outputDirectory.c_str()));
std::vector<std::string> files(
TRI_FullTreeDirectory(_outputDirectory.c_str()));
// we don't care if the target directory is empty
isEmptyDirectory = (files.size() <= 1); // TODO: TRI_FullTreeDirectory always returns at least one element (""), even if directory is empty?
isEmptyDirectory = (files.size() <= 1); // TODO: TRI_FullTreeDirectory
// always returns at least one
// element (""), even if
// directory is empty?
}
}
if (_outputDirectory.empty() ||
(TRI_ExistsFile(_outputDirectory.c_str()) && !isDirectory)) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot write to output directory '" << _outputDirectory
<< "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot write to output directory '" << _outputDirectory << "'";
FATAL_ERROR_EXIT();
}
if (isDirectory && !isEmptyDirectory && !_overwrite) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "output directory '" << _outputDirectory
<< "' already exists. use \"--overwrite true\" to "
"overwrite data in it";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "output directory '" << _outputDirectory
<< "' already exists. use \"--overwrite true\" to "
"overwrite data in it";
FATAL_ERROR_EXIT();
}
@ -192,8 +200,9 @@ void DumpFeature::prepare() {
errorMessage);
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "unable to create output directory '" << _outputDirectory
<< "': " << errorMessage;
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "unable to create output directory '" << _outputDirectory
<< "': " << errorMessage;
FATAL_ERROR_EXIT();
}
}
@ -209,9 +218,8 @@ int DumpFeature::startBatch(std::string DBserver, std::string& errorMsg) {
urlExt = "?DBserver=" + DBserver;
}
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::POST, url + urlExt,
body.c_str(), body.size()));
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::POST, url + urlExt, body.c_str(), body.size()));
if (response == nullptr || !response->isComplete()) {
errorMsg =
@ -262,9 +270,8 @@ void DumpFeature::extendBatch(std::string DBserver) {
urlExt = "?DBserver=" + DBserver;
}
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::PUT, url + urlExt,
body.c_str(), body.size()));
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::PUT, url + urlExt, body.c_str(), body.size()));
// ignore any return value
}
@ -294,8 +301,8 @@ int DumpFeature::dumpCollection(int fd, std::string const& cid,
std::string& errorMsg) {
uint64_t chunkSize = _chunkSize;
std::string const baseUrl = "/_api/replication/dump?collection=" + cid +
"&ticks=false&flush=false";
std::string const baseUrl =
"/_api/replication/dump?collection=" + cid + "&ticks=false&flush=false";
uint64_t fromTick = _tickStart;
@ -313,8 +320,8 @@ int DumpFeature::dumpCollection(int fd, std::string const& cid,
_stats._totalBatches++;
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::GET, url, nullptr, 0));
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::GET, url, nullptr, 0));
if (response == nullptr || !response->isComplete()) {
errorMsg =
@ -543,7 +550,8 @@ int DumpFeature::runDump(std::string& dbName, std::string& errorMsg) {
return TRI_ERROR_INTERNAL;
}
uint64_t const cid = arangodb::basics::VelocyPackHelper::extractIdValue(parameters);
uint64_t const cid =
arangodb::basics::VelocyPackHelper::extractIdValue(parameters);
std::string const name = arangodb::basics::VelocyPackHelper::getStringValue(
parameters, "name", "");
bool const deleted = arangodb::basics::VelocyPackHelper::getBooleanValue(
@ -642,7 +650,8 @@ int DumpFeature::runDump(std::string& dbName, std::string& errorMsg) {
}
extendBatch("");
int res = dumpCollection(fd, std::to_string(cid), name, maxTick, errorMsg);
int res =
dumpCollection(fd, std::to_string(cid), name, maxTick, errorMsg);
TRI_CLOSE(fd);
@ -664,8 +673,7 @@ int DumpFeature::dumpShard(int fd, std::string const& DBserver,
std::string const& name, std::string& errorMsg) {
std::string const baseUrl = "/_api/replication/dump?DBserver=" + DBserver +
"&collection=" + name + "&chunkSize=" +
StringUtils::itoa(_chunkSize) +
"&ticks=false";
StringUtils::itoa(_chunkSize) + "&ticks=false";
uint64_t fromTick = 0;
uint64_t maxTick = UINT64_MAX;
@ -679,8 +687,8 @@ int DumpFeature::dumpShard(int fd, std::string const& DBserver,
_stats._totalBatches++;
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::GET, url, nullptr, 0));
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::GET, url, nullptr, 0));
if (response == nullptr || !response->isComplete()) {
errorMsg =
@ -825,7 +833,8 @@ int DumpFeature::runClusterDump(std::string& errorMsg) {
return TRI_ERROR_INTERNAL;
}
uint64_t const cid = arangodb::basics::VelocyPackHelper::extractIdValue(parameters);
uint64_t const cid =
arangodb::basics::VelocyPackHelper::extractIdValue(parameters);
std::string const name = arangodb::basics::VelocyPackHelper::getStringValue(
parameters, "name", "");
bool const deleted = arangodb::basics::VelocyPackHelper::getBooleanValue(
@ -967,7 +976,9 @@ int DumpFeature::runClusterDump(std::string& errorMsg) {
}
void DumpFeature::start() {
ClientFeature* client = application_features::ApplicationServer::getFeature<ClientFeature>("Client");
ClientFeature* client =
application_features::ApplicationServer::getFeature<ClientFeature>(
"Client");
int ret = EXIT_SUCCESS;
*_result = ret;
@ -975,22 +986,26 @@ void DumpFeature::start() {
try {
_httpClient = client->createHttpClient();
} catch (...) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot create server connection, giving up!";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot create server connection, giving up!";
FATAL_ERROR_EXIT();
}
std::string dbName = client->databaseName();
_httpClient->setLocationRewriter(static_cast<void*>(client), &rewriteLocation);
_httpClient->setLocationRewriter(static_cast<void*>(client),
&rewriteLocation);
_httpClient->setUserNamePassword("/", client->username(), client->password());
std::string const versionString = _httpClient->getServerVersion();
if (!_httpClient->isConnected()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Could not connect to endpoint '" << client->endpoint()
<< "', database: '" << dbName << "', username: '"
<< client->username() << "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Error message: '" << _httpClient->getErrorMessage() << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Could not connect to endpoint '" << client->endpoint()
<< "', database: '" << dbName << "', username: '" << client->username()
<< "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "Error message: '" << _httpClient->getErrorMessage() << "'";
FATAL_ERROR_EXIT();
}
@ -1003,8 +1018,8 @@ void DumpFeature::start() {
if (version.first < 3) {
// we can connect to 3.x
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Error: got incompatible server version '" << versionString
<< "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Error: got incompatible server version '" << versionString << "'";
if (!_force) {
FATAL_ERROR_EXIT();
@ -1015,16 +1030,19 @@ void DumpFeature::start() {
if (_clusterMode) {
if (_tickStart != 0 || _tickEnd != 0) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Error: cannot use tick-start or tick-end on a cluster";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Error: cannot use tick-start or tick-end on a cluster";
FATAL_ERROR_EXIT();
}
}
if (!_httpClient->isConnected()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Lost connection to endpoint '" << client->endpoint()
<< "', database: '" << dbName << "', username: '"
<< client->username() << "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "Error message: '" << _httpClient->getErrorMessage() << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Lost connection to endpoint '" << client->endpoint()
<< "', database: '" << dbName << "', username: '" << client->username()
<< "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "Error message: '" << _httpClient->getErrorMessage() << "'";
FATAL_ERROR_EXIT();
}
@ -1063,7 +1081,8 @@ void DumpFeature::start() {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "caught exception " << ex.what();
res = TRI_ERROR_INTERNAL;
} catch (...) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Error: caught unknown exception";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Error: caught unknown exception";
res = TRI_ERROR_INTERNAL;
}

View File

@ -32,9 +32,9 @@
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include <regex>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <regex>
using namespace arangodb;
using namespace arangodb::basics;
@ -67,8 +67,8 @@ ExportFeature::ExportFeature(application_features::ApplicationServer* server,
startsAfter("Config");
startsAfter("Logger");
_outputDirectory =
FileUtils::buildFilename(FileUtils::currentDirectory(), "export");
_outputDirectory = FileUtils::buildFilename(
FileUtils::currentDirectory().result(), "export");
}
void ExportFeature::collectOptions(
@ -84,7 +84,8 @@ void ExportFeature::collectOptions(
options->addOption("--xgmml-label-only", "export only xgmml label",
new BooleanParameter(&_xgmmlLabelOnly));
options->addOption("--xgmml-label-attribute", "specify document attribute that will be the xgmml label",
options->addOption("--xgmml-label-attribute",
"specify document attribute that will be the xgmml label",
new StringParameter(&_xgmmlLabelAttribute));
options->addOption("--output-directory", "output directory",
@ -96,12 +97,15 @@ void ExportFeature::collectOptions(
options->addOption("--progress", "show progress",
new BooleanParameter(&_progress));
options->addOption("--fields", "comma separated list of fileds to export into a csv file",
options->addOption("--fields",
"comma separated list of fileds to export into a csv file",
new StringParameter(&_csvFieldOptions));
std::unordered_set<std::string> exports = {"csv", "json", "jsonl", "xgmml", "xml"};
std::unordered_set<std::string> exports = {"csv", "json", "jsonl", "xgmml",
"xml"};
options->addOption(
"--type", "type of export", new DiscreteValuesParameter<StringParameter>(&_typeExport, exports));
"--type", "type of export",
new DiscreteValuesParameter<StringParameter>(&_typeExport, exports));
}
void ExportFeature::validateOptions(
@ -112,8 +116,9 @@ void ExportFeature::validateOptions(
if (1 == n) {
_outputDirectory = positionals[0];
} else if (1 < n) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
LOG_TOPIC(FATAL, Logger::CONFIG)
<< "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
FATAL_ERROR_EXIT();
}
@ -126,24 +131,28 @@ void ExportFeature::validateOptions(
}
if (_graphName.empty() && _collections.empty()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting at least one collection or one graph name";
LOG_TOPIC(FATAL, Logger::CONFIG)
<< "expecting at least one collection or one graph name";
FATAL_ERROR_EXIT();
}
if (_typeExport == "xgmml" && _graphName.empty()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting a graph name to dump a graph";
LOG_TOPIC(FATAL, Logger::CONFIG)
<< "expecting a graph name to dump a graph";
FATAL_ERROR_EXIT();
}
if ( (_typeExport == "json" || _typeExport == "jsonl" || _typeExport == "csv") &&
_collections.empty()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting at least one collection";
FATAL_ERROR_EXIT();
if ((_typeExport == "json" || _typeExport == "jsonl" ||
_typeExport == "csv") &&
_collections.empty()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting at least one collection";
FATAL_ERROR_EXIT();
}
if (_typeExport == "csv") {
if (_csvFieldOptions.empty()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "expecting at least one field definition";
LOG_TOPIC(FATAL, Logger::CONFIG)
<< "expecting at least one field definition";
FATAL_ERROR_EXIT();
}
@ -159,23 +168,28 @@ void ExportFeature::prepare() {
isDirectory = TRI_IsDirectory(_outputDirectory.c_str());
if (isDirectory) {
std::vector<std::string> files(TRI_FullTreeDirectory(_outputDirectory.c_str()));
std::vector<std::string> files(
TRI_FullTreeDirectory(_outputDirectory.c_str()));
// we don't care if the target directory is empty
isEmptyDirectory = (files.size() <= 1); // TODO: TRI_FullTreeDirectory always returns at least one element (""), even if directory is empty?
isEmptyDirectory = (files.size() <= 1); // TODO: TRI_FullTreeDirectory
// always returns at least one
// element (""), even if
// directory is empty?
}
}
if (_outputDirectory.empty() ||
(TRI_ExistsFile(_outputDirectory.c_str()) && !isDirectory)) {
LOG_TOPIC(FATAL, Logger::SYSCALL) << "cannot write to output directory '" << _outputDirectory
<< "'";
LOG_TOPIC(FATAL, Logger::SYSCALL) << "cannot write to output directory '"
<< _outputDirectory << "'";
FATAL_ERROR_EXIT();
}
if (isDirectory && !isEmptyDirectory && !_overwrite) {
LOG_TOPIC(FATAL, Logger::SYSCALL) << "output directory '" << _outputDirectory
<< "' already exists. use \"--overwrite true\" to "
"overwrite data in it";
LOG_TOPIC(FATAL, Logger::SYSCALL)
<< "output directory '" << _outputDirectory
<< "' already exists. use \"--overwrite true\" to "
"overwrite data in it";
FATAL_ERROR_EXIT();
}
@ -186,15 +200,18 @@ void ExportFeature::prepare() {
errorMessage);
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, Logger::SYSCALL) << "unable to create output directory '" << _outputDirectory
<< "': " << errorMessage;
LOG_TOPIC(ERR, Logger::SYSCALL) << "unable to create output directory '"
<< _outputDirectory
<< "': " << errorMessage;
FATAL_ERROR_EXIT();
}
}
}
void ExportFeature::start() {
ClientFeature* client = application_features::ApplicationServer::getFeature<ClientFeature>("Client");
ClientFeature* client =
application_features::ApplicationServer::getFeature<ClientFeature>(
"Client");
int ret = EXIT_SUCCESS;
*_result = ret;
@ -204,7 +221,8 @@ void ExportFeature::start() {
try {
httpClient = client->createHttpClient();
} catch (...) {
LOG_TOPIC(FATAL, Logger::COMMUNICATION) << "cannot create server connection, giving up!";
LOG_TOPIC(FATAL, Logger::COMMUNICATION)
<< "cannot create server connection, giving up!";
FATAL_ERROR_EXIT();
}
@ -215,10 +233,12 @@ void ExportFeature::start() {
httpClient->getServerVersion();
if (!httpClient->isConnected()) {
LOG_TOPIC(ERR, Logger::COMMUNICATION) << "Could not connect to endpoint '" << client->endpoint()
<< "', database: '" << client->databaseName() << "', username: '"
<< client->username() << "'";
LOG_TOPIC(FATAL, Logger::COMMUNICATION) << httpClient->getErrorMessage() << "'";
LOG_TOPIC(ERR, Logger::COMMUNICATION)
<< "Could not connect to endpoint '" << client->endpoint()
<< "', database: '" << client->databaseName() << "', username: '"
<< client->username() << "'";
LOG_TOPIC(FATAL, Logger::COMMUNICATION) << httpClient->getErrorMessage()
<< "'";
FATAL_ERROR_EXIT();
}
@ -231,12 +251,14 @@ void ExportFeature::start() {
uint64_t exportedSize = 0;
if (_typeExport == "json" || _typeExport == "jsonl" || _typeExport == "xml" || _typeExport == "csv") {
if (_typeExport == "json" || _typeExport == "jsonl" || _typeExport == "xml" ||
_typeExport == "csv") {
if (_collections.size()) {
collectionExport(httpClient.get());
for (auto const& collection : _collections) {
std::string filePath = _outputDirectory + TRI_DIR_SEPARATOR_STR + collection + "." + _typeExport;
std::string filePath = _outputDirectory + TRI_DIR_SEPARATOR_STR +
collection + "." + _typeExport;
int64_t fileSize = TRI_SizeFile(filePath.c_str());
if (0 < fileSize) {
@ -246,7 +268,8 @@ void ExportFeature::start() {
}
} else if (_typeExport == "xgmml" && _graphName.size()) {
graphExport(httpClient.get());
std::string filePath = _outputDirectory + TRI_DIR_SEPARATOR_STR + _graphName + "." + _typeExport;
std::string filePath = _outputDirectory + TRI_DIR_SEPARATOR_STR +
_graphName + "." + _typeExport;
int64_t fileSize = TRI_SizeFile(filePath.c_str());
if (0 < fileSize) {
@ -254,7 +277,9 @@ void ExportFeature::start() {
}
}
std::cout << "Processed " << _collections.size() << " collection(s), wrote " << exportedSize << " byte(s), " << _httpRequestsDone << " HTTP request(s)" << std::endl;
std::cout << "Processed " << _collections.size() << " collection(s), wrote "
<< exportedSize << " byte(s), " << _httpRequestsDone
<< " HTTP request(s)" << std::endl;
*_result = ret;
}
@ -264,13 +289,14 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
for (auto const& collection : _collections) {
if (_progress) {
std::cout << "# Exporting collection '" << collection << "'..." << std::endl;
std::cout << "# Exporting collection '" << collection << "'..."
<< std::endl;
}
_currentCollection = collection;
std::string fileName =
_outputDirectory + TRI_DIR_SEPARATOR_STR + collection + "." + _typeExport;
std::string fileName = _outputDirectory + TRI_DIR_SEPARATOR_STR +
collection + "." + _typeExport;
// remove an existing file first
if (TRI_ExistsFile(fileName.c_str())) {
@ -287,17 +313,19 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
post.close();
post.close();
std::shared_ptr<VPackBuilder> parsedBody = httpCall(httpClient, url, rest::RequestType::POST, post.toJson());
std::shared_ptr<VPackBuilder> parsedBody =
httpCall(httpClient, url, rest::RequestType::POST, post.toJson());
VPackSlice body = parsedBody->slice();
int fd = TRI_CREATE(fileName.c_str(), O_CREAT | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
S_IRUSR | S_IWUSR);
int fd =
TRI_CREATE(fileName.c_str(), O_CREAT | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
S_IRUSR | S_IWUSR);
if (fd < 0) {
errorMsg = "cannot write to file '" + fileName + "'";
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_CANNOT_WRITE_FILE, errorMsg);
}
TRI_DEFER(TRI_CLOSE(fd));
_firstLine = true;
@ -306,8 +334,9 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
writeToFile(fd, openingBracket, fileName);
} else if (_typeExport == "xml") {
std::string xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
"<collection name=\"";
std::string xmlHeader =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
"<collection name=\"";
xmlHeader.append(encode_char_entities(collection));
xmlHeader.append("\">\n");
writeToFile(fd, xmlHeader, fileName);
@ -315,7 +344,7 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
} else if (_typeExport == "csv") {
std::string firstLine = "";
bool isFirstValue = true;
for(auto const& str : _csvFields) {
for (auto const& str : _csvFields) {
if (isFirstValue) {
firstLine += str;
isFirstValue = false;
@ -334,7 +363,8 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
parsedBody = httpCall(httpClient, url, rest::RequestType::PUT);
body = parsedBody->slice();
writeCollectionBatch(fd, VPackArrayIterator(body.get("result")), fileName);
writeCollectionBatch(fd, VPackArrayIterator(body.get("result")),
fileName);
}
if (_typeExport == "json") {
@ -347,7 +377,8 @@ void ExportFeature::collectionExport(SimpleHttpClient* httpClient) {
}
}
void ExportFeature::writeCollectionBatch(int fd, VPackArrayIterator it, std::string const& fileName) {
void ExportFeature::writeCollectionBatch(int fd, VPackArrayIterator it,
std::string const& fileName) {
std::string line;
line.reserve(1024);
@ -375,7 +406,7 @@ void ExportFeature::writeCollectionBatch(int fd, VPackArrayIterator it, std::str
line.clear();
bool isFirstValue = true;
for(auto const& key : _csvFields) {
for (auto const& key : _csvFields) {
std::string value = "";
if (isFirstValue) {
@ -399,7 +430,8 @@ void ExportFeature::writeCollectionBatch(int fd, VPackArrayIterator it, std::str
value = std::regex_replace(value, std::regex("\""), "\"\"");
if (value.find(",") != std::string::npos || value.find("\"\"") != std::string::npos) {
if (value.find(",") != std::string::npos ||
value.find("\"\"") != std::string::npos) {
value = "\"" + value;
value.append("\"");
}
@ -426,14 +458,17 @@ void ExportFeature::writeCollectionBatch(int fd, VPackArrayIterator it, std::str
}
}
void ExportFeature::writeToFile(int fd, std::string const& line, std::string const& fileName) {
void ExportFeature::writeToFile(int fd, std::string const& line,
std::string const& fileName) {
if (!TRI_WritePointer(fd, line.c_str(), line.size())) {
std::string errorMsg = "cannot write to file '" + fileName + "'";
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_CANNOT_WRITE_FILE, errorMsg);
}
}
std::shared_ptr<VPackBuilder> ExportFeature::httpCall(SimpleHttpClient* httpClient, std::string const& url, rest::RequestType requestType, std::string postBody) {
std::shared_ptr<VPackBuilder> ExportFeature::httpCall(
SimpleHttpClient* httpClient, std::string const& url,
rest::RequestType requestType, std::string postBody) {
std::string errorMsg;
std::unique_ptr<SimpleHttpResult> response(
@ -449,12 +484,13 @@ std::shared_ptr<VPackBuilder> ExportFeature::httpCall(SimpleHttpClient* httpClie
std::shared_ptr<VPackBuilder> parsedBody;
if (response->wasHttpError()) {
if (response->getHttpReturnCode() == 404) {
if (_currentGraph.size()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "Graph '" << _currentGraph << "' not found.";
LOG_TOPIC(FATAL, Logger::CONFIG) << "Graph '" << _currentGraph
<< "' not found.";
} else if (_currentCollection.size()) {
LOG_TOPIC(FATAL, Logger::CONFIG) << "Collection " << _currentCollection << " not found.";
LOG_TOPIC(FATAL, Logger::CONFIG) << "Collection " << _currentCollection
<< " not found.";
}
FATAL_ERROR_EXIT();
@ -462,8 +498,8 @@ std::shared_ptr<VPackBuilder> ExportFeature::httpCall(SimpleHttpClient* httpClie
parsedBody = response->getBodyVelocyPack();
std::cout << parsedBody->toJson() << std::endl;
errorMsg = "got invalid response from server: HTTP " +
StringUtils::itoa(response->getHttpReturnCode()) + ": " +
response->getHttpReturnMessage();
StringUtils::itoa(response->getHttpReturnCode()) + ": " +
response->getHttpReturnMessage();
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, errorMsg);
}
}
@ -494,20 +530,23 @@ void ExportFeature::graphExport(SimpleHttpClient* httpClient) {
if (_progress) {
std::cout << "# Export graph '" << _graphName << "'" << std::endl;
}
std::string const url = "/_api/gharial/" + StringUtils::urlEncode(_graphName);
std::shared_ptr<VPackBuilder> parsedBody = httpCall(httpClient, url, rest::RequestType::GET);
std::string const url =
"/_api/gharial/" + StringUtils::urlEncode(_graphName);
std::shared_ptr<VPackBuilder> parsedBody =
httpCall(httpClient, url, rest::RequestType::GET);
VPackSlice body = parsedBody->slice();
std::unordered_set<std::string> collections;
for(auto const& edgeDefs : VPackArrayIterator(body.get("graph").get("edgeDefinitions"))) {
for (auto const& edgeDefs :
VPackArrayIterator(body.get("graph").get("edgeDefinitions"))) {
collections.insert(edgeDefs.get("collection").copyString());
for(auto const& from : VPackArrayIterator(edgeDefs.get("from"))) {
for (auto const& from : VPackArrayIterator(edgeDefs.get("from"))) {
collections.insert(from.copyString());
}
for(auto const& to : VPackArrayIterator(edgeDefs.get("to"))) {
for (auto const& to : VPackArrayIterator(edgeDefs.get("to"))) {
collections.insert(to.copyString());
}
}
@ -517,18 +556,23 @@ void ExportFeature::graphExport(SimpleHttpClient* httpClient) {
}
} else {
if (_progress) {
std::cout << "# Export graph with collections " << StringUtils::join(_collections, ", ") << " as '" << _graphName << "'" << std::endl;
std::cout << "# Export graph with collections "
<< StringUtils::join(_collections, ", ") << " as '"
<< _graphName << "'" << std::endl;
}
}
std::string fileName = _outputDirectory + TRI_DIR_SEPARATOR_STR + _graphName + "." + _typeExport;
std::string fileName =
_outputDirectory + TRI_DIR_SEPARATOR_STR + _graphName + "." + _typeExport;
// remove an existing file first
if (TRI_ExistsFile(fileName.c_str())) {
TRI_UnlinkFile(fileName.c_str());
}
int fd = TRI_CREATE(fileName.c_str(), O_CREAT | O_EXCL | O_RDWR | TRI_O_CLOEXEC, S_IRUSR | S_IWUSR);
int fd =
TRI_CREATE(fileName.c_str(), O_CREAT | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
S_IRUSR | S_IWUSR);
if (fd < 0) {
errorMsg = "cannot write to file '" + fileName + "'";
@ -536,7 +580,8 @@ void ExportFeature::graphExport(SimpleHttpClient* httpClient) {
}
TRI_DEFER(TRI_CLOSE(fd));
std::string xmlHeader = R"(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
std::string xmlHeader =
R"(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<graph label=")";
writeToFile(fd, xmlHeader, fileName);
writeToFile(fd, _graphName, fileName);
@ -549,7 +594,8 @@ directed="1">
for (auto const& collection : _collections) {
if (_progress) {
std::cout << "# Exporting collection '" << collection << "'..." << std::endl;
std::cout << "# Exporting collection '" << collection << "'..."
<< std::endl;
}
std::string const url = "_api/cursor";
@ -562,7 +608,8 @@ directed="1">
post.close();
post.close();
std::shared_ptr<VPackBuilder> parsedBody = httpCall(httpClient, url, rest::RequestType::POST, post.toJson());
std::shared_ptr<VPackBuilder> parsedBody =
httpCall(httpClient, url, rest::RequestType::POST, post.toJson());
VPackSlice body = parsedBody->slice();
writeGraphBatch(fd, VPackArrayIterator(body.get("result")), fileName);
@ -579,17 +626,26 @@ directed="1">
writeToFile(fd, closingGraphTag, fileName);
if (_skippedDeepNested) {
std::cout << "skipped " << _skippedDeepNested << " deep nested objects / arrays" << std::endl;
std::cout << "skipped " << _skippedDeepNested
<< " deep nested objects / arrays" << std::endl;
}
}
void ExportFeature::writeGraphBatch(int fd, VPackArrayIterator it, std::string const& fileName) {
void ExportFeature::writeGraphBatch(int fd, VPackArrayIterator it,
std::string const& fileName) {
std::string xmlTag;
for(auto const& doc : it) {
for (auto const& doc : it) {
if (doc.hasKey("_from")) {
xmlTag = "<edge label=\"" + encode_char_entities(doc.hasKey(_xgmmlLabelAttribute) && doc.get(_xgmmlLabelAttribute).isString() ? doc.get(_xgmmlLabelAttribute).copyString() : "Default-Label") +
"\" source=\"" + encode_char_entities(doc.get("_from").copyString()) + "\" target=\"" + encode_char_entities(doc.get("_to").copyString()) + "\"";
xmlTag =
"<edge label=\"" +
encode_char_entities(doc.hasKey(_xgmmlLabelAttribute) &&
doc.get(_xgmmlLabelAttribute).isString()
? doc.get(_xgmmlLabelAttribute).copyString()
: "Default-Label") +
"\" source=\"" + encode_char_entities(doc.get("_from").copyString()) +
"\" target=\"" + encode_char_entities(doc.get("_to").copyString()) +
"\"";
writeToFile(fd, xmlTag, fileName);
if (!_xgmmlLabelOnly) {
xmlTag = ">\n";
@ -608,8 +664,13 @@ void ExportFeature::writeGraphBatch(int fd, VPackArrayIterator it, std::string c
}
} else {
xmlTag = "<node label=\"" + encode_char_entities(doc.hasKey(_xgmmlLabelAttribute) && doc.get(_xgmmlLabelAttribute).isString() ? doc.get(_xgmmlLabelAttribute).copyString() : "Default-Label") +
"\" id=\"" + encode_char_entities(doc.get("_id").copyString()) + "\"";
xmlTag =
"<node label=\"" +
encode_char_entities(doc.hasKey(_xgmmlLabelAttribute) &&
doc.get(_xgmmlLabelAttribute).isString()
? doc.get(_xgmmlLabelAttribute).copyString()
: "Default-Label") +
"\" id=\"" + encode_char_entities(doc.get("_id").copyString()) + "\"";
writeToFile(fd, xmlTag, fileName);
if (!_xgmmlLabelOnly) {
xmlTag = ">\n";
@ -630,11 +691,13 @@ void ExportFeature::writeGraphBatch(int fd, VPackArrayIterator it, std::string c
}
}
void ExportFeature::xgmmlWriteOneAtt(int fd, std::string const& fileName, VPackSlice const& slice, std::string const& name, int deep) {
void ExportFeature::xgmmlWriteOneAtt(int fd, std::string const& fileName,
VPackSlice const& slice,
std::string const& name, int deep) {
std::string value, type, xmlTag;
if (deep == 0 &&
(name == "_id" || name == "_key" || name == "_rev" || name == "_from" || name == "_to")) {
if (deep == 0 && (name == "_id" || name == "_key" || name == "_rev" ||
name == "_from" || name == "_to")) {
return;
}
@ -664,17 +727,21 @@ void ExportFeature::xgmmlWriteOneAtt(int fd, std::string const& fileName, VPackS
}
} else {
xmlTag = " <att name=\"" + encode_char_entities(name) + "\" type=\"string\" value=\"" + encode_char_entities(slice.toString()) + "\"/>\n";
xmlTag = " <att name=\"" + encode_char_entities(name) +
"\" type=\"string\" value=\"" +
encode_char_entities(slice.toString()) + "\"/>\n";
writeToFile(fd, xmlTag, fileName);
return;
}
if (!type.empty()) {
xmlTag = " <att name=\"" + encode_char_entities(name) + "\" type=\"" + type + "\" value=\"" + encode_char_entities(value) + "\"/>\n";
xmlTag = " <att name=\"" + encode_char_entities(name) + "\" type=\"" +
type + "\" value=\"" + encode_char_entities(value) + "\"/>\n";
writeToFile(fd, xmlTag, fileName);
} else if (slice.isArray()) {
xmlTag = " <att name=\"" + encode_char_entities(name) + "\" type=\"list\">\n";
xmlTag =
" <att name=\"" + encode_char_entities(name) + "\" type=\"list\">\n";
writeToFile(fd, xmlTag, fileName);
for (auto const& val : VPackArrayIterator(slice)) {
@ -685,7 +752,8 @@ void ExportFeature::xgmmlWriteOneAtt(int fd, std::string const& fileName, VPackS
writeToFile(fd, xmlTag, fileName);
} else if (slice.isObject()) {
xmlTag = " <att name=\"" + encode_char_entities(name) + "\" type=\"list\">\n";
xmlTag =
" <att name=\"" + encode_char_entities(name) + "\" type=\"list\">\n";
writeToFile(fd, xmlTag, fileName);
for (auto const& it : VPackObjectIterator(slice)) {

View File

@ -68,14 +68,14 @@ RestoreFeature::RestoreFeature(application_features::ApplicationServer* server,
_defaultNumberOfShards(1),
_defaultReplicationFactor(1),
_result(result),
_stats{ 0, 0, 0 } {
_stats{0, 0, 0} {
requiresElevatedPrivileges(false);
setOptional(false);
startsAfter("Client");
startsAfter("Logger");
_inputDirectory =
FileUtils::buildFilename(FileUtils::currentDirectory(), "dump");
FileUtils::buildFilename(FileUtils::currentDirectory().result(), "dump");
}
void RestoreFeature::collectOptions(
@ -112,8 +112,7 @@ void RestoreFeature::collectOptions(
options->addOption("--overwrite", "overwrite collections if they exist",
new BooleanParameter(&_overwrite));
options->addOption("--recycle-ids",
"recycle collection ids from dump",
options->addOption("--recycle-ids", "recycle collection ids from dump",
new BooleanParameter(&_recycleIds));
options->addOption("--default-number-of-shards",
@ -137,8 +136,9 @@ void RestoreFeature::validateOptions(
if (1 == n) {
_inputDirectory = positionals[0];
} else if (1 < n) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "expecting at most one directory, got " +
StringUtils::join(positionals, ", ");
FATAL_ERROR_EXIT();
}
@ -162,7 +162,8 @@ void RestoreFeature::prepare() {
// .............................................................................
if (_inputDirectory == "" || !TRI_IsDirectory(_inputDirectory.c_str())) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "input directory '" << _inputDirectory << "' does not exist";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "input directory '" << _inputDirectory << "' does not exist";
FATAL_ERROR_EXIT();
}
@ -188,9 +189,8 @@ int RestoreFeature::tryCreateDatabase(ClientFeature* client,
std::string const body = builder.slice().toJson();
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::POST, "/_api/database",
body.c_str(), body.size()));
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::POST, "/_api/database", body.c_str(), body.size()));
if (response == nullptr || !response->isComplete()) {
return TRI_ERROR_INTERNAL;
@ -202,7 +202,7 @@ int RestoreFeature::tryCreateDatabase(ClientFeature* client,
returnCode == static_cast<int>(rest::ResponseCode::CREATED)) {
// all ok
return TRI_ERROR_NO_ERROR;
}
}
if (returnCode == static_cast<int>(rest::ResponseCode::UNAUTHORIZED) ||
returnCode == static_cast<int>(rest::ResponseCode::FORBIDDEN)) {
// invalid authorization
@ -238,14 +238,14 @@ int RestoreFeature::sendRestoreCollection(VPackSlice const& slice,
<< _defaultNumberOfShards << std::endl;
url += "&numberOfShards=" + std::to_string(_defaultNumberOfShards);
}
if (!slice.hasKey(std::vector<std::string>({"parameters", "replicationFactor"}))) {
if (!slice.hasKey(
std::vector<std::string>({"parameters", "replicationFactor"}))) {
// No replication factor given, so take the default:
std::cerr << "# no replication information specified for collection '"
<< name << "', using default replication factor "
<< _defaultReplicationFactor << std::endl;
url += "&replicationFactor=" + std::to_string(_defaultReplicationFactor);
}
}
std::string const body = slice.toJson();
@ -312,8 +312,8 @@ int RestoreFeature::sendRestoreData(std::string const& cname,
(_recycleIds ? "true" : "false") + "&force=" +
(_force ? "true" : "false");
std::unique_ptr<SimpleHttpResult> response(_httpClient->request(
rest::RequestType::PUT, url, buffer, bufferSize));
std::unique_ptr<SimpleHttpResult> response(
_httpClient->request(rest::RequestType::PUT, url, buffer, bufferSize));
if (response == nullptr || !response->isComplete()) {
errorMsg =
@ -344,7 +344,7 @@ static bool SortCollections(VPackSlice const& l, VPackSlice const& r) {
// We first have to create collections defining the distribution.
VPackSlice leftDist = left.get("distributeShardsLike");
VPackSlice rightDist = right.get("distributeShardsLike");
if (leftDist.isNone() && !rightDist.isNone()) {
return true;
}
@ -471,7 +471,7 @@ int RestoreFeature::processInputDirectory(std::string& errorMsg) {
}
std::sort(collections.begin(), collections.end(), SortCollections);
StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE);
// step2: run the actual import
@ -654,7 +654,9 @@ int RestoreFeature::processInputDirectory(std::string& errorMsg) {
}
void RestoreFeature::start() {
ClientFeature* client = application_features::ApplicationServer::getFeature<ClientFeature>("Client");
ClientFeature* client =
application_features::ApplicationServer::getFeature<ClientFeature>(
"Client");
int ret = EXIT_SUCCESS;
*_result = ret;
@ -662,13 +664,15 @@ void RestoreFeature::start() {
try {
_httpClient = client->createHttpClient();
} catch (...) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot create server connection, giving up!";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot create server connection, giving up!";
FATAL_ERROR_EXIT();
}
std::string dbName = client->databaseName();
_httpClient->setLocationRewriter(static_cast<void*>(client), &rewriteLocation);
_httpClient->setLocationRewriter(static_cast<void*>(client),
&rewriteLocation);
_httpClient->setUserNamePassword("/", client->username(), client->password());
int err = TRI_ERROR_NO_ERROR;
@ -683,8 +687,10 @@ void RestoreFeature::start() {
int res = tryCreateDatabase(client, dbName);
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Could not create database '" << dbName << "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << _httpClient->getErrorMessage() << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Could not create database '"
<< dbName << "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< _httpClient->getErrorMessage() << "'";
FATAL_ERROR_EXIT();
}
@ -696,9 +702,11 @@ void RestoreFeature::start() {
}
if (!_httpClient->isConnected()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Could not connect to endpoint "
<< _httpClient->getEndpointSpecification();
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << _httpClient->getErrorMessage() << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Could not connect to endpoint "
<< _httpClient->getEndpointSpecification();
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << _httpClient->getErrorMessage()
<< "'";
FATAL_ERROR_EXIT();
}
@ -710,7 +718,8 @@ void RestoreFeature::start() {
if (version.first < 3) {
// we can connect to 3.x
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "got incompatible server version '" << versionString << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "got incompatible server version '" << versionString << "'";
if (!_force) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "giving up!";
@ -735,7 +744,8 @@ void RestoreFeature::start() {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "caught exception " << ex.what();
res = TRI_ERROR_INTERNAL;
} catch (...) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "Error: caught unknown exception";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Error: caught unknown exception";
res = TRI_ERROR_INTERNAL;
}
@ -759,6 +769,6 @@ void RestoreFeature::start() {
<< std::endl;
}
}
*_result = ret;
}

View File

@ -894,7 +894,7 @@ void V8ShellFeature::initGlobals() {
}
if (_currentModuleDirectory) {
modules += sep + FileUtils::currentDirectory();
modules += sep + FileUtils::currentDirectory().result();
}
// we take the last entry in _startupDirectory as global path;

View File

@ -148,9 +148,9 @@ void ConfigFeature::loadConfigFile(std::shared_ptr<ProgramOptions> options,
locations.emplace_back(location);
}
locations.emplace_back(FileUtils::currentDirectory());
locations.emplace_back(FileUtils::buildFilename(FileUtils::currentDirectory(),
"etc", "relative"));
std::string current = FileUtils::currentDirectory().result();
locations.emplace_back(current);
locations.emplace_back(FileUtils::buildFilename(current, "etc", "relative"));
locations.emplace_back(
FileUtils::buildFilename(FileUtils::homeDirectory(), ".arangodb"));
locations.emplace_back(FileUtils::configDirectory(binaryPath));

View File

@ -77,8 +77,7 @@ void DaemonFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
logger->setBackgrounded(true);
// make the pid filename absolute
int err = 0;
std::string currentDir = FileUtils::currentDirectory(&err);
std::string currentDir = FileUtils::currentDirectory().result();
char* absoluteFile =
TRI_GetAbsolutePath(_pidFile.c_str(), currentDir.c_str());
@ -235,14 +234,16 @@ int DaemonFeature::forkProcess() {
}
// store current working directory
int err = 0;
_current = FileUtils::currentDirectory(&err);
FileResultString cwd = FileUtils::currentDirectory();
if (err != 0) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot get current directory";
if (!cwd.ok()) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot get current directory: " << cwd.errorMessage();
FATAL_ERROR_EXIT();
}
_current = cwd.result();
// change the current working directory
if (!_workingDirectory.empty()) {
FileResult res = FileUtils::changeDirectory(_workingDirectory);

View File

@ -28,15 +28,16 @@
namespace arangodb {
class FileResult : public Result {
public:
explicit FileResult(bool state);
FileResult(bool state, int sysErrorNumber);
FileResult() : Result(), _sysErrorNumber(0) {}
explicit FileResult(int sysErrorNumber)
: Result(TRI_ERROR_SYS_ERROR, strerror(sysErrorNumber)),
_sysErrorNumber(sysErrorNumber) {}
public:
bool state() const { return _state; }
int sysErrorNumber() const { return _sysErrorNumber; }
private:
bool const _state;
protected:
int const _sysErrorNumber;
};
}

View File

@ -20,13 +20,28 @@
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "FileResult.h"
#ifndef ARANGODB_BASICS_FILE_RESULT_STRING_H
#define ARANGODB_BASICS_FILE_RESULT_STRING_H 1
#include "Basics/Result.h"
namespace arangodb {
FileResult::FileResult(bool state)
: Result(), _state(state), _sysErrorNumber(0) {}
class FileResultString : public FileResult {
public:
FileResultString(std::string result) : FileResult(), _result(result) {}
FileResult::FileResult(bool state, int sysErrorNumber)
: Result(TRI_ERROR_SYS_ERROR, strerror(sysErrorNumber)),
_state(state), _sysErrorNumber(sysErrorNumber) {}
FileResultString(int sysErrorNumber, std::string result)
: FileResult(sysErrorNumber), _result(result) {}
FileResultString(int sysErrorNumber)
: FileResult(sysErrorNumber), _result() {}
public:
std::string const& result() const { return _result; }
protected:
std::string const _result;
};
}
#endif

View File

@ -34,8 +34,8 @@
#include "Basics/Exceptions.h"
#include "Basics/StringBuffer.h"
#include "Basics/files.h"
#include "Logger/Logger.h"
#include "Basics/tri-strings.h"
#include "Logger/Logger.h"
#if defined(_WIN32) && defined(_MSC_VER)
@ -91,7 +91,8 @@ std::string buildFilename(char const* path, char const* name) {
}
if (!result.empty() && *name == TRI_DIR_SEPARATOR_CHAR) {
// skip initial forward slash in name to avoid having two forward slashes in result
// skip initial forward slash in name to avoid having two forward slashes in
// result
result.append(name + 1);
} else {
result.append(name);
@ -109,7 +110,8 @@ std::string buildFilename(std::string const& path, std::string const& name) {
}
if (!result.empty() && !name.empty() && name[0] == TRI_DIR_SEPARATOR_CHAR) {
// skip initial forward slash in name to avoid having two forward slashes in result
// skip initial forward slash in name to avoid having two forward slashes in
// result
result.append(name.c_str() + 1, name.size() - 1);
} else {
result.append(name);
@ -119,7 +121,7 @@ std::string buildFilename(std::string const& path, std::string const& name) {
return result;
}
void throwFileReadError(int fd, std::string const& filename) {
static void throwFileReadError(int fd, std::string const& filename) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
int res = TRI_errno();
@ -134,21 +136,6 @@ void throwFileReadError(int fd, std::string const& filename) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_SYS_ERROR);
}
void throwFileWriteError(int fd, std::string const& filename) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
int res = TRI_errno();
if (fd >= 0) {
TRI_CLOSE(fd);
}
std::string message("write failed for file '" + filename + "': " +
strerror(res));
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "" << message;
THROW_ARANGO_EXCEPTION(TRI_ERROR_SYS_ERROR);
}
std::string slurp(std::string const& filename) {
int fd = TRI_OPEN(filename.c_str(), O_RDONLY | TRI_O_CLOEXEC);
@ -212,6 +199,21 @@ void slurp(std::string const& filename, StringBuffer& result) {
TRI_CLOSE(fd);
}
static void throwFileWriteError(int fd, std::string const& filename) {
TRI_set_errno(TRI_ERROR_SYS_ERROR);
int res = TRI_errno();
if (fd >= 0) {
TRI_CLOSE(fd);
}
std::string message("write failed for file '" + filename + "': " +
strerror(res));
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "" << message;
THROW_ARANGO_EXCEPTION(TRI_ERROR_SYS_ERROR);
}
void spit(std::string const& filename, char const* ptr, size_t len) {
int fd =
TRI_CREATE(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | TRI_O_CLOEXEC,
@ -356,11 +358,10 @@ bool copyRecursive(std::string const& source, std::string const& target,
bool copyDirectoryRecursive(std::string const& source,
std::string const& target, std::string& error) {
bool rc = true;
auto isSubDirectory = [](std::string const& name) -> bool {
return isDirectory(name);
return isDirectory(name);
};
#ifdef TRI_HAVE_WIN32_LIST_FILES
struct _finddata_t oneItem;
@ -386,7 +387,8 @@ bool copyDirectoryRecursive(std::string const& source,
struct dirent* oneItem = nullptr;
// do not use readdir_r() here anymore as it is not safe and deprecated
// in newer versions of libc: http://man7.org/linux/man-pages/man3/readdir_r.3.html
// in newer versions of libc:
// http://man7.org/linux/man-pages/man3/readdir_r.3.html
// the man page recommends to use plain readdir() because it can be expected
// to be thread-safe in reality, and newer versions of POSIX may require its
// thread-safety formally, and in addition obsolete readdir_r() altogether
@ -561,17 +563,13 @@ FileResult changeDirectory(std::string const& path) {
int res = TRI_CHDIR(path.c_str());
if (res == 0) {
return FileResult(true);
return FileResult();
} else {
return FileResult(false, errno);
return FileResult(errno);
}
}
std::string currentDirectory(int* errorNumber) {
if (errorNumber != 0) {
*errorNumber = 0;
}
FileResultString currentDirectory() {
size_t len = 1000;
char* current = new char[len];
@ -583,19 +581,13 @@ std::string currentDirectory(int* errorNumber) {
} else {
delete[] current;
if (errorNumber != 0) {
*errorNumber = errno;
}
return ".";
return FileResultString(errno, ".");
}
}
std::string result = current;
delete[] current;
return result;
return FileResultString(result);
}
std::string homeDirectory() {
@ -610,7 +602,7 @@ std::string configDirectory(char const* binaryPath) {
char* dir = TRI_LocateConfigDirectory(binaryPath);
if (dir == nullptr) {
return currentDirectory();
return currentDirectory().result();
}
std::string result = dir;
@ -631,15 +623,12 @@ std::string dirname(std::string const& name) {
return base;
}
void makePathAbsolute(std::string &path) {
int err = 0;
std::string cwd = FileUtils::currentDirectory(&err);
char * p = TRI_GetAbsolutePath(path.c_str(), cwd.c_str());
void makePathAbsolute(std::string& path) {
std::string cwd = FileUtils::currentDirectory().result();
char* p = TRI_GetAbsolutePath(path.c_str(), cwd.c_str());
path = p;
TRI_FreeString(TRI_CORE_MEM_ZONE, p);
}
}
}
}

View File

@ -26,8 +26,9 @@
#include "Basics/Common.h"
#include "Basics/files.h"
#include "Basics/FileResult.h"
#include "Basics/FileResultString.h"
#include "Basics/files.h"
namespace arangodb {
namespace basics {
@ -55,12 +56,6 @@ inline std::string buildFilename(std::string path, std::string name, Args... arg
return buildFilename(buildFilename(path, name), args...);
}
// throws a read error
void throwFileReadError(int fd, std::string const& filename);
// throws a write error
void throwFileWriteError(int fd, std::string const& filename);
// reads file into string
std::string slurp(std::string const& filename);
void slurp(std::string const& filename, StringBuffer&);
@ -72,6 +67,8 @@ void spit(std::string const& filename, StringBuffer const& content);
// returns true if a file could be removed
bool remove(std::string const& fileName, int* errorNumber = 0);
// returns true if a file could be renamed
bool rename(std::string const& oldName, std::string const& newName,
int* errorNumber = 0);
@ -112,7 +109,7 @@ std::string stripExtension(std::string const& path,
FileResult changeDirectory(std::string const& path);
// returns the current directory
std::string currentDirectory(int* errorNumber = 0);
FileResultString currentDirectory();
// returns the home directory
std::string homeDirectory();

View File

@ -29,20 +29,26 @@ namespace arangodb {
class Result {
public:
Result() : _errorNumber(TRI_ERROR_NO_ERROR) {}
Result(int errorNumber, std::string const& errorMessage)
Result(int errorNumber)
: _errorNumber(errorNumber),
_errorMessage(TRI_errno_string(errorNumber)) {}
Result(int errorNumber, std::string const& errorMessage)
: _errorNumber(errorNumber), _errorMessage(errorMessage) {}
Result(int errorNumber, std::string&& errorMessage)
Result(int errorNumber, std::string&& errorMessage)
: _errorNumber(errorNumber), _errorMessage(std::move(errorMessage)) {}
virtual ~Result() {}
public:
// the default implementations are const, but subclasses might
// really do more work to compute - for example - the error
// string.
bool ok() const { return _errorNumber == TRI_ERROR_NO_ERROR; }
int errorNumber() const { return _errorNumber; }
// the default implementations is const, but sub-classes might
// really do more work to compute.
virtual bool ok() { return _errorNumber == TRI_ERROR_NO_ERROR; }
virtual int errorNumber() { return _errorNumber; }
virtual std::string errorMessage() { return _errorMessage; }
protected:

View File

@ -130,7 +130,6 @@ add_library(${LIB_ARANGO} STATIC
Basics/ConditionVariable.cpp
Basics/DataProtector.cpp
Basics/Exceptions.cpp
Basics/FileResult.cpp
Basics/FileUtils.cpp
Basics/HybridLogicalClock.cpp
Basics/LocalTaskQueue.cpp

View File

@ -27,9 +27,9 @@
#include "Basics/win-utils.h"
#endif
#include <signal.h>
#include <fstream>
#include <iostream>
#include <signal.h>
#include "3rdParty/valgrind/valgrind.h"
#include "unicode/normalizer2.h"
@ -112,7 +112,8 @@ static void CreateErrorObject(v8::Isolate* isolate, int errorNumber,
std::string const& message) noexcept {
try {
if (errorNumber == TRI_ERROR_OUT_OF_MEMORY) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "encountered out-of-memory error";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "encountered out-of-memory error";
}
v8::Handle<v8::String> errorMessage = TRI_V8_STD_STRING(message);
@ -137,7 +138,7 @@ static void CreateErrorObject(v8::Isolate* isolate, int errorNumber,
}
errorObject->Set(TRI_V8_ASCII_STRING("errorNum"),
v8::Number::New(isolate, errorNumber));
v8::Number::New(isolate, errorNumber));
errorObject->Set(TRI_V8_ASCII_STRING("errorMessage"), errorMessage);
TRI_GET_GLOBALS();
@ -169,8 +170,9 @@ static bool LoadJavaScriptFile(v8::Isolate* isolate, char const* filename,
char* content = TRI_SlurpFile(TRI_UNKNOWN_MEM_ZONE, filename, &length);
if (content == nullptr) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot load java script file '" << filename
<< "': " << TRI_last_error();
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot load java script file '"
<< filename
<< "': " << TRI_last_error();
return false;
}
@ -205,8 +207,9 @@ static bool LoadJavaScriptFile(v8::Isolate* isolate, char const* filename,
}
if (content == nullptr) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot load java script file '" << filename
<< "': " << TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY);
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "cannot load java script file '" << filename
<< "': " << TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY);
return false;
}
@ -227,8 +230,9 @@ static bool LoadJavaScriptFile(v8::Isolate* isolate, char const* filename,
// compilation failed, print errors that happened during compilation
if (script.IsEmpty()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot load java script file '" << filename
<< "': compilation failed.";
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot load java script file '"
<< filename
<< "': compilation failed.";
return false;
}
@ -246,7 +250,8 @@ static bool LoadJavaScriptFile(v8::Isolate* isolate, char const* filename,
}
}
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "loaded java script file: '" << filename << "'";
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "loaded java script file: '"
<< filename << "'";
return true;
}
@ -260,7 +265,8 @@ static bool LoadJavaScriptDirectory(v8::Isolate* isolate, char const* path,
v8::HandleScope scope(isolate);
bool result;
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "loading JavaScript directory: '" << path << "'";
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "loading JavaScript directory: '"
<< path << "'";
std::vector<std::string> files = TRI_FilesDirectory(path);
@ -412,10 +418,13 @@ static void JS_Parse(v8::FunctionCallbackInfo<v8::Value> const& args) {
// compilation failed, we have caught an exception
if (tryCatch.HasCaught()) {
if (tryCatch.CanContinue()) {
v8::Local<v8::Object> exceptionObj = tryCatch.Exception().As<v8::Object>();
v8::Local<v8::Object> exceptionObj =
tryCatch.Exception().As<v8::Object>();
v8::Handle<v8::Message> message = tryCatch.Message();
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"), v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"), v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"),
v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"),
v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("fileName"), filename->ToString());
tryCatch.ReThrow();
return;
@ -472,19 +481,21 @@ static void JS_ParseFile(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
v8::TryCatch tryCatch;
v8::Handle<v8::Script> script =
v8::Script::Compile(TRI_V8_PAIR_STRING(content, (int)length),
args[0]->ToString());
v8::Handle<v8::Script> script = v8::Script::Compile(
TRI_V8_PAIR_STRING(content, (int)length), args[0]->ToString());
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, content);
// compilation failed, we have caught an exception
if (tryCatch.HasCaught()) {
if (tryCatch.CanContinue()) {
v8::Local<v8::Object> exceptionObj = tryCatch.Exception().As<v8::Object>();
v8::Local<v8::Object> exceptionObj =
tryCatch.Exception().As<v8::Object>();
v8::Handle<v8::Message> message = tryCatch.Message();
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"), v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"), v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"),
v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"),
v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("fileName"), args[0]);
tryCatch.ReThrow();
return;
@ -659,7 +670,7 @@ void JS_Download(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (options.IsEmpty()) {
TRI_V8_THROW_EXCEPTION_USAGE(signature);
}
// ssl protocol
if (options->Has(TRI_V8_ASCII_STRING("sslProtocol"))) {
if (sslProtocol >= SSL_LAST) {
@ -667,14 +678,15 @@ void JS_Download(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"invalid option value for sslProtocol");
}
sslProtocol = TRI_ObjectToUInt64(options->Get(TRI_V8_ASCII_STRING("sslProtocol")), false);
sslProtocol = TRI_ObjectToUInt64(
options->Get(TRI_V8_ASCII_STRING("sslProtocol")), false);
}
// method
if (options->Has(TRI_V8_ASCII_STRING("method"))) {
std::string methodString =
TRI_ObjectToString(isolate, options->Get(TRI_V8_ASCII_STRING("method")));
std::string methodString = TRI_ObjectToString(
isolate, options->Get(TRI_V8_ASCII_STRING("method")));
method = HttpRequest::translateMethod(methodString);
}
@ -819,8 +831,9 @@ void JS_Download(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_SYNTAX_ERROR("unsupported URL specified");
}
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "downloading file. endpoint: " << endpoint
<< ", relative URL: " << url;
LOG_TOPIC(TRACE, arangodb::Logger::FIXME)
<< "downloading file. endpoint: " << endpoint
<< ", relative URL: " << url;
std::unique_ptr<Endpoint> ep(Endpoint::clientFactory(endpoint));
@ -829,7 +842,8 @@ void JS_Download(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
std::unique_ptr<GeneralClientConnection> connection(
GeneralClientConnection::factory(ep.get(), timeout, timeout, 3, sslProtocol));
GeneralClientConnection::factory(ep.get(), timeout, timeout, 3,
sslProtocol));
if (connection == nullptr) {
TRI_V8_THROW_EXCEPTION_MEMORY();
@ -993,8 +1007,8 @@ static void JS_Execute(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_Utf8ValueNFC keyName(TRI_UNKNOWN_MEM_ZONE, key);
if (*keyName != nullptr) {
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "copying key '" << *keyName
<< "' from sandbox to context";
LOG_TOPIC(TRACE, arangodb::Logger::FIXME)
<< "copying key '" << *keyName << "' from sandbox to context";
}
}
@ -1023,11 +1037,15 @@ static void JS_Execute(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
if (tryCatch.CanContinue()) {
v8::Local<v8::Object> exceptionObj = tryCatch.Exception().As<v8::Object>();
v8::Local<v8::Object> exceptionObj =
tryCatch.Exception().As<v8::Object>();
v8::Handle<v8::Message> message = tryCatch.Message();
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"), v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"), v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("fileName"), filename->ToString());
exceptionObj->Set(TRI_V8_ASCII_STRING("lineNumber"),
v8::Number::New(isolate, message->GetLineNumber()));
exceptionObj->Set(TRI_V8_ASCII_STRING("columnNumber"),
v8::Number::New(isolate, message->GetStartColumn()));
exceptionObj->Set(TRI_V8_ASCII_STRING("fileName"),
filename->ToString());
tryCatch.ReThrow();
return;
} else {
@ -1071,8 +1089,8 @@ static void JS_Execute(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_Utf8ValueNFC keyName(TRI_UNKNOWN_MEM_ZONE, key);
if (*keyName != nullptr) {
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "copying key '" << *keyName
<< "' from context to sandbox";
LOG_TOPIC(TRACE, arangodb::Logger::FIXME)
<< "copying key '" << *keyName << "' from context to sandbox";
}
}
@ -1361,20 +1379,22 @@ static void JS_MakeAbsolute(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_THROW_TYPE_ERROR("<path> must be a string");
}
int err = 0;
std::string cwd = arangodb::basics::FileUtils::currentDirectory(&err);
if (0 != err) {
TRI_V8_THROW_EXCEPTION_MESSAGE(err, "cannot get current working directory");
FileResultString cwd = FileUtils::currentDirectory();
if (!cwd.ok()) {
TRI_V8_THROW_EXCEPTION_MESSAGE(
cwd.sysErrorNumber(),
"cannot get current working directory: " + cwd.errorMessage());
}
char* abs = TRI_GetAbsolutePath(*name, cwd.c_str());
char* abs = TRI_GetAbsolutePath(*name, cwd.result().c_str());
v8::Handle<v8::String> res;
if (0 != abs) {
if (nullptr != abs) {
res = TRI_V8_STRING(abs);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, abs);
} else {
res = TRI_V8_STD_STRING(cwd);
res = TRI_V8_STD_STRING(cwd.result());
}
// return result
@ -3183,7 +3203,7 @@ static void JS_PBKDF2HS1(v8::FunctionCallbackInfo<v8::Value> const& args) {
std::string result =
SslInterface::sslPBKDF2HS1(salt.c_str(), salt.size(), password.c_str(),
password.size(), iterations, keyLength);
password.size(), iterations, keyLength);
TRI_V8_RETURN_STD_STRING(result);
TRI_V8_TRY_CATCH_END
}
@ -3205,7 +3225,8 @@ static void JS_PBKDF2(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (args.Length() < 4 || !args[0]->IsString() || !args[1]->IsString() ||
!args[2]->IsNumber() || !args[3]->IsNumber()) {
TRI_V8_THROW_EXCEPTION_USAGE(
"PBKDF2_SHA(<salt>, <password>, <iterations>, <keyLength>, <algorithm>)");
"PBKDF2_SHA(<salt>, <password>, <iterations>, <keyLength>, "
"<algorithm>)");
}
SslInterface::Algorithm al = SslInterface::Algorithm::ALGORITHM_SHA1;
@ -3650,7 +3671,8 @@ static void JS_KillExternal(v8::FunctionCallbackInfo<v8::Value> const& args) {
// extract the arguments
if (args.Length() < 1 || args.Length() > 2) {
TRI_V8_THROW_EXCEPTION_USAGE("killExternal(<external-identifier>, <signal>)");
TRI_V8_THROW_EXCEPTION_USAGE(
"killExternal(<external-identifier>, <signal>)");
}
int signal = SIGTERM;
if (args.Length() == 2) {
@ -3812,11 +3834,13 @@ static void JS_V8ToVPack(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
VPackSlice slice = builder.slice();
V8Buffer* buffer = V8Buffer::New(isolate, slice.startAs<char const>(), slice.byteSize());
v8::Local<v8::Object> bufferObject = v8::Local<v8::Object>::New(isolate, buffer->_handle);
V8Buffer* buffer =
V8Buffer::New(isolate, slice.startAs<char const>(), slice.byteSize());
v8::Local<v8::Object> bufferObject =
v8::Local<v8::Object>::New(isolate, buffer->_handle);
TRI_V8_RETURN(bufferObject);
TRI_V8_RETURN_FALSE();
TRI_V8_TRY_CATCH_END
}
@ -3834,9 +3858,9 @@ static void JS_VPackToV8(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (args[0]->IsString() || args[0]->IsStringObject()) {
// supplied argument is a string
std::string const value = TRI_ObjectToString(isolate, args[0]);
VPackValidator validator;
validator.validate(value.c_str(), value.size(), false);
validator.validate(value.c_str(), value.size(), false);
VPackSlice slice(value.c_str());
v8::Handle<v8::Value> result = TRI_VPackToV8(isolate, slice);
@ -3847,16 +3871,17 @@ static void JS_VPackToV8(v8::FunctionCallbackInfo<v8::Value> const& args) {
size_t size = V8Buffer::length(args[0].As<v8::Object>());
VPackValidator validator;
validator.validate(data, size, false);
validator.validate(data, size, false);
VPackSlice slice(data);
v8::Handle<v8::Value> result = TRI_VPackToV8(isolate, slice);
TRI_V8_RETURN(result);
} else {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "invalid argument type for VPACK_TO_V8()");
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"invalid argument type for VPACK_TO_V8()");
}
TRI_V8_RETURN_FALSE();
TRI_V8_TRY_CATCH_END
}
@ -4092,7 +4117,8 @@ void TRI_LogV8Exception(v8::Isolate* isolate, v8::TryCatch* tryCatch) {
if (exceptionString == nullptr) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception";
} else {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception: " << exceptionString;
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception: "
<< exceptionString;
}
} else {
TRI_Utf8ValueNFC filename(TRI_UNKNOWN_MEM_ZONE,
@ -4108,16 +4134,18 @@ void TRI_LogV8Exception(v8::Isolate* isolate, v8::TryCatch* tryCatch) {
if (exceptionString == nullptr) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception";
} else {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception: " << exceptionString;
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception: "
<< exceptionString;
}
} else {
if (exceptionString == nullptr) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception in file '" << filenameString
<< "' at " << linenum << "," << start;
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "JavaScript exception in file '" << filenameString << "' at "
<< linenum << "," << start;
} else {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "JavaScript exception in file '" << filenameString
<< "' at " << linenum << "," << start << ": "
<< exceptionString;
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "JavaScript exception in file '" << filenameString << "' at "
<< linenum << "," << start << ": " << exceptionString;
}
}
@ -4225,7 +4253,8 @@ v8::Handle<v8::Value> TRI_ExecuteJavaScriptString(
}
}
} else {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "no output function defined in Javascript context";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "no output function defined in Javascript context";
}
}
@ -4590,8 +4619,8 @@ void TRI_InitV8Utils(v8::Isolate* isolate, v8::Handle<v8::Context> context,
TRI_V8_ASCII_STRING("SYS_PARSE"), JS_Parse);
TRI_AddGlobalFunctionVocbase(
isolate, context, TRI_V8_ASCII_STRING("SYS_PARSE_FILE"), JS_ParseFile);
TRI_AddGlobalFunctionVocbase(isolate, context,
TRI_V8_ASCII_STRING("SYS_PBKDF2HS1"), JS_PBKDF2HS1);
TRI_AddGlobalFunctionVocbase(
isolate, context, TRI_V8_ASCII_STRING("SYS_PBKDF2HS1"), JS_PBKDF2HS1);
TRI_AddGlobalFunctionVocbase(isolate, context,
TRI_V8_ASCII_STRING("SYS_PBKDF2"), JS_PBKDF2);
TRI_AddGlobalFunctionVocbase(isolate, context,
@ -4636,10 +4665,10 @@ void TRI_InitV8Utils(v8::Isolate* isolate, v8::Handle<v8::Context> context,
TRI_AddGlobalFunctionVocbase(
isolate, context, TRI_V8_ASCII_STRING("SYS_IS_STOPPING"), JS_IsStopping);
TRI_AddGlobalFunctionVocbase(
isolate, context, TRI_V8_ASCII_STRING("V8_TO_VPACK"), JS_V8ToVPack);
TRI_AddGlobalFunctionVocbase(
isolate, context, TRI_V8_ASCII_STRING("VPACK_TO_V8"), JS_VPackToV8);