mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel
This commit is contained in:
commit
a589bf70b6
16
CHANGELOG
16
CHANGELOG
|
@ -1,6 +1,22 @@
|
||||||
v1.4
|
v1.4
|
||||||
----
|
----
|
||||||
|
|
||||||
|
* added "details" URL parameter for bulk import API
|
||||||
|
|
||||||
|
Setting the `details` URL parameter to `true` in a call to POST `/_api/import` will make
|
||||||
|
the import return details about non-imported documents in the `details` attribute. If
|
||||||
|
`details` is `false` or omitted, no `details` attribute will be present in the response.
|
||||||
|
This is the same behavior that previous ArangoDB versions exposed.
|
||||||
|
|
||||||
|
* added "complete" option for bulk import API
|
||||||
|
|
||||||
|
Setting the `complete` URL parameter to `true` in a call to POST `/_api/import` will make
|
||||||
|
the import completely fail if at least one of documents cannot be imported successfully.
|
||||||
|
|
||||||
|
It defaults to `false`, which will make ArangoDB continue importing the other documents
|
||||||
|
from the import even if some documents cannot be imported. This is the same behaviour that
|
||||||
|
previous ArangoDB versions exposed.
|
||||||
|
|
||||||
* calling `/_api/logs` (or `/_admin/logs`) is only permitted from the `_system` database now.
|
* calling `/_api/logs` (or `/_admin/logs`) is only permitted from the `_system` database now.
|
||||||
|
|
||||||
Calling this API method for/from other database will result in an HTTP 400.
|
Calling this API method for/from other database will result in an HTTP 400.
|
||||||
|
|
|
@ -40,6 +40,12 @@ If `complete` has a value other than `true`, valid documents will be imported wh
|
||||||
invalid documents will be rejected, meaning only some of the uploaded documents
|
invalid documents will be rejected, meaning only some of the uploaded documents
|
||||||
might have been imported.
|
might have been imported.
|
||||||
|
|
||||||
|
The `details` URL parameter can be set to `true` to make the import API return
|
||||||
|
details about documents that could not be imported. If `details` is `true`, then
|
||||||
|
the result will also contain a `details` attribute which is a list of detailed
|
||||||
|
error messages. If the `details` is set to `false` or omitted, no details will be
|
||||||
|
returned.
|
||||||
|
|
||||||
Importing Self-Contained JSON Documents {#HttpImportSelfContained}
|
Importing Self-Contained JSON Documents {#HttpImportSelfContained}
|
||||||
==================================================================
|
==================================================================
|
||||||
|
|
||||||
|
|
|
@ -107,9 +107,63 @@ Then remove the LaunchAgent
|
||||||
rm ~/Library/LaunchAgents/homebrew.mxcl.arangodb.plist
|
rm ~/Library/LaunchAgents/homebrew.mxcl.arangodb.plist
|
||||||
|
|
||||||
|
|
||||||
Apples App Store {#InstallingMacOSXAppStore}
|
Apple's App Store {#InstallingMacOSXAppStore}
|
||||||
--------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
ArangoDB is available in Apple's App-Store. Please note, that it
|
ArangoDB is available in Apple's App-Store. Please note, that it
|
||||||
sometimes take a few days or weeks until the latest versions will be
|
sometimes take a few days or weeks until the latest versions will be
|
||||||
available.
|
available.
|
||||||
|
|
||||||
|
Windows {#InstallingWindows}
|
||||||
|
============================
|
||||||
|
|
||||||
|
We provide precompiled Windows binaries for ArangoDB. The binaries
|
||||||
|
are statically linked with the required libraries such as V8, but
|
||||||
|
they may still require some Windows platform libraries to be present.
|
||||||
|
These libraries should be present on a Windows Vista, Windows 7, and
|
||||||
|
Windows 8 by default, but there may be issues with other platforms.
|
||||||
|
|
||||||
|
The Windows builds are available as `.msi` packages
|
||||||
|
@EXTREF{http://www.arangodb.org/download/,here}.
|
||||||
|
Please note that we provide binaries for 32 and 64 bit Windows, and
|
||||||
|
that you need the package that matches your platform.
|
||||||
|
|
||||||
|
The msi installer will install the ArangoDB server, shell (arangosh) and
|
||||||
|
the ArangoDB import tool (arangoimp) in a directory of the user's choice.
|
||||||
|
|
||||||
|
Included in the distribution are some `.bat` files that can be used
|
||||||
|
to easily start the ArangoDB server and shell. The `.bat` files will be
|
||||||
|
installed in the same directory as ArangoDB so they should be easy to find.
|
||||||
|
The batch files contain a lot of configuration settings, and you might want
|
||||||
|
to eventually adjust these parameters to match your own environment.
|
||||||
|
|
||||||
|
To start the ArangoDB server, use the batch file `serverExample.bat`.
|
||||||
|
It will start the ArangoDB server and will wait until you terminate it
|
||||||
|
by pressing CTRL-C. Starting ArangoDB for the first time will automatically
|
||||||
|
create a database sub-directory in the directory ArangoDB was installed in.
|
||||||
|
|
||||||
|
If you already have a previous version of ArangoDB installed and want to
|
||||||
|
upgrade to a newer version, use the `upgradeExample.bat` file. This will
|
||||||
|
start ArangoDB with the `--upgrade` option and perform a migration of an
|
||||||
|
existing database.
|
||||||
|
|
||||||
|
To start _arangosh_, use the batch file `shellExample.bat`.
|
||||||
|
|
||||||
|
Please note an important limitation when running ArangoDB under Cygwin:
|
||||||
|
Starting ArangoDB can be started from out of a Cygwin terminal, but pressing
|
||||||
|
CTRL-C will forcefully kill the server process, without giving it a chance to
|
||||||
|
handle the kill signal. In this case, a regular server shutdown is not
|
||||||
|
possible, which may leave a file `LOCK` around in the server's data directory.
|
||||||
|
This file needs to be removed manually to make ArangoDB start again.
|
||||||
|
Additionally, as ArangoDB does not have a chance to handle the kill signal,
|
||||||
|
the server cannot forcefully flush any data to disk on shutdown, leading to
|
||||||
|
potential data loss.
|
||||||
|
|
||||||
|
Starting ArangoDB from an MS-DOS command prompt does not impose the
|
||||||
|
limitations, and the kill signal will be handled normally by the server,
|
||||||
|
allowing it to shut down normally.
|
||||||
|
|
||||||
|
Please note that when using ArangoDB's web interface with Internet Explorer
|
||||||
|
(IE), you will need IE version 9 or higher to use all features. The web
|
||||||
|
interface partly relies on SVG, which is not available in previous versions
|
||||||
|
of IE.
|
||||||
|
|
|
@ -8,3 +8,4 @@ TOC {#InstallingTOC}
|
||||||
- @ref InstallingMacOSX
|
- @ref InstallingMacOSX
|
||||||
- @ref InstallingMacOSXHomebrew
|
- @ref InstallingMacOSXHomebrew
|
||||||
- @ref InstallingMacOSXAppStore
|
- @ref InstallingMacOSXAppStore
|
||||||
|
- @ref InstallingWindows
|
||||||
|
|
|
@ -182,6 +182,9 @@ The web interface now provides a graph viewer on the **Graphs** tab. The graph v
|
||||||
can be used to explore and navigate an existing ArangoDB graph. It supports both
|
can be used to explore and navigate an existing ArangoDB graph. It supports both
|
||||||
graphs in the `_graphs` system collection as well as user-defined graphs that are
|
graphs in the `_graphs` system collection as well as user-defined graphs that are
|
||||||
composed of an arbitrary vertex and edge collection.
|
composed of an arbitrary vertex and edge collection.
|
||||||
|
Please note that when using ArangoDB's web interface with Internet Explorer
|
||||||
|
(IE), you will need IE version 9 or higher. The graph viewer relies on client-side
|
||||||
|
SVG which is not available in previous versions of IE.
|
||||||
|
|
||||||
The **Dashboard** tab in the web interface provides an overview of server figures, which
|
The **Dashboard** tab in the web interface provides an overview of server figures, which
|
||||||
can be adjusted to user needs. New figures are polled by the web interface in a
|
can be adjusted to user needs. New figures are polled by the web interface in a
|
||||||
|
@ -410,6 +413,13 @@ Miscellaneous Improvements {#NewFeatures14Misc}
|
||||||
ArangoDB 1.4 now provides a REST API to execute server-side traversals with custom
|
ArangoDB 1.4 now provides a REST API to execute server-side traversals with custom
|
||||||
traversal functions. The API is described @ref HttpTraversals "here".
|
traversal functions. The API is described @ref HttpTraversals "here".
|
||||||
|
|
||||||
|
The bulk import API now provides a `complete` URL parameter that can be used to
|
||||||
|
control the behaviour when at least one document cannot be imported. Setting
|
||||||
|
`complete` to `true` will abort the whole import and roll back any already imported
|
||||||
|
documents. Setting it to `false` or omitting it will make the import continue
|
||||||
|
importing documents even if some documents could not be imported. This is also the
|
||||||
|
behaviour that previous ArangoDB versions exposed.
|
||||||
|
|
||||||
Command-Line Options added {#NewFeatures14Options}
|
Command-Line Options added {#NewFeatures14Options}
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
#include "Basics/JsonHelper.h"
|
#include "Basics/JsonHelper.h"
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
#include "BasicsC/string-buffer.h"
|
|
||||||
#include "BasicsC/tri-strings.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
#include "Rest/HttpRequest.h"
|
#include "Rest/HttpRequest.h"
|
||||||
#include "VocBase/document-collection.h"
|
#include "VocBase/document-collection.h"
|
||||||
|
@ -137,19 +136,24 @@ bool RestImportHandler::extractComplete () const {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief log an error document
|
/// @brief create a position string
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RestImportHandler::logDocument (TRI_json_t const* json) const {
|
std::string RestImportHandler::positionise (size_t i) const {
|
||||||
TRI_string_buffer_t buffer;
|
return string("at position " + StringUtils::itoa(i) + ": ");
|
||||||
|
}
|
||||||
|
|
||||||
TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int res = TRI_StringifyJson(&buffer, json);
|
/// @brief register an error
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
void RestImportHandler::registerError (RestImportResult& result,
|
||||||
LOGGER_WARNING("offending document: " << buffer._buffer);
|
std::string const& errorMsg) {
|
||||||
}
|
++result._numErrors;
|
||||||
TRI_DestroyStringBuffer(&buffer);
|
|
||||||
|
result._errors.push_back(errorMsg);
|
||||||
|
|
||||||
|
LOGGER_WARNING(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -158,11 +162,12 @@ void RestImportHandler::logDocument (TRI_json_t const* json) const {
|
||||||
|
|
||||||
int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
TRI_json_t const* json,
|
TRI_json_t const* json,
|
||||||
|
string& errorMsg,
|
||||||
const bool isEdgeCollection,
|
const bool isEdgeCollection,
|
||||||
const bool waitForSync,
|
const bool waitForSync,
|
||||||
const size_t i) {
|
const size_t i) {
|
||||||
if (! TRI_IsArrayJson(json)) {
|
if (! TRI_IsArrayJson(json)) {
|
||||||
LOGGER_WARNING("invalid JSON type (expecting array) at position " << i);
|
errorMsg = positionise(i) + "invalid JSON type (expecting array)";
|
||||||
|
|
||||||
return TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID;
|
return TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +181,7 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
const char* to = extractJsonStringValue(json, TRI_VOC_ATTRIBUTE_TO);
|
const char* to = extractJsonStringValue(json, TRI_VOC_ATTRIBUTE_TO);
|
||||||
|
|
||||||
if (from == 0 || to == 0) {
|
if (from == 0 || to == 0) {
|
||||||
LOGGER_WARNING("missing '_from' or '_to' attribute at position " << i);
|
errorMsg = positionise(i) + "missing '_from' or '_to' attribute";
|
||||||
|
|
||||||
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
return TRI_ERROR_ARANGO_INVALID_EDGE_ATTRIBUTE;
|
||||||
}
|
}
|
||||||
|
@ -211,8 +216,15 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
LOGGER_WARNING("creating document failed with error: " << TRI_errno_string(res));
|
string part = JsonHelper::toString(json);
|
||||||
logDocument(json);
|
if (part.size() > 255) {
|
||||||
|
// UTF-8 chars in string will be escaped so we can truncate it at any point
|
||||||
|
part = part.substr(0, 255) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
errorMsg = positionise(i) +
|
||||||
|
"creating document failed with error '" + TRI_errno_string(res) +
|
||||||
|
"', offending document: " + part;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -259,6 +271,10 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
/// occurs. Otherwise the import will continue even if some documents cannot
|
/// occurs. Otherwise the import will continue even if some documents cannot
|
||||||
/// be imported.
|
/// be imported.
|
||||||
///
|
///
|
||||||
|
/// @RESTQUERYPARAM{details,boolean,optional}
|
||||||
|
/// If set to `true` or `yes`, the result will include an attribute `details`
|
||||||
|
/// with details about documents that could not be imported.
|
||||||
|
///
|
||||||
/// @RESTDESCRIPTION
|
/// @RESTDESCRIPTION
|
||||||
/// Creates documents in the collection identified by `collection-name`.
|
/// Creates documents in the collection identified by `collection-name`.
|
||||||
/// The JSON representations of the documents must be passed as the body of the
|
/// The JSON representations of the documents must be passed as the body of the
|
||||||
|
@ -274,6 +290,10 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
/// - `empty`: number of empty lines found in the input (will only contain a
|
/// - `empty`: number of empty lines found in the input (will only contain a
|
||||||
/// value greater zero for types `documents` or `auto`).
|
/// value greater zero for types `documents` or `auto`).
|
||||||
///
|
///
|
||||||
|
/// - `details`: if URL parameter `details` is set to true, the result will
|
||||||
|
/// contain a `details` attribute which is a list with more detailed
|
||||||
|
/// information about which documents could not be inserted.
|
||||||
|
///
|
||||||
/// @RESTRETURNCODES
|
/// @RESTRETURNCODES
|
||||||
///
|
///
|
||||||
/// @RESTRETURNCODE{201}
|
/// @RESTRETURNCODE{201}
|
||||||
|
@ -426,7 +446,7 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
///
|
///
|
||||||
/// var body = [ { name: "some name" } ];
|
/// var body = [ { name: "some name" } ];
|
||||||
///
|
///
|
||||||
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&type=list", JSON.stringify(body));
|
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&type=list&details=true", JSON.stringify(body));
|
||||||
///
|
///
|
||||||
/// assert(response.code === 201);
|
/// assert(response.code === 201);
|
||||||
/// var r = JSON.parse(response.body);
|
/// var r = JSON.parse(response.body);
|
||||||
|
@ -447,7 +467,7 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
///
|
///
|
||||||
/// var body = '{ "_key": "abc", "value1": 25, "value2": "test" }\n{ "_key": "abc", "value1": "bar", "value2": "baz" }';
|
/// var body = '{ "_key": "abc", "value1": 25, "value2": "test" }\n{ "_key": "abc", "value1": "bar", "value2": "baz" }';
|
||||||
///
|
///
|
||||||
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&type=documents", body);
|
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&type=documents&details=true", body);
|
||||||
///
|
///
|
||||||
/// assert(response.code === 201);
|
/// assert(response.code === 201);
|
||||||
/// var r = JSON.parse(response.body);
|
/// var r = JSON.parse(response.body);
|
||||||
|
@ -510,9 +530,7 @@ int RestImportHandler::handleSingleDocument (ImportTransactionType& trx,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestImportHandler::createFromJson (const string& type) {
|
bool RestImportHandler::createFromJson (const string& type) {
|
||||||
size_t numCreated = 0;
|
RestImportResult result;
|
||||||
size_t numError = 0;
|
|
||||||
size_t numEmpty = 0;
|
|
||||||
|
|
||||||
vector<string> const& suffix = _request->suffix();
|
vector<string> const& suffix = _request->suffix();
|
||||||
|
|
||||||
|
@ -621,23 +639,24 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
|
|
||||||
StringUtils::trimInPlace(line, "\r\n\t ");
|
StringUtils::trimInPlace(line, "\r\n\t ");
|
||||||
if (line.length() == 0) {
|
if (line.length() == 0) {
|
||||||
++numEmpty;
|
++result._numEmpty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_json_t* json = parseJsonLine(line);
|
TRI_json_t* json = parseJsonLine(line);
|
||||||
|
|
||||||
res = handleSingleDocument(trx, json, isEdgeCollection, waitForSync, i);
|
string errorMsg;
|
||||||
|
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||||
|
|
||||||
if (json != 0) {
|
if (json != 0) {
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
++numCreated;
|
++result._numCreated;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++numError;
|
registerError(result, errorMsg);
|
||||||
|
|
||||||
if (complete) {
|
if (complete) {
|
||||||
// only perform a full import: abort
|
// only perform a full import: abort
|
||||||
|
@ -669,13 +688,14 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
TRI_json_t const* json = (TRI_json_t const*) TRI_AtVector(&documents->_value._objects, i);
|
TRI_json_t const* json = (TRI_json_t const*) TRI_AtVector(&documents->_value._objects, i);
|
||||||
|
|
||||||
res = handleSingleDocument(trx, json, isEdgeCollection, waitForSync, i + 1);
|
string errorMsg;
|
||||||
|
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i + 1);
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
++numCreated;
|
++result._numCreated;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++numError;
|
registerError(result, errorMsg);
|
||||||
|
|
||||||
if (complete) {
|
if (complete) {
|
||||||
// only perform a full import: abort
|
// only perform a full import: abort
|
||||||
|
@ -703,7 +723,7 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// generate result
|
// generate result
|
||||||
generateDocumentsCreated(numCreated, numError, numEmpty);
|
generateDocumentsCreated(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -737,6 +757,10 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
/// occurs. Otherwise the import will continue even if some documents cannot
|
/// occurs. Otherwise the import will continue even if some documents cannot
|
||||||
/// be imported.
|
/// be imported.
|
||||||
///
|
///
|
||||||
|
/// @RESTQUERYPARAM{details,boolean,optional}
|
||||||
|
/// If set to `true` or `yes`, the result will include an attribute `details`
|
||||||
|
/// with details about documents that could not be imported.
|
||||||
|
///
|
||||||
/// @RESTDESCRIPTION
|
/// @RESTDESCRIPTION
|
||||||
/// Creates documents in the collection identified by `collection-name`.
|
/// Creates documents in the collection identified by `collection-name`.
|
||||||
/// The first line of the request body must contain a JSON-encoded list of
|
/// The first line of the request body must contain a JSON-encoded list of
|
||||||
|
@ -754,6 +778,10 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
/// - `empty`: number of empty lines found in the input (will only contain a
|
/// - `empty`: number of empty lines found in the input (will only contain a
|
||||||
/// value greater zero for types `documents` or `auto`).
|
/// value greater zero for types `documents` or `auto`).
|
||||||
///
|
///
|
||||||
|
/// - `details`: if URL parameter `details` is set to true, the result will
|
||||||
|
/// contain a `details` attribute which is a list with more detailed
|
||||||
|
/// information about which documents could not be inserted.
|
||||||
|
///
|
||||||
/// @RESTRETURNCODES
|
/// @RESTRETURNCODES
|
||||||
///
|
///
|
||||||
/// @RESTRETURNCODE{201}
|
/// @RESTRETURNCODE{201}
|
||||||
|
@ -854,7 +882,7 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
///
|
///
|
||||||
/// var body = '[ "name" ]\n[ "some name" ]\n[ "other name" ]';
|
/// var body = '[ "name" ]\n[ "some name" ]\n[ "other name" ]';
|
||||||
///
|
///
|
||||||
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn, body);
|
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&details=true", body);
|
||||||
///
|
///
|
||||||
/// assert(response.code === 201);
|
/// assert(response.code === 201);
|
||||||
/// var r = JSON.parse(response.body)
|
/// var r = JSON.parse(response.body)
|
||||||
|
@ -875,7 +903,7 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
///
|
///
|
||||||
/// var body = '[ "_key", "value1", "value2" ]\n[ "abc", 25, "test" ]\n[ "abc", "bar", "baz" ]';
|
/// var body = '[ "_key", "value1", "value2" ]\n[ "abc", 25, "test" ]\n[ "abc", "bar", "baz" ]';
|
||||||
///
|
///
|
||||||
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn, body);
|
/// var response = logCurlRequestRaw('POST', "/_api/import?collection=" + cn + "&details=true", body);
|
||||||
///
|
///
|
||||||
/// assert(response.code === 201);
|
/// assert(response.code === 201);
|
||||||
/// var r = JSON.parse(response.body)
|
/// var r = JSON.parse(response.body)
|
||||||
|
@ -938,9 +966,7 @@ bool RestImportHandler::createFromJson (const string& type) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestImportHandler::createFromKeyValueList () {
|
bool RestImportHandler::createFromKeyValueList () {
|
||||||
size_t numCreated = 0;
|
RestImportResult result;
|
||||||
size_t numError = 0;
|
|
||||||
size_t numEmpty = 0;
|
|
||||||
|
|
||||||
vector<string> const& suffix = _request->suffix();
|
vector<string> const& suffix = _request->suffix();
|
||||||
|
|
||||||
|
@ -997,25 +1023,15 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
keys = parseJsonLine(line);
|
keys = parseJsonLine(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys == 0 || keys->_type != TRI_JSON_LIST) {
|
|
||||||
if (keys != 0) {
|
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER_WARNING("no JSON string list found first line");
|
|
||||||
generateError(HttpResponse::BAD,
|
|
||||||
TRI_ERROR_HTTP_BAD_PARAMETER,
|
|
||||||
"no JSON string list found in first line");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! checkKeys(keys)) {
|
if (! checkKeys(keys)) {
|
||||||
LOGGER_WARNING("no JSON string list in first line found");
|
LOGGER_WARNING("no JSON string list in first line found");
|
||||||
generateError(HttpResponse::BAD,
|
generateError(HttpResponse::BAD,
|
||||||
TRI_ERROR_HTTP_BAD_PARAMETER,
|
TRI_ERROR_HTTP_BAD_PARAMETER,
|
||||||
"no JSON string list in first line found");
|
"no JSON string list in first line found");
|
||||||
|
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);
|
if (keys != 0) {
|
||||||
|
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, keys);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1063,7 +1079,7 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
|
|
||||||
StringUtils::trimInPlace(line, "\r\n\t ");
|
StringUtils::trimInPlace(line, "\r\n\t ");
|
||||||
if (line.length() == 0) {
|
if (line.length() == 0) {
|
||||||
++numEmpty;
|
++result._numEmpty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,20 +1087,25 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
|
|
||||||
if (values != 0) {
|
if (values != 0) {
|
||||||
// build the json object from the list
|
// build the json object from the list
|
||||||
TRI_json_t* json = createJsonObject(keys, values, line);
|
string errorMsg;
|
||||||
|
|
||||||
|
TRI_json_t* json = createJsonObject(keys, values, errorMsg, line, i);
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, values);
|
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, values);
|
||||||
|
|
||||||
res = handleSingleDocument(trx, json, isEdgeCollection, waitForSync, i);
|
|
||||||
|
|
||||||
if (json != 0) {
|
if (json != 0) {
|
||||||
|
res = handleSingleDocument(trx, json, errorMsg, isEdgeCollection, waitForSync, i);
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// raise any error
|
||||||
|
res = TRI_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
if (res == TRI_ERROR_NO_ERROR) {
|
||||||
++numCreated;
|
++result._numCreated;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++numError;
|
registerError(result, errorMsg);
|
||||||
|
|
||||||
if (complete) {
|
if (complete) {
|
||||||
// only perform a full import: abort
|
// only perform a full import: abort
|
||||||
|
@ -1096,8 +1117,8 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOGGER_WARNING("no valid JSON data in line: " << line);
|
string errorMsg = positionise(i) + "no valid JSON data";
|
||||||
++numError;
|
registerError(result, errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,7 +1136,7 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// generate result
|
// generate result
|
||||||
generateDocumentsCreated(numCreated, numError, numEmpty);
|
generateDocumentsCreated(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1125,18 +1146,34 @@ bool RestImportHandler::createFromKeyValueList () {
|
||||||
/// @brief create response for number of documents created / failed
|
/// @brief create response for number of documents created / failed
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RestImportHandler::generateDocumentsCreated (size_t numCreated, size_t numError, size_t numEmpty) {
|
void RestImportHandler::generateDocumentsCreated (RestImportResult const& result) {
|
||||||
_response = createResponse(HttpResponse::CREATED);
|
_response = createResponse(HttpResponse::CREATED);
|
||||||
_response->setContentType("application/json; charset=utf-8");
|
_response->setContentType("application/json; charset=utf-8");
|
||||||
|
|
||||||
_response->body()
|
TRI_json_t json;
|
||||||
.appendText("{\"error\":false,\"created\":")
|
|
||||||
.appendInteger(numCreated)
|
TRI_InitArrayJson(TRI_CORE_MEM_ZONE, &json);
|
||||||
.appendText(",\"errors\":")
|
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, &json, "error", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, false));
|
||||||
.appendInteger(numError)
|
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, &json, "created", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) result._numCreated));
|
||||||
.appendText(",\"empty\":")
|
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, &json, "errors", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) result._numErrors));
|
||||||
.appendInteger(numEmpty)
|
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, &json, "empty", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) result._numEmpty));
|
||||||
.appendText("}");
|
|
||||||
|
bool found;
|
||||||
|
char const* detailsStr = _request->value("details", found);
|
||||||
|
|
||||||
|
// include failure details?
|
||||||
|
if (found && StringUtils::boolean(detailsStr)) {
|
||||||
|
TRI_json_t* messages = TRI_CreateListJson(TRI_CORE_MEM_ZONE);
|
||||||
|
|
||||||
|
for (size_t i = 0, n = result._errors.size(); i < n; ++i) {
|
||||||
|
const string& msg = result._errors[i];
|
||||||
|
TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, messages, TRI_CreateString2CopyJson(TRI_CORE_MEM_ZONE, msg.c_str(), msg.size()));
|
||||||
|
}
|
||||||
|
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, &json, "details", messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateResult(HttpResponse::CREATED, &json);
|
||||||
|
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &json);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1160,21 +1197,24 @@ TRI_json_t* RestImportHandler::parseJsonLine (const string& line) {
|
||||||
|
|
||||||
TRI_json_t* RestImportHandler::createJsonObject (const TRI_json_t* keys,
|
TRI_json_t* RestImportHandler::createJsonObject (const TRI_json_t* keys,
|
||||||
const TRI_json_t* values,
|
const TRI_json_t* values,
|
||||||
const string& line) {
|
string& errorMsg,
|
||||||
|
const string& line,
|
||||||
|
const size_t lineNumber) {
|
||||||
|
|
||||||
if (values->_type != TRI_JSON_LIST) {
|
if (values->_type != TRI_JSON_LIST) {
|
||||||
LOGGER_WARNING("no valid JSON list data in line: " << line);
|
errorMsg = positionise(lineNumber) + "no valid JSON list data";
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys->_value._objects._length != values->_value._objects._length) {
|
|
||||||
LOGGER_WARNING("wrong number of JSON values in line: " << line);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t n = keys->_value._objects._length;
|
const size_t n = keys->_value._objects._length;
|
||||||
|
|
||||||
|
if (n != values->_value._objects._length) {
|
||||||
|
errorMsg = positionise(lineNumber) + "wrong number of JSON values";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TRI_json_t* result = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, n);
|
TRI_json_t* result = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, n);
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
LOGGER_ERROR("out of memory");
|
LOGGER_ERROR("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1197,8 +1237,8 @@ TRI_json_t* RestImportHandler::createJsonObject (const TRI_json_t* keys,
|
||||||
/// @brief validate keys
|
/// @brief validate keys
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool RestImportHandler::checkKeys (TRI_json_t* keys) {
|
bool RestImportHandler::checkKeys (TRI_json_t const* keys) {
|
||||||
if (keys->_type != TRI_JSON_LIST) {
|
if (! TRI_IsListJson(keys)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,29 @@
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace arango {
|
namespace arango {
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- RestImportResult
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct RestImportResult {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RestImportResult () :
|
||||||
|
_numErrors(0),
|
||||||
|
_numEmpty(0),
|
||||||
|
_numCreated(0),
|
||||||
|
_errors() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~RestImportResult () { }
|
||||||
|
|
||||||
|
size_t _numErrors;
|
||||||
|
size_t _numEmpty;
|
||||||
|
size_t _numCreated;
|
||||||
|
|
||||||
|
std::vector<std::string> _errors;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief import request handler
|
/// @brief import request handler
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -131,10 +154,17 @@ namespace triagens {
|
||||||
bool extractComplete () const;
|
bool extractComplete () const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief log an error document
|
/// @brief create a position string
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void logDocument (TRI_json_t const*) const;
|
std::string positionise (size_t) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief register an error
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void registerError (RestImportResult&,
|
||||||
|
std::string const&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief process a single JSON document
|
/// @brief process a single JSON document
|
||||||
|
@ -142,6 +172,7 @@ namespace triagens {
|
||||||
|
|
||||||
int handleSingleDocument (ImportTransactionType&,
|
int handleSingleDocument (ImportTransactionType&,
|
||||||
TRI_json_t const*,
|
TRI_json_t const*,
|
||||||
|
std::string&,
|
||||||
const bool,
|
const bool,
|
||||||
const bool,
|
const bool,
|
||||||
const size_t);
|
const size_t);
|
||||||
|
@ -170,13 +201,13 @@ namespace triagens {
|
||||||
/// @brief creates the result
|
/// @brief creates the result
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void generateDocumentsCreated (size_t, size_t, size_t);
|
void generateDocumentsCreated (RestImportResult const&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief parses a string
|
/// @brief parses a string
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_json_t* parseJsonLine (const string&);
|
TRI_json_t* parseJsonLine (const std::string&);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief builds a TRI_json_t object from a key and value list
|
/// @brief builds a TRI_json_t object from a key and value list
|
||||||
|
@ -184,13 +215,15 @@ namespace triagens {
|
||||||
|
|
||||||
TRI_json_t* createJsonObject (const TRI_json_t*,
|
TRI_json_t* createJsonObject (const TRI_json_t*,
|
||||||
const TRI_json_t*,
|
const TRI_json_t*,
|
||||||
const string&);
|
std::string&,
|
||||||
|
const std::string&,
|
||||||
|
const size_t);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief checks the keys, returns true if all values in the list are strings.
|
/// @brief checks the keys, returns true if all values in the list are strings.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool checkKeys (TRI_json_t*);
|
bool checkKeys (TRI_json_t const*);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,20 +80,21 @@
|
||||||
.footer-left {
|
.footer-left {
|
||||||
background: none repeat scroll 0 0 #333232;
|
background: none repeat scroll 0 0 #333232;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
width: 33.3%;
|
width: 45%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-mid {
|
.footer-mid {
|
||||||
background: none repeat scroll 0 0 #333232;
|
background: none repeat scroll 0 0 #333232;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
width: 33.3%;
|
width: 45%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-right {
|
.footer-right {
|
||||||
background: none repeat scroll 0 0 #333232;
|
background: none repeat scroll 0 0 #333232;
|
||||||
color: #333232;
|
color: #333232;
|
||||||
|
width: 45%;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
|
|
||||||
<div class="footer-left">
|
<div class="footer-left">
|
||||||
<p> <a id="currentUser" style="color:#FFFFFF"></a></p>
|
<!--p> <a id="currentUser" style="color:#FFFFFF"></a></p-->
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="copy footer-mid">
|
|
||||||
<p>Copyright (c) triAGENS GmbH | <a href="#about">About</a></p>
|
<p>Copyright (c) triAGENS GmbH | <a href="#about">About</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ gs = _.sortBy(gs, sortF);
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="randomStart" class="control-label">Display random vertex at start</label>
|
<label for="randomStart" class="control-label">Display random vertex at start</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input id="randomStart" type="checkbox" name="randomStart" class="input-xlarge">
|
<input id="randomStart" type="checkbox" name="randomStart" class="input-xlarge" checked>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ var footerView = Backbone.View.extend({
|
||||||
$('.logs-menu').css('visibility', 'hidden');
|
$('.logs-menu').css('visibility', 'hidden');
|
||||||
$('.logs-menu').css('display', 'none');
|
$('.logs-menu').css('display', 'none');
|
||||||
}
|
}
|
||||||
|
self.renderVersion();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,13 +61,29 @@ window.graphView = Backbone.View.extend({
|
||||||
width,
|
width,
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
ecol = $("#edgeCollection").val();
|
|
||||||
ncol = $("#nodeCollection").val();
|
|
||||||
undirected = !!$("#undirected").attr("checked");
|
undirected = !!$("#undirected").attr("checked");
|
||||||
label = $("#nodeLabel").val();
|
label = $("#nodeLabel").val();
|
||||||
color = $("#nodeColor").val();
|
color = $("#nodeColor").val();
|
||||||
randomStart = !!$("#randomStart").attr("checked");
|
randomStart = !!$("#randomStart").attr("checked");
|
||||||
|
|
||||||
|
var selected = $("input[type='radio'][name='loadtype']:checked").attr("id");
|
||||||
|
if (selected === "collections") {
|
||||||
|
// selected two individual collections
|
||||||
|
ecol = $("#edgeCollection").val();
|
||||||
|
ncol = $("#nodeCollection").val();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// selected a "graph"
|
||||||
|
var graphName = $("#graph").val(),
|
||||||
|
graph = _.find(this.graphs, function(g) { return g._key === graphName; });
|
||||||
|
|
||||||
|
if (graph) {
|
||||||
|
ecol = graph.edges;
|
||||||
|
ncol = graph.vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
groupByAttribute = [];
|
groupByAttribute = [];
|
||||||
$("#group_by_list input").each(function() {
|
$("#group_by_list input").each(function() {
|
||||||
var a = $(this).val();
|
var a = $(this).val();
|
||||||
|
@ -103,6 +119,7 @@ window.graphView = Backbone.View.extend({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
width = this.width || $("#content").width();
|
width = this.width || $("#content").width();
|
||||||
|
|
||||||
$("#background").remove();
|
$("#background").remove();
|
||||||
if (randomStart) {
|
if (randomStart) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -119,7 +136,7 @@ window.graphView = Backbone.View.extend({
|
||||||
width,
|
width,
|
||||||
680,
|
680,
|
||||||
config,
|
config,
|
||||||
data.document._id);
|
(data.document && data.document._id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -142,8 +159,11 @@ window.graphView = Backbone.View.extend({
|
||||||
url: "/_api/graph",
|
url: "/_api/graph",
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
self.graphs = _.pluck(data.graphs, "_key");
|
self.graphs = data.graphs;
|
||||||
$(self.el).html(self.template.render({col: self.collection, gs: self.graphs}));
|
$(self.el).html(self.template.render({
|
||||||
|
col: self.collection,
|
||||||
|
gs: _.pluck(self.graphs, "_key")
|
||||||
|
}));
|
||||||
delete self.ui;
|
delete self.ui;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,8 +91,17 @@ void RestBaseHandler::handleError (TriagensError const& error) {
|
||||||
/// @brief generates a result from JSON
|
/// @brief generates a result from JSON
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RestBaseHandler::generateResult (TRI_json_t* json) {
|
void RestBaseHandler::generateResult (TRI_json_t const* json) {
|
||||||
_response = createResponse(HttpResponse::OK);
|
generateResult(HttpResponse::OK, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief generates a result from JSON
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void RestBaseHandler::generateResult (HttpResponse::HttpResponseCode code,
|
||||||
|
TRI_json_t const* json) {
|
||||||
|
_response = createResponse(code);
|
||||||
_response->setContentType("application/json; charset=utf-8");
|
_response->setContentType("application/json; charset=utf-8");
|
||||||
|
|
||||||
int res = TRI_StringifyJson(_response->body().stringBuffer(), json);
|
int res = TRI_StringifyJson(_response->body().stringBuffer(), json);
|
||||||
|
@ -108,7 +117,8 @@ void RestBaseHandler::generateResult (TRI_json_t* json) {
|
||||||
/// @brief generates an error
|
/// @brief generates an error
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RestBaseHandler::generateError (HttpResponse::HttpResponseCode code, int errorCode) {
|
void RestBaseHandler::generateError (HttpResponse::HttpResponseCode code,
|
||||||
|
int errorCode) {
|
||||||
char const* message = TRI_errno_string(errorCode);
|
char const* message = TRI_errno_string(errorCode);
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
|
|
|
@ -112,22 +112,29 @@ namespace triagens {
|
||||||
/// @brief generates a result from JSON
|
/// @brief generates a result from JSON
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual void generateResult (TRI_json_t* json);
|
virtual void generateResult (TRI_json_t const* json);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief generates a result from JSON
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
virtual void generateResult (rest::HttpResponse::HttpResponseCode,
|
||||||
|
TRI_json_t const*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief generates an error
|
/// @brief generates an error
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual void generateError (rest::HttpResponse::HttpResponseCode,
|
virtual void generateError (rest::HttpResponse::HttpResponseCode,
|
||||||
int errorCode);
|
int);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief generates an error
|
/// @brief generates an error
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual void generateError (rest::HttpResponse::HttpResponseCode,
|
virtual void generateError (rest::HttpResponse::HttpResponseCode,
|
||||||
int errorCode,
|
int,
|
||||||
string const& details);
|
string const&);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue