mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into data-modification
This commit is contained in:
commit
c62c26e088
|
@ -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)
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'.
|
||||
"
|
|
@ -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
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
/etc/init.d/arangodb stop
|
|
@ -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
108
README
|
@ -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 won’t 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.
|
||||
We’ve 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’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/} }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "Aql/BindParameters.h"
|
||||
#include "Basics/json.h"
|
||||
#include "Utils/Exception.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/Function.h"
|
||||
#include "Utils/Exception.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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&) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/Scopes.h"
|
||||
#include "Utils/Exception.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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, ¶meters, doSync);
|
||||
}
|
||||
catch (triagens::arango::Exception const& ex) {
|
||||
catch (triagens::basics::Exception const& ex) {
|
||||
return ex.code();
|
||||
}
|
||||
catch (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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&) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -81,7 +81,13 @@ namespace triagens {
|
|||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void handleError (basics::TriagensError const&);
|
||||
void handleError (const basics::TriagensError&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// {@inheritDoc}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void handleError (const basics::Exception&);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
|
@ -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:
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
|
@ -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:
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 (...) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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:
|
|
@ -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:
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue