1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into data-modification

This commit is contained in:
Jan Steemann 2015-03-23 15:31:41 +01:00
commit c62c26e088
83 changed files with 1762 additions and 1179 deletions

View File

@ -40,6 +40,12 @@ v2.6.0 (XXXX-XX-XX)
* removed remainders of MRuby integration, removed arangoirb
v2.5.2 (XXXX-XX-XX)
-------------------
* moved /_api/query to C++
v2.5.1 (2015-03-19)
-------------------

View File

@ -163,3 +163,97 @@ FOR u IN users
This will continue execution of the query even if errors occur during the
*REPLACE* operation. It works similar for *UPDATE*, *INSERT*, and *REMOVE*.
###Altering substructures
To modify lists in documents we have to work with temporary variables.
We will collect the sublist in there and alter it. We choose a simple
boolean filter condition to make the query better comprehensible.
First lets create a collection with a sample:
```js
database = db._create('complexCollection')
database.save({
"topLevelAttribute" : "a",
"subList" : [
{
"attributeToAlter" : "oldValue",
"filterByMe" : true
},
{
"attributeToAlter" : "moreOldValues",
"filterByMe" : true
},
{
"attributeToAlter" : "unchangedValue",
"filterByMe" : false
}
]
})
```
Heres the Query which keeps the *subList* on *alteredList* to update it later:
```js
FOR document in complexCollection
LET alteredList = (
FOR element IN document.subList
LET newItem = (! element.filterByMe ?
element :
MERGE(element, { attributeToAlter: "shiny New Value" }))
RETURN newItem)
UPDATE document WITH { subList: alteredList } IN complexCollection
```
While the query as it is is now functional:
```js
db.complexCollection.toArray()
[
{
"_id" : "complexCollection/392671569467",
"_key" : "392671569467",
"_rev" : "392799430203",
"topLevelAttribute" : "a",
"subList" : [
{
"filterByMe" : true,
"attributeToAlter" : "shiny New Value"
},
{
"filterByMe" : true,
"attributeToAlter" : "shiny New Value"
},
{
"filterByMe" : false,
"attributeToAlter" : "unchangedValue"
}
]
}
]
```
It will probably be soonish a performance bottleneck, since it **modifies**
all documents in the collection **regardless whether the values change or not**.
Therefore we want to only *UPDATE* the documents if we really change their value.
Hence we employ a second *FOR* to test whether *subList* will be altered or not:
```js
FOR document in complexCollection
LET willUpdateDocument = (
FOR element IN docToAlter.subList
FILTER element.filterByMe LIMIT 1 RETURN 1)
FILTER LENGTH(willUpdateDocument) > 0
LET alteredList = (
FOR element IN document.subList
LET newItem = (! element.filterByMe ?
element :
MERGE(element, { attributeToAlter: "shiny New Value" }))
RETURN newItem)
UPDATE document WITH { subList: alteredList } IN complexCollection
```

View File

@ -13,9 +13,62 @@ inspect it and return meta information about it.
<!-- js/actions/api-explain.js -->
@startDocuBlock JSF_post_api_explain
<!-- js/actions/api-query.js -->
@startDocuBlock JSF_post_api_query
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{POST /_api/query, Parse an AQL query}
@RESTBODYPARAM{query,json,required}
To validate a query string without executing it, the query string can be
passed to the server via an HTTP POST request.
The query string needs to be passed in the attribute *query* of a JSON
object as the body of the POST request.
@RESTRETURNCODES
@RESTRETURNCODE{200}
If the query is valid, the server will respond with *HTTP 200* and
return the names of the bind parameters it found in the query (if any) in
the *bindVars* attribute of the response. It will also return an array
of the collections used in the query in the *collections* attribute.
If a query can be parsed successfully, the *ast* attribute of the returned
JSON will contain the abstract syntax tree representation of the query.
The format of the *ast* is subject to change in future versions of
ArangoDB, but it can be used to inspect how ArangoDB interprets a given
query. Note that the abstract syntax tree will be returned without any
optimizations applied to it.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request,
or if the query contains a parse error. The body of the response will
contain the error details embedded in a JSON object.
@EXAMPLES
Valid query:
@EXAMPLE_ARANGOSH_RUN{RestQueryValid}
var url = "/_api/query";
var body = '{ "query" : "FOR p IN products FILTER p.name == @name LIMIT 2 RETURN p.n" }';
var response = logCurlRequest('POST', url, body);
assert(response.code === 200);
logJsonResponse(response);
@END_EXAMPLE_ARANGOSH_RUN
Invalid query:
@EXAMPLE_ARANGOSH_RUN{RestQueryInvalid}
var url = "/_api/query";
var body = '{ "query" : "FOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n" }';
var response = logCurlRequest('POST', url, body);
assert(response.code === 400);
logJsonResponse(response);
@END_EXAMPLE_ARANGOSH_RUN
!SUBSECTION Query tracking
@ -24,16 +77,148 @@ executing AQL queries and the list of slow AQL queries. In order to make meaning
use of these APIs, query tracking needs to be enabled in the database the HTTP
request is executed for.
@startDocuBlock GetApiQueryProperties
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{GET /_api/query/properties, Returns the properties for the AQL query tracking}
@startDocuBlock PutApiQueryProperties
Returns the current query tracking configuration. The configuration is a
JSON object with the following properties:
@startDocuBlock GetApiQueryCurrent
- *enabled*: if set to *true*, then queries will be tracked. If set to
*false*, neither queries nor slow queries will be tracked.
@startDocuBlock GetApiQuerySlow
- *trackSlowQueries*: if set to *true*, then slow queries will be tracked
in the list of slow queries if their runtime exceeds the value set in
*slowQueryThreshold*. In order for slow queries to be tracked, the *enabled*
property must also be set to *true*.
@startDocuBlock DeleteApiQuerySlow
- *maxSlowQueries*: the maximum number of slow queries to keep in the list
of slow queries. If the list of slow queries is full, the oldest entry in
it will be discarded when additional slow queries occur.
- *slowQueryThreshold*: the threshold value for treating a query as slow. A
query with a runtime greater or equal to this threshold value will be
put into the list of slow queries when slow query tracking is enabled.
The value for *slowQueryThreshold* is specified in seconds.
- *maxQueryStringLength*: the maximum query string length to keep in the
list of queries. Query strings can have arbitrary lengths, and this property
can be used to save memory in case very long query strings are used. The
value is specified in bytes.
@RESTRETURNCODES
@RESTRETURNCODE{200}
Is returned when the list of queries can be retrieved successfully.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request,
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{PUT /_api/query/properties, Changes the properties for the AQL query tracking}
@RESTBODYPARAM{properties,json,required}
The properties for query tracking in the current database.
The properties need to be passed in the attribute *properties* in the body
of the HTTP request. *properties* needs to be a JSON object with the following
properties:
- *enabled*: if set to *true*, then queries will be tracked. If set to
*false*, neither queries nor slow queries will be tracked.
- *trackSlowQueries*: if set to *true*, then slow queries will be tracked
in the list of slow queries if their runtime exceeds the value set in
*slowQueryThreshold*. In order for slow queries to be tracked, the *enabled*
property must also be set to *true*.
- *maxSlowQueries*: the maximum number of slow queries to keep in the list
of slow queries. If the list of slow queries is full, the oldest entry in
it will be discarded when additional slow queries occur.
- *slowQueryThreshold*: the threshold value for treating a query as slow. A
query with a runtime greater or equal to this threshold value will be
put into the list of slow queries when slow query tracking is enabled.
The value for *slowQueryThreshold* is specified in seconds.
- *maxQueryStringLength*: the maximum query string length to keep in the
list of queries. Query strings can have arbitrary lengths, and this property
can be used to save memory in case very long query strings are used. The
value is specified in bytes.
After the properties have been changed, the current set of properties will
be returned in the HTTP response.
@RESTRETURNCODES
@RESTRETURNCODE{200}
Is returned if the properties were changed successfully.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request,
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{GET /_api/query/current, Returns the currently running AQL queries}
Returns an array containing the AQL queries currently running in the selected
database. Each query is a JSON object with the following attributes:
- *id*: the query's id
- *query*: the query string (potentially truncated)
- *started*: the date and time when the query was started
- *runTime*: the query's run time up to the point the list of queries was
queried
@RESTRETURNCODES
@RESTRETURNCODE{200}
Is returned when the list of queries can be retrieved successfully.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request,
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{GET /_api/query/slow, Returns the list of slow AQL queries}
Returns an array containing the last AQL queries that exceeded the slow
query threshold in the selected database.
The maximum amount of queries in the list can be controlled by setting
the query tracking property `maxSlowQueries`. The threshold for treating
a query as *slow* can be adjusted by setting the query tracking property
`slowQueryThreshold`.
Each query is a JSON object with the following attributes:
- *id*: the query's id
- *query*: the query string (potentially truncated)
- *started*: the date and time when the query was started
- *runTime*: the query's run time up to the point the list of queries was
queried
@RESTRETURNCODES
@RESTRETURNCODE{200}
Is returned when the list of queries can be retrieved successfully.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request,
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{DELETE /_api/query/slow, Clears the list of slow AQL queries}
@RESTRETURNCODES
@RESTRETURNCODE{204}
The server will respond with *HTTP 200* when the list of queries was
cleared successfully.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request.
!SUBSECTION Killing queries
@ -42,5 +227,18 @@ via an Http interface. To kill a running query, its id (as returned for the quer
list of currently running queries) must be specified. The kill flag of the query will
then be set, and the query will be aborted as soon as it reaches a cancellation point.
@startDocuBlock DeleteApiQueryKill
<!-- ----------------------------------------------------------------------------- -->
@RESTHEADER{DELETE /_api/query/{query-id}, Kills a running AQL query}
@RESTRETURNCODES
@RESTRETURNCODE{200}
The server will respond with *HTTP 200* when the query was still running when
the kill request was executed and the query's kill flag was set.
@RESTRETURNCODE{400}
The server will respond with *HTTP 400* in case of a malformed request.
@RESTRETURNCODE{404}
The server will respond with *HTTP 404* when no query with the specified
id was found.

View File

@ -42,11 +42,11 @@ start () {
RETVAL=$?
log_end_msg $RETVAL
else
$DAEMON -c $CONF --uid arangodb --gid arangodb --no-server --check-version
$DAEMON -c $CONF --uid arangodb --gid arangodb --no-server --log.tty "" --check-version
RETVAL=$?
if [ "$RETVAL" -eq 0 ]; then
$DAEMON -c $CONF --uid arangodb --gid arangodb --pid-file "$PIDFILE" --temp-path "/var/tmp/arangod" --supervisor $@
$DAEMON -c $CONF --uid arangodb --gid arangodb --pid-file "$PIDFILE" --temp-path "/var/tmp/arangod" --log.tty "" --supervisor $@
RETVAL=$?
log_end_msg $RETVAL
else

View File

@ -1,31 +0,0 @@
#!/bin/sh
update-rc.d arangodb start 99 2 3 4 5 . stop 00 0 1 6 . >/dev/null
/etc/init.d/arangodb start
echo "
ArangoDB 2 (http://www.arangodb.com)
A multi-purpose open-source database with a flexible data model for documents,
graphs, and key-values.
First Steps with ArangoDB:
https://docs.arangodb.com/FirstSteps/README.html
Upgrading ArangoDB:
https://docs.arangodb.com/Installing/Upgrading.html
Upgrading ArangoDB database files:
> /etc/init.d/arangodb upgrade
Configuration file:
/etc/arangodb/arangod.conf
Start ArangoDB shell client:
> /usr/bin/arangosh
Start ArangoDB service:
> /etc/init.d/arangodb start
Remote access to the ArangoDB server is disabled for security reasons.
In order to enable it, please change the server endpoint from '127.0.0.1'
to '0.0.0.0' in ArangoDB's configuration file '/etc/init.d/arangod.conf'.
"

View File

@ -1,10 +0,0 @@
#!/bin/sh
if [ purge = "$1" ]; then
update-rc.d arangodb remove >/dev/null
rm -rf /usr/share/arangodb/js/apps
rm -rf /var/log/arangodb
rm -rf /var/lib/arangodb
rm -rf /var/lib/arangodb-apps
fi

View File

@ -1,9 +0,0 @@
#!/bin/sh
getent group arangodb >/dev/null || groupadd -r arangodb
getent passwd arangodb >/dev/null || useradd -r -g arangodb -d /usr/share/arangodb -s /bin/false -c "ArangoDB Application User" arangodb
install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb
install -o arangodb -g arangodb -m 755 -d /var/lib/arangodb-apps
install -o arangodb -g arangodb -m 755 -d /var/run/arangodb
install -o arangodb -g arangodb -m 755 -d /var/log/arangodb

View File

@ -1,3 +0,0 @@
#!/bin/sh
/etc/init.d/arangodb stop

View File

@ -1,121 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: arangodb
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: arangodb
# Description: arango database server
### END INIT INFO
. /lib/lsb/init-functions
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/arangod
DESC="arango database server"
NAME="arangod"
PIDDIR=/var/run/arangodb
PIDFILE=/var/run/arangodb/arangod.pid
CONF=/etc/arangodb/arangod.conf
test -x $DAEMON || exit 0
if [ `id -u` -ne 0 ]; then
echo "You need root privileges to run this script"
exit 1
fi
start () {
[ -d $PIDDIR ] || mkdir $PIDDIR || exit 1
[ -d /var/run/arangodb ] || mkdir /var/run/arangodb || exit 1
( cd /var/log/arangodb && chown -R arangodb:arangodb . ) || exit 1
( cd /var/lib/arangodb && chown -R arangodb:arangodb . ) || exit 1
( cd /var/lib/arangodb-apps && chown -R arangodb:arangodb . ) || exit 1
( cd /var/run/arangodb && chown -R arangodb:arangodb . ) || exit 1
( cd $PIDDIR && chown arangodb:arangodb . ) || exit 1
if [ "$1" = "--upgrade" ]; then
$DAEMON -c $CONF --uid arangodb --gid arangodb --no-server $@
RETVAL=$?
log_end_msg $RETVAL
else
$DAEMON -c $CONF --uid arangodb --gid arangodb --no-server --check-version
RETVAL=$?
if [ "$RETVAL" -eq 0 ]; then
$DAEMON -c $CONF --uid arangodb --gid arangodb --pid-file "$PIDFILE" --temp-path "/var/tmp/arangod" --supervisor $@
RETVAL=$?
log_end_msg $RETVAL
else
log_failure_msg "database version check failed, maybe need to run 'upgrade'?"
fi
fi
return $RETVAL
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
start
exit $?
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
RETVAL=$?
log_end_msg $RETVAL
log_daemon_msg "Waiting for shutdown" ""
c=0
while test -f $PIDFILE -a $c -lt 30 && ps --pid `cat $PIDFILE` > /dev/null; do
log_progress_msg "."
sleep 2
c=`expr $c + 1`
done
log_progress_msg "done"
log_end_msg 0
rm -f $PIDFILE
exit $RETVAL
;;
restart)
$0 stop
sleep 3
$0 start
exit $?
;;
force-reload)
$0 restart
exit $?
;;
status)
status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
;;
upgrade)
log_daemon_msg "Upgrading $DESC" "$NAME"
start --upgrade
exit $?
;;
*)
log_success_msg "Usage: /etc/init.d/arangodb {start|stop|restart|force-reload|status|upgrade}"
exit 1
;;
esac
exit 0

108
README
View File

@ -1,17 +1,44 @@
ArangoDB
ArangoDB is a multi-purpose, open-source database with flexible data models for
ArangoDB is a multi-model, open-source database with flexible data models for
documents, graphs, and key-values. Build high performance applications using a
convenient SQL-like query language or JavaScript extensions. Use ACID
transactions if you require them. Scale horizontally and vertically with a few
mouse clicks.
ArangoDB is Polyglot Persistence done right. The supported data models can be
mixed in queries and allow ArangoDB to be the aggregation point for the data
request you have in mind.
To get started, try one of our 10 Minutes Tutorials in your favourite
programming language or try one of our ArangoDB_Cookbook_recipes.
For the impatient: download and install ArangoDB. Start the server arangod and
point your browser to http://127.0.0.1:8529/.
Key Features in ArangoDB
Multi-Model Documents, graphs and key-value pairs — model your data as you
see fit for your application.
Joins Conveniently join what belongs together for flexible ad-hoc querying,
less data redundancy.
Transactions Easy application development keeping your data consistent and
safe. No hassle in your client.
Here is an AQL query that makes use of all those features: AQL Query Example
Joins and Transactions are key features for flexible, secure data designs,
widely used in RDBMSs that you wont want to miss in NoSQL products. You
decide how and when to use Joins and strong consistency guarantees, keeping all
the power for scaling and performance as choice.
Furthermore, ArangoDB offers a microservice framework called Foxx to build your
own Rest API with a few lines of code.
Microservice Example Microservice Example
Next step, bundle your Foxx application as a docker_container and get it
running in the cloud.
Key features include:
* Schema-free schemata let you combine the space efficiency of MySQL with the
performance power of NoSQL
* Use ArangoDB as an application server and fuse your application and database
together for maximal throughput
* Use a data-centric microservices approach with ArangoDB Foxx and fuse your
application-logic and database together for maximal throughput
* JavaScript for all: no language zoo, you can use one language from your
browser to your back-end
* ArangoDB is multi-threaded - exploit the power of all your cores
@ -23,52 +50,37 @@ Key features include:
durability or more performance
* No-nonsense storage: ArangoDB uses all of the power of modern storage
hardware, like SSD and large caches
* Powerful query language (AQL) to retrieve data
* Powerful query language (AQL) to retrieve and modify data
* Transactions: run queries on multiple documents or collections with optional
transactional consistency and isolation
* Replication and Sharding: set up the database in a master-slave configuration
or spread bigger datasets across multiple servers
* It is open source (Apache Licence 2.0)
For more in-depth information
For more in-depth information read the design_goals_of_ArangoDB
* read more on the design_goals_of_ArangoDB
* watch_the_video - Martin Schoenert, architect of ArangoDB, gives an
introduction of what the ArangoDB project is about.
* or give it a try.
For the Impatient
For Mac OSX users: execute
brew install arangodb
For Windows and Linux users: use the installer script or distribution package
from our download_page.
If the package manager has not already started the ArangoDB server, use
unix> /path/to/sbin/arangod
2012-03-30T12:54:19Z [11794] INFO ArangoDB (version 2.x.y) is ready for
business
2012-03-30T12:54:19Z [11794] INFO Have Fun!
/path/to/sbin is OS dependent. It will normally by either /usr/sbin or /user/
local/sbin. Point your browser to
http://localhost:8529/
and select Tools / JS Shell. You can now use the Arango shell from within your
browser. Alternative, it is available as command-line tool arangosh.
arangosh> db._create("hello");
arangosh> db.hello.save({ world: "earth" });
Congratulations! You have created your first collection called hello and your
first document. To verify your achievements, type:
arangosh> db.hello.toArray();
Latest Release - ArangoDB 2.5
The full changelog could be found in the documentation.
Sparse Indizes: In ArangoDB 2.5, hash and skiplist indexes can optionally be
made sparse. Here is a performance_comparison that shows how you can benefit
from great savings in memory and index creation CPU time declaring indexes as
sparse.
Weve added some small but useful AQL language improvements plus several AQL
optimizer improvements.
Object attribute names in ArangoDB 2.5 can be specified using static string
literals, bind parameters, and dynamic expressions.
Function RANDOM_TOKEN(length): produces a pseudo-random string of the specified
length. Such strings can be used for id or token generation.
One example implementation is the API-Key_management that restricts access to
certain routes of an API. You can use this custom Foxx library to start
charging your valuable data right away.
Streamlined development process: ArangoDB 2.5 improves the development process
of data-centric microservices with the Foxx framework.
Installing an app is now as easy as it should be: * install: get your Foxx app
up and running * uninstall: shut it down and erase it from disk
Developers can enable the new development mode for a single app. This
deactivates caching and provides fine-graded debugging information.
More Information
@ -76,21 +88,11 @@ Please check the Installation_Manual for installation and compilation
instructions.
The User_Manual has an introductory chapter showing the basic operations of
ArangoDB.
Or you can use the online_tutorial to play with ArangoDB without installing it
locally.
Stay in Contact
Please note that there will be bugs and we'd really appreciate it if you report
them:
Please note that there will be bugs and we&#8217;d really appreciate it if you
report them:
https://github.com/arangodb/arangodb/issues
You can use the Google group for improvements, feature requests, comments
http://www.arangodb.com/community
Citing ArangoDB
Please kindly cite ArangoDB in your publications if it helps your research:
bibtex @misc{ArangoDB2014, Author = {ArangoDB}, Title = { {ArangoDB 2.2}: An
Open Source multi-purpose database supporting flexible data models for
documents, graphs, and key-values.}, Year = {2014}, Howpublished = {\url{http:/
/arangodb.com/} }

View File

@ -32,7 +32,7 @@
#include "Aql/Collection.h"
#include "Aql/Executor.h"
#include "Basics/tri-strings.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/collection.h"
using namespace triagens::aql;

View File

@ -31,10 +31,10 @@
#define ARANGODB_AQL_ASTNODE_H 1
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Basics/json.h"
#include "Basics/vector.h"
#include "Basics/JsonHelper.h"
#include "Utils/Exception.h"
#include "Aql/Query.h"
namespace triagens {

View File

@ -29,7 +29,7 @@
#include "Aql/BindParameters.h"
#include "Basics/json.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;

View File

@ -30,10 +30,10 @@
#include "Collection.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/StringUtils.h"
#include "Basics/Exceptions.h"
#include "Cluster/ClusterInfo.h"
#include "Cluster/ClusterMethods.h"
#include "Cluster/ServerState.h"
#include "Utils/Exception.h"
#include "VocBase/document-collection.h"
#include "VocBase/transaction.h"
#include "VocBase/vocbase.h"

View File

@ -31,8 +31,8 @@
#define ARANGODB_AQL_COLLECTIONS_H 1
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Aql/Collection.h"
#include "Utils/Exception.h"
struct TRI_vocbase_s;

View File

@ -32,8 +32,8 @@
#include "Basics/StringUtils.h"
#include "Basics/StringBuffer.h"
#include "Basics/json-utilities.h"
#include "Basics/Exceptions.h"
#include "HashIndex/hash-index.h"
#include "Utils/Exception.h"
#include "V8/v8-globals.h"
#include "VocBase/edge-collection.h"
#include "VocBase/index.h"

View File

@ -34,7 +34,7 @@
#include "Aql/QueryRegistry.h"
#include "Aql/WalkerWorker.h"
#include "Cluster/ClusterComm.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "Basics/logging.h"
using namespace triagens::aql;

View File

@ -38,7 +38,7 @@
#include "Aql/Variable.h"
#include "Aql/WalkerWorker.h"
#include "Basics/JsonHelper.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;
using namespace triagens::basics;

View File

@ -28,7 +28,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "Aql/ExecutionStats.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;

View File

@ -33,7 +33,7 @@
#include "Aql/V8Expression.h"
#include "Aql/Variable.h"
#include "Basics/StringBuffer.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "V8/v8-conv.h"
#include "V8/v8-globals.h"

View File

@ -38,7 +38,7 @@
#include "Basics/json.h"
#include "ShapedJson/shaped-json.h"
#include "VocBase/document-collection.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;
@ -169,7 +169,7 @@ AqlValue Expression::execute (triagens::arango::AqlTransaction* trx,
// std::cout << triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, _node->toJson(TRI_UNKNOWN_MEM_ZONE, true)).toString()<< "\n";
return _func->execute(isolate, _ast->query(), trx, docColls, argv, startPos, vars, regs);
}
catch (triagens::arango::Exception& ex) {
catch (triagens::basics::Exception& ex) {
if (_ast->query()->verboseErrors()) {
ex.addToMessage(" while evaluating expression ");
auto json = _node->toJson(TRI_UNKNOWN_MEM_ZONE, false);

View File

@ -28,7 +28,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "Aql/Function.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;

View File

@ -30,7 +30,7 @@
#include "Aql/Functions.h"
#include "Basics/fpconv.h"
#include "Basics/JsonHelper.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;

View File

@ -31,10 +31,10 @@
#define ARANGODB_AQL_INDEX_H 1
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Basics/json.h"
#include "Basics/JsonHelper.h"
#include "HashIndex/hash-index.h"
#include "Utils/Exception.h"
#include "VocBase/index.h"
namespace triagens {

View File

@ -38,10 +38,10 @@
#include "Basics/JsonHelper.h"
#include "Basics/json.h"
#include "Basics/tri-strings.h"
#include "Basics/Exceptions.h"
#include "Cluster/ServerState.h"
#include "Utils/AqlTransaction.h"
#include "Utils/CollectionNameResolver.h"
#include "Utils/Exception.h"
#include "Utils/StandaloneTransactionContext.h"
#include "Utils/V8TransactionContext.h"
#include "V8Server/ApplicationV8.h"
@ -597,7 +597,7 @@ QueryResult Query::prepare (QueryRegistry* registry) {
_engine = engine;
return QueryResult();
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
cleanupPlanAndEngine(ex.code());
return QueryResult(ex.code(), ex.message() + getStateString());
}
@ -667,7 +667,7 @@ QueryResult Query::execute (QueryRegistry* registry) {
return result;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
cleanupPlanAndEngine(ex.code());
return QueryResult(ex.code(), ex.message() + getStateString());
}
@ -739,7 +739,7 @@ QueryResultV8 Query::executeV8 (v8::Isolate* isolate, QueryRegistry* registry) {
return result;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
cleanupPlanAndEngine(ex.code());
return QueryResultV8(ex.code(), ex.message() + getStateString());
}
@ -766,7 +766,7 @@ QueryResult Query::parse () {
Parser parser(this);
return parser.parse(true);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return QueryResult(ex.code(), ex.message());
}
catch (...) {
@ -854,7 +854,7 @@ QueryResult Query::explain () {
return result;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return QueryResult(ex.code(), ex.message() + getStateString());
}
catch (std::bad_alloc const&) {

View File

@ -32,7 +32,7 @@
#include "Basics/logging.h"
#include "Basics/ReadLocker.h"
#include "Basics/WriteLocker.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"
using namespace triagens::aql;

View File

@ -434,7 +434,7 @@ void RestAqlHandler::useQuery (std::string const& operation,
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
generateError(HttpResponse::SERVER_ERROR,
ex.code(),
@ -549,7 +549,7 @@ void RestAqlHandler::getInfoQuery (std::string const& operation,
return;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
LOG_ERROR("failed during use of query: %s", ex.message().c_str());
generateError(HttpResponse::SERVER_ERROR,

View File

@ -28,7 +28,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "Aql/Scopes.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;

View File

@ -27,8 +27,8 @@
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Utils/Exception.h"
#include "Aql/VariableGenerator.h"
#include "Basics/Exceptions.h"
using namespace triagens::aql;
using Json = triagens::basics::Json;

View File

@ -115,7 +115,6 @@ add_executable(
RestServer/arangod.cpp
SkipLists/skiplistIndex.cpp
Utils/DocumentHelper.cpp
Utils/Exception.cpp
Utils/StandaloneTransactionContext.cpp
Utils/Transaction.cpp
Utils/TransactionContext.cpp

View File

@ -31,7 +31,7 @@
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "Utils/transactions.h"
#include "VocBase/document-collection.h"
#include "VocBase/headers.h"

View File

@ -79,6 +79,7 @@ arangod_libarangod_a_SOURCES = \
arangod/RestHandler/RestEdgeHandler.cpp \
arangod/RestHandler/RestImportHandler.cpp \
arangod/RestHandler/RestPleaseUpgradeHandler.cpp \
arangod/RestHandler/RestQueryHandler.cpp \
arangod/RestHandler/RestReplicationHandler.cpp \
arangod/RestHandler/RestUploadHandler.cpp \
arangod/RestHandler/RestVocbaseBaseHandler.cpp \
@ -88,7 +89,6 @@ arangod_libarangod_a_SOURCES = \
arangod/RestServer/arangod.cpp \
arangod/SkipLists/skiplistIndex.cpp \
arangod/Utils/DocumentHelper.cpp \
arangod/Utils/Exception.cpp \
arangod/Utils/StandaloneTransactionContext.cpp \
arangod/Utils/Transaction.cpp \
arangod/Utils/TransactionContext.cpp \

View File

@ -29,6 +29,7 @@
#include "ContinuousSyncer.h"
#include "Basics/Exceptions.h"
#include "Basics/json.h"
#include "Basics/JsonHelper.h"
#include "Basics/StringBuffer.h"
@ -38,7 +39,6 @@
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include "Utils/CollectionGuard.h"
#include "Utils/Exception.h"
#include "Utils/transactions.h"
#include "VocBase/document-collection.h"
#include "VocBase/transaction.h"
@ -647,7 +647,7 @@ int ContinuousSyncer::changeCollection (TRI_json_t const* json) {
bool doSync = _vocbase->_settings.forceSyncProperties;
return TRI_UpdateCollectionInfo(_vocbase, guard.collection()->_collection, &parameters, doSync);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {

View File

@ -29,6 +29,7 @@
#include "InitialSyncer.h"
#include "Basics/Exceptions.h"
#include "Basics/json.h"
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
@ -37,7 +38,6 @@
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include "Utils/CollectionGuard.h"
#include "Utils/Exception.h"
#include "Utils/transactions.h"
#include "VocBase/index.h"
#include "VocBase/document-collection.h"
@ -858,7 +858,7 @@ int InitialSyncer::handleCollection (TRI_json_t const* parameters,
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(document);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -33,13 +33,13 @@
#include "Basics/json.h"
#include "Basics/tri-strings.h"
#include "Basics/JsonHelper.h"
#include "Basics/Exceptions.h"
#include "Rest/HttpRequest.h"
#include "SimpleHttpClient/GeneralClientConnection.h"
#include "SimpleHttpClient/SimpleHttpClient.h"
#include "SimpleHttpClient/SimpleHttpResult.h"
#include "Utils/CollectionGuard.h"
#include "Utils/DocumentHelper.h"
#include "Utils/Exception.h"
#include "Utils/transactions.h"
#include "VocBase/collection.h"
#include "VocBase/document-collection.h"
@ -291,7 +291,7 @@ int Syncer::applyCollectionDumpMarker (TRI_transaction_collection_t* trxCollecti
return res;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -313,7 +313,7 @@ int Syncer::applyCollectionDumpMarker (TRI_transaction_collection_t* trxCollecti
res = TRI_ERROR_NO_ERROR;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -501,7 +501,7 @@ int Syncer::createIndex (TRI_json_t const* json) {
return res;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -542,7 +542,7 @@ int Syncer::dropIndex (TRI_json_t const* json) {
return TRI_ERROR_NO_ERROR;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {

View File

@ -83,7 +83,14 @@ HttpHandler::status_t RestPleaseUpgradeHandler::execute () {
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void RestPleaseUpgradeHandler::handleError (TriagensError const&) {
void RestPleaseUpgradeHandler::handleError (const TriagensError&) {
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void RestPleaseUpgradeHandler::handleError (const Exception&) {
}
// -----------------------------------------------------------------------------

View File

@ -81,7 +81,13 @@ namespace triagens {
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void handleError (basics::TriagensError const&);
void handleError (const basics::TriagensError&);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void handleError (const basics::Exception&);
};
}
}

View File

@ -0,0 +1,467 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief query request handler
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2010-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "RestQueryHandler.h"
#include "Aql/Query.h"
#include "Aql/QueryList.h"
#include "Basics/StringUtils.h"
#include "Basics/conversions.h"
#include "Basics/json.h"
#include "Basics/string-buffer.h"
#include "Basics/json-utilities.h"
#include "Rest/HttpRequest.h"
#include "VocBase/document-collection.h"
#include "VocBase/vocbase.h"
#include "Cluster/ServerState.h"
#include "Cluster/ClusterInfo.h"
#include "Cluster/ClusterComm.h"
#include "Cluster/ClusterMethods.h"
using namespace std;
using namespace triagens::basics;
using namespace triagens::rest;
using namespace triagens::arango;
using namespace triagens::aql;
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestQueryHandler::RestQueryHandler (HttpRequest* request, ApplicationV8* applicationV8)
: RestVocbaseBaseHandler(request),
_applicationV8(applicationV8) {
}
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::isDirect () {
return _request->requestType() != HttpRequest::HTTP_REQUEST_POST;
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
HttpHandler::status_t RestQueryHandler::execute () {
// extract the sub-request type
HttpRequest::HttpRequestType type = _request->requestType();
// execute one of the CRUD methods
switch (type) {
case HttpRequest::HTTP_REQUEST_DELETE: deleteQuery(); break;
case HttpRequest::HTTP_REQUEST_GET: readQuery(); break;
case HttpRequest::HTTP_REQUEST_PUT: replaceProperties(); break;
case HttpRequest::HTTP_REQUEST_POST: parseQuery(); break;
case HttpRequest::HTTP_REQUEST_HEAD:
case HttpRequest::HTTP_REQUEST_PATCH:
case HttpRequest::HTTP_REQUEST_ILLEGAL:
default: {
generateNotImplemented("ILLEGAL " + DOCUMENT_PATH);
break;
}
}
// this handler is done
return status_t(HANDLER_DONE);
}
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the list of properties
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::readQueryProperties () {
try {
auto queryList = static_cast<QueryList*>(_vocbase->_queries);
Json result(Json::Object);
result
.set("error", Json(false))
.set("code", Json(HttpResponse::OK))
.set("enabled", Json(queryList->enabled()))
.set("trackSlowQueries", Json(queryList->trackSlowQueries()))
.set("maxSlowQueries", Json(static_cast<double>(queryList->maxSlowQueries())))
.set("slowQueryThreshold", Json(queryList->slowQueryThreshold()))
.set("maxQueryStringLength", Json(static_cast<double>(queryList->maxQueryStringLength())));
generateResult(HttpResponse::OK, result.json());
}
catch (const TriagensError& err) {
handleError(err);
}
catch (const Exception& err) {
handleError(err);
}
catch (std::exception const& ex) {
triagens::basics::InternalError err(ex, __FILE__, __LINE__);
handleError(err);
}
catch (...) {
triagens::basics::InternalError err("executeDirectHandler", __FILE__, __LINE__);
handleError(err);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the list of slow queries
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::readQuery (bool slow) {
try {
auto queryList = static_cast<QueryList*>(_vocbase->_queries);
auto const&& queries = slow ? queryList->listSlow() : queryList->listCurrent();
Json result(Json::Array);
for (auto it : queries) {
const auto&& timeString = TRI_StringTimeStamp(it.started);
const auto& queryString = it.queryString;
Json entry(Json::Object);
entry
.set("id", Json(StringUtils::itoa(it.id)))
.set("query", Json(queryString))
.set("started", Json(timeString))
.set("runTime", Json(it.runTime));
result.add(entry);
}
generateResult(HttpResponse::OK, result.json());
}
catch (const TriagensError& err) {
handleError(err);
}
catch (const Exception& err) {
handleError(err);
}
catch (std::exception const& ex) {
triagens::basics::InternalError err(ex, __FILE__, __LINE__);
handleError(err);
}
catch (...) {
triagens::basics::InternalError err("executeDirectHandler", __FILE__, __LINE__);
handleError(err);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns AQL query tracking
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::readQuery () {
const auto& suffix = _request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting GET /_api/query/<type>");
return true;
}
const auto& name = suffix[0];
if (name == "slow") {
return readQuery(true);
}
else if (name == "current") {
return readQuery(false);
}
else if (name == "properties") {
return readQueryProperties();
}
generateError(HttpResponse::NOT_FOUND,
TRI_ERROR_HTTP_NOT_FOUND,
"unknown type '" + name + "', expecting 'slow', 'current', or 'properties'");
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief removes the slow log
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::deleteQuerySlow () {
auto queryList = static_cast<triagens::aql::QueryList*>(_vocbase->_queries);
queryList->clearSlow();
Json result(Json::Object);
// added a "generateOk"?
result
.set("error", Json(false))
.set("code", Json(HttpResponse::OK));
generateResult(HttpResponse::OK, result.json());
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief interrupts a named query
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::deleteQuery (const string& name) {
auto id = StringUtils::uint64(name);
auto queryList = static_cast<triagens::aql::QueryList*>(_vocbase->_queries);
TRI_ASSERT(queryList != nullptr);
auto res = queryList->kill(id);
if (res == TRI_ERROR_NO_ERROR) {
Json result(Json::Object);
result
.set("error", Json(false))
.set("code", Json(HttpResponse::OK));
generateResult(HttpResponse::OK, result.json());
}
else {
generateError(HttpResponse::BAD, res, "cannot kill query '" + name + "'");
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief interrupts a query
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::deleteQuery () {
const auto& suffix = _request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting DELETE /_api/query/<id> or /_api/query/slow");
return true;
}
const auto& name = suffix[0];
if (name == "slow") {
return deleteQuerySlow();
}
else {
return deleteQuery(name);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief changes the settings
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::replaceProperties () {
const auto& suffix = _request->suffix();
if (suffix.size() != 1 || suffix[0] != "properties") {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting PUT /_api/query/properties");
return true;
}
unique_ptr<TRI_json_t> body(parseJsonBody());
if (body == nullptr) {
// error message generated in parseJsonBody
return true;
}
auto queryList = static_cast<triagens::aql::QueryList*>(_vocbase->_queries);
try {
bool enabled = queryList->enabled();
bool trackSlowQueries = queryList->trackSlowQueries();
size_t maxSlowQueries = queryList->maxSlowQueries();
double slowQueryThreshold = queryList->slowQueryThreshold();
size_t maxQueryStringLength = queryList->maxQueryStringLength();
// TODO(fc) add a "hasSomething" to JsonHelper?
if (JsonHelper::getObjectElement(body.get(), "enabled") != nullptr) {
enabled = JsonHelper::checkAndGetBooleanValue(body.get(), "enabled");
}
if (JsonHelper::getObjectElement(body.get(), "trackSlowQueries") != nullptr) {
trackSlowQueries = JsonHelper::checkAndGetBooleanValue(body.get(), "trackSlowQueries");
}
if (JsonHelper::getObjectElement(body.get(), "maxSlowQueries") != nullptr) {
maxSlowQueries = JsonHelper::checkAndGetNumericValue<size_t>(body.get(), "maxSlowQueries");
}
if (JsonHelper::getObjectElement(body.get(), "slowQueryThreshold") != nullptr) {
slowQueryThreshold = JsonHelper::checkAndGetNumericValue<double>(body.get(), "slowQueryThreshold");
}
if (JsonHelper::getObjectElement(body.get(), "maxQueryStringLength") != nullptr) {
maxQueryStringLength = JsonHelper::checkAndGetNumericValue<size_t>(body.get(), "maxQueryStringLength");
}
queryList->enabled(enabled);
queryList->trackSlowQueries(trackSlowQueries);
queryList->maxSlowQueries(maxSlowQueries);
queryList->slowQueryThreshold(slowQueryThreshold);
queryList->maxQueryStringLength(maxQueryStringLength);
return readQueryProperties();
}
catch (const TriagensError& err) {
handleError(err);
}
catch (const Exception& err) {
handleError(err);
}
catch (std::exception const& ex) {
triagens::basics::InternalError err(ex, __FILE__, __LINE__);
handleError(err);
}
catch (...) {
triagens::basics::InternalError err("executeDirectHandler", __FILE__, __LINE__);
handleError(err);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a query
////////////////////////////////////////////////////////////////////////////////
bool RestQueryHandler::parseQuery () {
const auto& suffix = _request->suffix();
if (! suffix.empty()) {
generateError(HttpResponse::BAD,
TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting POST /_api/query");
return true;
}
unique_ptr<TRI_json_t> body(parseJsonBody());
if (body.get() == nullptr) {
// error message generated in parseJsonBody
return true;
}
try {
const string&& queryString = JsonHelper::checkAndGetStringValue(body.get(), "query");
Query query(_applicationV8, true, _vocbase, queryString.c_str(), queryString.size(), nullptr, nullptr, PART_MAIN);
auto parseResult = query.parse();
if (parseResult.code != TRI_ERROR_NO_ERROR) {
generateError(HttpResponse::BAD,
parseResult.code,
parseResult.details);
return true;
}
Json collections(Json::Array);
for (const auto& it : parseResult.collectionNames) {
collections.add(Json(it));
}
Json bindVars(Json::Array);
for (const auto& it : parseResult.bindParameters) {
bindVars.add(Json(it));
}
Json result(Json::Object);
result
.set("error", Json(false))
.set("code", Json(HttpResponse::OK))
.set("parsed", Json(true))
.set("collections", collections)
.set("bindVars", bindVars)
.set("ast", Json(TRI_UNKNOWN_MEM_ZONE, parseResult.json, Json::NOFREE).copy());
if (parseResult.warnings == nullptr) {
result.set("warnings", Json(Json::Array));
}
else {
result.set("warnings", Json(TRI_UNKNOWN_MEM_ZONE, parseResult.warnings, Json::NOFREE).copy());
}
generateResult(HttpResponse::OK, result.json());
}
catch (const TriagensError& err) {
handleError(err);
}
catch (const Exception& err) {
handleError(err);
}
catch (std::exception const& ex) {
triagens::basics::InternalError err(ex, __FILE__, __LINE__);
handleError(err);
}
catch (...) {
triagens::basics::InternalError err("executeDirectHandler", __FILE__, __LINE__);
handleError(err);
}
return true;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -0,0 +1,163 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief query request handler
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2010-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_REST_HANDLER_REST_QUERY_HANDLER_H
#define ARANGODB_REST_HANDLER_REST_QUERY_HANDLER_H 1
#include "Basics/Common.h"
#include "RestHandler/RestVocbaseBaseHandler.h"
// -----------------------------------------------------------------------------
// --SECTION-- forward declarations
// -----------------------------------------------------------------------------
namespace triagens {
namespace arango {
class ApplicationV8;
// -----------------------------------------------------------------------------
// --SECTION-- class RestQueryHandler
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief document request handler
////////////////////////////////////////////////////////////////////////////////
class RestQueryHandler : public RestVocbaseBaseHandler {
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestQueryHandler (rest::HttpRequest*, ApplicationV8*);
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool isDirect ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
status_t execute ();
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the list of properties
////////////////////////////////////////////////////////////////////////////////
bool readQueryProperties ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the list of slow queries
////////////////////////////////////////////////////////////////////////////////
bool readQuery (bool slow);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns AQL query tracking
////////////////////////////////////////////////////////////////////////////////
bool readQuery ();
////////////////////////////////////////////////////////////////////////////////
/// @brief removes the slow log
////////////////////////////////////////////////////////////////////////////////
bool deleteQuerySlow ();
////////////////////////////////////////////////////////////////////////////////
/// @brief interrupts a named query
////////////////////////////////////////////////////////////////////////////////
bool deleteQuery (const std::string& name);
////////////////////////////////////////////////////////////////////////////////
/// @brief interrupts a query
////////////////////////////////////////////////////////////////////////////////
bool deleteQuery ();
////////////////////////////////////////////////////////////////////////////////
/// @brief changes the settings
////////////////////////////////////////////////////////////////////////////////
bool replaceProperties ();
////////////////////////////////////////////////////////////////////////////////
/// @brief parses a query
////////////////////////////////////////////////////////////////////////////////
bool parseQuery ();
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief application V8
////////////////////////////////////////////////////////////////////////////////
ApplicationV8* _applicationV8;
};
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -1073,7 +1073,7 @@ void RestReplicationHandler::handleCommandLoggerFollow () {
insertClient(dump._lastFoundTick);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -1987,7 +1987,7 @@ int RestReplicationHandler::processRestoreIndexes (TRI_json_t const* collection,
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
errorMsg = "could not create index: " + string(TRI_errno_string(ex.code()));
}
catch (...) {
@ -2161,7 +2161,7 @@ int RestReplicationHandler::applyCollectionDumpMarker (CollectionNameResolver co
return res;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
TRI_FreeShapedJson(zone, shaped);
return ex.code();
}
@ -2186,7 +2186,7 @@ int RestReplicationHandler::applyCollectionDumpMarker (CollectionNameResolver co
res = TRI_ERROR_NO_ERROR;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -2960,7 +2960,7 @@ void RestReplicationHandler::handleCommandDump () {
// avoid double freeing
TRI_StealStringBuffer(dump._buffer);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -62,6 +62,7 @@
#include "RestHandler/RestEdgeHandler.h"
#include "RestHandler/RestImportHandler.h"
#include "RestHandler/RestPleaseUpgradeHandler.h"
#include "RestHandler/RestQueryHandler.h"
#include "RestHandler/RestReplicationHandler.h"
#include "RestHandler/RestUploadHandler.h"
#include "RestServer/ConsoleThread.h"
@ -99,6 +100,7 @@ bool IGNORE_DATAFILE_ERRORS;
////////////////////////////////////////////////////////////////////////////////
void ArangoServer::defineHandlers (HttpHandlerFactory* factory) {
// First the "_api" handlers:
// add "/version" handler
@ -145,6 +147,11 @@ void ArangoServer::defineHandlers (HttpHandlerFactory* factory) {
RestHandlerCreator<aql::RestAqlHandler>::createData<std::pair<ApplicationV8*, aql::QueryRegistry*>*>,
_pairForAql);
factory->addPrefixHandler("/_api/query",
RestHandlerCreator<RestQueryHandler>::createData<ApplicationV8*>,
_applicationV8);
// And now the "_admin" handlers
// add "/_admin/version" handler
@ -1083,7 +1090,6 @@ int ArangoServer::runConsole (TRI_vocbase_t* vocbase) {
////////////////////////////////////////////////////////////////////////////////
int ArangoServer::runUnitTests (TRI_vocbase_t* vocbase) {
ApplicationV8::V8Context* context = _applicationV8->enterContext("STANDARD", vocbase, true);
auto isolate = context->isolate;

View File

@ -31,7 +31,7 @@
#define ARANGODB_UTILS_COLLECTION_GUARD_H 1
#include "Basics/Common.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"
namespace triagens {

View File

@ -31,7 +31,7 @@
#define ARANGODB_UTILS_DATABASE_GUARD_H 1
#include "Basics/Common.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/server.h"
struct TRI_vocbase_s;

View File

@ -1,188 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief arango exceptions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Exception.h"
#include "Basics/StringUtils.h"
using namespace std;
using namespace triagens::arango;
////////////////////////////////////////////////////////////////////////////////
/// @brief controls if backtraces are printed with exceptions
////////////////////////////////////////////////////////////////////////////////
static bool WithBackTrace = false;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor, without format string
////////////////////////////////////////////////////////////////////////////////
Exception::Exception (int code,
char const* file,
int line)
: _errorMessage(TRI_errno_string(code)),
_file(file),
_line(line),
_code(code) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
#if HAVE_BACKTRACE
if (WithBackTrace) {
_errorMessage += std::string("\n\n");
TRI_GetBacktrace(_errorMessage);
_errorMessage += std::string("\n\n");
}
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor, for creating an exception with an already created
/// error message (normally based on error templates containing %s, %d etc.)
////////////////////////////////////////////////////////////////////////////////
Exception::Exception (int code,
string const& errorMessage,
char const* file,
int line)
: _errorMessage(errorMessage),
_file(file),
_line(line),
_code(code) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
#if HAVE_BACKTRACE
if (WithBackTrace) {
_errorMessage += std::string("\n\n");
TRI_GetBacktrace(_errorMessage);
_errorMessage += std::string("\n\n");
}
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
Exception::~Exception () throw () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return exception message
////////////////////////////////////////////////////////////////////////////////
char const* Exception::what () const throw () {
// we have to use an instance member here because we should not return a
// pointer (c_str()) to the internals of a stack object (stack object will
// be destroyed when function is left...)
// additionally, we should not create new string values here as this might
// throw exceptions - but this function is marked to throw no exceptions!
/*
std::string message = "exception in '";
message.append(_file);
message.append("' at line ");
message.append(basics::StringUtils::itoa(_line));
message.append(": ");
message += this->message();
return message.c_str();
*/
return _errorMessage.c_str();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct an error message from a template string
////////////////////////////////////////////////////////////////////////////////
std::string Exception::FillExceptionString (int code,
...) {
char const* format = TRI_errno_string(code);
TRI_ASSERT(format != nullptr);
#ifdef TRI_ENABLE_MAINTAINER_MODE
// Obviously the formatstring of the error code has to support parameters.
TRI_ASSERT(strchr(format, '%') != nullptr);
#endif
char buffer[1024];
va_list ap;
va_start(ap, code);
vsnprintf(buffer, sizeof(buffer) - 1, format, ap);
va_end(ap);
buffer[sizeof(buffer) - 1] = '\0'; // Windows
return std::string(buffer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct an error message from a template string
////////////////////////////////////////////////////////////////////////////////
std::string Exception::FillFormatExceptionString (char const* format,
...) {
TRI_ASSERT(format != nullptr);
#ifdef TRI_ENABLE_MAINTAINER_MODE
// Format #1 should come from the macro...
TRI_ASSERT(strchr(format, '%') != nullptr);
// Obviously the user has to give us a format string.
TRI_ASSERT(strchr(strchr(format, '%'), '%') != nullptr);
#endif
char buffer[1024];
va_list ap;
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer) - 1, format, ap);
va_end(ap);
buffer[sizeof(buffer) - 1] = '\0'; // Windows
return std::string(buffer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief controls whether a backtrace is created for each exception
////////////////////////////////////////////////////////////////////////////////
void Exception::SetVerbose (bool verbose) {
WithBackTrace = verbose;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -1,151 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief arango exceptions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_UTILS_EXCEPTION_H
#define ARANGODB_UTILS_EXCEPTION_H 1
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include <errno.h>
// -----------------------------------------------------------------------------
// --SECTION-- public macros
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION(code) \
throw triagens::arango::Exception(code, __FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and arbitrary
/// arguments (to be inserted in printf-style manner)
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_PARAMS(code, ...) \
throw triagens::arango::Exception(code, triagens::arango::Exception::FillExceptionString(code, __VA_ARGS__), __FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and arbitrary
/// arguments (to be inserted in printf-style manner)
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_FORMAT(code, format, ...) \
throw triagens::arango::Exception(code, \
triagens::arango::Exception::FillFormatExceptionString( \
"%s: " format,\
TRI_errno_string(code), \
__VA_ARGS__),\
__FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and an already-built
/// error message
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_MESSAGE(code, message) \
throw triagens::arango::Exception(code, message, __FILE__, __LINE__)
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
namespace triagens {
namespace arango {
////////////////////////////////////////////////////////////////////////////////
/// @brief arango exception type
////////////////////////////////////////////////////////////////////////////////
class Exception : public virtual std::exception {
public:
Exception (int code,
char const* file,
int line);
Exception (int code,
std::string const& errorMessage,
char const* file,
int line);
~Exception () throw ();
public:
char const * what () const throw ();
std::string message () const throw () {
return _errorMessage;
}
int code () const throw () {
return _code;
}
void addToMessage(std::string More) {
_errorMessage += More;
}
static std::string FillExceptionString (int, ...);
static std::string FillFormatExceptionString (char const * format,
...);
////////////////////////////////////////////////////////////////////////////////
/// @brief controls whether a backtrace is created for each exception
////////////////////////////////////////////////////////////////////////////////
static void SetVerbose (bool);
protected:
std::string _errorMessage;
char const* _file;
int const _line;
int const _code;
};
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -34,7 +34,7 @@
#include "Cluster/ServerState.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/barrier.h"
#include "VocBase/collection.h"
#include "VocBase/document-collection.h"
@ -542,7 +542,7 @@ namespace triagens {
! isLocked(trxCollection, TRI_TRANSACTION_WRITE),
forceSync);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -648,7 +648,7 @@ namespace triagens {
mptr,
! isLocked(trxCollection, TRI_TRANSACTION_READ));
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -1179,7 +1179,7 @@ namespace triagens {
forceSync,
false);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -1218,7 +1218,7 @@ namespace triagens {
! isLocked(trxCollection, TRI_TRANSACTION_WRITE),
forceSync);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
return ex.code();
}
catch (...) {
@ -1270,7 +1270,7 @@ namespace triagens {
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -2257,7 +2257,7 @@ static void JS_PropertiesVocbaseCol (const v8::FunctionCallbackInfo<v8::Value>&
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -28,6 +28,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "v8-user-structures.h"
#include "Basics/Exceptions.h"
#include "Basics/ReadWriteLock.h"
#include "Basics/ReadLocker.h"
#include "Basics/WriteLocker.h"
@ -35,7 +36,6 @@
#include "Basics/json.h"
#include "Basics/json-utilities.h"
#include "Basics/tri-strings.h"
#include "Utils/Exception.h"
#include "VocBase/vocbase.h"
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"

View File

@ -582,7 +582,7 @@ static void JS_EnableNativeBacktraces (const v8::FunctionCallbackInfo<v8::Value>
TRI_V8_THROW_EXCEPTION_USAGE("ENABLE_NATIVE_BACKTRACES(<value>)");
}
triagens::arango::Exception::SetVerbose(TRI_ObjectToBoolean(args[0]));
triagens::basics::Exception::SetVerbose(TRI_ObjectToBoolean(args[0]));
TRI_V8_RETURN_UNDEFINED();
}

View File

@ -35,6 +35,7 @@
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "Basics/ThreadPool.h"
#include "Basics/Exceptions.h"
#include "CapConstraint/cap-constraint.h"
#include "FulltextIndex/fulltext-index.h"
#include "GeoIndex/geo-index.h"
@ -44,7 +45,6 @@
#include "Utils/transactions.h"
#include "Utils/CollectionReadLocker.h"
#include "Utils/CollectionWriteLocker.h"
#include "Utils/Exception.h"
#include "VocBase/edge-collection.h"
#include "VocBase/index.h"
#include "VocBase/key-generator.h"
@ -3505,7 +3505,7 @@ bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document,
return true;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -39,6 +39,7 @@
#include "Basics/fasthash.h"
#include "Basics/json-utilities.h"
#include "Basics/JsonHelper.h"
#include "Basics/Exceptions.h"
#include "CapConstraint/cap-constraint.h"
#include "FulltextIndex/fulltext-index.h"
#include "FulltextIndex/fulltext-wordlist.h"
@ -46,7 +47,6 @@
#include "HashIndex/hash-index.h"
#include "ShapedJson/shape-accessor.h"
#include "ShapedJson/shaped-json.h"
#include "Utils/Exception.h"
#include "VocBase/document-collection.h"
#include "VocBase/edge-collection.h"
#include "VocBase/server.h"
@ -386,7 +386,7 @@ int TRI_SaveIndex (TRI_document_collection_t* document,
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
return TRI_ERROR_NO_ERROR;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -1442,7 +1442,7 @@ int TRI_DumpLogReplication (TRI_replication_dump_t* dump,
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -34,8 +34,8 @@
#include "Basics/associative.h"
#include "Basics/string-buffer.h"
#include "Basics/Exceptions.h"
#include "ShapedJson/shaped-json.h"
#include "Utils/Exception.h"
#include "VocBase/replication-common.h"
#include "VocBase/voc-types.h"
#include "VocBase/vocbase.h"

View File

@ -46,7 +46,7 @@
#include "Basics/random.h"
#include "Basics/tri-strings.h"
#include "Basics/JsonHelper.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/auth.h"
#include "VocBase/replication-applier.h"
#include "VocBase/vocbase.h"
@ -1503,7 +1503,7 @@ static int WriteCreateMarker (TRI_voc_tick_t id,
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -1533,7 +1533,7 @@ static int WriteDropMarker (TRI_voc_tick_t id) {
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -32,8 +32,7 @@
#include "Basics/conversions.h"
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/collection.h"
#include "VocBase/document-collection.h"
#include "VocBase/server.h"
@ -648,7 +647,7 @@ static int WriteBeginMarker (TRI_transaction_t* trx) {
trx->_beginWritten = true;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -695,7 +694,7 @@ static int WriteAbortMarker (TRI_transaction_t* trx) {
res = GetLogfileManager()->allocateAndWrite(marker, false).errorCode;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -738,7 +737,7 @@ static int WriteCommitMarker (TRI_transaction_t* trx) {
res = GetLogfileManager()->allocateAndWrite(marker, false).errorCode;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -41,7 +41,7 @@
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "Basics/utf8-helper.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/document-collection.h"
#include "Wal/LogfileManager.h"
@ -218,7 +218,7 @@ static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
return aid;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -387,7 +387,7 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
return result;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -45,8 +45,7 @@
#include "Basics/random.h"
#include "Basics/tri-strings.h"
#include "Basics/threads.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "Utils/transactions.h"
#include "VocBase/auth.h"
#include "VocBase/barrier.h"
@ -182,7 +181,7 @@ static int WriteDropCollectionMarker (TRI_vocbase_t* vocbase,
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -682,7 +681,7 @@ static TRI_vocbase_col_t* CreateCollection (TRI_vocbase_t* vocbase,
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
return collection;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -833,7 +832,7 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
return TRI_ERROR_NO_ERROR;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -30,7 +30,7 @@
#include "AllocatorThread.h"
#include "Basics/logging.h"
#include "Basics/ConditionLocker.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "Wal/LogfileManager.h"
using namespace triagens::wal;
@ -157,7 +157,7 @@ void AllocatorThread::run () {
LOG_ERROR("unable to create new WAL reserve logfile");
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
int res = ex.code();
LOG_ERROR("got unexpected error in allocatorThread: %s", TRI_errno_string(res));
}

View File

@ -28,13 +28,14 @@
////////////////////////////////////////////////////////////////////////////////
#include "CollectorThread.h"
#include "Basics/MutexLocker.h"
#include "Basics/hashes.h"
#include "Basics/logging.h"
#include "Basics/ConditionLocker.h"
#include "Basics/Exceptions.h"
#include "Utils/CollectionGuard.h"
#include "Utils/DatabaseGuard.h"
#include "Utils/Exception.h"
#include "Utils/transactions.h"
#include "VocBase/document-collection.h"
#include "VocBase/server.h"
@ -365,7 +366,7 @@ void CollectorThread::run () {
throw;
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
int res = ex.code();
LOG_ERROR("got unexpected error in collectorThread::run: %s", TRI_errno_string(res));
}
@ -468,7 +469,7 @@ bool CollectorThread::processQueuedOperations () {
try {
res = processCollectionOperations((*it2));
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
@ -704,7 +705,7 @@ int CollectorThread::processCollectionOperations (CollectorCache* cache) {
res = TRI_ERROR_NO_ERROR;
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -807,7 +808,7 @@ int CollectorThread::collect (Logfile* logfile) {
try {
res = transferMarkers(logfile, cid, state.collections[cid], state.operationsCount[cid], sortedOperations);
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -886,7 +887,7 @@ int CollectorThread::transferMarkers (Logfile* logfile,
queueOperations(logfile, cache);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -38,7 +38,6 @@
#include "Basics/ReadLocker.h"
#include "Basics/StringUtils.h"
#include "Basics/WriteLocker.h"
#include "Utils/Exception.h"
#include "VocBase/server.h"
#include "Wal/AllocatorThread.h"
#include "Wal/CollectorThread.h"

View File

@ -31,12 +31,12 @@
#include "Basics/FileUtils.h"
#include "Basics/conversions.h"
#include "Basics/files.h"
#include "Basics/Exceptions.h"
#include "VocBase/collection.h"
#include "VocBase/replication-applier.h"
#include "VocBase/voc-shaper.h"
#include "Wal/LogfileManager.h"
#include "Wal/Slots.h"
#include "Utils/Exception.h"
using namespace triagens::wal;
@ -452,7 +452,7 @@ int RecoverState::executeRemoteOperation (TRI_voc_tick_t databaseId,
THROW_ARANGO_EXCEPTION(res);
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -536,7 +536,7 @@ int RecoverState::executeSingleOperation (TRI_voc_tick_t databaseId,
// commit the operation
res = trx->commit();
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {
@ -1620,7 +1620,7 @@ int RecoverState::abortOpenTransactions () {
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
res = ex.code();
}
catch (...) {

View File

@ -28,9 +28,10 @@
////////////////////////////////////////////////////////////////////////////////
#include "RemoverThread.h"
#include "Basics/logging.h"
#include "Basics/ConditionLocker.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "Wal/LogfileManager.h"
using namespace triagens::wal;
@ -108,7 +109,7 @@ void RemoverThread::run () {
worked = _logfileManager->removeLogfiles();
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
int res = ex.code();
LOG_ERROR("got unexpected error in removerThread::run: %s", TRI_errno_string(res));
}

View File

@ -28,9 +28,10 @@
////////////////////////////////////////////////////////////////////////////////
#include "SynchroniserThread.h"
#include "Basics/logging.h"
#include "Basics/ConditionLocker.h"
#include "Utils/Exception.h"
#include "Basics/Exceptions.h"
#include "VocBase/server.h"
#include "Wal/LogfileManager.h"
#include "Wal/Slots.h"
@ -137,7 +138,7 @@ void SynchroniserThread::run () {
}
}
}
catch (triagens::arango::Exception const& ex) {
catch (triagens::basics::Exception const& ex) {
int res = ex.code();
LOG_ERROR("got unexpected error in synchroniserThread: %s", TRI_errno_string(res));
}

View File

@ -61,6 +61,7 @@ namespace triagens {
_mutex(),
_value(initialValue),
_maxValue(maxValue),
_incompleteFailures(0),
_failures(0),
_done(0) {
}
@ -96,6 +97,15 @@ namespace triagens {
return _failures;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the failures value
////////////////////////////////////////////////////////////////////////////////
size_t incompleteFailures () {
MUTEX_LOCKER(this->_mutex);
return _incompleteFailures;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the next x until the max is reached
////////////////////////////////////////////////////////////////////////////////
@ -148,6 +158,15 @@ namespace triagens {
_failures += value;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register a failure
////////////////////////////////////////////////////////////////////////////////
void incIncompleteFailures (const size_t value) {
MUTEX_LOCKER(this->_mutex);
_incompleteFailures += value;
}
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
@ -172,6 +191,12 @@ namespace triagens {
const T _maxValue;
////////////////////////////////////////////////////////////////////////////////
/// @brief the number of incomplete replies
////////////////////////////////////////////////////////////////////////////////
size_t _incompleteFailures;
////////////////////////////////////////////////////////////////////////////////
/// @brief the number of errors
////////////////////////////////////////////////////////////////////////////////

View File

@ -77,7 +77,8 @@ namespace triagens {
double connectTimeout,
uint32_t sslProtocol,
bool keepAlive,
bool async)
bool async,
bool verbose)
: Thread("arangob"),
_operation(operation),
_startCondition(condition),
@ -100,7 +101,8 @@ namespace triagens {
_connection(0),
_offset(0),
_counter(0),
_time(0.0) {
_time(0.0),
_verbose(verbose) {
_errorHeader = StringUtils::tolower(rest::HttpResponse::getBatchErrorHeader());
}
@ -296,6 +298,9 @@ namespace triagens {
_time += TRI_microtime() - start;
if (result == nullptr || ! result->isComplete()) {
if (result != nullptr){
_operationsCounter->incIncompleteFailures(numOperations);
}
_operationsCounter->incFailures(numOperations);
if (result != nullptr) {
delete result;
@ -333,6 +338,13 @@ namespace triagens {
if (errorCount > 0) {
_operationsCounter->incFailures(errorCount);
_warningCount++;
if (_warningCount < MaxWarnings) {
LOG_WARNING("Server side warning count: %lu", errorCount);
if (_verbose) {
LOG_WARNING("Server reply: %s", result->getBody().c_str());
}
}
}
}
}
@ -369,6 +381,7 @@ namespace triagens {
if (result == nullptr || ! result->isComplete()) {
_operationsCounter->incFailures(1);
if (result != nullptr) {
_operationsCounter->incIncompleteFailures(1);
delete result;
}
_warningCount++;
@ -564,6 +577,12 @@ namespace triagens {
static const int MaxWarnings = 5;
////////////////////////////////////////////////////////////////////////////////
/// @brief output replies if error count in http relpy > 0
////////////////////////////////////////////////////////////////////////////////
bool _verbose;
};
}
}

View File

@ -139,12 +139,19 @@ static bool Progress = true;
static string TestCase = "version";
////////////////////////////////////////////////////////////////////////////////
/// @brief print out replies on error
////////////////////////////////////////////////////////////////////////////////
static bool verbose = false;
////////////////////////////////////////////////////////////////////////////////
/// @brief includes all the test cases
////////////////////////////////////////////////////////////////////////////////
#include "Benchmark/test-cases.h"
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
@ -194,6 +201,7 @@ static void ParseProgramOptions (int argc, char* argv[]) {
("complexity", &Complexity, "complexity parameter for the test")
("delay", &Delay, "use a startup delay (necessary only when run in series)")
("progress", &Progress, "show progress")
("verbose", &verbose, "print out replies if the http-header indicates db-errors")
;
BaseClient.setupGeneral(description);
@ -355,7 +363,8 @@ int main (int argc, char* argv[]) {
BaseClient.connectTimeout(),
BaseClient.sslProtocol(),
KeepAlive,
Async);
Async,
verbose);
threads.push_back(thread);
thread->setOffset((size_t) (i * realStep));
@ -412,6 +421,7 @@ int main (int argc, char* argv[]) {
}
size_t failures = operationsCounter.failures();
size_t incomplete = operationsCounter.incompleteFailures();
cout << endl;
cout << "Total number of operations: " << Operations <<
@ -437,6 +447,9 @@ int main (int argc, char* argv[]) {
if (failures > 0) {
cerr << "WARNING: " << failures << " arangob request(s) failed!!" << endl;
}
if (incomplete > 0) {
cerr << "WARNING: " << incomplete << " arangob requests with incomplete results!!" << endl;
}
testCase->tearDown();

View File

@ -1,453 +0,0 @@
/*jshint strict: false */
/*global require, AQL_PARSE, AQL_QUERIES_CURRENT, AQL_QUERIES_SLOW,
AQL_QUERIES_PROPERTIES, AQL_QUERIES_KILL */
////////////////////////////////////////////////////////////////////////////////
/// @brief query actions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var arangodb = require("org/arangodb");
var actions = require("org/arangodb/actions");
var ArangoError = arangodb.ArangoError;
// -----------------------------------------------------------------------------
// --SECTION-- HTTP methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock GetApiQueryCurrent
/// @brief returns a list of currently running AQL queries
///
/// @RESTHEADER{GET /_api/query/current, Returns the currently running AQL queries}
///
/// Returns an array containing the AQL queries currently running in the selected
/// database. Each query is a JSON object with the following attributes:
///
/// - *id*: the query's id
///
/// - *query*: the query string (potentially truncated)
///
/// - *started*: the date and time when the query was started
///
/// - *runTime*: the query's run time up to the point the list of queries was
/// queried
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// Is returned when the list of queries can be retrieved successfully.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request,
///
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock GetApiQuerySlow
/// @brief returns a list of slow running AQL queries
///
/// @RESTHEADER{GET /_api/query/slow, Returns the list of slow AQL queries}
///
/// Returns an array containing the last AQL queries that exceeded the slow
/// query threshold in the selected database.
/// The maximum amount of queries in the list can be controlled by setting
/// the query tracking property `maxSlowQueries`. The threshold for treating
/// a query as *slow* can be adjusted by setting the query tracking property
/// `slowQueryThreshold`.
///
/// Each query is a JSON object with the following attributes:
///
/// - *id*: the query's id
///
/// - *query*: the query string (potentially truncated)
///
/// - *started*: the date and time when the query was started
///
/// - *runTime*: the query's run time up to the point the list of queries was
/// queried
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// Is returned when the list of queries can be retrieved successfully.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request,
///
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock GetApiQueryProperties
/// @brief returns the configuration for the AQL query tracking
///
/// @RESTHEADER{GET /_api/query/properties, Returns the properties for the AQL query tracking}
///
/// Returns the current query tracking configuration. The configuration is a
/// JSON object with the following properties:
///
/// - *enabled*: if set to *true*, then queries will be tracked. If set to
/// *false*, neither queries nor slow queries will be tracked.
///
/// - *trackSlowQueries*: if set to *true*, then slow queries will be tracked
/// in the list of slow queries if their runtime exceeds the value set in
/// *slowQueryThreshold*. In order for slow queries to be tracked, the *enabled*
/// property must also be set to *true*.
///
/// - *maxSlowQueries*: the maximum number of slow queries to keep in the list
/// of slow queries. If the list of slow queries is full, the oldest entry in
/// it will be discarded when additional slow queries occur.
///
/// - *slowQueryThreshold*: the threshold value for treating a query as slow. A
/// query with a runtime greater or equal to this threshold value will be
/// put into the list of slow queries when slow query tracking is enabled.
/// The value for *slowQueryThreshold* is specified in seconds.
///
/// - *maxQueryStringLength*: the maximum query string length to keep in the
/// list of queries. Query strings can have arbitrary lengths, and this property
/// can be used to save memory in case very long query strings are used. The
/// value is specified in bytes.
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// Is returned when the list of queries can be retrieved successfully.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request,
///
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
function get_api_query (req, res) {
var suffixes = [ "slow", "current", "properties" ];
if (req.suffix.length !== 1 ||
suffixes.indexOf(req.suffix[0]) === -1) {
actions.resultNotFound(req,
res,
arangodb.ERROR_HTTP_NOT_FOUND,
arangodb.errors.ERROR_HTTP_NOT_FOUND.message);
return;
}
var result;
if (req.suffix[0] === "slow") {
result = AQL_QUERIES_SLOW();
}
else if (req.suffix[0] === "current") {
result = AQL_QUERIES_CURRENT();
}
else if (req.suffix[0] === "properties") {
result = AQL_QUERIES_PROPERTIES();
}
if (result instanceof ArangoError) {
actions.resultBad(req, res, result.errorNum, result.errorMessage);
return;
}
actions.resultOk(req, res, actions.HTTP_OK, result);
}
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock DeleteApiQuerySlow
/// @brief clears the list of slow AQL queries
///
/// @RESTHEADER{DELETE /_api/query/slow, Clears the list of slow AQL queries}
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{204}
/// The server will respond with *HTTP 200* when the list of queries was
/// cleared successfully.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock DeleteApiQueryKill
/// @brief kills an AQL query
///
/// @RESTHEADER{DELETE /_api/query/{query-id}, Kills a running AQL query}
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// The server will respond with *HTTP 200* when the query was still running when
/// the kill request was executed and the query's kill flag was set.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request.
///
/// @RESTRETURNCODE{404}
/// The server will respond with *HTTP 404* when no query with the specified
/// id was found.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
function delete_api_query (req, res) {
if (req.suffix.length !== 1) {
actions.resultNotFound(req,
res,
arangodb.ERROR_HTTP_NOT_FOUND,
arangodb.errors.ERROR_HTTP_NOT_FOUND.message);
return;
}
if (req.suffix[0] === "slow") {
// erase the slow log
AQL_QUERIES_SLOW(true);
actions.resultOk(req, res, actions.HTTP_NO_CONTENT);
}
else {
// kill a single query
AQL_QUERIES_KILL(req.suffix[0]);
actions.resultOk(req, res, actions.HTTP_OK);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock PutApiQueryProperties
/// @brief changes the configuration for the AQL query tracking
///
/// @RESTHEADER{PUT /_api/query/properties, Changes the properties for the AQL query tracking}
///
/// @RESTBODYPARAM{properties,json,required}
/// The properties for query tracking in the current database.
///
/// The properties need to be passed in the attribute *properties* in the body
/// of the HTTP request. *properties* needs to be a JSON object with the following
/// properties:
///
/// - *enabled*: if set to *true*, then queries will be tracked. If set to
/// *false*, neither queries nor slow queries will be tracked.
///
/// - *trackSlowQueries*: if set to *true*, then slow queries will be tracked
/// in the list of slow queries if their runtime exceeds the value set in
/// *slowQueryThreshold*. In order for slow queries to be tracked, the *enabled*
/// property must also be set to *true*.
///
/// - *maxSlowQueries*: the maximum number of slow queries to keep in the list
/// of slow queries. If the list of slow queries is full, the oldest entry in
/// it will be discarded when additional slow queries occur.
///
/// - *slowQueryThreshold*: the threshold value for treating a query as slow. A
/// query with a runtime greater or equal to this threshold value will be
/// put into the list of slow queries when slow query tracking is enabled.
/// The value for *slowQueryThreshold* is specified in seconds.
///
/// - *maxQueryStringLength*: the maximum query string length to keep in the
/// list of queries. Query strings can have arbitrary lengths, and this property
/// can be used to save memory in case very long query strings are used. The
/// value is specified in bytes.
///
/// After the properties have been changed, the current set of properties will
/// be returned in the HTTP response.
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// Is returned if the properties were changed successfully.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request,
///
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
function put_api_query (req, res) {
if (req.suffix.length !== 1 ||
req.suffix[0] !== "properties") {
actions.resultNotFound(req,
res,
arangodb.ERROR_HTTP_NOT_FOUND,
arangodb.errors.ERROR_HTTP_NOT_FOUND.message);
return;
}
var json = actions.getJsonBody(req, res);
if (json === undefined) {
return;
}
var result = AQL_QUERIES_PROPERTIES(json);
if (result instanceof ArangoError) {
actions.resultBad(req, res, result.errorNum, result.errorMessage);
return;
}
actions.resultOk(req, res, actions.HTTP_OK, result);
}
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_post_api_query
/// @brief parse an AQL query and return information about it
///
/// @RESTHEADER{POST /_api/query, Parse an AQL query}
///
/// @RESTBODYPARAM{query,json,required}
/// To validate a query string without executing it, the query string can be
/// passed to the server via an HTTP POST request.
///
/// The query string needs to be passed in the attribute *query* of a JSON
/// object as the body of the POST request.
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// If the query is valid, the server will respond with *HTTP 200* and
/// return the names of the bind parameters it found in the query (if any) in
/// the *bindVars* attribute of the response. It will also return an array
/// of the collections used in the query in the *collections* attribute.
/// If a query can be parsed successfully, the *ast* attribute of the returned
/// JSON will contain the abstract syntax tree representation of the query.
/// The format of the *ast* is subject to change in future versions of
/// ArangoDB, but it can be used to inspect how ArangoDB interprets a given
/// query. Note that the abstract syntax tree will be returned without any
/// optimizations applied to it.
///
/// @RESTRETURNCODE{400}
/// The server will respond with *HTTP 400* in case of a malformed request,
/// or if the query contains a parse error. The body of the response will
/// contain the error details embedded in a JSON object.
///
/// @EXAMPLES
///
/// Valid query:
///
/// @EXAMPLE_ARANGOSH_RUN{RestQueryValid}
/// var url = "/_api/query";
/// var body = '{ "query" : "FOR p IN products FILTER p.name == @name LIMIT 2 RETURN p.n" }';
///
/// var response = logCurlRequest('POST', url, body);
///
/// assert(response.code === 200);
///
/// logJsonResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
///
/// Invalid query:
///
/// @EXAMPLE_ARANGOSH_RUN{RestQueryInvalid}
/// var url = "/_api/query";
/// var body = '{ "query" : "FOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n" }';
///
/// var response = logCurlRequest('POST', url, body);
///
/// assert(response.code === 400);
///
/// logJsonResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
function post_api_query (req, res) {
if (req.suffix.length !== 0) {
actions.resultNotFound(req,
res,
arangodb.ERROR_HTTP_NOT_FOUND,
arangodb.errors.ERROR_HTTP_NOT_FOUND.message);
return;
}
var json = actions.getJsonBody(req, res);
if (json === undefined) {
return;
}
var result = AQL_PARSE(json.query);
if (result instanceof ArangoError) {
actions.resultBad(req, res, result.errorNum, result.errorMessage);
return;
}
result = {
bindVars: result.parameters,
collections: result.collections,
ast: result.ast
};
actions.resultOk(req, res, actions.HTTP_OK, result);
}
// -----------------------------------------------------------------------------
// --SECTION-- initialiser
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief query actions gateway
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: "_api/query",
callback : function (req, res) {
try {
switch (req.requestType) {
case actions.GET:
get_api_query(req, res);
break;
case actions.PUT:
put_api_query(req, res);
break;
case actions.POST:
post_api_query(req, res);
break;
case actions.DELETE:
delete_api_query(req, res);
break;
default:
actions.resultUnsupported(req, res);
}
}
catch (err) {
actions.resultException(req, res, err, undefined, false);
}
}
});
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -0,0 +1,103 @@
/*jshint strict: true, sub: true */
/*global require, assertTrue, assertFalse, assertEqual, assertNotEqual */
////////////////////////////////////////////////////////////////////////////////
/// @brief test filesystem functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Wilfried Goesgens
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var jsunity = require("jsunity");
// -----------------------------------------------------------------------------
// --SECTION-- filesystem
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief test attributes
////////////////////////////////////////////////////////////////////////////////
function EnvironmentSuite () {
"use strict";
var env = require("process").env;
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief exists() - test if a file / directory exists
////////////////////////////////////////////////////////////////////////////////
testEnv : function () {
assertNotEqual(Object.keys(env).length, 0);
assertFalse(env.hasOwnProperty('UNITTEST'));
env['UNITTEST'] = 1;
assertTrue(env.hasOwnProperty('UNITTEST'));
assertEqual(env['UNITTEST'], 1);
assertEqual(env.UNITTEST, 1);
assertEqual(typeof env.UNITTEST, "string");
delete env.UNITTEST;
assertFalse(env.hasOwnProperty('UNITTEST'));
assertEqual(typeof env.UNITTEST, "undefined");
}
};
}
// -----------------------------------------------------------------------------
// --SECTION-- main
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suite
////////////////////////////////////////////////////////////////////////////////
jsunity.run(EnvironmentSuite);
return jsunity.done();
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
// End:

View File

@ -1,5 +1,5 @@
/*jshint esnext: true, strict: false, unused: false, -W051: true */
/*global require */
/*global require, exports */
exports.env = require("internal").env;
exports.stdout = {
isTTY: false

View File

@ -71,6 +71,8 @@ var optionsDocumentation = [
' - `jasmineReportFormat`: this option is passed on to the `format`',
' option of the Jasmine options object, only for Jasmine tests.',
'',
' - benchargs : additional commandline arguments to arangob',
'',
' - `valgrind`: if set to true the arangods are run with the valgrind',
' memory checker',
' - `valgrindXmlFileBase`: string to prepend to the xml report name',
@ -177,6 +179,10 @@ function printUsage () {
}
function filterTestcaseByOptions (testname, options, whichFilter) {
if (options.hasOwnProperty('test')) {
whichFilter.filter = "testcase";
return testname === options.test;
}
if ((testname.indexOf("-cluster") !== -1) && (options.cluster === false)) {
whichFilter.filter = 'noncluster';
return false;
@ -1362,14 +1368,20 @@ function runArangoDumpRestore (options, instanceInfo, which, database) {
}
function runArangoBenchmark (options, instanceInfo, cmds) {
var args = ["--configuration", "none",
"--quiet",
"--server.username", options.username,
"--server.password", options.password,
"--server.endpoint", instanceInfo.endpoint];
args = args.concat(cmds);
var args = {
"configuration": "none",
"server.username": options.username,
"server.password": options.password,
"server.endpoint": instanceInfo.endpoint,
};
args = _.extend(args, cmds);
if (!args.hasOwnProperty('verbose')) {
args.quiet = "true";
}
var exe = fs.join("bin","arangob");
return executeAndWait(exe, args);
return executeAndWait(exe, toArgv(args));
}
var impTodo = [
@ -1575,24 +1587,23 @@ testFuncs.dump = function (options) {
};
var benchTodo = [
["--requests","10000","--concurrency","2","--test","version", "--keep-alive","false"],
["--requests","10000","--concurrency","2","--test","version", "--async","true"],
["--requests","20000","--concurrency","1","--test","version", "--async","true"],
["--requests","100000","--concurrency","2","--test","shapes", "--batch-size","16", "--complexity","2"],
["--requests","100000","--concurrency","2","--test","shapes-append", "--batch-size","16", "--complexity","4"],
["--requests","100000","--concurrency","2","--test","random-shapes", "--batch-size","16", "--complexity","2"],
["--requests","1000","--concurrency","2","--test","version", "--batch-size", "16"],
["--requests","100","--concurrency","1","--test","version", "--batch-size", "0"],
["--requests","100","--concurrency","2","--test","document", "--batch-size",
"10", "--complexity", "1"],
["--requests","2000","--concurrency","2","--test","crud", "--complexity", "1"],
["--requests","4000","--concurrency","2","--test","crud-append", "--complexity", "4"],
["--requests","4000","--concurrency","2","--test","edge", "--complexity", "4"],
["--requests","5000","--concurrency","2","--test","hash","--complexity","1"],
["--requests","5000","--concurrency","2","--test","skiplist","--complexity","1"],
["--requests","500","--concurrency","3","--test","aqltrx","--complexity","1"],
["--requests","100","--concurrency","3","--test","counttrx"],
["--requests","500","--concurrency","3","--test","multitrx"]
{"requests":"10000", "concurrency":"2", "test":"version", "keep-alive":"false"},
{"requests":"10000", "concurrency":"2", "test":"version", "async":"true"},
{"requests":"20000", "concurrency":"1", "test":"version", "async":"true"},
{"requests":"100000","concurrency":"2", "test":"shapes", "batch-size":"16", "complexity":"2"},
{"requests":"100000","concurrency":"2", "test":"shapes-append", "batch-size":"16", "complexity":"4"},
{"requests":"100000","concurrency":"2", "test":"random-shapes", "batch-size":"16", "complexity":"2"},
{"requests":"1000", "concurrency":"2", "test":"version", "batch-size":"16"},
{"requests":"100", "concurrency":"1", "test":"version", "batch-size": "0"},
{"requests":"100", "concurrency":"2", "test":"document", "batch-size":"10", "complexity":"1"},
{"requests":"2000", "concurrency":"2", "test":"crud", "complexity":"1"},
{"requests":"4000", "concurrency":"2", "test":"crud-append", "complexity":"4"},
{"requests":"4000", "concurrency":"2", "test":"edge", "complexity":"4"},
{"requests":"5000", "concurrency":"2", "test":"hash", "complexity":"1"},
{"requests":"5000", "concurrency":"2", "test":"skiplist", "complexity":"1"},
{"requests":"500", "concurrency":"3", "test":"aqltrx", "complexity":"1"},
{"requests":"100", "concurrency":"3", "test":"counttrx"},
{"requests":"500", "concurrency":"3", "test":"multitrx"}
];
testFuncs.arangob = function (options) {
@ -1617,8 +1628,11 @@ testFuncs.arangob = function (options) {
instanceInfo.exitStatus = "server is gone.";
continue;
}
r = runArangoBenchmark(options, instanceInfo, benchTodo[i]);
var args = benchTodo[i];
if (options.hasOwnProperty('benchargs')) {
args = _.extend(args, options.benchargs);
}
r = runArangoBenchmark(options, instanceInfo, args);
results[i] = r;
continueTesting = checkInstanceAlive(instanceInfo, options);

View File

@ -53,15 +53,29 @@ RestBaseHandler::RestBaseHandler (HttpRequest* request)
}
// -----------------------------------------------------------------------------
// --SECTION-- HttpHandler methods
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
void RestBaseHandler::handleError (TriagensError const& error) {
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::handleError (const TriagensError& error) {
generateError(HttpResponse::SERVER_ERROR,
TRI_ERROR_INTERNAL,
DIAGNOSTIC_INFORMATION(error));
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::handleError (const Exception& error) {
generateError(HttpResponse::responseCode(error.code()),
error.code(),
DIAGNOSTIC_INFORMATION(error));
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------

View File

@ -63,7 +63,7 @@ namespace triagens {
RestBaseHandler (rest::HttpRequest* request);
// -----------------------------------------------------------------------------
// --SECTION-- HttpHandler methods
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
public:
@ -74,6 +74,12 @@ namespace triagens {
void handleError (basics::TriagensError const&);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void handleError (basics::Exception const&);
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------

View File

@ -985,7 +985,7 @@ bool ApplicationServer::readConfigurationFile () {
}
}
else {
LOG_DEBUG("no system init override file '%s' found", sysDir.c_str());
LOG_DEBUG("no system init override file '%s' found", localSysDir.c_str());
}
// check and see if file exists

View File

@ -32,10 +32,24 @@
using namespace std;
using namespace triagens::basics;
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief controls if backtraces are printed with exceptions
////////////////////////////////////////////////////////////////////////////////
static bool WithBackTrace = false;
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- class TriagensError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief base class for all errors
////////////////////////////////////////////////////////////////////////////////
@ -57,20 +71,27 @@ TriagensError::TriagensError (string const& type, string const& details, char co
TRI_GetBacktrace(_message);
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
TriagensError::~TriagensError () throw () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the error messages
////////////////////////////////////////////////////////////////////////////////
char const * TriagensError::what () const throw() {
return _message.c_str();
}
// -----------------------------------------------------------------------------
// --SECTION-- class InternalError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for internal errors
////////////////////////////////////////////////////////////////////////////////
@ -79,12 +100,25 @@ InternalError::InternalError (string const& details, char const* file, int line)
: TriagensError("internal error", details, file, line) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for internal errors
////////////////////////////////////////////////////////////////////////////////
InternalError::InternalError (std::exception const& ex, char const* file, int line)
: TriagensError("internal exception", ex.what(), file, line) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
InternalError::~InternalError () throw () {
}
// -----------------------------------------------------------------------------
// --SECTION-- class OutOfMemoryError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for out-of-memory errors
////////////////////////////////////////////////////////////////////////////////
@ -93,6 +127,17 @@ OutOfMemoryError::OutOfMemoryError (char const* file, int line)
: TriagensError("out-of-memory", "", file, line) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
OutOfMemoryError::~OutOfMemoryError () throw () {
}
// -----------------------------------------------------------------------------
// --SECTION-- class FileError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for file errors
////////////////////////////////////////////////////////////////////////////////
@ -122,12 +167,16 @@ FileError::FileError (string const& func,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
FileError::~FileError () throw () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the filename
////////////////////////////////////////////////////////////////////////////////
void FileError::setFilename (string const& filename) {
_filename = filename;
@ -137,6 +186,10 @@ void FileError::setFilename (string const& filename) {
}
}
// -----------------------------------------------------------------------------
// --SECTION-- class ParseError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for parse errors
////////////////////////////////////////////////////////////////////////////////
@ -152,7 +205,16 @@ ParseError::ParseError (string const& details,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
ParseError::~ParseError () throw () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sets the line number
////////////////////////////////////////////////////////////////////////////////
void ParseError::setLineNumber (int lineNumber) {
_lineNumber = lineNumber;
@ -162,6 +224,10 @@ void ParseError::setLineNumber (int lineNumber) {
}
}
// -----------------------------------------------------------------------------
// --SECTION-- class ParameterError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for parameter errors
////////////////////////////////////////////////////////////////////////////////
@ -181,11 +247,160 @@ ParameterError::ParameterError (string const& parameter,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
ParameterError::~ParameterError () throw () {
}
// -----------------------------------------------------------------------------
// --SECTION-- class Exception
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief controls whether a backtrace is created for each exception
////////////////////////////////////////////////////////////////////////////////
void Exception::SetVerbose (bool verbose) {
WithBackTrace = verbose;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor, without format string
////////////////////////////////////////////////////////////////////////////////
Exception::Exception (int code,
char const* file,
int line)
: _errorMessage(TRI_errno_string(code)),
_file(file),
_line(line),
_code(code) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
#if HAVE_BACKTRACE
if (WithBackTrace) {
_errorMessage += std::string("\n\n");
TRI_GetBacktrace(_errorMessage);
_errorMessage += std::string("\n\n");
}
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the error message
////////////////////////////////////////////////////////////////////////////////
string Exception::message () const throw () {
return _errorMessage;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the error code
////////////////////////////////////////////////////////////////////////////////
int Exception::code () const throw () {
return _code;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief adds to the message
////////////////////////////////////////////////////////////////////////////////
void Exception::addToMessage (string More) {
_errorMessage += More;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor, for creating an exception with an already created
/// error message (normally based on error templates containing %s, %d etc.)
////////////////////////////////////////////////////////////////////////////////
Exception::Exception (int code,
string const& errorMessage,
char const* file,
int line)
: _errorMessage(errorMessage),
_file(file),
_line(line),
_code(code) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
#if HAVE_BACKTRACE
if (WithBackTrace) {
_errorMessage += std::string("\n\n");
TRI_GetBacktrace(_errorMessage);
_errorMessage += std::string("\n\n");
}
#endif
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
Exception::~Exception () throw () {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return exception message
////////////////////////////////////////////////////////////////////////////////
const char* Exception::what () const throw () {
return _errorMessage.c_str();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct an error message from a template string
////////////////////////////////////////////////////////////////////////////////
std::string Exception::FillExceptionString (int code, ...) {
char const* format = TRI_errno_string(code);
TRI_ASSERT(format != nullptr);
#ifdef TRI_ENABLE_MAINTAINER_MODE
// Obviously the formatstring of the error code has to support parameters.
TRI_ASSERT(strchr(format, '%') != nullptr);
#endif
char buffer[1024];
va_list ap;
va_start(ap, code);
vsnprintf(buffer, sizeof(buffer) - 1, format, ap);
va_end(ap);
buffer[sizeof(buffer) - 1] = '\0'; // Windows
return std::string(buffer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct an error message from a template string
////////////////////////////////////////////////////////////////////////////////
std::string Exception::FillFormatExceptionString (char const* format, ...) {
TRI_ASSERT(format != nullptr);
#ifdef TRI_ENABLE_MAINTAINER_MODE
// Format #1 should come from the macro...
TRI_ASSERT(strchr(format, '%') != nullptr);
// Obviously the user has to give us a format string.
TRI_ASSERT(strchr(strchr(format, '%'), '%') != nullptr);
#endif
char buffer[1024];
va_list ap;
va_start(ap, format);
vsnprintf(buffer, sizeof(buffer) - 1, format, ap);
va_end(ap);
buffer[sizeof(buffer) - 1] = '\0'; // Windows
return std::string(buffer);
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +23,8 @@
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Jan Steemann
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
@ -130,6 +131,48 @@
#define THROW_PARAMETER_ERROR(parameter, details, func) \
throw triagens::basics::ParameterError(parameter, details, func, __FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION(code) \
throw triagens::basics::Exception(code, __FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and arbitrary
/// arguments (to be inserted in printf-style manner)
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_PARAMS(code, ...) \
throw triagens::basics::Exception( \
code, \
triagens::basics::Exception::FillExceptionString( \
code, \
__VA_ARGS__), \
__FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and arbitrary
/// arguments (to be inserted in printf-style manner)
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_FORMAT(code, format, ...) \
throw triagens::basics::Exception( \
code, \
triagens::basics::Exception::FillFormatExceptionString( \
"%s: " format, \
TRI_errno_string(code), \
__VA_ARGS__), \
__FILE__, __LINE__)
////////////////////////////////////////////////////////////////////////////////
/// @brief throws an arango exception with an error code and an already-built
/// error message
////////////////////////////////////////////////////////////////////////////////
#define THROW_ARANGO_EXCEPTION_MESSAGE(code, message) \
throw triagens::basics::Exception(code, message, __FILE__, __LINE__)
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
@ -137,6 +180,10 @@
namespace triagens {
namespace basics {
// -----------------------------------------------------------------------------
// --SECTION-- class TriagensError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief base class for all errors
////////////////////////////////////////////////////////////////////////////////
@ -161,6 +208,10 @@ namespace triagens {
int _line;
};
// -----------------------------------------------------------------------------
// --SECTION-- class InternalError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for internal errors
////////////////////////////////////////////////////////////////////////////////
@ -169,8 +220,14 @@ namespace triagens {
public:
InternalError (std::string const& details, char const* file, int line);
InternalError (std::exception const& ex, char const* file, int line);
~InternalError () throw ();
};
// -----------------------------------------------------------------------------
// --SECTION-- class OutOfMemoryError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for out-of-memory errors
////////////////////////////////////////////////////////////////////////////////
@ -178,8 +235,14 @@ namespace triagens {
class OutOfMemoryError : public TriagensError {
public:
OutOfMemoryError (char const* file, int line);
~OutOfMemoryError () throw ();
};
// -----------------------------------------------------------------------------
// --SECTION-- class FileError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for file errors
////////////////////////////////////////////////////////////////////////////////
@ -206,6 +269,10 @@ namespace triagens {
int _error;
};
// -----------------------------------------------------------------------------
// --SECTION-- class ParseError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for parse errors
////////////////////////////////////////////////////////////////////////////////
@ -217,6 +284,8 @@ namespace triagens {
char const* file,
int line);
~ParseError () throw ();
public:
void setLineNumber (int);
@ -224,6 +293,10 @@ namespace triagens {
int _lineNumber;
};
// -----------------------------------------------------------------------------
// --SECTION-- class ParameterError
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief exception for parameter errors
////////////////////////////////////////////////////////////////////////////////
@ -242,6 +315,45 @@ namespace triagens {
std::string _parameter;
std::string _func;
};
// -----------------------------------------------------------------------------
// --SECTION-- class Exception
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief arango exception type
////////////////////////////////////////////////////////////////////////////////
class Exception : public virtual std::exception {
public:
static std::string FillExceptionString (int, ...);
static std::string FillFormatExceptionString (char const * format, ...);
static void SetVerbose (bool);
public:
Exception (int code,
char const* file,
int line);
Exception (int code,
std::string const& errorMessage,
char const* file,
int line);
~Exception () throw ();
public:
char const * what () const throw ();
std::string message () const throw ();
int code () const throw ();
void addToMessage (std::string More);
protected:
std::string _errorMessage;
char const* _file;
int const _line;
int const _code;
};
}
}

View File

@ -297,7 +297,7 @@ bool JsonHelper::checkAndGetBooleanValue (TRI_json_t const* json,
if (! isBoolean(sub)) {
std::string msg = "The attribute '" + std::string(name)
+ "' was not found or is not a boolean.";
THROW_INTERNAL_ERROR(msg);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return sub->_value._boolean;
@ -315,7 +315,7 @@ std::string JsonHelper::checkAndGetStringValue (TRI_json_t const* json,
if (! isString(sub)) {
std::string msg = "The attribute '" + std::string(name)
+ "' was not found or is not a string.";
THROW_INTERNAL_ERROR(msg);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return string(sub->_value._string.data, sub->_value._string.length - 1);
}
@ -332,7 +332,7 @@ TRI_json_t const* JsonHelper::checkAndGetObjectValue (TRI_json_t const* json,
if (! isObject(sub)) {
std::string msg = "The attribute '" + std::string(name)
+ "' was not found or is not an object.";
THROW_INTERNAL_ERROR(msg);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return sub;
@ -350,7 +350,7 @@ TRI_json_t const* JsonHelper::checkAndGetArrayValue (TRI_json_t const* json,
if (! isArray(sub)) {
std::string msg = "The attribute '" + std::string(name)
+ "' was not found or is not an array.";
THROW_INTERNAL_ERROR(msg);
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return sub;

View File

@ -72,7 +72,11 @@ namespace {
return status_t(HANDLER_DONE);
};
void handleError (TriagensError const& error) {
void handleError (const TriagensError& error) {
_response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);
};
void handleError (const Exception& error) {
_response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);
};
};

View File

@ -204,7 +204,11 @@ namespace triagens {
void PathHandler::handleError (TriagensError const&) {
void PathHandler::handleError (const TriagensError&) {
_response = createResponse(HttpResponse::SERVER_ERROR);
}
void PathHandler::handleError (const Exception&) {
_response = createResponse(HttpResponse::SERVER_ERROR);
}
}

View File

@ -108,7 +108,13 @@ namespace triagens {
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void handleError (basics::TriagensError const&);
void handleError (const basics::TriagensError&);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void handleError (const basics::Exception&);
private:
std::string path;

View File

@ -187,7 +187,13 @@ namespace triagens {
/// @brief handles error
////////////////////////////////////////////////////////////////////////////////
virtual void handleError (basics::TriagensError const&) = 0;
virtual void handleError (const basics::TriagensError&) = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief handles error
////////////////////////////////////////////////////////////////////////////////
virtual void handleError (const basics::Exception&) = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a job

View File

@ -190,6 +190,53 @@ HttpResponse::HttpResponseCode HttpResponse::responseCode (const string& str) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get http response code from integer error code
////////////////////////////////////////////////////////////////////////////////
HttpResponse::HttpResponseCode HttpResponse::responseCode (int code) {
TRI_ASSERT(code != TRI_ERROR_NO_ERROR);
switch (code) {
case TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD:
case TRI_ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED:
case TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID:
case TRI_ERROR_BAD_PARAMETER:
case TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES:
case TRI_ERROR_CLUSTER_MUST_NOT_SPECIFY_KEY:
return BAD;
case TRI_ERROR_ARANGO_READ_ONLY:
return FORBIDDEN;
case TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND:
case TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND:
return NOT_FOUND;
case TRI_ERROR_REQUEST_CANCELED:
case TRI_ERROR_QUERY_KILLED:
return REQUEST_TIMEOUT;
case TRI_ERROR_ARANGO_CONFLICT:
case TRI_ERROR_ARANGO_GEO_INDEX_VIOLATED:
case TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED:
return CONFLICT;
case TRI_ERROR_ARANGO_OUT_OF_KEYS:
case TRI_ERROR_CLUSTER_SHARD_GONE:
case TRI_ERROR_CLUSTER_TIMEOUT:
return SERVER_ERROR;
case TRI_ERROR_CLUSTER_UNSUPPORTED:
return NOT_IMPLEMENTED;
case TRI_ERROR_OUT_OF_MEMORY:
case TRI_ERROR_INTERNAL:
default:
return SERVER_ERROR;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the batch error count header
////////////////////////////////////////////////////////////////////////////////

View File

@ -150,6 +150,12 @@ namespace triagens {
static HttpResponseCode responseCode (std::string const& str);
////////////////////////////////////////////////////////////////////////////////
/// @brief get http response code from integer error code
////////////////////////////////////////////////////////////////////////////////
static HttpResponseCode responseCode (int);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the batch response error count header
////////////////////////////////////////////////////////////////////////////////

View File

@ -28,10 +28,17 @@
#ifdef _WIN32
#include "Basics/win-utils.h"
#endif
#else
#include "v8-utils.h"
#ifdef __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#elif !defined(_MSC_VER)
extern char **environ;
#endif
#endif
static void EnvGetter(v8::Local<v8::String> property,