diff --git a/.gitignore b/.gitignore index 24524e3609..0179c7cf6a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,12 @@ core TAGS tags +Documentation/Examples/*.generated +Documentation/Books/Users/book.json +Documentation/Books/Users/manual.epub +Documentation/Books/Users/manual.mobi +Documentation/Books/Users/manual.pdf +Documentation/Books/Makefile Documentation/Examples/*.generated UnitTests/HttpInterface/logs/ UnitTests/basics_suite diff --git a/CHANGELOG b/CHANGELOG index f405dcf4e0..55a1aa3fb0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,48 @@ -v2.3.0 (XXXX-XX-XX) +v2.4.0 (XXXX-XX-XX) ------------------- +* fixed non-working subquery index optimizations + +* do not restrict summary of Foxx applications to 60 characters + +* fixed display of "required" path parameters in Foxx application documentation + +* added more optimizations of constants values in AQL FILTER conditions + +* fixed invalid or-to-in optimization for FILTERs containing comparisons + with boolean values + +* fixed replication of `_graphs` collection + +* added AQL list functions `PUSH`, `POP`, `UNSHIFT`, `SHIFT`, `REMOVE_VALUES`, + `REMOVE_VALUE`, `REMOVE_NTH` and `APPEND` + +* added AQL functions `CALL` and `APPLY` to dynamically call other functions + +* fixed AQL optimizer cost estimation for LIMIT node + +* prevent Foxx queues from permanently writing to the journal even when + server is idle + + +v2.3.0 (2014-11-18) +------------------- + +* fixed syslog flags. `--log.syslog` is deprecated and setting it has no effect, + `--log.facility` now works as described. Application name has been changed from + `triagens` to `arangod`. It can be changed using `--log.application`. The syslog + will only contain the actual log message. The datetime prefix is omiited. + +* fixed deflate in SimpleHttpClient + +* fixed issue #1104: edgeExamples broken or changed + +* fixed issue #1103: Error while importing user queries + +* fixed issue #1100: AQL: HAS() fails on doc[attribute_name] + +* fixed issue #1098: runtime error when creating graph vertex + * hide system applications in **Applications** tab by default Display of system applications can be toggled by using the *system applications* @@ -20,10 +62,14 @@ v2.3.0 (XXXX-XX-XX) * added AQL string functions `LTRIM`, `RTRIM`, `FIND_FIRST`, `FIND_LAST`, `SPLIT`, `SUBSTITUTE` -* added AQL functions `ASSEMBLE` and `VALUES` +* added AQL functions `ZIP`, `VALUES` and `PERCENTILE` * made AQL functions `CONCAT` and `CONCAT_SEPARATOR` work with list arguments +* dynamically create extra dispatcher threads if required + +* fixed issue #1097: schemas in the API docs no longer show required properties as optional + v2.3.0-beta2 (2014-11-08) ------------------------- @@ -117,22 +163,23 @@ v2.3.0-beta1 (2014-11-01) V8 contexts created in arangod. Previously, the number of V8 contexts was equal to the number of server threads - (as specified by option `--server.threads`). However, it may be sensible to - create different amounts of threads and V8 contexts. If the option is not - specified, the number of V8 contexts created will be equal to the number of - server threads. Thus no change in configuration is required to keep the old - behavior. - - However, the default configuration files shipped with ArangoDB have been changed. - The number of server threads has been increased in the configuration files, and - the number of V8 contexts is now explicitly set in the configuration files (to - the same value as the number of server threads was set to in 2.2). + (as specified by option `--server.threads`). - If you are using the default config files or merge them with your local config files, - please review if the higher default number of server threads is okay in your + However, it may be sensible to create different amounts of threads and V8 + contexts. If the option is not specified, the number of V8 contexts created + will be equal to the number of server threads. Thus no change in configuration + is required to keep the old behavior. + + If you are using the default config files or merge them with your local config + files, please review if the default number of server threads is okay in your environment. Additionally you should verify that the number of V8 contexts created (as specified in option `--javascript.v8-contexts`) is okay. +* the number of server.threads specified is now the minimum of threads + started. There are situation in which threads are waiting for results of + distributed database servers. In this case the number of threads is + dynamically increased. + * removed index type "bitarray" Bitarray indexes were only half-way documented and integrated in previous versions @@ -307,7 +354,7 @@ v2.3.0-beta1 (2014-11-01) storing JavaScript date objects in the database in a sensible manner. -v2.2.7 (XXXX-XX-XX) +v2.2.7 (2014-11-19) ------------------- * fixed issue #998: Incorrect application URL for non-system Foxx apps diff --git a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp index 7dbe93d558..5d9ee26641 100644 --- a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp +++ b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp @@ -94,15 +94,14 @@ AQL supports the following functions to operate on document values: as a list. If *removeInternal* is set to *true*, then all internal attributes (such as *_id*, *_key* etc.) are removed from the result. -- *ASSEMBLE(attributes, values)*: Returns a document object assembled from the +- *ZIP(attributes, values)*: Returns a document object assembled from the separate parameters *attributes* and *values*. *attributes* and *values* must be lists and must have the same length. The items in *attributes* will be used for naming the attributes in the result. The items in *values* will be used as the actual values of the result. /* { "name" : "some user", "active" : true, "hobbies" : [ "swimming", "riding" ] } */ - ASSEMBLE([ 'name', 'active', 'hobbies' ], - [ 'some user', true, [ 'swimming', 'riding' ] ]) + ZIP([ 'name', 'active', 'hobbies' ], [ 'some user', true, [ 'swimming', 'riding' ] ]) - *UNSET(document, attributename, ...)*: Removes the attributes *attributename* (can be one or many) from *document*. All other attributes will be preserved. diff --git a/Documentation/Books/Users/Aql/Invoke.mdpp b/Documentation/Books/Users/Aql/Invoke.mdpp index f7073b7df0..c4fe63e826 100644 --- a/Documentation/Books/Users/Aql/Invoke.mdpp +++ b/Documentation/Books/Users/Aql/Invoke.mdpp @@ -35,6 +35,8 @@ return an empty list. To retrieve statistics for a data-modification query, use "warnings" : [ ] } +The meaning of the statistics values is described below. + The *_query* method is a shorthand for creating an ArangoStatement object, executing it and iterating over the resulting cursor. If more control over the result set iteration is needed, it is recommended to first create an @@ -134,6 +136,43 @@ on the server-side and may be able to apply optimizations if a result set is not a client. +!SECTION Query statistics + +A query that has been executed will always return execution statistics. Execution statistics +can be retrieved by calling `getExtra()` on the cursor. The statistics are returned in the +return value's `stats` attribute: + + arangosh> db._query("FOR i IN 1..100 INSERT { _key: CONCAT('test', TO_STRING(i)) } INTO mycollection").getExtra(); + { + "stats" : { + "writesExecuted" : 100, + "writesIgnored" : 0, + "scannedFull" : 0, + "scannedIndex" : 0 + }, + "warnings" : [ ] + } + +The meaning of the statistics attributes is as follows: + +* *writesExecuted*: the total number of data-modification operations successfully executed. + This is equivalent to the number of documents created, updated or removed by `INSERT`, + `UPDATE`, `REPLACE` or `REMOVE` operations. +* *writesIgnored*: the total number of data-modification operations that were unsuccessful, + but have been ignored because of query option `ignoreErrors`. +* *scannedFull*: the total number of documents iterated over when scanning a collection + without an index. Documents scanned by sub-queries will be included in the result, but not + no operations triggered by built-in or user-defined AQL functions. +* *scannedIndex*: the total number of documents iterated over when scanning a collection using + an index. Documents scanned by sub-queries will be included in the result, but not + no operations triggered by built-in or user-defined AQL functions. +* *fullCount*: the total number of documents that matched the search condition if the query's + final `LIMIT` statement were not present. + This attribute will only be returned if the `fullCount` option was set when starting the + query and will only contain a sensible value if the query contained a `LIMIT` operation on + the top level. + + !SECTION Explaining queries If it is unclear how a given query will perform, clients can retrieve a query's execution from @@ -153,7 +192,7 @@ is a list of warnings that occurred during optimization or execution plan creati Each plan in the result is an object with the following attributes: - *nodes*: the list of execution nodes of the plan. The list of available node types - can be found [here](.../Aql/Optimizer.html) + can be found [here](../Aql/Optimizer.html) - *estimatedCost*: the total estimated cost for the plan. If there are multiple plans, the optimizer will choose the plan with the lowest total cost. - *collections*: a list of collections used in the query diff --git a/Documentation/Books/Users/Aql/ListFunctions.mdpp b/Documentation/Books/Users/Aql/ListFunctions.mdpp index 7b297104cf..8070c50624 100644 --- a/Documentation/Books/Users/Aql/ListFunctions.mdpp +++ b/Documentation/Books/Users/Aql/ListFunctions.mdpp @@ -48,6 +48,12 @@ AQL supports the following functions to operate on list values: list is empty or only *null* values are contained in the list, the function will return *null*. +- *PERCENTILE(list, n, method)*: Returns the *n*th percentile of the values in *list*. + This requires the elements in *list* to be numbers. *null* values are ignored. *n* must + be between 0 (excluded) and 100 (included). *method* can be *rank* or *interpolation*. + The function will return null if the list is empty or only *null* values are contained + in it or the percentile cannot be calculated. + - *VARIANCE_POPULATION(list)*: Returns the population variance of the values in *list*. This requires the elements in *list* to be numbers. *null* values are ignored. If the list is empty or only *null* values are contained in the list, @@ -167,6 +173,85 @@ AQL supports the following functions to operate on list values: Note: Duplicates will be removed. +- *APPEND(list, values, unique)*: Adds all elements from the list *values* to the list + specified by *list*. If *unique* is set to true, then only those *values* will be added + that are not already contained in *list*. + The modified list is returned. All values are added at the end of the list (right side). + + /* [ 1, 2, 3, 5, 6, 9 ] */ + APPEND([ 1, 2, 3 ], [ 5, 6, 9 ]) + + /* [ 1, 2, 3, 4, 5, 9 ] */ + APPEND([ 1, 2, 3 ], [ 3, 4, 5, 2, 9 ], true) + +- *PUSH(list, value, unique)*: Adds *value* to the list specified by *list*. If + *unique* is set to true, then *value* is not added if already present in the list. + The modified list is returned. The value is added at the end of the list (right side). + + Note: non-unique elements will not be removed from the list if they were already present + before the call to `PUSH`. The *unique* flag will only control if the value will + be added again to the list if already present. To make a list unique, use the `UNIQUE` + function. + + /* [ 1, 2, 3, 4 ] */ + PUSH([ 1, 2, 3 ], 4) + + /* [ 1, 2, 3 ] */ + PUSH([ 1, 2, 3 ], 2, true) + +- *UNSHIFT(list, value, unique)*: Adds *value* to the list specified by *list*. If + *unique* is set to true, then *value* is not added if already present in the list. + The modified list is returned. The value is added at the start of the list (left side). + + Note: non-unique elements will not be removed from the list if they were already present + before the call to `UNSHIFT`. The *unique* flag will only control if the value will + be added again to the list if already present. To make a list unique, use the `UNIQUE` + function. + + /* [ 4, 1, 2, 3 ] */ + UNSHIFT([ 1, 2, 3 ], 4) + + /* [ 1, 2, 3 ] */ + UNSHIFT([ 1, 2, 3 ], 2, true) + +- *POP(list)*: Removes the element at the end (right side) of *list*. The modified list + is returned. If the list is already empty or *null*, an empty list is returned. + + /* [ 1, 2, 3 ] */ + POP([ 1, 2, 3, 4 ]) + +- *SHIFT(list)*: Removes the element at the start (left side) of *list*. The modified list + is returned. If the list is already empty or *null*, an empty list is returned. + + /* [ 2, 3, 4 ] */ + SHIFT([ 1, 2, 3, 4 ]) + +- *REMOVE_VALUE(list, value, limit)*: Removes all occurrences of *value* in the list + specified by *list*. If the optional *limit* is specified, only *limit* occurrences + will be removed. + + /* [ "b", "b", "c" ] */ + REMOVE_VALUE([ "a", "b", "b", "a", "c" ], "a") + + /* [ "b", "b", "a", "c" ] */ + REMOVE_VALUE([ "a", "b", "b", "a", "c" ], "a", 1) + +- *REMOVE_VALUES(list, values)*: Removes all occurrences of any of the values specified + in list *values* from the list specified by *list*. + + /* [ "b", "c", "e", "g" ] */ + REMOVE_VALUES([ "a", "b", "c", "d", "e", "f", "g" ], [ "a", "f", "d" ]) + +- *REMOVE_NTH(list, position)*: Removes the element at position *position* from the + list specified by *list*. Positions start at 0. Negative positions are supported, + with -1 being the last list element. If *position* is out of bounds, the list is + returned unmodified. Otherwise, the modified list is returned. + + /* [ "a", "c", "d", "e" ] */ + REMOVE_NTH([ "a", "b", "c", "d", "e" ], 1) + + /* [ "a", "b", "c", "e" ] */ + REMOVE_NTH([ "a", "b", "c", "d", "e" ], -2) Apart from these functions, AQL also offers several language constructs (e.g. -*FOR*, *SORT*, *LIMIT*, *COLLECT*) to operate on lists. \ No newline at end of file +*FOR*, *SORT*, *LIMIT*, *COLLECT*) to operate on lists. diff --git a/Documentation/Books/Users/Aql/MiscellaneousFunctions.mdpp b/Documentation/Books/Users/Aql/MiscellaneousFunctions.mdpp index ed7a88dc0e..172cd57232 100644 --- a/Documentation/Books/Users/Aql/MiscellaneousFunctions.mdpp +++ b/Documentation/Books/Users/Aql/MiscellaneousFunctions.mdpp @@ -66,3 +66,17 @@ function categories: as in the index. If no suitable skiplist index is found, an error will be raised and the query will be aborted. +- *CALL(function, arg1, ..., argn)*: Dynamically calls the function with name *function* + with the arguments specified. Both built-in and user-defined functions can be called. + Arguments are passed as seperate parameters to the called function. + + /* "this" */ + CALL('SUBSTRING', 'this is a test', 0, 4) + +- *APPLY(function, arguments)*: Dynamically calls the function with name *function* + with the arguments specified. Both built-in and user-defined functions can be called. + Arguments are passed as seperate parameters to the called function. + + /* "this is" */ + APPLY('SUBSTRING', [ 'this is a test', 0, 7 ]) + diff --git a/Documentation/Books/Users/Aql/StringFunctions.mdpp b/Documentation/Books/Users/Aql/StringFunctions.mdpp index 42464e779e..17d316be99 100644 --- a/Documentation/Books/Users/Aql/StringFunctions.mdpp +++ b/Documentation/Books/Users/Aql/StringFunctions.mdpp @@ -17,10 +17,10 @@ For string processing, AQL offers the following functions: *separator* string. *null* values are ignored. List value arguments are expanded automatically, and their individual members will be concatenated. - /* "foo,bar,baz" */ + /* "foo, bar, baz" */ CONCAT_SEPARATOR(', ', 'foo', 'bar', 'baz') - /* "foo,bar,baz" */ + /* "foo, bar, baz" */ CONCAT_SEPARATOR(', ', [ 'foo', 'bar', 'baz' ]) - *CHAR_LENGTH(value)*: Return the number of characters in *value*. This is @@ -88,7 +88,7 @@ For string processing, AQL offers the following functions: TRIM(" foobar\t \r\n ") /* "foo;bar;baz" */ - TRIM(";foo;bar;baz, ", "; ") + TRIM(";foo;bar;baz, ", ",; ") - *LTRIM(value, chars)*: Returns the string *value* with whitespace stripped from the start only. The optional *chars* parameter can be used to override the diff --git a/Documentation/Books/Users/Arangodump/README.mdpp b/Documentation/Books/Users/Arangodump/README.mdpp index 7832dabdc5..cd82bf294b 100644 --- a/Documentation/Books/Users/Arangodump/README.mdpp +++ b/Documentation/Books/Users/Arangodump/README.mdpp @@ -70,10 +70,10 @@ will behave exactly as described above, working on sharded collections in the cluster. However, as opposed to the single instance situation, this operation -does not lock the data in the cluster and can therefore not guarantee -to dump a consistent snapshot if writing operations happen during the -dump operation! That is, it is recommended not to perform any data -modifying operations on the cluster whilst *arangodump* is running. +does not guarantee to dump a consistent snapshot if write operations +happen during the dump operation. It is therefore recommended not to +perform any data-modifcation operations on the cluster whilst *arangodump* +is running. As above, the output will be one structure description file and one data file per sharded collection. Note that the data in the data file is diff --git a/Documentation/Books/Users/Blueprint-Graphs/EdgeMethods.mdpp b/Documentation/Books/Users/Blueprint-Graphs/EdgeMethods.mdpp index 32dfd3d76f..d736851949 100644 --- a/Documentation/Books/Users/Blueprint-Graphs/EdgeMethods.mdpp +++ b/Documentation/Books/Users/Blueprint-Graphs/EdgeMethods.mdpp @@ -1,5 +1,7 @@ !CHAPTER Edge Methods +**Warning: This Chapter is Deprecated** + `edge.getId()` Returns the identifier of the edge. diff --git a/Documentation/Books/Users/Blueprint-Graphs/GraphConstructor.mdpp b/Documentation/Books/Users/Blueprint-Graphs/GraphConstructor.mdpp index c0e1ae4fb7..fc3123b047 100644 --- a/Documentation/Books/Users/Blueprint-Graphs/GraphConstructor.mdpp +++ b/Documentation/Books/Users/Blueprint-Graphs/GraphConstructor.mdpp @@ -1,5 +1,6 @@ !CHAPTER Graph Constructors and Methods +**Warning: This Chapter is Deprecated** The graph module provides basic functions dealing with graph structures. The examples assume diff --git a/Documentation/Books/Users/Blueprint-Graphs/README.mdpp b/Documentation/Books/Users/Blueprint-Graphs/README.mdpp index 406dd029b5..8fa76be82c 100644 --- a/Documentation/Books/Users/Blueprint-Graphs/README.mdpp +++ b/Documentation/Books/Users/Blueprint-Graphs/README.mdpp @@ -1,6 +1,6 @@ !CHAPTER Graphs -**Warning: Deprecated** +**Warning: This Chapter is Deprecated** This module is deprecated and will be removed soon. Please use [General Graphs](../General-Graphs/README.md) instead. diff --git a/Documentation/Books/Users/Blueprint-Graphs/VertexMethods.mdpp b/Documentation/Books/Users/Blueprint-Graphs/VertexMethods.mdpp index b804e83779..db961ee53f 100644 --- a/Documentation/Books/Users/Blueprint-Graphs/VertexMethods.mdpp +++ b/Documentation/Books/Users/Blueprint-Graphs/VertexMethods.mdpp @@ -1,5 +1,7 @@ !CHAPTER Vertex Methods +**Warning: This Chapter is Deprecated** + `vertex.addInEdge( peer, id)` Creates a new edge from peer to vertex and returns the edge object. The identifier id must be a unique identifier or null. diff --git a/Documentation/Books/Users/ConfigureArango/Logging.mdpp b/Documentation/Books/Users/ConfigureArango/Logging.mdpp index daeb37ab0c..f091f3ee7c 100644 --- a/Documentation/Books/Users/ConfigureArango/Logging.mdpp +++ b/Documentation/Books/Users/ConfigureArango/Logging.mdpp @@ -19,10 +19,6 @@ statistics about executed requests and timings about computation steps. @startDocuBlock logSeverity -!SUBSECTION Syslog - -@startDocuBlock logSyslog - !SECTION Human Readable Logging !SUBSECTION Level @@ -62,7 +58,3 @@ statistics about executed requests and timings about computation steps. !SUBSECTION Facility @startDocuBlock logFacility - -!SUBSECTION Histname - -@startDocuBlock logHostname diff --git a/Documentation/Books/Users/Foxx/FoxxModel.mdpp b/Documentation/Books/Users/Foxx/FoxxModel.mdpp index aa31ed9dab..af8bf182ba 100644 --- a/Documentation/Books/Users/Foxx/FoxxModel.mdpp +++ b/Documentation/Books/Users/Foxx/FoxxModel.mdpp @@ -55,6 +55,47 @@ person.attributes // => { name: "Pete", admin: true, active: true } person.errors // => {admin: [ValidationError: value is not allowed]} ``` +The following events are emitted by a model: + +- beforeCreate +- afterCreate +- beforeSave +- afterSave +- beforeUpdate +- afterUpdate +- beforeRemove +- afterRemove + +Model lifecycle: + +```js +var person = new PersonModel(); +person.on('beforeCreate', function() { + var model = this; + model.fancyMethod(); // Do something fancy with the model +}); +var people = new Repository(appContext.collection("people"), { model: PersonModel }); + +people.save(person); +// beforeCreate() +// beforeSave() +// The model is created at db +// afterSave() +// afterCreate() + +people.update(person, data); +// beforeUpdate(data) +// beforeSave(data) +// The model is updated at db +// afterSave(data) +// afterUpdate(data) + +people.remove(person); +// beforeRemove() +// The model is deleted at db +// afterRemove() +``` + !SUBSECTION Extend @startDocuBlock JSF_foxx_model_extend diff --git a/Documentation/Books/Users/Glossary/README.mdpp b/Documentation/Books/Users/Glossary/README.mdpp index 7337fc7ef9..30f91c12e3 100644 --- a/Documentation/Books/Users/Glossary/README.mdpp +++ b/Documentation/Books/Users/Glossary/README.mdpp @@ -4,9 +4,8 @@ A collection consists of documents. It is uniquely identified by its collection identifier. It also has a unique name that clients should use to identify and access it. -Collections can be renamed. is will change the collection name, but not the collection identifier. -Collections have a type that is specified by the user when the collection is created. -There are currently two types: document and edge. The default type is document. +Collections can be renamed. It will change the collection name, but not the collection identifier. +Collections contain documents of a specific type. There are currently two types: document (default) and edge. The type is specified by the user when the collection is created, and cannot be changed later. !SUBSECTION Collection Identifier @@ -15,7 +14,6 @@ A collection identifier identifies a collection in a database. It is a string va ArangoDB currently uses 64bit unsigned integer values to maintain collection ids internally. When returning collection ids to clients, ArangoDB will put them into a string to ensure the collection id is not clipped by clients that do not support big integers. Clients should treat the collection ids returned by ArangoDB as opaque strings when they store or use it locally. - !SUBSECTION Collection Name A collection name identifies a collection in a database. It is a string and is unique within the database. Unlike the collection identifier it is supplied by the creator of the collection. The collection name must consist of letters, digits, and the _ (underscore) and - (dash) characters only. Please refer to [NamingConventions](../NamingConventions/CollectionNames.html) for more information on valid collection names. @@ -28,7 +26,7 @@ A database contains its own collections (which cannot be accessed from other dat There will always be at least one database in ArangoDB. This is the default database, named _system. This database cannot be dropped, and provides special operations for creating, dropping, and enumerating databases. Users can create additional databases and give them unique names to access them later. Database management operations cannot be initiated from out of user-defined databases. -When ArangoDB is accessed via its HTTP REST API, the database name is read from the first part of the request URI path (e.g. /_db/_system/...). If the request URI does not contain a database name, the database name is automatically. +When ArangoDB is accessed via its HTTP REST API, the database name is read from the first part of the request URI path (e.g. /_db/_system/...). If the request URI does not contain a database name, the database name is automatically derived from the endpoint. Please refer to [DatabaseEndpoint](../HttpDatabase/DatabaseEndpoint.html) for more information. !SUBSECTION Database Name @@ -101,17 +99,17 @@ ArangoDB currently uses 64bit unsigned integer values to maintain document revis !SUBSECTION Edge -Edges in ArangoDB are special documents. In addition to the internal attributes _key, _id and _rev, they have two attributes _from and _to, which contain document handles, namely the start-point and the end-point of the edge. +Edges are special documents used for connecting other documents into a graph. An edge describe the connection between two documents using the internal attributes: _from and _to. These contain document handles, namely the start-point and the end-point of the edge. The values of _from and _to are immutable once saved. !SUBSECTION Edge Collection -Edge collections are special collection that store edge documents. Edge documents are connection documents that reference other documents. The type of a collection must be specified when a collection is created and cannot be changed afterwards. +Edge collections are collections that store edges. !SUBSECTION Index -Indexes are used to allow fast access to documents. For each collection there is always the primary index which is a hash index for the document key (_key attribute). This index cannot be dropped or changed. +Indexes are used to allow fast access to documents in a collection. All collections have a primary index, which is the document's _key attribute. This index cannot be dropped or changed. Edge collections will also have an automatically created edges index, which cannot be modified. This index provides quick access to documents via the _from and _to attributes. @@ -145,4 +143,4 @@ If the index is declared unique, then access to the indexed attributes should be !SUBSECTION Skiplist Index -A skiplist is used to find ranges of documents. \ No newline at end of file +A skiplist is used to find ranges of documents. diff --git a/Documentation/Books/Users/HttpGraphs/Edge.mdpp b/Documentation/Books/Users/HttpGraphs/Edge.mdpp index 3931ae2026..0f319a58a6 100644 --- a/Documentation/Books/Users/HttpGraphs/Edge.mdpp +++ b/Documentation/Books/Users/HttpGraphs/Edge.mdpp @@ -1,6 +1,6 @@ !CHAPTER Edge -**Warning Deprecated** +**Warning: This Chapter is Deprecated** `POST /_api/graph/graph-name/edge-name`*(create edge)* diff --git a/Documentation/Books/Users/HttpGraphs/README.mdpp b/Documentation/Books/Users/HttpGraphs/README.mdpp index a062ae6f19..f0585c6c08 100644 --- a/Documentation/Books/Users/HttpGraphs/README.mdpp +++ b/Documentation/Books/Users/HttpGraphs/README.mdpp @@ -1,6 +1,6 @@ !CHAPTER HTTP Interface for Graphs -**Warning Deprecated** +**Warning: This Chapter is Deprecated** This api is deprecated and will be removed soon. Please use [General Graphs](../HttpGharial/README.md) instead. diff --git a/Documentation/Books/Users/HttpGraphs/Vertex.mdpp b/Documentation/Books/Users/HttpGraphs/Vertex.mdpp index 82851c8326..c9544fd24a 100644 --- a/Documentation/Books/Users/HttpGraphs/Vertex.mdpp +++ b/Documentation/Books/Users/HttpGraphs/Vertex.mdpp @@ -1,6 +1,6 @@ !CHAPTER Vertex -**Warning Deprecated** +**Warning: This Chapter is Deprecated** `POST /_api/graph/graph-name/vertex-name`*(create vertex)* diff --git a/Documentation/Books/Users/Installing/Compiling.mdpp b/Documentation/Books/Users/Installing/Compiling.mdpp index 27948288e3..0380f7fd95 100644 --- a/Documentation/Books/Users/Installing/Compiling.mdpp +++ b/Documentation/Books/Users/Installing/Compiling.mdpp @@ -1,25 +1,25 @@ !CHAPTER Compiling ArangoDB from scratch The following sections describe how to compile and build the ArangoDB from -scratch. The ArangoDB will compile on most Linux and Mac OS X systems. It -assumes that you use the GNU C/C++ compiler or clang/clang++ to compile the +scratch. The ArangoDB will compile on most Linux and Mac OS X systems. We +assume that you use the GNU C/C++ compiler or clang/clang++ to compile the source. ArangoDB has been tested with the GNU C/C++ compiler and clang/clang++, -but should be able to compile with any Posix-compliant compiler. +but should be able to compile with any Posix-compliant, C++11-enabled compiler. Please let us know whether you successfully compiled it with another C/C++ compiler. There are the following possibilities: -* all-in-one: this version contains the source code of the ArangoDB, all +* **all-in-one**: this version contains the source code of the ArangoDB, all generated files from the autotools, FLEX, and BISON as well as a version of V8, libev, and ICU. -* devel: this version contains the development version of the ArangoDB. +* **devel**: this version contains the development version of the ArangoDB. Use this branch if you want to make changes to the ArangoDB source. -The devel version requires a complete development environment, while the -all-in-one version allows you to compile the ArangoDB without installing all the +The **devel** version requires a complete development environment, while the +**all-in-one** version allows you to compile the ArangoDB without installing all the prerequisites. The disadvantage is that it takes longer to compile and you cannot make changes to the flex or bison files. @@ -43,11 +43,11 @@ Note: there are separate instructions for the **devel** version in the next sect Verify that your system contains: -* the GNU C/C++ compilers "gcc" and "g++" and the standard C/C++ libraries. You will +* the GNU C/C++ compilers "gcc" and "g++" and the standard C/C++ libraries. You will need compiler and library support for C++11. To be on the safe side with gcc/g++, you will need version number 4.8.1 or higher. For "clang" and "clang++", you will need at least version 3.4. -* the GNU make +* GNU make In addition you will need the following libraries: @@ -159,53 +159,47 @@ parameter once to perform required upgrade or initialisation tasks. !SECTION Devel Version +Note: a seperate [blog article](http://jsteemann.github.io/blog/2014/10/16/how-to-compile-arangodb-from-source/) +is available that describes how to compile ArangoDB from source on Ubuntu. + !SUBSECTION Basic System Requirements Verify that your system contains -* the GNU C/C++ compilers "gcc" and "g++" and the standard C/C++ libraries. You will -* compiler and library support for C++11. To be on the safe side with gcc/g++, you will -* need version number 4.8.1 or higher. For "clang" and "clang++", you will need at least -* version 3.4. +* the GNU C/C++ compilers "gcc" and "g++" and the standard C/C++ libraries, with support + for C++11. You will need version gcc number 4.8.1 or higher. For "clang" and "clang++", + you will need at least version 3.4. * the GNU autotools (autoconf, automake) -* the GNU make +* GNU make * the GNU scanner generator FLEX, at least version 2.3.35 * the GNU parser generator BISON, at least version 2.4 * Python, version 2 or 3 +* the OpenSSL library, version 1.0.1g or higher (development package) +* the GNU readline library (development package) * Go, version 1.2.2 -In addition you will need the following libraries +Most Linux systems already supply RPMs or DPKGs for these packages. +Some distributions, for example Ubuntu 12.04 or Centos 5, provide only very out-dated +versions of compilers, FLEX, BISON, and/or the V8 engine. In that case you need to compile +newer versions of the programs and/or libraries. -* libev in version 3 or 4 (only when configured with `--disable-all-in-one-libev`) -* Google's V8 engine (only when configured with `--disable-all-in-one-v8`) -* the ICU library (only when not configured with `--enable-all-in-one-icu`) -* the GNU readline library -* the OpenSSL library -* the Boost test framework library (boost_unit_test_framework) +When compiling with special configure options, you may need the following extra libraries: -To compile Google V8 yourself, you will also need Python 2 and SCons. +* libev in version 3 or 4 (only when using configure option `--disable-all-in-one-libev`, + available from http://software.schmorp.de/pkg/libev.html) +* Google's V8 engine, version 3.16.14 (only when using configure option + `--disable-all-in-one-v8`, available from http://code.google.com/p/v8) +* SCons for compiling V8 (only when using configure option + `--disable-all-in-one-v8`, see http://www.scons.org) +* the ICU library (only when not using configure option `--enable-all-in-one-icu`) +* the Boost test framework library (only when using configure option `--enable-maintainer-mode`) -Some distributions, for example Centos 5, provide only very out-dated versions -of compilers, FLEX, BISON, and the V8 engine. In that case you need to compile newer -versions of the programs and/or libraries. - -If necessary, install or download the prerequisites: - -* GNU C/C++ 4.8.1 or higher (see http://gcc.gnu.org) -* Google's V8 engine (see http://code.google.com/p/v8) -* SCons for compiling V8 (see http://www.scons.org) -* libev (see http://software.schmorp.de/pkg/libev.html) -* OpenSSL (http://openssl.org/) -* Go (http://golang.org/) - -Most linux systems already supply RPM or DEP for these -packages. Please note that you have to install the development packages. !SUBSECTION Download the Source -Download the latest source using GIT: +Download the latest ArangoDB source using *git*: - git clone git://github.com/triAGENS/ArangoDB.git + git clone -b devel git://github.com/triAGENS/ArangoDB.git !SUBSECTION Setup diff --git a/Documentation/Books/Users/ModuleGraph/EdgeMethods.mdpp b/Documentation/Books/Users/ModuleGraph/EdgeMethods.mdpp index b86812e83a..5443fbeee6 100644 --- a/Documentation/Books/Users/ModuleGraph/EdgeMethods.mdpp +++ b/Documentation/Books/Users/ModuleGraph/EdgeMethods.mdpp @@ -1,6 +1,6 @@ !CHAPTER Edge Methods -**Warning Deprecated** +**Warning: This Chapter is Deprecated** `edge.getId()` diff --git a/Documentation/Books/Users/ModuleGraph/GraphConstructor.mdpp b/Documentation/Books/Users/ModuleGraph/GraphConstructor.mdpp index f0e05a3e3c..e65ca334c3 100644 --- a/Documentation/Books/Users/ModuleGraph/GraphConstructor.mdpp +++ b/Documentation/Books/Users/ModuleGraph/GraphConstructor.mdpp @@ -1,6 +1,6 @@ !CHAPTER Graph Constructors and Methods -**Warning Deprecated** +**Warning: This Chapter is Deprecated** The graph module provides basic functions dealing with graph structures. The examples assume diff --git a/Documentation/Books/Users/ModuleGraph/README.mdpp b/Documentation/Books/Users/ModuleGraph/README.mdpp index bad6b305f6..7fcfa2ccf2 100644 --- a/Documentation/Books/Users/ModuleGraph/README.mdpp +++ b/Documentation/Books/Users/ModuleGraph/README.mdpp @@ -1,6 +1,6 @@ !CHAPTER Module "graph" -**Warning: Deprecated** +**Warning: This Chapter is Deprecated** !SUBSECTION First Steps with Graphs diff --git a/Documentation/Books/Users/ModuleGraph/VertexMethods.mdpp b/Documentation/Books/Users/ModuleGraph/VertexMethods.mdpp index 6985b000b8..fbeb93f56d 100644 --- a/Documentation/Books/Users/ModuleGraph/VertexMethods.mdpp +++ b/Documentation/Books/Users/ModuleGraph/VertexMethods.mdpp @@ -1,6 +1,6 @@ !CHAPTER Vertex Methods -**Warning Deprecated** +**Warning: This Chapter is Deprecated** `vertex.addInEdge( peer, id)` diff --git a/Documentation/Books/Users/NewFeatures/NewFeatures21.mdpp b/Documentation/Books/Users/NewFeatures/NewFeatures21.mdpp new file mode 100644 index 0000000000..90b06d2fda --- /dev/null +++ b/Documentation/Books/Users/NewFeatures/NewFeatures21.mdpp @@ -0,0 +1,299 @@ +!CHAPTER Features and Improvements + +The following list shows in detail which features have been added or improved in +ArangoDB 2.1. ArangoDB 2.1 also contains several bugfixes that are not listed +here. + +!SECTION New Edges Index + +The edges index (used to store connections between nodes in a graph) internally +uses a new data structure. This data structure improves the performance when +populating the edge index (i.e. when loading an edge collection). For large +graphs loading can be 20 times faster than with ArangoDB 2.0. + +Additionally, the new index fixes performance problems that occurred when many +duplicate `_from` or `_to` values were contained in the index. Furthermore, the +new index supports faster removal of edges. + +Finally, when loading an existing collection and building the edges index for +the collection, less memory re-allocations will be performed. + +Overall, this should considerably speed up loading edge collections. + +The new index type replaces the old edges index type automatically, without any +changes being required by the end user. + +The API of the new index is compatible with the API of the old index. Still it +is possible that the new index returns edges in a different order than the old +index. This is still considered to be compatible because the old index had never +guaranteed any result order either. + +!SECTION AQL Improvements + +AQL offers functionality to work with dates. Dates are no datatypes of their own +in AQL (neither they are in JSON, which is often used as a format to ship data +into and out of ArangoDB). Instead, dates in AQL are internally represented by +either numbers (timestamps) or strings. The date functions in AQL provide +mechanisms to convert from a numeric timestamp to a string representation and +vice versa. + +There are two date functions in AQL to create dates for further use: + +- `DATE_TIMESTAMP(date)` Creates a UTC timestamp value from `date` + +- `DATE_TIMESTAMP(year, month, day, hour, minute, second, millisecond)`: + Same as before, but allows specifying the individual date components separately. + All parameters after `day` are optional. + +- `DATE_ISO8601(date)`: Returns an ISO8601 datetime string from `date`. + The datetime string will always use UTC time, indicated by the `Z` at its end. + +- `DATE_ISO8601(year, month, day, hour, minute, second, millisecond)`: + same as before, but allows specifying the individual date components separately. + All parameters after `day` are optional. + +These two above date functions accept the following input values: + +- numeric timestamps, indicating the number of milliseconds elapsed since the UNIX + epoch (i.e. January 1st 1970 00:00:00 UTC). + An example timestamp value is `1399472349522`, which translates to + `2014-05-07T14:19:09.522Z`. + +- datetime strings in formats `YYYY-MM-DDTHH:MM:SS.MMM`, `YYYY-MM-DD HH:MM:SS.MMM`, or + `YYYY-MM-DD`. Milliseconds are always optional. + + A timezone difference may optionally be added at the end of the string, with the + hours and minutes that need to be added or subtracted to the datetime value. + For example, `2014-05-07T14:19:09+01:00` can be used to specify a one hour offset, + and `2014-05-07T14:19:09+07:30` can be specified for seven and half hours offset. + Negative offsets are also possible. Alternatively to an offset, a `Z` can be used + to indicate UTC / Zulu time. + + An example value is `2014-05-07T14:19:09.522Z` meaning May 7th 2014, 14:19:09 and + 522 milliseconds, UTC / Zulu time. Another example value without time component is + `2014-05-07Z`. + + Please note that if no timezone offset is specified in a datestring, ArangoDB will + assume UTC time automatically. This is done to ensure portability of queries across + servers with different timezone settings, and because timestamps will always be + UTC-based. + +- individual date components as separate function arguments, in the following order: + - year + - month + - day + - hour + - minute + - second + - millisecond + + All components following `day` are optional and can be omitted. Note that no + timezone offsets can be specified when using separate date components, and UTC / + Zulu time will be used. + +The following calls to `DATE_TIMESTAMP` are equivalent and will all return +`1399472349522`: + + DATE_TIMESTAMP("2014-05-07T14:19:09.522") + DATE_TIMESTAMP("2014-05-07T14:19:09.522Z") + DATE_TIMESTAMP("2014-05-07 14:19:09.522") + DATE_TIMESTAMP("2014-05-07 14:19:09.522Z") + DATE_TIMESTAMP(2014, 5, 7, 14, 19, 9, 522) + DATE_TIMESTAMP(1399472349522) + +The same is true for calls to `DATE_ISO8601` that also accepts variable input +formats: + + DATE_ISO8601("2014-05-07T14:19:09.522Z") + DATE_ISO8601("2014-05-07 14:19:09.522Z") + DATE_ISO8601(2014, 5, 7, 14, 19, 9, 522) + DATE_ISO8601(1399472349522) + +The above functions are all equivalent and will return `"2014-05-07T14:19:09.522Z"`. + +The following date functions can be used with dates created by `DATE_TIMESTAMP` and +`DATE_ISO8601`: + +- `DATE_DAYOFWEEK(date)`: Returns the weekday number of `date`. The return values have + the following meanings: + - 0: Sunday + - 1: Monday + - 2: Tuesday + - 3: Wednesday + - 4: Thursday + - 5: Friday + - 6: Saturday + +- `DATE_YEAR(date)`: Returns the year part of `date` as a number. + +- `DATE_MONTH(date)`: Returns the month part of `date` as a number. + +- `DATE_DAY(date)`: Returns the day part of `date` as a number. + +- `DATE_HOUR(date)`: Returns the hour part of `date` as a number. + +- `DATE_MINUTE(date)`: Returns the minute part of `date` as a number. + +- `DATE_SECOND(date)`: Returns the seconds part of `date` as a number. + +- `DATE_MILLISECOND(date)`: Returns the milliseconds part of `date` as a number. + +The following other date functions are also available: + +- `DATE_NOW()`: Returns the current time as a timestamp. + + Note that this function is evaluated on every invocation and may return different + values when invoked multiple times in the same query. + +The following other AQL functions have been added in ArangoDB 2.1: + +- `FLATTEN`: this function can turn a list of sub-lists into a single flat list. All + list elements in the original list will be expanded recursively up to a configurable + depth. The expanded values will be added to the single result list. + + Example: + + FLATTEN([ 1, 2, [ 3, 4 ], 5, [ 6, 7 ], [ 8, [ 9, 10 ] ]) + + will expand the sub-lists on the first level and produce: + + [ 1, 2, 3, 4, 5, 6, 7, 8, [ 9, 10 ] ] + + To fully flatten the list, the maximum depth can be specified (e.g. with a value of `2`): + + FLATTEN([ 1, 2, [ 3, 4 ], 5, [ 6, 7 ], [ 8, [ 9, 10 ] ], 2) + + This will fully expand the sub-lists and produce: + + [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + +- `CURRENT_DATABASE`: this function will return the name of the database the current + query is executed in. + +- `CURRENT_USER`: this function returns the name of the current user that is executing + the query. If authorization is turned off or the query is executed outside of a + request context, no user is present and the function will return `null`. + +!SECTION Cluster Dump and Restore + +The dump and restore tools, _arangodump_ and _arangorestore_, can now be used to +dump and restore collections in a cluster. Additionally, a collection dump from +a standalone ArangoDB server can be imported into a cluster, and vice versa. + +!SECTION Web Interface Improvements + +The web interface in version 2.1 has a more compact dashboard. It provides +charts with time-series for incoming requests, HTTP transfer volume and some +server resource usage figures. + +Additionally it provides trend indicators (e.g. 15 min averages) and +distribution charts (aka histogram) for some figures. + +!SECTION Foxx Improvements + +To easily access a file inside the directory of a Foxx application from within +Foxx, Foxx's `applicationContext` now provides the `foxxFilename()` function. It +can be used to assemble the full filename of a file inside the application's +directory. The `applicationContext` can be accessed as global variable from any +module within a Foxx application. + +The filename can be used inside Foxx actions or setup / teardown scripts, +e.g. to populate a Foxx application's collection with data. + +The `require` function now also prefers local modules when used from inside a +Foxx application. This allows putting modules inside the Foxx application +directory and requiring them easily. It also allows using application-specific +versions of libraries that are bundled with ArangoDB (such as underscore.js). + +!SECTION Windows Installer + +The Windows installer shipped with ArangoDB now supports installation of +ArangoDB for the current user or all users, with the required privileges. It +also supports the installation of ArangoDB as a service. + +!SECTION Fixes for 32 bit systems + +Several issues have been fixed that occured only when using ArangoDB on a 32 bits +operating system, specifically: + +- a crash in a third party component used to manage cluster data + +- a third party library that failed to initialize on 32 bit Windows, making arangod + and arangosh crash immediately. + +- overflows of values used for nanosecond-precision timeouts: these overflows + have led to invalid values being passed to socket operations, making them fail + and re-try too often + +!SECTION Updated drivers + +Several drivers for ArangoDB have been checked for compatibility with 2.1. The +current list of drivers with compatibility notes can be found online +[here](https://www.arangodb.org/driver). + +!SECTION C++11 usage + +We have moved several files from C to C++, allowing more code reuse and reducing +the need for shipping data between the two. We have also decided to require +C++11 support for ArangoDB, which allows us to use some of the simplifications, +features and guarantees that this standard has in stock. + +That also means a compiler with C++11 support is required to build ArangoDB from +source. For instance GNU CC of at least version 4.8. + +!SECTION Miscellaneous Improvements + +- Cancelable asynchronous jobs: several potentially long-running jobs can now be + cancelled via an explicit cancel operation. This allows stopping long-running + queries, traversals or scripts without shutting down the complete ArangoDB + process. Job cancellation is provided for asynchronously executed jobs as is + described in @ref HttpJobCancel. + +- Server-side periodic task management: an ArangoDB server now provides + functionality to register and unregister periodic tasks. Tasks are + user-defined JavaScript actions that can be run periodically and + automatically, independent of any HTTP requests. + + The following task management functions are provided: + + - require("org/arangodb/tasks").register(): registers a periodic task + - require("org/arangodb/tasks").unregister(): unregisters and removes a periodic task + - require("org/arangodb/tasks").get(): retrieves a specific tasks or all existing tasks + + An example task (to be executed every 15 seconds) can be registered like this: + + var tasks = require("org/arangodb/tasks"); + tasks.register({ + name: "this is an example task with parameters", + period: 15, + command: function (params) { + var greeting = params.greeting; + var data = JSON.stringify(params.data); + require('console').log('%s from parameter task: %s', greeting, data); + }, + params: { greeting: "hi", data: "how are you?" } + }); + + Please refer to the section @ref Tasks for more details. + +- The `figures` method of a collection now returns data about the collection's + index memory consumption. The returned value `indexes.size` will contain the + total amount of memory acquired by all indexes of the collection. This figure + can be used to assess the memory impact of indexes. + +- Capitalized HTTP response headers: from version 2.1, ArangoDB will return + capitalized HTTP headers by default, e.g. `Content-Length` instead of + `content-length`. Though the HTTP specification states that headers field + name are case-insensitive, several older client tools rely on a specific case + in HTTP response headers. This changes make ArangoDB a bit more compatible + with those. + +- Simplified usage of `db._createStatement()`: to easily run an AQL query, the + method `db._createStatement` now allows passing the AQL query as a string. + Previously it required the user to pass an object with a `query` attribute + (which then contained the query string). + + ArangoDB now supports both versions: + + db._createStatement(queryString); + db._createStatement({ query: queryString }); \ No newline at end of file diff --git a/Documentation/Books/Users/NewFeatures/NewFeatures23.mdpp b/Documentation/Books/Users/NewFeatures/NewFeatures23.mdpp index b68946f720..73df537856 100644 --- a/Documentation/Books/Users/NewFeatures/NewFeatures23.mdpp +++ b/Documentation/Books/Users/NewFeatures/NewFeatures23.mdpp @@ -40,7 +40,7 @@ in the future. !SUBSUBSECTION Alternative operator syntax -ArangoDB 2.3 allows to write the use the following alternative forms for the +ArangoDB 2.3 allows to use the following alternative forms for the logical operators: - `AND`: logical and - `OR`: logical or @@ -85,17 +85,19 @@ The following other AQL functions have been added: - `VALUES(document)`: returns the values of a document as a list (this is the counterpart to the already existing `ATTRIBUTES` function) -- `ASSEMBLE(attributes, values)`: returns a document constructed from attributes +- `ZIP(attributes, values)`: returns a document constructed from attributes and values passed in separate parameters +- `PERCENTILE(values, n, method)`: returns the nths percentile of the + values provided, using rank or interpolation method The already existing functions `CONCAT` and `CONCAT_SEPARATOR` now support list arguments, e.g.: - /* "foobarbaz" */ - CONCAT([ 'foo', 'bar', 'baz']) + /* "foobarbaz" */ + CONCAT([ 'foo', 'bar', 'baz']) - /* "foo,bar,baz" */ - CONCAT_SEPARATOR(", ", [ 'foo', 'bar', 'baz']) + /* "foo,bar,baz" */ + CONCAT_SEPARATOR(", ", [ 'foo', 'bar', 'baz']) !SUBSUBSECTION AQL queries throw less exceptions @@ -274,5 +276,28 @@ ArangoDB's built-in HTTP server now supports HTTP pipelining. The ArangoShell tutorial from the arangodb.com website is now integrated into the ArangoDB shell. +!SECTION Powerful Foxx Enhancements +With the new **job queue** feature you can run async jobs to communicate with external services, **Foxx queries** make writing complex AQL queries much easier and **Foxx sessions** will handle the authentication and session hassle for you. +!SUBSECTION Foxx Queries + +Writing long AQL queries in JavaScript can quickly become unwieldy. As of 2.3 ArangoDB bundles the [ArangoDB Query Builder](https://npmjs.org/package/aqb) module that provides a JavaScript API for writing complex AQL queries without string concatenation. All built-in functions that accept AQL strings now support query builder instances directly. Additionally Foxx provides a method `Foxx.createQuery` for creating parametrized queries that can return Foxx models or apply arbitrary transformations to the query results. + +!SUBSECTION Foxx Sessions + +The session functionality in Foxx has been completely rewritten. The old `activateAuthentication` API is still supported but may be deprecated in the future. The new `activateSessions` API supports cookies or configurable headers, provides optional JSON Web Token and cryptographic signing support and uses the new sessions Foxx app. + +ArangoDB 2.3 provides Foxx apps for user management and salted hash-based authentication which can be replaced with or supplemented by alternative implementations. For an example app using both the built-in authentication and OAuth2 see the [Foxx Sessions Example app](https://github.com/arangodb/foxx-sessions-example). + +!SUBSECTION Foxx Queues + +Foxx now provides async workers via the Foxx Queues API. Jobs enqueued in a job queue will be executed asynchronously outside of the request/response cycle of Foxx controllers and can be used to communicate with external services or perform tasks that take a long time to complete or may require multiple attempts. + +Jobs can be scheduled in advance or set to be executed immediately, the number of retry attempts, the retry delay as well as sucess and failure handlers can be defined for each job individually. Job types that integrate various external services for transactional e-mails, logging and user tracking can be found in the Foxx app registry. + +!SUBSECTION Misc + +The request and response objects in Foxx controllers now provide methods for reading and writing raw cookies and signed cookies. + +Mounted Foxx apps will now be loaded when arangod starts rather than at the first database request. This may result in slightly slower start up times (but a faster response for the first request). diff --git a/Documentation/Books/Users/SUMMARY.md b/Documentation/Books/Users/SUMMARY.md index a5a5d6375d..bc10d32421 100644 --- a/Documentation/Books/Users/SUMMARY.md +++ b/Documentation/Books/Users/SUMMARY.md @@ -12,6 +12,9 @@ * [Upgrading in general](Installing/Upgrading.md) * [Cluster setup](Installing/Cluster.md) +* [Whats New](NewFeatures/NewFeatures23.md) + * [Whats New in 2.2](NewFeatures/NewFeatures22.md) + * [Whats New in 2.1](NewFeatures/NewFeatures21.md) * [First Steps](FirstSteps/README.md) * [Getting Familiar](FirstSteps/GettingFamiliar.md) * [The ArangoDB Server](FirstSteps/Arangod.md) @@ -134,7 +137,6 @@ * [Example Setup](Replication/ExampleSetup.md) * [Replication Limitations](Replication/Limitations.md) * [Replication Overhead](Replication/Overhead.md) - * [Replication Events](Replication/Events.md) * [Sharding](Sharding/README.md) * [How to try it out](Sharding/HowTo.md) diff --git a/Documentation/Books/Users/Upgrading/UpgradingChanges23.mdpp b/Documentation/Books/Users/Upgrading/UpgradingChanges23.mdpp index 910a05cf64..21aa5f9dae 100644 --- a/Documentation/Books/Users/Upgrading/UpgradingChanges23.mdpp +++ b/Documentation/Books/Users/Upgrading/UpgradingChanges23.mdpp @@ -4,12 +4,19 @@ It is recommended to check the following list of incompatible changes **before** upgrading to ArangoDB 2.3, and adjust any client programs if necessary. -!SECTION Default configuration file changes +!SECTION Configuration file changes -With ArangoDB 2.3, the number of server threads can be configured independently of -the number of V8 contexts. The configuration option `--javascript.v8-contexts` was -added to arangod to provide better control over the number of V8 contexts created -in arangod. +!SUBSECTION Threads and contexts + +The number of server threads specified is now the minimum of threads +started. There are situation in which threads are waiting for results of +distributed database servers. In this case the number of threads is dynamically +increased. + +With ArangoDB 2.3, the number of server threads can be configured independently +of the number of V8 contexts. The configuration option +`--javascript.v8-contexts` was added to arangod to provide better control over +the number of V8 contexts created in arangod. Previously, the number of V8 contexts arangod created at startup was equal to the number of server threads (as specified by option `--server.threads`). @@ -19,21 +26,42 @@ and V8 contexts. This is because each V8 contexts created will consume memory and requires CPU resources for periodic garbage collection. Contrary, server threads do not have such high memory or CPU footprint. -If the option `--javascript.v8-contexts` is not specified, the number of V8 -contexts created at startup will remain equal to the number of server threads. -Thus no change in configuration is required to keep the same behavior as in +If the option `--javascript.v8-contexts` is not specified, the number of V8 +contexts created at startup will remain equal to the number of server threads. +Thus no change in configuration is required to keep the same behavior as in previous ArangoDB versions. -However, the default configuration files shipped with ArangoDB have been changed. -The number of server threads has been increased in the configuration files, and -the number of V8 contexts is now explicitly set in the configuration files (to -the same value as the number of server threads was set to in 2.2). - -If you are using the default config files or merge them with your local config files, -please review if the higher default number of server threads is okay in your +If you are using the default config files or merge them with your local config +files, please review if the default number of server threads is okay in your environment. Additionally you should verify that the number of V8 contexts created (as specified in option `--javascript.v8-contexts`) is okay. +!SUBSECTION Syslog + +The command-line option `--log.syslog` was used in previous versions of +ArangoDB to turn logging to syslog on or off: when setting to a non-empty +string, syslog logging was turned on, otherwise turned off. +When syslog logging was turned on, logging was done with the application +name specified in `--log.application`, which defaulted to `triagens`. +There was also a command-line option `--log.hostname` which could be set +but did not have any effect. + +This behavior turned out to be unintuitive and was changed in 2.3 as follows: + +* the command-line option `--log.syslog` is deprecated and does not have any + effect when starting ArangoDB. +* to turn on syslog logging in 2.3, the option `--log.facility` has to be set + to a non-empty string. The value for `facility` is OS-dependent (possible + values can be found in `/usr/include/syslog.h` or the like - `user` should + be available on many systems). +* the default value for `--log.application` has been changed from `triagens` to + `arangod`. +* the command-line option `--log.hostname` is deprecated and does not have any + effect when starting ArangoDB. Instead, the host name will be set by syslog + automatically. +* when logging to syslog, ArangoDB now omits the datetime prefix and the process + id, because they'll be added by syslog automatically. + !SECTION AQL @@ -77,7 +105,15 @@ Here is a summary of changes: receive invalid arguments will then return `null`. -!SUBSECTION Changed return values in ArangoQueryCursor.getExtra() +!SUBSECTION Nested FOR loop execution order + +The query optimizer in 2.3 may permute the order of nested `FOR` loops in AQL queries, +provided that exchanging the loops will not alter a query result. However, a change +in the order of returned values is allowed because no sort order is guaranteed by AQL +(and was never) unless an explicit `SORT` statement is used in a query. + + +!SUBSECTION Changed return values of ArangoQueryCursor.getExtra() The return value of `ArangoQueryCursor.getExtra()` has been changed in ArangoDB 2.3. It now contains a `stats` attribute with statistics about the query previously executed. @@ -222,6 +258,21 @@ updating variables in queries that run on different nodes in a cluster would lik non-deterministic behavior because queries are not executed linearly. +!SUBSECTION Changed return value of `TO_BOOL` + +The AQL function `TO_BOOL` now always returns *true* if its argument is a list or a document. +In previous versions of ArangoDB, the function returned *false* for empty lists or for +documents without attributes. + + +!SUBSECTION Changed return value of `TO_NUMBER` + +The AQL function `TO_NUMBER` now returns *null* if its argument is a document or a +list with more than one member. In previous version of ArangoDB, the return +value in these cases was 0. `TO_NUMBER` will return 0 for empty lists, and the numeric +equivalent of the list member's value for lists with a single member. + + !SUBSECTION New AQL keywords The following keywords have been added to AQL in ArangoDB 2.3: @@ -259,3 +310,17 @@ warnings will eventually disappear. The HTTP REST API method at `POST /_admin/modules/flush` has been removed. + +!SECTION Known issues + +In ArangoDB 2.3.0, AQL queries containing filter conditions with an IN expression +will not yet use an index: + + FOR doc IN collection FILTER doc.indexedAttribute IN [ ... ] RETURN doc + + FOR doc IN collection + FILTER doc.indexedAttribute IN [ ... ] + RETURN doc + +We’re currently working on getting the IN optimizations done, and will ship them in +a 2.3 maintenance release soon (e.g. 2.3.1 or 2.3.2). diff --git a/Documentation/Books/Users/localtheme/templates/book/includes/summary.html b/Documentation/Books/Users/localtheme/templates/book/includes/summary.html index eac01df05c..e1de4b8627 100644 --- a/Documentation/Books/Users/localtheme/templates/book/includes/summary.html +++ b/Documentation/Books/Users/localtheme/templates/book/includes/summary.html @@ -50,11 +50,8 @@ {% if options.links.gitbook !== false %}
  • - Have any issues? - Have any questions? -
  • -
  • - Whats new in the latest version? + Have any issues? + Have any questions?
  • {% endif %}
  • diff --git a/GNUmakefile b/GNUmakefile index 474d6e3f3c..3e78d15d60 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -35,14 +35,13 @@ setup: MAINTAINER = \ README \ - arangod/Ahuacatl/ahuacatl-tokens.cpp \ - arangod/Ahuacatl/ahuacatl-grammar.cpp \ - arangod/Ahuacatl/ahuacatl-grammar.h \ + arangod/Aql/tokens.cpp \ + arangod/Aql/grammar.cpp \ + arangod/Aql/grammar.h \ lib/JsonParser/json-parser.cpp \ lib/V8/v8-json.cpp \ - lib/V8/v8-json.h \ - lib/BasicsC/voc-errors.h \ - lib/BasicsC/voc-errors.c \ + lib/Basics/voc-errors.h \ + lib/Basics/voc-errors.cpp \ js/common/bootstrap/errors.js \ mr/common/bootstrap/mr-error.h diff --git a/Makefile.am b/Makefile.am index e6cbbbd596..6ff0187405 100644 --- a/Makefile.am +++ b/Makefile.am @@ -297,16 +297,16 @@ install-exec-hook: ################################################################################ install-data-hook: - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/c - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/d - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/e - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/f - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/sub/b - rm -f $(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/hoek/test/modules/ignore.txt - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/setup.sh - rm -f $(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/isemail/dns-no-mx.js - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh - rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/c + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/d + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/e + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/f + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/sub/b + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/hoek/test/modules/ignore.txt + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/setup.sh + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/isemail/dns-no-mx.js + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh + rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh ## ----------------------------------------------------------------------------- diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index 78d34e2712..4608b38379 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -533,6 +533,7 @@ unittests-shell-server-ahuacatl: SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \ @top_srcdir@/js/server/tests/aql-bind.js \ + @top_srcdir@/js/server/tests/aql-call-apply.js \ @top_srcdir@/js/server/tests/aql-complex.js \ @top_srcdir@/js/server/tests/aql-cross.js \ @top_srcdir@/js/server/tests/aql-edges-noncluster.js \ @@ -540,6 +541,7 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \ @top_srcdir@/js/server/tests/aql-explain-noncluster.js \ @top_srcdir@/js/server/tests/aql-functions.js \ @top_srcdir@/js/server/tests/aql-functions-date.js \ + @top_srcdir@/js/server/tests/aql-functions-list.js \ @top_srcdir@/js/server/tests/aql-functions-misc.js \ @top_srcdir@/js/server/tests/aql-functions-numeric.js \ @top_srcdir@/js/server/tests/aql-functions-string.js \ @@ -553,6 +555,8 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \ @top_srcdir@/js/server/tests/aql-modify-noncluster-serializetest.js \ @top_srcdir@/js/server/tests/aql-operators.js \ @top_srcdir@/js/server/tests/aql-optimizer-dynamic-bounds.js \ + @top_srcdir@/js/server/tests/aql-optimizer-filters.js \ + @top_srcdir@/js/server/tests/aql-optimizer-indexes.js \ @top_srcdir@/js/server/tests/aql-optimizer-rule-interchange-adjacent-enumerations-noncluster.js \ @top_srcdir@/js/server/tests/aql-optimizer-rule-move-calculations-up.js \ @top_srcdir@/js/server/tests/aql-optimizer-rule-move-filters-up.js \ diff --git a/VERSION b/VERSION index 276cbf9e28..04acb7549a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3.0 +2.3.0-beta2 diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index ce496bd6a7..a8fbdf84be 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -205,7 +205,6 @@ namespace triagens { std::string toString () const; - //////////////////////////////////////////////////////////////////////////////// /// @brief get a string representation of the AqlValue /// this will fail if the value is not a string diff --git a/arangod/Aql/Ast.cpp b/arangod/Aql/Ast.cpp index e7d9b69b52..bc3f597066 100644 --- a/arangod/Aql/Ast.cpp +++ b/arangod/Aql/Ast.cpp @@ -905,7 +905,7 @@ void Ast::injectBindParameters (BindParameters& parameters) { AstNode* Ast::replaceVariables (AstNode* node, std::unordered_map const& replacements) { - auto func = [&](AstNode* node, void*) -> AstNode* { + auto visitor = [&](AstNode* node, void*) -> AstNode* { if (node == nullptr) { return nullptr; } @@ -926,7 +926,7 @@ AstNode* Ast::replaceVariables (AstNode* node, return node; }; - return traverse(node, func, nullptr); + return traverse(node, visitor, nullptr); } //////////////////////////////////////////////////////////////////////////////// @@ -934,7 +934,19 @@ AstNode* Ast::replaceVariables (AstNode* node, //////////////////////////////////////////////////////////////////////////////// void Ast::optimize () { - auto func = [&](AstNode* node, void*) -> AstNode* { + auto preVisitor = [&](AstNode const* node, void* data) -> void { + if (node->type == NODE_TYPE_FILTER) { + *(static_cast(data)) = true; + } + }; + + auto postVisitor = [&](AstNode const* node, void* data) -> void { + if (node->type == NODE_TYPE_FILTER) { + *(static_cast(data)) = false; + } + }; + + auto visitor = [&](AstNode* node, void* data) -> AstNode* { if (node == nullptr) { return nullptr; } @@ -952,7 +964,7 @@ void Ast::optimize () { // binary operators if (node->type == NODE_TYPE_OPERATOR_BINARY_AND || node->type == NODE_TYPE_OPERATOR_BINARY_OR) { - return optimizeBinaryOperatorLogical(node); + return optimizeBinaryOperatorLogical(node, *(static_cast(data))); } if (node->type == NODE_TYPE_OPERATOR_BINARY_EQ || @@ -1007,8 +1019,9 @@ void Ast::optimize () { return node; }; - // optimization - _root = traverse(_root, func, nullptr); + // run the optimizations + bool canModifyResultType = false; + _root = traverse(_root, preVisitor, visitor, postVisitor, &canModifyResultType); } //////////////////////////////////////////////////////////////////////////////// @@ -1016,7 +1029,7 @@ void Ast::optimize () { //////////////////////////////////////////////////////////////////////////////// std::unordered_set Ast::getReferencedVariables (AstNode const* node) { - auto func = [&](AstNode const* node, void* data) -> void { + auto visitor = [&](AstNode const* node, void* data) -> void { if (node == nullptr) { return; } @@ -1037,7 +1050,7 @@ std::unordered_set Ast::getReferencedVariables (AstNode const* node) }; std::unordered_set result; - traverse(node, func, &result); + traverse(node, visitor, &result); return result; } @@ -1287,7 +1300,8 @@ AstNode* Ast::optimizeUnaryOperatorLogical (AstNode* node) { /// @brief optimizes the binary logical operators && and || //////////////////////////////////////////////////////////////////////////////// -AstNode* Ast::optimizeBinaryOperatorLogical (AstNode* node) { +AstNode* Ast::optimizeBinaryOperatorLogical (AstNode* node, + bool canModifyResultType) { TRI_ASSERT(node != nullptr); TRI_ASSERT(node->type == NODE_TYPE_OPERATOR_BINARY_AND || node->type == NODE_TYPE_OPERATOR_BINARY_OR); @@ -1301,8 +1315,8 @@ AstNode* Ast::optimizeBinaryOperatorLogical (AstNode* node) { } if (lhs->isConstant()) { + // left operand is a constant value if (node->type == NODE_TYPE_OPERATOR_BINARY_AND) { - // left operand is a constant value if (lhs->isFalse()) { // return it if it is falsey return lhs; @@ -1312,7 +1326,6 @@ AstNode* Ast::optimizeBinaryOperatorLogical (AstNode* node) { return rhs; } else if (node->type == NODE_TYPE_OPERATOR_BINARY_OR) { - // left operand is a constant value if (lhs->isTrue()) { // return it if it is trueish return lhs; @@ -1323,6 +1336,29 @@ AstNode* Ast::optimizeBinaryOperatorLogical (AstNode* node) { } } + if (canModifyResultType) { + if (rhs->isConstant() && ! lhs->canThrow()) { + // right operand is a constant value + if (node->type == NODE_TYPE_OPERATOR_BINARY_AND) { + if (rhs->isFalse()) { + return createNodeValueBool(false); + } + + // right-operand was trueish, now return it + return lhs; + } + else if (node->type == NODE_TYPE_OPERATOR_BINARY_OR) { + if (rhs->isTrue()) { + // return it if it is trueish + return createNodeValueBool(true); + } + + // right-operand was falsey, now return left operand + return lhs; + } + } + } + // default case return node; } @@ -1815,11 +1851,44 @@ AstNode* Ast::nodeFromJson (TRI_json_t const* json) { } //////////////////////////////////////////////////////////////////////////////// -/// @brief traverse the AST +/// @brief traverse the AST, using pre- and post-order visitors //////////////////////////////////////////////////////////////////////////////// AstNode* Ast::traverse (AstNode* node, - std::function func, + std::function preVisitor, + std::function visitor, + std::function postVisitor, + void* data) { + if (node == nullptr) { + return nullptr; + } + + preVisitor(node, data); + size_t const n = node->numMembers(); + + for (size_t i = 0; i < n; ++i) { + auto member = node->getMember(i); + + if (member != nullptr) { + AstNode* result = traverse(member, preVisitor, visitor, postVisitor, data); + + if (result != node) { + node->changeMember(i, result); + } + } + } + + auto result = visitor(node, data); + postVisitor(node, data); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief traverse the AST, using a visitor +//////////////////////////////////////////////////////////////////////////////// + +AstNode* Ast::traverse (AstNode* node, + std::function visitor, void* data) { if (node == nullptr) { return nullptr; @@ -1831,7 +1900,7 @@ AstNode* Ast::traverse (AstNode* node, auto member = node->getMember(i); if (member != nullptr) { - AstNode* result = traverse(member, func, data); + AstNode* result = traverse(member, visitor, data); if (result != node) { node->changeMember(i, result); @@ -1839,15 +1908,15 @@ AstNode* Ast::traverse (AstNode* node, } } - return func(node, data); + return visitor(node, data); } //////////////////////////////////////////////////////////////////////////////// -/// @brief traverse the AST, with const nodes +/// @brief traverse the AST using a visitor, with const nodes //////////////////////////////////////////////////////////////////////////////// void Ast::traverse (AstNode const* node, - std::function func, + std::function visitor, void* data) { if (node == nullptr) { return; @@ -1859,11 +1928,11 @@ void Ast::traverse (AstNode const* node, auto member = node->getMember(i); if (member != nullptr) { - traverse(const_cast(member), func, data); + traverse(const_cast(member), visitor, data); } } - func(node, data); + visitor(node, data); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Ast.h b/arangod/Aql/Ast.h index 7b9506dfa6..dc317c6224 100644 --- a/arangod/Aql/Ast.h +++ b/arangod/Aql/Ast.h @@ -392,13 +392,13 @@ namespace triagens { /// @brief create an AST null value node //////////////////////////////////////////////////////////////////////////////// - AstNode* createNodeValueNull (); + static AstNode* createNodeValueNull (); //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST bool value node //////////////////////////////////////////////////////////////////////////////// - AstNode* createNodeValueBool (bool); + static AstNode* createNodeValueBool (bool); //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST int value node @@ -543,7 +543,7 @@ namespace triagens { /// @brief optimizes the binary logical operators && and || //////////////////////////////////////////////////////////////////////////////// - AstNode* optimizeBinaryOperatorLogical (AstNode*); + AstNode* optimizeBinaryOperatorLogical (AstNode*, bool); //////////////////////////////////////////////////////////////////////////////// /// @brief optimizes the binary relational operators <, <=, >, >=, ==, != and IN @@ -602,7 +602,17 @@ namespace triagens { AstNode* nodeFromJson (TRI_json_t const*); //////////////////////////////////////////////////////////////////////////////// -/// @brief traverse the AST +/// @brief traverse the AST, using pre- and post-order visitors +//////////////////////////////////////////////////////////////////////////////// + + static AstNode* traverse (AstNode*, + std::function, + std::function, + std::function, + void*); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief traverse the AST using a visitor //////////////////////////////////////////////////////////////////////////////// static AstNode* traverse (AstNode*, @@ -610,7 +620,7 @@ namespace triagens { void*); //////////////////////////////////////////////////////////////////////////////// -/// @brief traverse the AST, with const nodes +/// @brief traverse the AST using a visitor, with const nodes //////////////////////////////////////////////////////////////////////////////// static void traverse (AstNode const*, diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 0b12650729..c64df178d5 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -132,12 +132,74 @@ std::unordered_map const AstNode::valueTypeNames{ // ----------------------------------------------------------------------------- // --SECTION-- static helper functions // ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief resolve an attribute access +//////////////////////////////////////////////////////////////////////////////// + +static AstNode const* ResolveAttribute (AstNode const* node) { + TRI_ASSERT(node != nullptr); + TRI_ASSERT(node->type == NODE_TYPE_ATTRIBUTE_ACCESS); + + std::vector attributeNames; + + while (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) { + char const* attributeName = node->getStringValue(); + + TRI_ASSERT(attributeName != nullptr); + attributeNames.push_back(attributeName); + node = node->getMember(0); + } + + while (true) { + TRI_ASSERT(! attributeNames.empty()); + + TRI_ASSERT(node->type == NODE_TYPE_VALUE || + node->type == NODE_TYPE_LIST || + node->type == NODE_TYPE_ARRAY); + + bool found = false; + + if (node->type == NODE_TYPE_ARRAY) { + char const* attributeName = attributeNames.back().c_str(); + attributeNames.pop_back(); + + size_t const n = node->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = node->getMember(i); + + if (member != nullptr && strcmp(member->getStringValue(), attributeName) == 0) { + // found the attribute + node = member->getMember(0); + if (attributeNames.empty()) { + // we found what we looked for + return node; + } + else { + // we found the correct attribute but there is now an attribute access on the result + found = true; + break; + } + } + } + } + + if (! found) { + break; + } + } + + // attribute not found or non-array + return Ast::createNodeValueNull(); +} //////////////////////////////////////////////////////////////////////////////// /// @brief get the node type for inter-node comparisons //////////////////////////////////////////////////////////////////////////////// static TRI_json_type_e GetNodeCompareType (AstNode const* node) { + TRI_ASSERT(node != nullptr); + if (node->type == NODE_TYPE_VALUE) { switch (node->value.type) { case VALUE_TYPE_NULL: @@ -158,7 +220,11 @@ static TRI_json_type_e GetNodeCompareType (AstNode const* node) { else if (node->type == NODE_TYPE_ARRAY) { return TRI_JSON_ARRAY; } + + // we should never get here TRI_ASSERT(false); + + // return null in case assertions are turned off return TRI_JSON_NULL; } @@ -166,7 +232,15 @@ static TRI_json_type_e GetNodeCompareType (AstNode const* node) { /// @brief compare two nodes //////////////////////////////////////////////////////////////////////////////// -int triagens::aql::CompareAstNodes (AstNode const* lhs, AstNode const* rhs) { +int triagens::aql::CompareAstNodes (AstNode const* lhs, + AstNode const* rhs) { + if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { + lhs = ResolveAttribute(lhs); + } + if (rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { + rhs = ResolveAttribute(rhs); + } + auto lType = GetNodeCompareType(lhs); auto rType = GetNodeCompareType(rhs); diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 15fab289f3..b9406634fd 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -92,7 +92,7 @@ void AggregatorGroup::reset () { delete (*it); } groupBlocks.clear(); - groupValues[0].erase(); + groupValues[0].erase(); // FIXMEFIXME warum nur 0??? } void AggregatorGroup::addValues (AqlItemBlock const* src, @@ -851,7 +851,8 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine, _anyBoundVariable(true), _skiplistIterator(nullptr), _condition(&en->_ranges), - _posInRanges(0) { + _posInRanges(0), + _freeCondition(false) { std::vector> const& orRanges = en->_ranges; TRI_ASSERT(en->_index != nullptr); @@ -876,6 +877,10 @@ IndexRangeBlock::~IndexRangeBlock () { delete e; } _allVariableBoundExpressions.clear(); + + if (_freeCondition && _condition != nullptr) { + delete _condition; + } } int IndexRangeBlock::initialize () { @@ -966,7 +971,9 @@ bool IndexRangeBlock::initRanges () { ENTER_BLOCK _flag = true; auto en = static_cast(getPlanNode()); + freeCondition(); _condition = &en->_ranges; + _freeCondition = false; TRI_ASSERT(en->_index != nullptr); @@ -1069,7 +1076,9 @@ bool IndexRangeBlock::initRanges () { orCombineIndexOrAndIndexAnd(newCondition, newAnd); } //_condition = newCondition.release(); + freeCondition(); _condition = newCondition; + _freeCondition = true; } if (en->_index->type == TRI_IDX_TYPE_PRIMARY_INDEX) { @@ -1086,12 +1095,19 @@ bool IndexRangeBlock::initRanges () { else if (en->_index->type == TRI_IDX_TYPE_EDGE_INDEX) { return true; //no initialization here! } - else { - TRI_ASSERT(false); - } + + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected index type"); LEAVE_BLOCK; } +void IndexRangeBlock::freeCondition () { + if (_condition != nullptr && _freeCondition) { + delete _condition; + _condition = nullptr; + _freeCondition = false; + } +} + // this is called every time everything in _documents has been passed on bool IndexRangeBlock::readIndex (size_t atMost) { @@ -1457,10 +1473,10 @@ void IndexRangeBlock::readHashIndex (IndexOrCondition const& ranges) { TRI_index_result_t list = TRI_LookupHashIndex(idx, &searchValue); destroySearchValue(); - size_t const n = list._length; + size_t const n = TRI_LengthVectorPointer(&list); try { for (size_t i = 0; i < n; ++i) { - _documents.emplace_back(*(list._documents[i])); + _documents.emplace_back(* (static_cast(TRI_AtVectorPointer(&list, i)))); } _engine->_stats.scannedIndex += static_cast(n); @@ -1569,7 +1585,7 @@ void IndexRangeBlock::readEdgeIndex (IndexOrCondition const& ranges) { void IndexRangeBlock::getSkiplistIterator (IndexAndCondition const& ranges) { ENTER_BLOCK; - TRI_ASSERT(_skiplistIterator == nullptr) + TRI_ASSERT(_skiplistIterator == nullptr); auto en = static_cast(getPlanNode()); TRI_index_t* idx = en->_index->data; @@ -2474,7 +2490,7 @@ int AggregateBlock::getOrSkipSome (size_t atLeast, } while (skipped < atMost) { - // read the next input tow + // read the next input row bool newGroup = false; if (_currentGroup.groupValues[0].isEmpty()) { diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index 94f3e41a57..5420841afe 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -562,6 +562,12 @@ namespace triagens { private: +//////////////////////////////////////////////////////////////////////////////// +/// @brief free _condition if it belongs to us +//////////////////////////////////////////////////////////////////////////////// + + void freeCondition (); + //////////////////////////////////////////////////////////////////////////////// /// @brief continue fetching of documents //////////////////////////////////////////////////////////////////////////////// @@ -685,6 +691,13 @@ namespace triagens { bool _flag; size_t _posInRanges; +//////////////////////////////////////////////////////////////////////////////// +/// @brief _freeCondition: whether or not the _condition is owned by the +/// IndexRangeBlock and must be freed +//////////////////////////////////////////////////////////////////////////////// + + bool _freeCondition; + }; // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index fd6acb4576..096bb5dc73 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -618,7 +618,9 @@ triagens::basics::Json ExecutionNode::toJsonHelperGeneric (triagens::basics::Jso } json("id", triagens::basics::Json(static_cast(id()))); - json("estimatedCost", triagens::basics::Json(getCost())); + size_t nrItems = 0; + json("estimatedCost", triagens::basics::Json(getCost(nrItems))); + json("estimatedNrItems", triagens::basics::Json(static_cast(nrItems))); if (verbose) { json("depth", triagens::basics::Json(static_cast(_depth))); @@ -1000,6 +1002,15 @@ void SingletonNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a singleton is 1, it produces one item only +//////////////////////////////////////////////////////////////////////////////// + +double SingletonNode::estimateCost (size_t& nrItems) const { + nrItems = 1; + return 1.0; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of EnumerateCollectionNode // ----------------------------------------------------------------------------- @@ -1165,6 +1176,20 @@ std::vector return out; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an enumerate collection node is a multiple of the cost of +/// its unique dependency +//////////////////////////////////////////////////////////////////////////////// + +double EnumerateCollectionNode::estimateCost (size_t& nrItems) const { + size_t incoming; + double depCost = _dependencies.at(0)->getCost(incoming); + size_t count = _collection->count(); + nrItems = incoming * count; + return depCost + count * incoming; + // We do a full collection scan for each incoming item. +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of EnumerateListNode // ----------------------------------------------------------------------------- @@ -1216,6 +1241,25 @@ ExecutionNode* EnumerateListNode::clone (ExecutionPlan* plan, return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an enumerate list node +//////////////////////////////////////////////////////////////////////////////// + +double EnumerateListNode::estimateCost (size_t& nrItems) const { + size_t incoming = 0; + double depCost = _dependencies.at(0)->getCost(incoming); + nrItems = 100*incoming; + return depCost + 100.0 * incoming; + // Well, what can we say? The length of the list can in general + // only be determined at runtime... If we were to know that this + // list is constant, then we could maybe multiply by the length + // here... For the time being, we assume 100 +} + +// ----------------------------------------------------------------------------- +// --SECTION-- methods of IndexRangeNode +// ----------------------------------------------------------------------------- + //////////////////////////////////////////////////////////////////////////////// /// @brief toJson, for IndexRangeNode //////////////////////////////////////////////////////////////////////////////// @@ -1326,27 +1370,31 @@ ExecutionNode::IndexMatch IndexRangeNode::MatchesIndex (IndexMatchVec const& pat /// @brief the cost of an index range node is a multiple of the cost of /// its unique dependency //////////////////////////////////////////////////////////////////////////////// - -double IndexRangeNode::estimateCost () const { - // the cost of the enumerate collection node we are replacing . . . - double const dependencyCost = _dependencies.at(0)->getCost(); - double const oldCost = static_cast(_collection->count()) * dependencyCost; + +double IndexRangeNode::estimateCost (size_t& nrItems) const { + size_t incoming = 0; + double const dependencyCost = _dependencies.at(0)->getCost(incoming); + size_t docCount = _collection->count(); TRI_ASSERT(! _ranges.empty()); if (_index->type == TRI_IDX_TYPE_PRIMARY_INDEX) { - return dependencyCost; + nrItems = incoming; + return dependencyCost + nrItems; } if (_index->type == TRI_IDX_TYPE_EDGE_INDEX) { - return oldCost / 1000; + nrItems = incoming * docCount / 1000; + return dependencyCost + nrItems; } if (_index->type == TRI_IDX_TYPE_HASH_INDEX) { if (_index->unique) { - return dependencyCost; + nrItems = incoming; + return dependencyCost + nrItems; } - return oldCost / 1000; + nrItems = incoming * docCount / 1000; + return dependencyCost + nrItems; } if (_index->type == TRI_IDX_TYPE_SKIPLIST_INDEX) { @@ -1354,22 +1402,24 @@ double IndexRangeNode::estimateCost () const { if (count == 0) { // no ranges? so this is unlimited -> has to be more expensive - return oldCost; + nrItems = incoming * docCount; + return dependencyCost + nrItems; } if (_index->unique && count == _index->fields.size()) { if (_ranges.at(0).back().is1ValueRangeInfo()) { // unique index, all attributes compared using eq (==) operator - return dependencyCost; + nrItems = incoming; + return dependencyCost + nrItems; } } - double cost = oldCost; + double cost = static_cast(docCount) * incoming; for (auto x: _ranges.at(0)) { //only doing the 1-d case so far if (x.is1ValueRangeInfo()) { // equality lookup - cost /= 100; + cost /= 100.0; continue; } @@ -1385,11 +1435,11 @@ double IndexRangeNode::estimateCost () const { if (hasLowerBound && hasUpperBound) { // both lower and upper bounds defined - cost /= 10; + cost /= 10.0; } else if (hasLowerBound || hasUpperBound) { // either only low or high bound defined - cost /= 2; + cost /= 2.0; } // each bound (const and dynamic) counts! @@ -1404,11 +1454,13 @@ double IndexRangeNode::estimateCost () const { } } - return cost; + nrItems = static_cast(cost); + return dependencyCost + cost; } // no index - return dependencyCost; + nrItems = incoming * docCount; + return dependencyCost + nrItems; } //////////////////////////////////////////////////////////////////////////////// @@ -1479,6 +1531,18 @@ void LimitNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double LimitNode::estimateCost (size_t& nrItems) const { + size_t incoming = 0; + double depCost = _dependencies.at(0)->getCost(incoming); + nrItems = (std::min)(_limit, (std::max)(static_cast(0), + incoming - _offset)); + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of CalculationNode // ----------------------------------------------------------------------------- @@ -1527,6 +1591,15 @@ ExecutionNode* CalculationNode::clone (ExecutionPlan* plan, return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double CalculationNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of SubqueryNode // ----------------------------------------------------------------------------- @@ -1577,6 +1650,17 @@ void SubqueryNode::replaceOutVariable(Variable const* var) { _outVariable = var; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double SubqueryNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + size_t dummy; + double subCost = _subquery->getCost(dummy); + return depCost + nrItems * subCost; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief helper struct to find all (outer) variables used in a SubqueryNode //////////////////////////////////////////////////////////////////////////////// @@ -1720,6 +1804,24 @@ ExecutionNode* FilterNode::clone (ExecutionPlan* plan, return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double FilterNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + // We are pessimistic here by not reducing the nrItems. However, in the + // worst case the filter does not reduce the items at all. Furthermore, + // no optimiser rule introduces FilterNodes, thus it is not important + // that they appear to lower the costs. Note that contrary to this, + // an IndexRangeNode does lower the costs, it also has a better idea + // to what extent the number of items is reduced. On the other hand it + // is important that a FilterNode produces additional costs, otherwise + // the rule throwing away a FilterNode that is already covered by an + // IndexRangeNode cannot reduce the costs. + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of SortNode // ----------------------------------------------------------------------------- @@ -1848,6 +1950,18 @@ SortInformation SortNode::getSortInformation (ExecutionPlan* plan, return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double SortNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + if (nrItems <= 3.0) { + return depCost + nrItems; + } + return depCost + nrItems * log(nrItems); +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of AggregateNode // ----------------------------------------------------------------------------- @@ -1970,6 +2084,21 @@ std::vector AggregateNode::getVariablesUsedHere () const { return vv; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double AggregateNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + // As in the FilterNode case, we are pessimistic here by not reducing the + // nrItems, since this is the worst case. We have to look at all incoming + // items, and in particular in the COLLECT ... INTO ... case, we have + // to actually hand on all data anyway, albeit not as separate items. + // Nevertheless, the optimiser does not do much with AggregateNodes + // and thus this overestimation does not really matter. + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of ReturnNode // ----------------------------------------------------------------------------- @@ -2019,6 +2148,15 @@ ExecutionNode* ReturnNode::clone (ExecutionPlan* plan, return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double ReturnNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies.at(0)->getCost(nrItems); + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- ModificationNode // ----------------------------------------------------------------------------- @@ -2048,6 +2186,19 @@ void ModificationNode::toJsonHelper (triagens::basics::Json& json, _options.toJson(json, zone); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +/// Note that all the modifying nodes use this estimateCost method which is +/// why we can make it final here. +//////////////////////////////////////////////////////////////////////////////// + +double ModificationNode::estimateCost (size_t& nrItems) const { + size_t incoming = 0; + double depCost = _dependencies.at(0)->getCost(incoming); + nrItems = 0; + return depCost + incoming; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of RemoveNode @@ -2342,6 +2493,15 @@ void NoResultsNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost, the cost of a NoResults is nearly 0 +//////////////////////////////////////////////////////////////////////////////// + +double NoResultsNode::estimateCost (size_t& nrItems) const { + nrItems = 0; + return 0.5; // just to make it non-zero +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of RemoteNode // ----------------------------------------------------------------------------- @@ -2382,6 +2542,24 @@ void RemoteNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double RemoteNode::estimateCost (size_t& nrItems) const { + double depCost; + if (_dependencies.size() == 1) { + // This will usually be the case, however, in the context of the + // instantiation it is possible that there is no dependency... + depCost = _dependencies[0]->estimateCost(nrItems); + return depCost + nrItems; // we need to process them all + } + // We really should not get here, but if so, do something bordering on + // sensible: + nrItems = 1; + return 1.0; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of ScatterNode // ----------------------------------------------------------------------------- @@ -2416,6 +2594,17 @@ void ScatterNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double ScatterNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies[0]->getCost(nrItems); + std::vector shardIds = _collection->shardIds(); + size_t nrShards = shardIds.size(); + return depCost + nrItems * nrShards; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of DistributeNode // ----------------------------------------------------------------------------- @@ -2449,6 +2638,15 @@ void DistributeNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double DistributeNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies[0]->getCost(nrItems); + return depCost + nrItems; +} + // ----------------------------------------------------------------------------- // --SECTION-- methods of GatherNode // ----------------------------------------------------------------------------- @@ -2494,6 +2692,15 @@ void GatherNode::toJsonHelper (triagens::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +//////////////////////////////////////////////////////////////////////////////// + +double GatherNode::estimateCost (size_t& nrItems) const { + double depCost = _dependencies[0]->getCost(nrItems); + return depCost + nrItems; +} + // Local Variables: // mode: outline-minor // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 02139cc7e0..869b8d16bd 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -116,6 +116,7 @@ namespace triagens { ExecutionNode (ExecutionPlan* plan, size_t id) : _id(id), _estimatedCost(0.0), + _estimatedNrItems(0), _estimatedCostSet(false), _varUsageValid(false), _plan(plan), @@ -383,19 +384,25 @@ namespace triagens { /// @brief estimate the cost of the node . . . //////////////////////////////////////////////////////////////////////////////// - double getCost () const { + double getCost (size_t& nrItems) const { if (! _estimatedCostSet) { - _estimatedCost = estimateCost(); + _estimatedCost = estimateCost(_estimatedNrItems); + nrItems = _estimatedNrItems; _estimatedCostSet = true; TRI_ASSERT(_estimatedCost >= 0.0); } + else { + nrItems = _estimatedNrItems; + } return _estimatedCost; }; - virtual double estimateCost () const = 0; +//////////////////////////////////////////////////////////////////////////////// +/// @brief this actually estimates the costs as well as the number of items +/// coming out of the node +//////////////////////////////////////////////////////////////////////////////// - //TODO nodes should try harder to estimate their own cost, i.e. the cost - //of performing the operation of the node . . . + virtual double estimateCost (size_t& nrItems) const = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief walk a complete execution plan recursively @@ -674,11 +681,14 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// /// @brief _estimatedCost = 0 if uninitialised and otherwise stores the result /// of estimateCost(), the bool indicates if the cost has been set, it starts -/// out as false +/// out as false, _estimatedNrItems is the estimated number of items coming +/// out of this node. //////////////////////////////////////////////////////////////////////////////// double mutable _estimatedCost; + size_t mutable _estimatedNrItems; + bool mutable _estimatedCostSet; //////////////////////////////////////////////////////////////////////////////// @@ -791,9 +801,7 @@ namespace triagens { /// @brief the cost of a singleton is 1 //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.0; - } + virtual double estimateCost (size_t&) const override final; }; @@ -862,10 +870,7 @@ namespace triagens { /// its unique dependency //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return static_cast(_collection->count()) * _dependencies.at(0)->getCost(); - //FIXME improve this estimate . . . - } + virtual double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesSetHere @@ -1014,10 +1019,7 @@ namespace triagens { /// @brief the cost of an enumerate list node is . . . FIXME //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1000 * _dependencies.at(0)->getCost(); - //FIXME improve this estimate . . . - } + virtual double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -1179,7 +1181,7 @@ namespace triagens { /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final; + virtual double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief check whether the pattern matches this node's index @@ -1309,14 +1311,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a limit node is the minimum of the _limit, and the cost -/// the dependency . . . +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.005 * static_cast(_limit) + _dependencies.at(0)->getCost(); - // FIXME: improve this estimate . . . - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief tell the node to fully count what it will limit @@ -1434,14 +1432,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a calculation node is the cost of the unique dependency -// times a constant +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 2 * _dependencies.at(0)->getCost(); - //FIXME improve this estimate . . . - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -1572,14 +1566,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a subquery node is the cost of its unique dependency -/// times a small constant +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.005 * _dependencies.at(0)->getCost(); - //FIXME improve this estimate . . . - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -1687,14 +1677,10 @@ namespace triagens { bool withProperties) const; //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a filter node is . . . FIXME +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return _dependencies.at(0)->getCost() * 1.105; - // FIXME! 1.105 is the cost of doing the filter node under the - // assumption that it returns 10% of the results of its dependency - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -1849,16 +1835,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a sort node is . . . FIXME +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - double depCost = _dependencies.at(0)->getCost(); - if (depCost <= 3.0) { - return depCost; - } - return log(depCost) * depCost; - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -1974,13 +1954,10 @@ namespace triagens { bool withProperties) const; //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of an aggregate node is . . . FIXME +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 2 * _dependencies.at(0)->getCost(); - //FIXME improve this estimate . . . - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the node has an outVariable (i.e. INTO ...) @@ -2094,12 +2071,10 @@ namespace triagens { bool withProperties) const; //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a return node is the cost of its only dependency . . . +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return _dependencies.at(0)->getCost(); - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere @@ -2192,6 +2167,14 @@ namespace triagens { return _collection; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimateCost +/// Note that all the modifying nodes use this estimateCost method which is +/// why we can make it final here. +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost (size_t&) const override final; + // ----------------------------------------------------------------------------- // --SECTION-- protected variables // ----------------------------------------------------------------------------- @@ -2280,16 +2263,6 @@ namespace triagens { bool withDependencies, bool withProperties) const; -//////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a remove node is a multiple of the cost of its unique -/// dependency -//////////////////////////////////////////////////////////////////////////////// - - double estimateCost () const override final { - return _dependencies.at(0)->getCost(); - // TODO: improve this estimate! - } - //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere //////////////////////////////////////////////////////////////////////////////// @@ -2393,15 +2366,6 @@ namespace triagens { bool withDependencies, bool withProperties) const; -//////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of an insert node is a multiple of the cost of its unique -/// dependency -//////////////////////////////////////////////////////////////////////////////// - - double estimateCost () const override final { - return 1000 * _dependencies.at(0)->getCost(); //FIXME change this! - } - //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere //////////////////////////////////////////////////////////////////////////////// @@ -2508,15 +2472,6 @@ namespace triagens { bool withDependencies, bool withProperties) const; -//////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of an update node is a multiple of the cost of its unique -/// dependency -//////////////////////////////////////////////////////////////////////////////// - - double estimateCost () const override final { - return 1000 * _dependencies.at(0)->getCost(); //FIXME change this! - } - //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere //////////////////////////////////////////////////////////////////////////////// @@ -2633,15 +2588,6 @@ namespace triagens { bool withDependencies, bool withProperties) const; -//////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a replace node is a multiple of the cost of its unique -/// dependency -//////////////////////////////////////////////////////////////////////////////// - - double estimateCost () const override final { - return 1000 * _dependencies.at(0)->getCost(); //FIXME change this! - } - //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere //////////////////////////////////////////////////////////////////////////////// @@ -2755,9 +2701,7 @@ namespace triagens { /// @brief the cost of a NoResults is 0 //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 0.0; - } + double estimateCost (size_t&) const override final; }; @@ -2829,19 +2773,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a remote node is that of its dependency, -/// times a factor for extra HTTP work +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - if (_dependencies.size() == 1) { - // the 1.5 is an arbitrary factor to account for some overhead of the - // remote processing, HTTP communication etc. - return 1.5 * _dependencies[0]->estimateCost(); - } - - return 1.5; - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief return the database @@ -3012,12 +2947,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a scatter node is 1 +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.0; - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief return the database @@ -3115,12 +3048,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a distribute node is 1 +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.0; - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief return the database @@ -3223,12 +3154,10 @@ namespace triagens { } //////////////////////////////////////////////////////////////////////////////// -/// @brief the cost of a gather node is 1 +/// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// - double estimateCost () const override final { - return 1.0; - } + double estimateCost (size_t&) const override final; //////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index 35e0fb3de2..321ce37676 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -183,7 +183,9 @@ triagens::basics::Json ExecutionPlan::toJson (Ast* ast, result.set("collections", jsonCollectionList); result.set("variables", ast->variables()->toJson(TRI_UNKNOWN_MEM_ZONE)); - result.set("estimatedCost", triagens::basics::Json(_root->getCost())); + size_t nrItems = 0; + result.set("estimatedCost", triagens::basics::Json(_root->getCost(nrItems))); + result.set("estimatedNrItems", triagens::basics::Json(static_cast(nrItems))); return result; } @@ -1014,12 +1016,28 @@ void ExecutionPlan::checkLinkage () { struct VarUsageFinder : public WalkerWorker { std::unordered_set _usedLater; std::unordered_set _valid; - std::unordered_map _varSetBy; + std::unordered_map* _varSetBy; + bool const _ownsVarSetBy; - VarUsageFinder () { + VarUsageFinder () + : _varSetBy(new std::unordered_map()), + _ownsVarSetBy(true) { + + TRI_ASSERT(_varSetBy != nullptr); } - + + explicit VarUsageFinder (std::unordered_map* varSetBy) + : _varSetBy(varSetBy), + _ownsVarSetBy(false) { + + TRI_ASSERT(_varSetBy != nullptr); + } + ~VarUsageFinder () { + if (_ownsVarSetBy) { + TRI_ASSERT(_varSetBy != nullptr); + delete _varSetBy; + } } bool before (ExecutionNode* en) override final { @@ -1038,14 +1056,14 @@ struct VarUsageFinder : public WalkerWorker { auto&& setHere = en->getVariablesSetHere(); for (auto v : setHere) { _valid.insert(v); - _varSetBy.emplace(std::make_pair(v->id, en)); + _varSetBy->emplace(std::make_pair(v->id, en)); } en->setVarsValid(_valid); en->setVarUsageValid(); } bool enterSubquery (ExecutionNode*, ExecutionNode* sub) override final { - VarUsageFinder subfinder; + VarUsageFinder subfinder(_varSetBy); subfinder._valid = _valid; // need a copy for the subquery! sub->walk(&subfinder); @@ -1061,7 +1079,7 @@ struct VarUsageFinder : public WalkerWorker { void ExecutionPlan::findVarUsage () { ::VarUsageFinder finder; root()->walk(&finder); - _varSetBy = finder._varSetBy; + _varSetBy = *finder._varSetBy; _varUsageComputed = true; } @@ -1128,7 +1146,7 @@ void ExecutionPlan::replaceNode (ExecutionNode* oldNode, std::vector deps = oldNode->getDependencies(); // Intentional copy - + for (auto* x : deps) { newNode->addDependency(x); oldNode->removeDependency(x); @@ -1136,7 +1154,7 @@ void ExecutionPlan::replaceNode (ExecutionNode* oldNode, auto oldNodeParents = oldNode->getParents(); // Intentional copy for (auto* oldNodeParent : oldNodeParents) { - if(! oldNodeParent->replaceDependency(oldNode, newNode)){ + if (! oldNodeParent->replaceDependency(oldNode, newNode)){ THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "Could not replace dependencies of an old node."); } diff --git a/arangod/Aql/ExecutionPlan.h b/arangod/Aql/ExecutionPlan.h index 8476e3504d..1cdbd6a20b 100644 --- a/arangod/Aql/ExecutionPlan.h +++ b/arangod/Aql/ExecutionPlan.h @@ -184,7 +184,8 @@ namespace triagens { inline double getCost () { TRI_ASSERT(_root != nullptr); - return _root->getCost(); + size_t nrItems; + return _root->getCost(nrItems); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Executor.cpp b/arangod/Aql/Executor.cpp index 8d34b6cc43..88cbd9c6b3 100644 --- a/arangod/Aql/Executor.cpp +++ b/arangod/Aql/Executor.cpp @@ -155,6 +155,17 @@ std::unordered_map const Executor::FunctionNames{ { "LAST", Function("LAST", "AQL_LAST", "l", true, false, true) }, { "NTH", Function("NTH", "AQL_NTH", "l,n", true, false, true) }, { "POSITION", Function("POSITION", "AQL_POSITION", "l,.|b", true, false, true) }, + { "CALL", Function("CALL", "AQL_CALL", "s|.+", false, true, false) }, + { "APPLY", Function("APPLY", "AQL_APPLY", "s|l", false, true, false) }, + { "PUSH", Function("PUSH", "AQL_PUSH", "l,.|b", true, false, false) }, + { "APPEND", Function("APPEND", "AQL_APPEND", "l,lz|b", true, false, false) }, + { "POP", Function("POP", "AQL_POP", "l", true, false, false) }, + { "POP", Function("POP", "AQL_POP", "l", true, false, false) }, + { "SHIFT", Function("SHIFT", "AQL_SHIFT", "l", true, false, false) }, + { "UNSHIFT", Function("UNSHIFT", "AQL_UNSHIFT", "l,.|b", true, false, false) }, + { "REMOVE_VALUE", Function("REMOVE_VALUE", "AQL_REMOVE_VALUE", "l,.|n", true, false, false) }, + { "REMOVE_VALUES", Function("REMOVE_VALUES", "AQL_REMOVE_VALUES", "l,lz", true, false, false) }, + { "REMOVE_NTH", Function("REMOVE_NTH", "AQL_REMOVE_NTH", "l,n", true, false, false) }, // document functions { "HAS", Function("HAS", "AQL_HAS", "az,s", true, false, true) }, @@ -167,7 +178,7 @@ std::unordered_map const Executor::FunctionNames{ { "UNSET", Function("UNSET", "AQL_UNSET", "a,sl|+", true, false, true) }, { "KEEP", Function("KEEP", "AQL_KEEP", "a,sl|+", true, false, true) }, { "TRANSLATE", Function("TRANSLATE", "AQL_TRANSLATE", ".,a|.", true, false, true) }, - { "ASSEMBLE", Function("ASSEMBLE", "AQL_ASSEMBLE", "l,l", true, false, true) }, + { "ZIP", Function("ZIP", "AQL_ZIP", "l,l", true, false, true) }, // geo functions { "NEAR", Function("NEAR", "AQL_NEAR", "h,n,n|nz,s", false, true, false) }, diff --git a/arangod/Aql/Expression.cpp b/arangod/Aql/Expression.cpp index 919fa28368..7a994c8a91 100644 --- a/arangod/Aql/Expression.cpp +++ b/arangod/Aql/Expression.cpp @@ -376,18 +376,22 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs); if (result.isList()) { - if (index->isNumericValue()) { - auto j = result.extractListMember(trx, myCollection, index->getIntValue(), true); + TRI_document_collection_t const* myCollection2 = nullptr; + AqlValue indexResult = executeSimpleExpression(index, &myCollection2, trx, docColls, argv, startPos, vars, regs); + + if (indexResult.isNumber()) { + auto j = result.extractListMember(trx, myCollection, indexResult.toInt64(), true); + indexResult.destroy(); result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } - else if (index->isStringValue()) { - char const* p = index->getStringValue(); - TRI_ASSERT(p != nullptr); + else if (indexResult.isString()) { + auto&& value = indexResult.toString(); + indexResult.destroy(); try { // stoll() might throw an exception if the string is not a number - int64_t position = static_cast(std::stoll(p)); + int64_t position = static_cast(std::stoll(value.c_str())); auto j = result.extractListMember(trx, myCollection, position, true); result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); @@ -399,17 +403,21 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node, // fall-through to returning null } else if (result.isArray()) { - if (index->isNumericValue()) { - std::string const indexString = std::to_string(index->getIntValue()); + TRI_document_collection_t const* myCollection2 = nullptr; + AqlValue indexResult = executeSimpleExpression(index, &myCollection2, trx, docColls, argv, startPos, vars, regs); + + if (indexResult.isNumber()) { + auto&& indexString = std::to_string(indexResult.toInt64()); auto j = result.extractArrayMember(trx, myCollection, indexString.c_str()); + indexResult.destroy(); result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } - else if (index->isStringValue()) { - char const* p = index->getStringValue(); - TRI_ASSERT(p != nullptr); + else if (indexResult.isString()) { + auto&& value = indexResult.toString(); + indexResult.destroy(); - auto j = result.extractArrayMember(trx, myCollection, p); + auto j = result.extractArrayMember(trx, myCollection, value.c_str()); result.destroy(); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal())); } diff --git a/arangod/Aql/Function.h b/arangod/Aql/Function.h index bf86ce3245..8fa7414e47 100644 --- a/arangod/Aql/Function.h +++ b/arangod/Aql/Function.h @@ -177,7 +177,7 @@ namespace triagens { /// @brief maximum number of function arguments that can be used //////////////////////////////////////////////////////////////////////////////// - static size_t const MaxArguments = 1024; + static size_t const MaxArguments = 65536; }; diff --git a/arangod/Aql/Optimizer.h b/arangod/Aql/Optimizer.h index 2ee2c431ce..23385511e8 100644 --- a/arangod/Aql/Optimizer.h +++ b/arangod/Aql/Optimizer.h @@ -151,26 +151,26 @@ namespace triagens { ////////////////////////////////////////////////////////////////////////////// // make operations on sharded collections use distribute - distributeInCluster_pass10 = 1000, + distributeInCluster_pass10 = 1000, // make operations on sharded collections use scatter / gather / remote - scatterInCluster_pass10 = 1010, + scatterInCluster_pass10 = 1010, // move FilterNodes & Calculation nodes inbetween // scatter(remote) <-> gather(remote) so they're // distributed to the cluster nodes. - distributeFilternCalcToCluster_pass10 = 1020, + distributeFilternCalcToCluster_pass10 = 1020, // move SortNodes into the distribution. // adjust gathernode to also contain the sort criterions. - distributeSortToCluster_pass10 = 1030, + distributeSortToCluster_pass10 = 1030, // try to get rid of a RemoteNode->ScatterNode combination which has // only a SingletonNode and possibly some CalculationNodes as dependencies - removeUnnecessaryRemoteScatter_pass10 = 1040, + removeUnnecessaryRemoteScatter_pass10 = 1040, //recognise that a RemoveNode can be moved to the shards - undistributeRemoveAfterEnumColl_pass10 = 1050 + undistributeRemoveAfterEnumColl_pass10 = 1050 }; public: @@ -196,7 +196,7 @@ namespace triagens { struct Rule { std::string name; RuleFunction func; - RuleLevel level; + RuleLevel const level; bool const canBeDisabled; Rule () = delete; @@ -346,12 +346,19 @@ namespace triagens { }; +// ----------------------------------------------------------------------------- +// --SECTION-- constructors / destructors +// ----------------------------------------------------------------------------- + + public: + //////////////////////////////////////////////////////////////////////////////// /// @brief constructor, this will initialize the rules database +/// the .cpp file includes Aql/OptimizerRules.h +/// and add all methods there to the rules database //////////////////////////////////////////////////////////////////////////////// - Optimizer (size_t); // the .cpp file includes Aql/OptimizerRules.h - // and add all methods there to the rules database + explicit Optimizer (size_t); //////////////////////////////////////////////////////////////////////////////// /// @brief destructor @@ -360,6 +367,12 @@ namespace triagens { ~Optimizer () { } +// ----------------------------------------------------------------------------- +// --SECTION-- public methods +// ----------------------------------------------------------------------------- + + public: + //////////////////////////////////////////////////////////////////////////////// /// @brief do the optimization, this does the optimization, the resulting /// plans are all estimated, sorted by that estimate and can then be got @@ -440,6 +453,21 @@ namespace triagens { static std::vector translateRules (std::vector const&); +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the previous rule (sorted by rule levels) +//////////////////////////////////////////////////////////////////////////////// + + static RuleLevel previousRule (RuleLevel level) { + auto it = _rules.find(level); + if (it == _rules.begin()) { + // already at start + return level; + } + + --it; + return (*it).second.level; + } + // ----------------------------------------------------------------------------- // --SECTION-- private methods // ----------------------------------------------------------------------------- diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 87bd9ec978..712060a2d4 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -1081,7 +1081,10 @@ class FilterToEnumCollFinder : public WalkerWorker { indexOrCondition, false); newPlan->registerNode(newNode); newPlan->replaceNode(newPlan->getNodeById(node->id()), newNode); - _opt->addPlan(newPlan, _level, true); + // re-inject the new plan with the previous rule so it gets passed through + // use-index-range optimization again + // this allows to enable even more indexes + _opt->addPlan(newPlan, Optimizer::previousRule(_level), true); } catch (...) { delete newPlan; @@ -1138,6 +1141,7 @@ class FilterToEnumCollFinder : public WalkerWorker { auto lhs = node->getMember(0); auto rhs = node->getMember(1); RangeInfoMap* rim = new RangeInfoMap(); + if (rhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { findVarAndAttr(rhs, enumCollVar, attr); if (enumCollVar != nullptr) { @@ -1849,9 +1853,6 @@ int triagens::aql::removeFiltersCoveredByIndex (Optimizer* opt, while (current != nullptr) { if (current->getType() == EN::INDEX_RANGE) { // found an index range, now check if the expression is covered by the index - auto variable = static_cast(current)->outVariable(); - TRI_ASSERT(variable != nullptr); - auto const& ranges = static_cast(current)->ranges(); // TODO: this is not prepared for OR conditions @@ -2699,7 +2700,7 @@ struct CommonNodeFinder { bool find (AstNode const* node, AstNodeType condition, AstNode const*& commonNode, - std::string& commonName ) { + std::string& commonName) { if (node->type == NODE_TYPE_OPERATOR_BINARY_OR) { return (find(node->getMember(0), condition, commonNode, commonName) @@ -2819,7 +2820,7 @@ struct OrToInConverter { } bool canConvertExpression (AstNode const* node) { - if(finder.find(node, NODE_TYPE_OPERATOR_BINARY_EQ, commonNode, commonName)){ + if (finder.find(node, NODE_TYPE_OPERATOR_BINARY_EQ, commonNode, commonName)) { return canConvertExpressionWalker(node); } return false; @@ -2853,9 +2854,7 @@ struct OrToInConverter { node->type == NODE_TYPE_INDEXED_ACCESS) { // get a string representation of the node for comparisons return (node->toString() == commonName); - } else if (node->isBoolValue()) { - return true; - } + } return false; } diff --git a/arangod/HashIndex/hash-array-multi.cpp b/arangod/HashIndex/hash-array-multi.cpp index 002f1f2fa8..efe895c2f4 100644 --- a/arangod/HashIndex/hash-array-multi.cpp +++ b/arangod/HashIndex/hash-array-multi.cpp @@ -480,6 +480,58 @@ TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief lookups an element given a key and a state +//////////////////////////////////////////////////////////////////////////////// + +TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const* array, + TRI_index_search_value_t const* key, + TRI_hash_index_element_multi_t*& next, + size_t batchSize) { + TRI_ASSERT_EXPENSIVE(array->_nrUsed < array->_nrAlloc); + TRI_ASSERT(batchSize > 0); + + // ........................................................................... + // initialise the vector which will hold the result if any + // ........................................................................... + + TRI_vector_pointer_t result; + TRI_InitVectorPointer(&result, TRI_UNKNOWN_MEM_ZONE); + + if (next == nullptr) { + // no previous state. start at the beginning + uint64_t const n = array->_nrAlloc; + uint64_t i, k; + + i = k = HashKey(array, key) % n; + + for (; i < n && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i); + if (i == n) { + for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i); + } + + TRI_ASSERT_EXPENSIVE(i < n); + + if (array->_table[i]._document != nullptr) { + TRI_PushBackVectorPointer(&result, array->_table[i]._document); + } + next = array->_table[i]._next; + } + + if (next != nullptr) { + // we already had a state + size_t total = TRI_LengthVectorPointer(&result);; + + while (next != nullptr && total < batchSize) { + TRI_PushBackVectorPointer(&result, next->_document); + next = next->_next; + ++total; + } + } + + return result; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief adds an element to the array /// diff --git a/arangod/HashIndex/hash-array-multi.h b/arangod/HashIndex/hash-array-multi.h index 8f4fe66158..78db87764b 100644 --- a/arangod/HashIndex/hash-array-multi.h +++ b/arangod/HashIndex/hash-array-multi.h @@ -120,6 +120,15 @@ int TRI_ResizeHashArrayMulti (TRI_hash_array_multi_t*, TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const*, struct TRI_index_search_value_s const*); +//////////////////////////////////////////////////////////////////////////////// +/// @brief lookups an element given a key and a state +//////////////////////////////////////////////////////////////////////////////// + +TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const*, + struct TRI_index_search_value_s const*, + struct TRI_hash_index_element_multi_s*&, + size_t); + //////////////////////////////////////////////////////////////////////////////// /// @brief adds an element to the array //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/HashIndex/hash-index.cpp b/arangod/HashIndex/hash-index.cpp index 5302516954..fbbc267502 100644 --- a/arangod/HashIndex/hash-index.cpp +++ b/arangod/HashIndex/hash-index.cpp @@ -289,37 +289,24 @@ static int HashIndex_remove (TRI_hash_index_t* hashIndex, //////////////////////////////////////////////////////////////////////////////// /// @brief locates a key within the hash array part +/// it is the callers responsibility to destroy the result //////////////////////////////////////////////////////////////////////////////// -static TRI_index_result_t HashIndex_find (TRI_hash_index_t* hashIndex, - TRI_index_search_value_t* key) { - TRI_hash_index_element_t* result; - TRI_index_result_t results; +static TRI_vector_pointer_t HashIndex_find (TRI_hash_index_t* hashIndex, + TRI_index_search_value_t* key) { + TRI_vector_pointer_t results; + TRI_InitVectorPointer(&results, TRI_UNKNOWN_MEM_ZONE); // ............................................................................. // A find request means that a set of values for the "key" was sent. We need // to locate the hash array entry by key. // ............................................................................. - result = TRI_FindByKeyHashArray(&hashIndex->_hashArray, key); + TRI_hash_index_element_t* result = TRI_FindByKeyHashArray(&hashIndex->_hashArray, key); if (result != nullptr) { - // unique hash index: maximum number is 1 - results._length = 1; - results._documents = static_cast(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, 1 * sizeof(TRI_doc_mptr_t*), false)); - - if (results._documents == nullptr) { - // no memory. prevent worst case by re-setting results length to 0 - results._length = 0; - return results; - } - - results._documents[0] = result->_document; - } - else { - results._length = 0; - results._documents = nullptr; + TRI_PushBackVectorPointer(&results, result->_document); } return results; @@ -395,46 +382,6 @@ int MultiHashIndex_remove (TRI_hash_index_t* hashIndex, return res; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief locates a key within the hash array part -//////////////////////////////////////////////////////////////////////////////// - -static TRI_index_result_t MultiHashIndex_find (TRI_hash_index_t* hashIndex, - TRI_index_search_value_t* key) { - TRI_index_result_t results; - - // ............................................................................. - // We can only use the LookupByKey method for non-unique hash indexes, since - // we want more than one result returned! - // ............................................................................. - - TRI_vector_pointer_t result = TRI_LookupByKeyHashArrayMulti(&hashIndex->_hashArrayMulti, key); - - if (result._length == 0) { - results._length = 0; - results._documents = nullptr; - } - else { - results._length = result._length; - results._documents = static_cast(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, result._length * sizeof(TRI_doc_mptr_t*), false)); - - if (results._documents == nullptr) { - // no memory. prevent worst case by re-setting results length to 0 - TRI_DestroyVectorPointer(&result); - results._length = 0; - - return results; - } - - for (size_t j = 0; j < result._length; ++j) { - results._documents[j] = ((TRI_doc_mptr_t*) result._buffer[j]); - } - } - - TRI_DestroyVectorPointer(&result); - return results; -} - // ----------------------------------------------------------------------------- // --SECTION-- HASH INDEX // ----------------------------------------------------------------------------- @@ -698,18 +645,41 @@ void TRI_FreeHashIndex (TRI_index_t* idx) { //////////////////////////////////////////////////////////////////////////////// /// @brief locates entries in the hash index given shaped json objects +/// it is the callers responsibility to destroy the result //////////////////////////////////////////////////////////////////////////////// -TRI_index_result_t TRI_LookupHashIndex (TRI_index_t* idx, - TRI_index_search_value_t* searchValue) { +TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t* idx, + TRI_index_search_value_t* searchValue) { TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx; if (hashIndex->base._unique) { return HashIndex_find(hashIndex, searchValue); } - else { - return MultiHashIndex_find(hashIndex, searchValue); + + return TRI_LookupByKeyHashArrayMulti(&hashIndex->_hashArrayMulti, searchValue); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief locates entries in the hash index given shaped json objects +/// this function uses the state passed to it to return a fragment of the +/// total result - the next call to the function can resume at the state where +/// it was left off last +/// note: state is ignored for unique indexes as there will be at most one +/// item in the result +/// it is the callers responsibility to destroy the result +//////////////////////////////////////////////////////////////////////////////// + +TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t* idx, + TRI_index_search_value_t* searchValue, + TRI_hash_index_element_multi_t*& next, + size_t batchSize) { + TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx; + + if (hashIndex->base._unique) { + return HashIndex_find(hashIndex, searchValue); } + + return TRI_LookupByKeyHashArrayMulti(&hashIndex->_hashArrayMulti, searchValue, next, batchSize); } // ----------------------------------------------------------------------------- diff --git a/arangod/HashIndex/hash-index.h b/arangod/HashIndex/hash-index.h index e00a483745..9e323b6911 100644 --- a/arangod/HashIndex/hash-index.h +++ b/arangod/HashIndex/hash-index.h @@ -55,19 +55,25 @@ struct TRI_shaped_sub_s; //////////////////////////////////////////////////////////////////////////////// /// @brief hash index element /// -/// This structure is used for the elements of an hash index. +/// This structure is used for the elements of a unique hash index. //////////////////////////////////////////////////////////////////////////////// typedef struct TRI_hash_index_element_s { - struct TRI_doc_mptr_t* _document; - struct TRI_shaped_sub_s* _subObjects; + struct TRI_doc_mptr_t* _document; + struct TRI_shaped_sub_s* _subObjects; } TRI_hash_index_element_t; +//////////////////////////////////////////////////////////////////////////////// +/// @brief hash index element +/// +/// This structure is used for the elements of a non-unique hash index. +//////////////////////////////////////////////////////////////////////////////// + typedef struct TRI_hash_index_element_multi_s { - struct TRI_doc_mptr_t* _document; - struct TRI_shaped_sub_s* _subObjects; - struct TRI_hash_index_element_multi_s* _next; + struct TRI_doc_mptr_t* _document; + struct TRI_shaped_sub_s* _subObjects; + struct TRI_hash_index_element_multi_s* _next; } TRI_hash_index_element_multi_t; @@ -79,10 +85,10 @@ typedef struct TRI_hash_index_s { TRI_index_t base; union { - TRI_hash_array_t _hashArray; // the hash array itself, unique values + TRI_hash_array_t _hashArray; // the hash array itself, unique values TRI_hash_array_multi_t _hashArrayMulti; // the hash array itself, non-unique values }; - TRI_vector_t _paths; // a list of shape pid which identifies the fields of the index + TRI_vector_t _paths; // a list of shape pid which identifies the fields of the index } TRI_hash_index_t; @@ -118,10 +124,26 @@ void TRI_FreeHashIndex (TRI_index_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief locates entries in the hash index given shaped json objects +/// it is the callers responsibility to destroy the result //////////////////////////////////////////////////////////////////////////////// -TRI_index_result_t TRI_LookupHashIndex (TRI_index_t*, - struct TRI_index_search_value_s*); +TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t*, + struct TRI_index_search_value_s*); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief locates entries in the hash index given shaped json objects +/// this function uses the state passed to it to return a fragment of the +/// total result - the next call to the function can resume at the state where +/// it was left off last +/// note: state is ignored for unique indexes as there will be at most one +/// item in the result +/// it is the callers responsibility to destroy the result +//////////////////////////////////////////////////////////////////////////////// + +TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t*, + struct TRI_index_search_value_s*, + struct TRI_hash_index_element_multi_s*&, + size_t); #endif diff --git a/arangod/Replication/ContinuousSyncer.cpp b/arangod/Replication/ContinuousSyncer.cpp index bbea58c803..c1126ef15a 100644 --- a/arangod/Replication/ContinuousSyncer.cpp +++ b/arangod/Replication/ContinuousSyncer.cpp @@ -307,6 +307,20 @@ int ContinuousSyncer::processDocument (TRI_replication_operation_e type, return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND; } + // extract optional "cname" + TRI_json_t const* cnameJson = JsonHelper::getArrayElement(json, "cname"); + + if (JsonHelper::isString(cnameJson)) { + string const cnameString = JsonHelper::getStringValue(json, "cname", ""); + if (! cnameString.empty() && cnameString[0] == '_') { + // system collection + TRI_vocbase_col_t* col = TRI_LookupCollectionByNameVocBase(_vocbase, cnameString.c_str()); + if (col != nullptr && col->_cid != cid) { + // cid change? this may happen for system collections + cid = col->_cid; + } + } + } // extract "key" TRI_json_t const* keyJson = JsonHelper::getArrayElement(json, "key"); @@ -724,8 +738,8 @@ int ContinuousSyncer::applyLog (SimpleHttpResult* response, } if (ignoreCount == 0) { - if (line.size() > 128) { - errorMsg += ", offending marker: " + line.substr(0, 128) + "..."; + if (line.size() > 256) { + errorMsg += ", offending marker: " + line.substr(0, 256) + "..."; } else { errorMsg += ", offending marker: " + line;; diff --git a/arangod/Utils/ExplicitTransaction.h b/arangod/Utils/ExplicitTransaction.h index 998c16cb78..140f2975f6 100644 --- a/arangod/Utils/ExplicitTransaction.h +++ b/arangod/Utils/ExplicitTransaction.h @@ -62,8 +62,9 @@ namespace triagens { std::vector const& readCollections, std::vector const& writeCollections, double lockTimeout, - bool waitForSync) - : Transaction(new V8TransactionContext(false), vocbase, 0) { + bool waitForSync, + bool embed) + : Transaction(new V8TransactionContext(embed), vocbase, 0) { // std::cout << TRI_CurrentThreadId() << ", EXPLICITTRANSACTION " << this << " CTOR\r\n"; this->addHint(TRI_TRANSACTION_HINT_LOCK_ENTIRELY, false); diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index 8f8ab66bf1..c9cc99fad2 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -3420,9 +3420,9 @@ static v8::Handle JS_CheckPointersVocbaseCol (v8::Arguments const& ar /// `db._changeMode()` /// /// Sets the server to the given mode. -/// Possible parameters for mode are: +/// Possible values for mode are: /// - Normal -/// - ReadOnly +/// - NoCreate /// /// `db._changeMode()` /// diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 0407421634..f153b56225 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -1589,11 +1589,11 @@ static v8::Handle ByExampleHashIndexQuery (SingleCollectionReadOnlyTr } // find the matches - TRI_index_result_t list = TRI_LookupHashIndex(idx, &searchValue); + TRI_vector_pointer_t list = TRI_LookupHashIndex(idx, &searchValue); DestroySearchValue(shaper->_memoryZone, searchValue); // convert result - size_t total = list._length; + size_t total = TRI_LengthVectorPointer(&list); size_t count = 0; bool error = false; @@ -1605,7 +1605,7 @@ static v8::Handle ByExampleHashIndexQuery (SingleCollectionReadOnlyTr if (s < e) { for (size_t i = s; i < e; ++i) { - v8::Handle doc = WRAP_SHAPED_JSON(trx, collection->_cid, list._documents[i]->getDataPtr()); + v8::Handle doc = WRAP_SHAPED_JSON(trx, collection->_cid, static_cast(TRI_AtVectorPointer(&list, i))->getDataPtr()); if (doc.IsEmpty()) { error = true; @@ -1619,7 +1619,7 @@ static v8::Handle ByExampleHashIndexQuery (SingleCollectionReadOnlyTr } // free data allocated by hash index result - TRI_DestroyIndexResult(&list); + TRI_DestroyVectorPointer(&list); result->Set(v8::String::New("total"), v8::Number::New((double) total)); result->Set(v8::String::New("count"), v8::Number::New((double) count)); @@ -2535,7 +2535,7 @@ void TRI_InitV8Queries (v8::Handle context) { TRI_AddMethodVocbase(rt, "OFFSET", JS_OffsetQuery, true); TRI_AddMethodVocbase(rt, "OUTEDGES", JS_OutEdgesQuery, true); - TRI_AddMethodVocbase(rt, "WITHIN", JS_WithinQuery); + TRI_AddMethodVocbase(rt, "WITHIN", JS_WithinQuery, true); } // ----------------------------------------------------------------------------- diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 2728c2bc01..5e2196daa0 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -277,6 +277,11 @@ static v8::Handle JS_Transaction (v8::Arguments const& argv) { TRI_V8_EXCEPTION(scope, TRI_ERROR_INTERNAL); } + bool embed = false; + if (object->Has(TRI_V8_SYMBOL("embed"))) { + v8::Handle v = v8::Handle::Cast(object->Get(TRI_V8_SYMBOL("embed"))); + embed = TRI_ObjectToBoolean(v); + } v8::Handle current = v8::Context::GetCurrent()->Global(); @@ -306,13 +311,13 @@ static v8::Handle JS_Transaction (v8::Arguments const& argv) { TRI_V8_EXCEPTION_PARAMETER(scope, actionError); } - // start actual transaction ExplicitTransaction trx(vocbase, readCollections, writeCollections, lockTimeout, - waitForSync); + waitForSync, + embed); int res = trx.begin(); diff --git a/arangod/V8Server/v8-vocindex.cpp b/arangod/V8Server/v8-vocindex.cpp index 360172145c..4706e241d4 100644 --- a/arangod/V8Server/v8-vocindex.cpp +++ b/arangod/V8Server/v8-vocindex.cpp @@ -1643,7 +1643,7 @@ static v8::Handle CreateVocBase (v8::Arguments const& argv, /// a document will only return after the data was synced to disk. /// /// * *journalSize* (optional, default is a -/// [configuration parameter](../CommandLineOptions/Arangod.md): The maximal +/// configuration parameter: The maximal /// size of a journal or datafile. Note that this also limits the maximal /// size of a single object. Must be at least 1MB. /// diff --git a/arangod/VocBase/index.cpp b/arangod/VocBase/index.cpp index 28d58ef7f5..9b4fa9715b 100644 --- a/arangod/VocBase/index.cpp +++ b/arangod/VocBase/index.cpp @@ -105,32 +105,6 @@ void TRI_InitIndex (TRI_index_t* idx, // --SECTION-- public functions // ----------------------------------------------------------------------------- -//////////////////////////////////////////////////////////////////////////////// -/// @brief whether or not an index needs full coverage -//////////////////////////////////////////////////////////////////////////////// - -bool TRI_NeedsFullCoverageIndex (TRI_idx_type_e type) { - switch (type) { - case TRI_IDX_TYPE_PRIMARY_INDEX: - case TRI_IDX_TYPE_EDGE_INDEX: - case TRI_IDX_TYPE_HASH_INDEX: - case TRI_IDX_TYPE_SKIPLIST_INDEX: - case TRI_IDX_TYPE_FULLTEXT_INDEX: - case TRI_IDX_TYPE_GEO1_INDEX: - case TRI_IDX_TYPE_GEO2_INDEX: - case TRI_IDX_TYPE_CAP_CONSTRAINT: - return true; - case TRI_IDX_TYPE_BITARRAY_INDEX: // removed - case TRI_IDX_TYPE_PRIORITY_QUEUE_INDEX: // removed - case TRI_IDX_TYPE_UNKNOWN: - return false; - } - - // unknown type... - TRI_ASSERT(false); - return false; -} - //////////////////////////////////////////////////////////////////////////////// /// @brief return the name of an index type //////////////////////////////////////////////////////////////////////////////// @@ -470,16 +444,6 @@ TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone, return json; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief destroys a result set returned by a hash index query -//////////////////////////////////////////////////////////////////////////////// - -void TRI_DestroyIndexResult (TRI_index_result_t* result) { - if (result->_documents != nullptr) { - TRI_Free(TRI_UNKNOWN_MEM_ZONE, result->_documents); - } -} - //////////////////////////////////////////////////////////////////////////////// /// @brief copies a path vector //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/index.h b/arangod/VocBase/index.h index 53e99e1e61..c1c29048f9 100644 --- a/arangod/VocBase/index.h +++ b/arangod/VocBase/index.h @@ -199,16 +199,6 @@ typedef struct TRI_cap_constraint_s { } TRI_cap_constraint_t; -//////////////////////////////////////////////////////////////////////////////// -/// @brief index query result -//////////////////////////////////////////////////////////////////////////////// - -typedef struct TRI_index_result_s { - size_t _length; - struct TRI_doc_mptr_t** _documents; // simple list of elements -} -TRI_index_result_t; - //////////////////////////////////////////////////////////////////////////////// /// @brief index query parameter //////////////////////////////////////////////////////////////////////////////// @@ -242,12 +232,6 @@ void TRI_InitIndex (TRI_index_t*, // --SECTION-- public functions // ----------------------------------------------------------------------------- -//////////////////////////////////////////////////////////////////////////////// -/// @brief whether or not an index needs full coverage -//////////////////////////////////////////////////////////////////////////////// - -bool TRI_NeedsFullCoverageIndex (TRI_idx_type_e); - //////////////////////////////////////////////////////////////////////////////// /// @brief return the name of an index type //////////////////////////////////////////////////////////////////////////////// @@ -310,12 +294,6 @@ TRI_index_t* TRI_LookupIndex (struct TRI_document_collection_t*, TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t*, TRI_index_t const*); -//////////////////////////////////////////////////////////////////////////////// -/// @brief destroys a result set returned by a hash index query -//////////////////////////////////////////////////////////////////////////////// - -void TRI_DestroyIndexResult (TRI_index_result_t*); - //////////////////////////////////////////////////////////////////////////////// /// @brief copies a path vector //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/replication-applier.cpp b/arangod/VocBase/replication-applier.cpp index 356e3b7b31..b3f8c782ac 100644 --- a/arangod/VocBase/replication-applier.cpp +++ b/arangod/VocBase/replication-applier.cpp @@ -85,7 +85,7 @@ static int ReadTick (TRI_json_t const* json, TRI_voc_tick_t* dst) { TRI_json_t* tick; - TRI_ASSERT(json != NULL); + TRI_ASSERT(json != nullptr); TRI_ASSERT(json->_type == TRI_JSON_ARRAY); tick = TRI_LookupArrayJson(json, attributeName); @@ -117,32 +117,32 @@ static TRI_json_t* JsonConfiguration (TRI_replication_applier_configuration_t co json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 9); - if (json == NULL) { - return NULL; + if (json == nullptr) { + return nullptr; } - if (config->_endpoint != NULL) { + if (config->_endpoint != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "endpoint", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_endpoint)); } - if (config->_database != NULL) { + if (config->_database != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "database", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_database)); } - if (config->_username != NULL) { + if (config->_username != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "username", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_username)); } - if (config->_password != NULL && includePassword) { + if (config->_password != nullptr && includePassword) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "password", @@ -159,12 +159,11 @@ static TRI_json_t* JsonConfiguration (TRI_replication_applier_configuration_t co "connectTimeout", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, config->_connectTimeout)); -/* TODO: decide about the fate of this... TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "ignoreErrors", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) config->_ignoreErrors)); -*/ + TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "maxConnectRetries", @@ -215,11 +214,11 @@ static int LoadConfiguration (TRI_vocbase_t* vocbase, return TRI_ERROR_FILE_NOT_FOUND; } - json = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, NULL); + json = TRI_JsonFile(TRI_CORE_MEM_ZONE, filename, nullptr); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); if (! TRI_IsArrayJson(json)) { - if (json != NULL) { + if (json != nullptr) { TRI_FreeJson(TRI_CORE_MEM_ZONE, json); } @@ -228,21 +227,21 @@ static int LoadConfiguration (TRI_vocbase_t* vocbase, res = TRI_ERROR_NO_ERROR; - if (config->_endpoint != NULL) { + if (config->_endpoint != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_endpoint); - config->_endpoint = NULL; + config->_endpoint = nullptr; } - if (config->_database != NULL) { + if (config->_database != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_database); - config->_database = NULL; + config->_database = nullptr; } - if (config->_username != NULL) { + if (config->_username != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_username); - config->_username = NULL; + config->_username = nullptr; } - if (config->_password != NULL) { + if (config->_password != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, config->_password); - config->_password = NULL; + config->_password = nullptr; } // read the endpoint @@ -328,6 +327,20 @@ static int LoadConfiguration (TRI_vocbase_t* vocbase, if (TRI_IsBooleanJson(value)) { config->_adaptivePolling = value->_value._boolean; } + + value = TRI_LookupArrayJson(json, "ignoreErrors"); + + if (TRI_IsNumberJson(value)) { + config->_ignoreErrors = (uint64_t) value->_value._number; + } + else if (TRI_IsBooleanJson(value)) { + if (value->_value._boolean) { + config->_ignoreErrors = UINT64_MAX; + } + else { + config->_ignoreErrors = 0; + } + } TRI_FreeJson(TRI_CORE_MEM_ZONE, json); @@ -354,8 +367,8 @@ static TRI_json_t* JsonApplyState (TRI_replication_applier_state_t const* state) json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 4); - if (json == NULL) { - return NULL; + if (json == nullptr) { + return nullptr; } lastProcessedContinuousTick = TRI_StringUInt64(state->_lastProcessedContinuousTick); @@ -390,7 +403,7 @@ static int SetError (TRI_replication_applier_t* applier, TRI_replication_applier_state_t* state; char const* realMsg; - if (msg == NULL || strlen(msg) == 0) { + if (msg == nullptr || strlen(msg) == 0) { realMsg = TRI_errno_string(errorCode); } else { @@ -407,7 +420,7 @@ static int SetError (TRI_replication_applier_t* applier, TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); - if (state->_lastError._msg != NULL) { + if (state->_lastError._msg != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); } @@ -610,7 +623,7 @@ static TRI_json_t* JsonState (TRI_replication_applier_state_t const* state) { progress = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 2); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressTime)); - if (state->_progressMsg != NULL) { + if (state->_progressMsg != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "message", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressMsg)); } @@ -625,11 +638,11 @@ static TRI_json_t* JsonState (TRI_replication_applier_state_t const* state) { // lastError error = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); - if (error != NULL) { + if (error != nullptr) { if (state->_lastError._code > 0) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._time)); - if (state->_lastError._msg != NULL) { + if (state->_lastError._msg != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorMessage", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._msg)); } } @@ -903,12 +916,12 @@ int TRI_ConfigureReplicationApplier (TRI_replication_applier_t* applier, return TRI_ERROR_CLUSTER_UNSUPPORTED; } - if (config->_endpoint == NULL || strlen(config->_endpoint) == 0) { + if (config->_endpoint == nullptr || strlen(config->_endpoint) == 0) { // no endpoint return TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION; } - if (config->_database == NULL || strlen(config->_database) == 0) { + if (config->_database == nullptr || strlen(config->_database) == 0) { // no database return TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION; } @@ -955,20 +968,20 @@ int TRI_StateReplicationApplier (TRI_replication_applier_t* applier, state->_totalEvents = applier->_state._totalEvents; memcpy(&state->_lastError._time, &applier->_state._lastError._time, sizeof(state->_lastError._time)); - if (applier->_state._progressMsg != NULL) { + if (applier->_state._progressMsg != nullptr) { state->_progressMsg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._progressMsg); } else { - state->_progressMsg = NULL; + state->_progressMsg = nullptr; } memcpy(&state->_progressTime, &applier->_state._progressTime, sizeof(state->_progressTime)); - if (applier->_state._lastError._msg != NULL) { + if (applier->_state._lastError._msg != nullptr) { state->_lastError._msg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._lastError._msg); } else { - state->_lastError._msg = NULL; + state->_lastError._msg = nullptr; } TRI_ReadUnlockReadWriteLock(&applier->_statusLock); @@ -990,15 +1003,15 @@ TRI_json_t* TRI_JsonReplicationApplier (TRI_replication_applier_t* applier) { res = TRI_StateReplicationApplier(applier, &state); if (res != TRI_ERROR_NO_ERROR) { - return NULL; + return nullptr; } json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); - if (json == NULL) { + if (json == nullptr) { TRI_DestroyStateReplicationApplier(&state); - return NULL; + return nullptr; } TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "state", JsonState(&state)); @@ -1006,7 +1019,7 @@ TRI_json_t* TRI_JsonReplicationApplier (TRI_replication_applier_t* applier) { // add server info server = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); - if (server != NULL) { + if (server != nullptr) { TRI_server_id_t serverId; TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, server, "version", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, TRI_VERSION)); @@ -1023,11 +1036,11 @@ TRI_json_t* TRI_JsonReplicationApplier (TRI_replication_applier_t* applier) { TRI_CopyConfigurationReplicationApplier(&applier->_configuration, &config); TRI_ReadUnlockReadWriteLock(&applier->_statusLock); - if (config._endpoint != NULL) { + if (config._endpoint != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "endpoint", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config._endpoint)); } - if (config._database != NULL) { + if (config._database != nullptr) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "database", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config._database)); } @@ -1064,7 +1077,7 @@ void TRI_SetProgressReplicationApplier (TRI_replication_applier_t* applier, copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, msg); - if (copy == NULL) { + if (copy == nullptr) { return; } @@ -1072,7 +1085,7 @@ void TRI_SetProgressReplicationApplier (TRI_replication_applier_t* applier, TRI_WriteLockReadWriteLock(&applier->_statusLock); } - if (applier->_state._progressMsg != NULL) { + if (applier->_state._progressMsg != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, applier->_state._progressMsg); } @@ -1096,7 +1109,7 @@ void TRI_InitStateReplicationApplier (TRI_replication_applier_state_t* state) { state->_active = false; state->_lastError._code = TRI_ERROR_NO_ERROR; - state->_lastError._msg = NULL; + state->_lastError._msg = nullptr; state->_lastError._time[0] = '\0'; } @@ -1272,6 +1285,7 @@ void TRI_InitConfigurationReplicationApplier (TRI_replication_applier_configurat config->_autoStart = false; config->_chunkSize = 0; config->_adaptivePolling = true; + config->_ignoreErrors = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -1306,32 +1320,32 @@ void TRI_DestroyConfigurationReplicationApplier (TRI_replication_applier_configu void TRI_CopyConfigurationReplicationApplier (TRI_replication_applier_configuration_t const* src, TRI_replication_applier_configuration_t* dst) { - if (src->_endpoint != NULL) { + if (src->_endpoint != nullptr) { dst->_endpoint = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_endpoint); } else { - dst->_endpoint = NULL; + dst->_endpoint = nullptr; } - if (src->_database != NULL) { + if (src->_database != nullptr) { dst->_database = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_database); } else { - dst->_database = NULL; + dst->_database = nullptr; } - if (src->_username != NULL) { + if (src->_username != nullptr) { dst->_username = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_username); } else { - dst->_username = NULL; + dst->_username = nullptr; } - if (src->_password != NULL) { + if (src->_password != nullptr) { dst->_password = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_password); } else { - dst->_password = NULL; + dst->_password = nullptr; } dst->_requestTimeout = src->_requestTimeout; @@ -1358,7 +1372,7 @@ int TRI_RemoveConfigurationReplicationApplier (TRI_vocbase_t* vocbase) { filename = GetConfigurationFilename(vocbase); - if (filename == NULL) { + if (filename == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } @@ -1391,7 +1405,7 @@ int TRI_SaveConfigurationReplicationApplier (TRI_vocbase_t* vocbase, json = JsonConfiguration(config, true); - if (json == NULL) { + if (json == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } diff --git a/arangod/VocBase/replication-dump.cpp b/arangod/VocBase/replication-dump.cpp index 1dabed8426..e5b2cc9fba 100644 --- a/arangod/VocBase/replication-dump.cpp +++ b/arangod/VocBase/replication-dump.cpp @@ -130,7 +130,14 @@ char const* NameFromCid (TRI_replication_dump_t* dump, if (name != nullptr) { // insert into cache - dump->_collectionNames.insert(it, std::make_pair(cid, std::string(name))); + try { + dump->_collectionNames.emplace(std::make_pair(cid, std::string(name))); + } + catch (...) { + TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, name); + return nullptr; + } + TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, name); // and look it up again @@ -267,6 +274,14 @@ static int AppendContext (TRI_replication_dump_t* dump, APPEND_UINT64(dump->_buffer, databaseId); APPEND_STRING(dump->_buffer, "\",\"cid\":\""); APPEND_UINT64(dump->_buffer, collectionId); + + // also include collection name + char const* cname = NameFromCid(dump, collectionId); + if (cname != nullptr) { + APPEND_STRING(dump->_buffer, "\",\"cname\":\""); + APPEND_STRING(dump->_buffer, cname); + } + APPEND_STRING(dump->_buffer, "\","); return TRI_ERROR_NO_ERROR; diff --git a/arangod/VocBase/transaction.cpp b/arangod/VocBase/transaction.cpp index 51a5a1baec..34a9521e11 100644 --- a/arangod/VocBase/transaction.cpp +++ b/arangod/VocBase/transaction.cpp @@ -105,8 +105,17 @@ static inline bool IsSingleOperationTransaction (TRI_transaction_t const* trx) { /// @brief whether or not a marker needs to be written //////////////////////////////////////////////////////////////////////////////// -static inline bool NeedWriteMarker (TRI_transaction_t const* trx) { - return (trx->_nestingLevel == 0 && ! IsReadOnlyTransaction(trx) && ! IsSingleOperationTransaction(trx)); +static inline bool NeedWriteMarker (TRI_transaction_t const* trx, + bool isBeginMarker) { + if (isBeginMarker) { + return (! IsReadOnlyTransaction(trx) && + ! IsSingleOperationTransaction(trx)); + } + + return (trx->_nestingLevel == 0 && + trx->_beginWritten && + ! IsReadOnlyTransaction(trx) && + ! IsSingleOperationTransaction(trx)); } //////////////////////////////////////////////////////////////////////////////// @@ -581,7 +590,7 @@ static int ReleaseCollections (TRI_transaction_t* trx, //////////////////////////////////////////////////////////////////////////////// static int WriteBeginMarker (TRI_transaction_t* trx) { - if (! NeedWriteMarker(trx)) { + if (! NeedWriteMarker(trx, true)) { return TRI_ERROR_NO_ERROR; } @@ -593,6 +602,8 @@ static int WriteBeginMarker (TRI_transaction_t* trx) { return TRI_ERROR_DEBUG; } + TRI_ASSERT(! trx->_beginWritten); + int res; try { @@ -606,6 +617,11 @@ static int WriteBeginMarker (TRI_transaction_t* trx) { triagens::wal::BeginTransactionMarker marker(trx->_vocbase->_id, trx->_id); res = GetLogfileManager()->allocateAndWrite(marker, false).errorCode; } + + + if (res == TRI_ERROR_NO_ERROR) { + trx->_beginWritten = true; + } } catch (triagens::arango::Exception const& ex) { res = ex.code(); @@ -626,7 +642,7 @@ static int WriteBeginMarker (TRI_transaction_t* trx) { //////////////////////////////////////////////////////////////////////////////// static int WriteAbortMarker (TRI_transaction_t* trx) { - if (! NeedWriteMarker(trx)) { + if (! NeedWriteMarker(trx, false)) { return TRI_ERROR_NO_ERROR; } @@ -634,6 +650,8 @@ static int WriteAbortMarker (TRI_transaction_t* trx) { return TRI_ERROR_NO_ERROR; } + TRI_ASSERT(trx->_beginWritten); + TRI_IF_FAILURE("TransactionWriteAbortMarker") { return TRI_ERROR_DEBUG; } @@ -671,14 +689,16 @@ static int WriteAbortMarker (TRI_transaction_t* trx) { //////////////////////////////////////////////////////////////////////////////// static int WriteCommitMarker (TRI_transaction_t* trx) { - if (! NeedWriteMarker(trx)) { + if (! NeedWriteMarker(trx, false)) { return TRI_ERROR_NO_ERROR; } - + TRI_IF_FAILURE("TransactionWriteCommitMarker") { return TRI_ERROR_DEBUG; } + TRI_ASSERT(trx->_beginWritten); + int res; try { @@ -756,6 +776,7 @@ TRI_transaction_t* TRI_CreateTransaction (TRI_vocbase_t* vocbase, trx->_timeout = TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT; trx->_hasOperations = false; trx->_waitForSync = waitForSync; + trx->_beginWritten = false; if (timeout > 0.0) { trx->_timeout = (uint64_t) (timeout * 1000000.0); @@ -1063,6 +1084,14 @@ int TRI_AddOperationTransaction (triagens::wal::DocumentOperation& operation, TRI_IF_FAILURE("TransactionOperationNoSlotExcept") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } + + if (! trx->_beginWritten) { + int res = WriteBeginMarker(trx); + + if (res != TRI_ERROR_NO_ERROR) { + return res; + } + } TRI_voc_fid_t fid = 0; void const* position = nullptr; @@ -1262,13 +1291,11 @@ int TRI_BeginTransaction (TRI_transaction_t* trx, // all valid if (nestingLevel == 0) { UpdateTransactionStatus(trx, TRI_TRANSACTION_RUNNING); - - res = WriteBeginMarker(trx); + + // defer writing of the begin marker until necessary! } } - - - if (res != TRI_ERROR_NO_ERROR) { + else { // something is wrong if (nestingLevel == 0) { UpdateTransactionStatus(trx, TRI_TRANSACTION_ABORTED); diff --git a/arangod/VocBase/transaction.h b/arangod/VocBase/transaction.h index 43326dd6ee..04fbb71ec1 100644 --- a/arangod/VocBase/transaction.h +++ b/arangod/VocBase/transaction.h @@ -152,6 +152,7 @@ typedef struct TRI_transaction_s { int _nestingLevel; bool _hasOperations; bool _waitForSync; // whether or not the collection had a synchronous op + bool _beginWritten; // whether or not the begin marker was already written uint64_t _timeout; // timeout for lock acquisition } TRI_transaction_t; diff --git a/arangod/Wal/RecoverState.cpp b/arangod/Wal/RecoverState.cpp index df0125f796..fffd7d43ea 100644 --- a/arangod/Wal/RecoverState.cpp +++ b/arangod/Wal/RecoverState.cpp @@ -111,11 +111,16 @@ static int WaitForDeletion (TRI_server_t* server, TRI_RemoveDirectory(result.c_str()); } } - else if (++iterations >= 30 * 10) { + else if (iterations >= 30 * 10) { LOG_WARNING("unable to remove database directory '%s'", result.c_str()); return TRI_ERROR_INTERNAL; } + if (iterations == 5 * 10) { + LOG_INFO("waiting for deletion of database directory '%s'", result.c_str()); + } + + ++iterations; usleep(100000); } @@ -146,11 +151,16 @@ static int WaitForDeletion (TRI_vocbase_t* vocbase, TRI_RemoveDirectory(result.c_str()); } } - else if (++iterations >= 30 * 10) { + else if (iterations >= 30 * 10) { LOG_WARNING("unable to remove collection directory '%s'", result.c_str()); return TRI_ERROR_INTERNAL; } + + if (iterations == 5 * 10) { + LOG_INFO("waiting for deletion of collection directory '%s'", result.c_str()); + } + ++iterations; usleep(100000); } diff --git a/arangosh/V8Client/ImportHelper.cpp b/arangosh/V8Client/ImportHelper.cpp index 5d2bb56609..43ce85fa30 100644 --- a/arangosh/V8Client/ImportHelper.cpp +++ b/arangosh/V8Client/ImportHelper.cpp @@ -408,15 +408,28 @@ namespace triagens { void ImportHelper::reportProgress (int64_t totalLength, int64_t totalRead, double& nextProgress) { - if (! _progress || totalLength == 0) { + if (! _progress) { return; } - double pct = 100.0 * ((double) totalRead / (double) totalLength); + if (totalLength == 0) { + // length of input is unknown + // in this case we cannot report the progress as a percentage + // instead, report every 10 MB processed + static int64_t nextProcessed = 10 * 1000 * 1000; - if (pct >= nextProgress && totalLength >= 1024) { - LOG_INFO("processed %lld bytes (%0.1f%%) of input file", (long long) totalRead, nextProgress); - nextProgress = (double) ((int) (pct + ProgressStep)); + if (totalRead >= nextProcessed) { + LOG_INFO("processed %lld bytes of input file", (long long) totalRead); + nextProcessed += 10 * 1000 * 1000; + } + } + else { + double pct = 100.0 * ((double) totalRead / (double) totalLength); + + if (pct >= nextProgress && totalLength >= 1024) { + LOG_INFO("processed %lld bytes (%0.1f%%) of input file", (long long) totalRead, nextProgress); + nextProgress = (double) ((int) (pct + ProgressStep)); + } } } diff --git a/build.h b/build.h index 83d424a33e..e59c7b88ea 100644 --- a/build.h +++ b/build.h @@ -1 +1 @@ -#define TRI_VERSION "2.3.0-devel" +#define TRI_VERSION "2.3.0-beta2" diff --git a/configure.ac b/configure.ac index bf19be1693..6b535aa13e 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ dnl ============================================================================ dnl --SECTION-- triAGENS GmbH Build Environment dnl ============================================================================ -AC_INIT([triAGENS ArangoDB], [2.3.0-devel], [info@triagens.de], [arangodb], [http://www.arangodb.com]) +AC_INIT([triAGENS ArangoDB], [2.3.0-beta2], [info@triagens.de], [arangodb], [http://www.arangodb.org]) dnl ---------------------------------------------------------------------------- dnl auxillary directory for install-sh and missing diff --git a/js/actions/api-collection.js b/js/actions/api-collection.js index dae42afb52..232b8dc562 100644 --- a/js/actions/api-collection.js +++ b/js/actions/api-collection.js @@ -188,11 +188,9 @@ function parseBodyForCreateCollection (req, res) { /// - *doCompact* (optional, default is *true*): whether or not the collection /// will be compacted. /// -/// - *journalSize* (optional, default is a -/// configuration parameter): The maximal size of -/// a journal or datafile. -/// **Note**: This also limits the maximal -/// size of a single object. Must be at least 1MB. +/// - *journalSize* (optional, default is a configuration parameter): The +/// maximal size of a journal or datafile in bytes. The value +/// must be at least `1048576` (1 MB). /// /// - *isSystem* (optional, default is *false*): If *true*, create a /// system collection. In this case *collection-name* should start with @@ -476,7 +474,8 @@ function get_api_collections (req, res) { /// /// - *doCompact*: Whether or not the collection will be compacted. /// -/// - *journalSize*: The maximal size setting for journals / datafiles. +/// - *journalSize*: The maximal size setting for journals / datafiles +/// in bytes. /// /// - *isVolatile*: If *true* then the collection data will be /// kept in memory only and ArangoDB will not write or sync the data @@ -661,7 +660,7 @@ function get_api_collections (req, res) { /// log for this collection that have not been transferred to journals or /// datafiles. /// -/// - *journalSize*: The maximal size of the journal in bytes. +/// - *journalSize*: The maximal size of a journal or datafile in bytes. /// /// **Note**: collection data that are stored in the write-ahead log only are /// not reported in the results. When the write-ahead log is collected, documents @@ -1203,8 +1202,11 @@ function put_api_collection_truncate (req, res, collection) { /// - *waitForSync*: If *true* then creating or changing a /// document will wait until the data has been synchronised to disk. /// -/// - *journalSize*: Size (in bytes) for new journal files that are -/// created for the collection. +/// - *journalSize*: The maximal size of a journal or datafile in bytes. +/// The value must be at least `1048576` (1 MB). Note that when +/// changing the journalSize value, it will only have an effect for +/// additional journals or datafiles that are created. Already +/// existing journals or datafiles will not be affected. /// /// If returns an object with the attributes /// diff --git a/js/actions/api-explain.js b/js/actions/api-explain.js index 50d6cbb93a..ceb148d5a2 100644 --- a/js/actions/api-explain.js +++ b/js/actions/api-explain.js @@ -86,7 +86,7 @@ var ERRORS = require("internal").errors; /// /// Each plan in the result is a JSON object with the following attributes: /// - *nodes*: the list of execution nodes of the plan. The list of available node types -/// can be found [here](.../Aql/Optimizer.html) +/// can be found [here](../Aql/Optimizer.html) /// /// - *estimatedCost*: the total estimated cost for the plan. If there are multiple /// plans, the optimizer will choose the plan with the lowest total cost. diff --git a/js/actions/api-simple.js b/js/actions/api-simple.js index 5277f8db25..343d1a7a03 100644 --- a/js/actions/api-simple.js +++ b/js/actions/api-simple.js @@ -325,7 +325,7 @@ setupIndexQueries(); /// @EXAMPLE_ARANGOSH_RUN{RestSimpleAllSkipLimit} /// var cn = "products"; /// db._drop(cn); -/// var collection = db._create(cn, { waitForSync: true }); +/// var collection = db._create(cn); /// collection.save({"Hello1" : "World1" }); /// collection.save({"Hello2" : "World2" }); /// collection.save({"Hello3" : "World3" }); @@ -523,7 +523,7 @@ actions.defineHttp({ /// /// In order to use the *near* operator, a geo index must be defined for the /// collection. This index also defines which attribute holds the coordinates -/// for the document. If you have more then one geo-spatial index, you can use +/// for the document. If you have more than one geo-spatial index, you can use /// the *geo* field to select a particular index. /// /// The call expects a JSON object as body with the following attributes: @@ -566,7 +566,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleNear} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// var loc = products.ensureGeoIndex("loc"); /// var i; /// for (i = -0.01; i <= 0.01; i += 0.002) { @@ -594,7 +594,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleNearDistance} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// var loc = products.ensureGeoIndex("loc"); /// var i; /// for (i = -0.01; i <= 0.01; i += 0.002) { @@ -702,7 +702,7 @@ actions.defineHttp({ /// /// In order to use the *within* operator, a geo index must be defined for /// the collection. This index also defines which attribute holds the -/// coordinates for the document. If you have more then one geo-spatial index, +/// coordinates for the document. If you have more than one geo-spatial index, /// you can use the *geo* field to select a particular index. /// /// The call expects a JSON object as body with the following attributes: @@ -747,7 +747,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithin} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// var loc = products.ensureGeoIndex("loc"); /// var i; /// for (i = -0.01; i <= 0.01; i += 0.002) { @@ -776,7 +776,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithinDistance} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// var loc = products.ensureGeoIndex("loc"); /// var i; /// for (i = -0.01; i <= 0.01; i += 0.002) { @@ -862,6 +862,159 @@ actions.defineHttp({ } }); +//////////////////////////////////////////////////////////////////////////////// +/// @startDocuBlock JSA_put_api_simple_within_rectangle +/// @brief returns all documents of a collection within a rectangle +/// +/// @RESTHEADER{PUT /_api/simple/within-rectangle, Within rectangle query} +/// +/// @RESTBODYPARAM{query,string,required} +/// Contains the query. +/// +/// @RESTDESCRIPTION +/// +/// This will find all documents within the specified rectangle (determined by +/// the given coordinates (*latitude1*, *longitude1*, *latitude2*, *longitude2*). +/// +/// In order to use the *within-rectangle* query, a geo index must be defined for +/// the collection. This index also defines which attribute holds the +/// coordinates for the document. If you have more than one geo-spatial index, +/// you can use the *geo* field to select a particular index. +/// +/// The call expects a JSON object as body with the following attributes: +/// +/// - *collection*: The name of the collection to query. +/// +/// - *latitude1*: The latitude of the first rectangle coordinate. +/// +/// - *longitude1*: The longitude of the first rectangle coordinate. +/// +/// - *latitude2*: The latitude of the second rectangle coordinate. +/// +/// - *longitude2*: The longitude of the second rectangle coordinate. +/// +/// - *skip*: The number of documents to skip in the query. (optional) +/// +/// - *limit*: The maximal amount of documents to return. The *skip* is +/// applied before the *limit* restriction. The default is 100. (optional) +/// +/// - *geo*: If given, the identifier of the geo-index to use. (optional) +/// +/// Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details. +/// +/// @RESTRETURNCODES +/// +/// @RESTRETURNCODE{201} +/// is returned if the query was executed successfully. +/// +/// @RESTRETURNCODE{400} +/// is returned if the body does not contain a valid JSON representation of a +/// query. The response body contains an error document in this case. +/// +/// @RESTRETURNCODE{404} +/// is returned if the collection specified by *collection* is unknown. The +/// response body contains an error document in this case. +/// +/// @EXAMPLES +/// +/// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithinRectangle} +/// var cn = "products"; +/// db._drop(cn); +/// var products = db._create(cn); +/// var loc = products.ensureGeoIndex("loc"); +/// var i; +/// for (i = -0.01; i <= 0.01; i += 0.002) { +/// products.save({ name : "Name/" + i + "/",loc: [ i, 0 ] }); +/// } +/// var url = "/_api/simple/within-rectangle"; +/// var body = { +/// collection: "products", +/// latitude1 : 0, +/// longitude1 : 0, +/// latitude2 : 0.2, +/// longitude2 : 0.2, +/// skip : 1, +/// limit : 2 +/// }; +/// +/// var response = logCurlRequest('PUT', url, JSON.stringify(body)); +/// +/// assert(response.code === 201); +/// +/// logJsonResponse(response); +/// db._drop(cn); +/// @END_EXAMPLE_ARANGOSH_RUN +/// @endDocuBlock +//////////////////////////////////////////////////////////////////////////////// + +actions.defineHttp({ + url: API + "within-rectangle", + + callback : function (req, res) { + try { + var body = actions.getJsonBody(req, res); + + if (body === undefined) { + return; + } + + if (req.requestType !== actions.PUT) { + actions.resultUnsupported(req, res); + } + else { + var limit = body.limit; + var skip = body.skip; + var latitude1 = body.latitude1; + var longitude1 = body.longitude1; + var latitude2 = body.latitude2; + var longitude2 = body.longitude2; + var geo = body.geo; + var name = body.collection; + var collection = db._collection(name); + + if (collection === null) { + actions.collectionNotFound(req, res, name); + } + else if (latitude1 === null || latitude1 === undefined) { + actions.badParameter(req, res, "latitude1"); + } + else if (longitude1 === null || longitude1 === undefined) { + actions.badParameter(req, res, "longitude1"); + } + else if (latitude2 === null || latitude2 === undefined) { + actions.badParameter(req, res, "latitude2"); + } + else if (longitude2 === null || longitude2 === undefined) { + actions.badParameter(req, res, "longitude2"); + } + else { + var result; + + if (geo === null || geo === undefined) { + result = collection.withinRectangle(latitude1, longitude1, latitude2, longitude2); + } + else { + result = collection.geo({ id : geo }).withinRectangle(latitude1, longitude1, latitude2, longitude2); + } + + if (skip !== null && skip !== undefined) { + result = result.skip(skip); + } + + if (limit !== null && limit !== undefined) { + result = result.limit(limit); + } + + createCursorResponse(req, res, CREATE_CURSOR(result.toArray(), true, body.batchSize, body.ttl)); + } + } + } + catch (err) { + actions.resultException(req, res, err, undefined, false); + } + } +}); + //////////////////////////////////////////////////////////////////////////////// /// @startDocuBlock JSA_put_api_simple_fulltext /// @brief returns documents of a collection as a result of a fulltext query @@ -915,7 +1068,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleFulltext} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({"text" : "this text contains word" }); /// products.save({"text" : "this text also has a word" }); /// products.save({"text" : "this is nothing" }); @@ -1032,7 +1185,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1053,7 +1206,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample2} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1074,7 +1227,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample3} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1186,7 +1339,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstExample} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1207,7 +1360,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstExampleNotFound} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1315,7 +1468,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirst} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: false }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1336,7 +1489,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstSingle} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: false }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1434,7 +1587,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleLast} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: false }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1455,7 +1608,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleLastSingle} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: false }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1557,7 +1710,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleRange} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.ensureUniqueSkiplist("i"); /// products.save({ "i": 1}); /// products.save({ "i": 2}); @@ -1689,7 +1842,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1708,7 +1861,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample_1} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1728,7 +1881,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample_2} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1857,7 +2010,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExample} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -1881,7 +2034,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExampleWaitForSync} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -2020,7 +2173,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleUpdateByExample} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); @@ -2044,7 +2197,7 @@ actions.defineHttp({ /// @EXAMPLE_ARANGOSH_RUN{RestSimpleUpdateByExample_1} /// var cn = "products"; /// db._drop(cn); -/// var products = db._create(cn, { waitForSync: true }); +/// var products = db._create(cn); /// products.save({ "a": { "k": 1, "j": 1 }, "i": 1}); /// products.save({ "a": { "j": 1 }, "i": 1}); /// products.save({ "i": 1}); diff --git a/js/apps/system/aardvark/aardvark.js b/js/apps/system/aardvark/aardvark.js index 131176f317..f70a835068 100644 --- a/js/apps/system/aardvark/aardvark.js +++ b/js/apps/system/aardvark/aardvark.js @@ -367,25 +367,24 @@ controller.post("/query/upload/:user", function(req, res) { queries = req.body(); userColl = db._users.byExample({"user": user}).toArray()[0]; - storedQueries = userColl.extra.queries; - queriesToSave = []; + queriesToSave = userColl.userData.queries || [ ]; underscore.each(queries, function(newq) { - var toBeStored = true; - underscore.each(storedQueries, function(stored) { - if (stored.name === newq.name) { - toBeStored = false; + var found = false, i; + for (i = 0; i < queriesToSave.length; ++i) { + if (queriesToSave[i].name === newq.name) { + queriesToSave[i] = newq; + found = true; + break; } - }); - if (toBeStored === true) { + } + if (! found) { queriesToSave.push(newq); } }); - queriesToSave = queriesToSave.concat(storedQueries); - var toUpdate = { - extra: { + userData: { queries: queriesToSave } } diff --git a/js/apps/system/aardvark/api-docs.json b/js/apps/system/aardvark/api-docs.json index b5c400c7b7..d275dd1894 100644 --- a/js/apps/system/aardvark/api-docs.json +++ b/js/apps/system/aardvark/api-docs.json @@ -1,6 +1,6 @@ { "swaggerVersion": "1.1", - "apiVersion": "2.3.0", + "apiVersion": "2.3.0-beta2", "apis": [ { "path": "api-docs/aqlfunction.{format}", diff --git a/js/apps/system/aardvark/api-docs/batch.json b/js/apps/system/aardvark/api-docs/batch.json index 73e210cca9..d65ec19d29 100644 --- a/js/apps/system/aardvark/api-docs/batch.json +++ b/js/apps/system/aardvark/api-docs/batch.json @@ -32,7 +32,7 @@ "notes": "Executes a batch request. A batch request can contain any number of other requests that can be sent to ArangoDB in isolation. The benefit of using batch requests is that batching requests requires less client/server roundtrips than when sending isolated requests.

    All parts of a batch request are executed serially on the server. The server will return the results of all parts in a single response when all parts are finished.

    Technically, a batch request is a multipart HTTP request, with content-type multipart/form-data. A batch request consists of an envelope and the individual batch part actions. Batch part actions are \"regular\" HTTP requests, including full header and an optional body. Multiple batch parts are separated by a boundary identifier. The boundary identifier is declared in the batch envelope. The MIME content-type for each individual batch part must be application/x-arango-batchpart.

    Please note that when constructing the individual batch parts, you must use CRLF (\\r\\n) as the line terminator as in regular HTTP messages.

    The response sent by the server will be an HTTP 200 response, with an optional error summary header x-arango-errors. This header contains the number of batch part operations that failed with an HTTP error code of at least 400. This header is only present in the response if the number of errors is greater than zero.

    The response sent by the server is a multipart response, too. It contains the individual HTTP responses for all batch parts, including the full HTTP result header (with status code and other potential headers) and an optional result body. The individual batch parts in the result are seperated using the same boundary value as specified in the request.

    The order of batch parts in the response will be the same as in the original client request. Client can additionally use the Content-Id MIME header in a batch part to define an individual id for each batch part. The server will return this id is the batch part responses, too.

    ", "summary": "executes a batch request", "httpMethod": "POST", - "examples": "

    Sending a batch request with five batch parts:

    • GET /_api/version
    • DELETE /_api/collection/products
    • POST /_api/collection/products
    • GET /_api/collection/products/figures
    • DELETE /_api/collection/products
    The boundary (SomeBoundaryValue) is passed to the server in the HTTP Content-Type HTTP header.



    shell> curl -X POST --header 'Content-Type: multipart/form-data; boundary=SomeBoundaryValue' --data-binary @- --dump - http://localhost:8529/_api/batch\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId1\r\n\r\nGET /_api/version HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId2\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: someId\r\n\r\nPOST /_api/collection/products HTTP/1.1\r\n\r\n{ \"name\": \"products\" }\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: nextId\r\n\r\nGET /_api/collection/products/figures HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: otherId\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n--SomeBoundaryValue--\r\n\n\nHTTP/1.1 200 OK\ncontent-type: multipart/form-data; boundary=SomeBoundaryValue\nx-arango-errors: 1\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId1\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 43\\r\\n\\r\\n{\\\"server\\\":\\\"arango\\\",\\\"version\\\":\\\"2.3.0-devel\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId2\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 88\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'products'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: someId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nlocation: /_db/_system/_api/collection/products\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 138\\r\\n\\r\\n{\\\"id\\\":\\\"1364982952\\\",\\\"name\\\":\\\"products\\\",\\\"waitForSync\\\":false,\\\"isVolatile\\\":false,\\\"isSystem\\\":false,\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: nextId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nlocation: /_db/_system/_api/collection/products/figures\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 618\\r\\n\\r\\n{\\\"id\\\":\\\"1364982952\\\",\\\"name\\\":\\\"products\\\",\\\"isSystem\\\":false,\\\"doCompact\\\":true,\\\"isVolatile\\\":false,\\\"journalSize\\\":1048576,\\\"keyOptions\\\":{\\\"type\\\":\\\"traditional\\\",\\\"allowUserKeys\\\":true},\\\"waitForSync\\\":false,\\\"count\\\":0,\\\"figures\\\":{\\\"alive\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"dead\\\":{\\\"count\\\":0,\\\"size\\\":0,\\\"deletion\\\":0},\\\"datafiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"journals\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"compactors\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapefiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"attributes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"indexes\\\":{\\\"count\\\":1,\\\"size\\\":2008},\\\"lastTick\\\":\\\"0\\\",\\\"uncollectedLogfileEntries\\\":0},\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: otherId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 44\\r\\n\\r\\n{\\\"id\\\":\\\"1364982952\\\",\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue--\"\n



    Sending a batch request, setting the boundary implicitly (the server will in this case try to find the boundary at the beginning of the request body).



    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/batch\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting1 HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting2 HTTP/1.1\r\n--SomeBoundaryValue--\r\n\n\nHTTP/1.1 200 OK\nx-arango-errors: 2\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting1'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncontent-length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting2'\\\"}\\r\\n--SomeBoundaryValue--\"\n

    ", + "examples": "

    Sending a batch request with five batch parts:

    • GET /_api/version
    • DELETE /_api/collection/products
    • POST /_api/collection/products
    • GET /_api/collection/products/figures
    • DELETE /_api/collection/products
    The boundary (SomeBoundaryValue) is passed to the server in the HTTP Content-Type HTTP header.



    shell> curl -X POST --header 'Content-Type: multipart/form-data; boundary=SomeBoundaryValue' --data-binary @- --dump - http://localhost:8529/_api/batch\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId1\r\n\r\nGET /_api/version HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: myId2\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: someId\r\n\r\nPOST /_api/collection/products HTTP/1.1\r\n\r\n{ \"name\": \"products\" }\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: nextId\r\n\r\nGET /_api/collection/products/figures HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\nContent-Id: otherId\r\n\r\nDELETE /_api/collection/products HTTP/1.1\r\n--SomeBoundaryValue--\r\n\n\nHTTP/1.1 200 OK\ncontent-type: multipart/form-data; boundary=SomeBoundaryValue\nx-arango-errors: 1\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId1\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 43\\r\\n\\r\\n{\\\"server\\\":\\\"arango\\\",\\\"version\\\":\\\"2.3.0-beta2\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: myId2\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 88\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'products'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: someId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nLocation: /_db/_system/_api/collection/products\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 138\\r\\n\\r\\n{\\\"id\\\":\\\"1426886089\\\",\\\"name\\\":\\\"products\\\",\\\"waitForSync\\\":false,\\\"isVolatile\\\":false,\\\"isSystem\\\":false,\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: nextId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nLocation: /_db/_system/_api/collection/products/figures\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 618\\r\\n\\r\\n{\\\"id\\\":\\\"1426886089\\\",\\\"name\\\":\\\"products\\\",\\\"isSystem\\\":false,\\\"doCompact\\\":true,\\\"isVolatile\\\":false,\\\"journalSize\\\":1048576,\\\"keyOptions\\\":{\\\"type\\\":\\\"traditional\\\",\\\"allowUserKeys\\\":true},\\\"waitForSync\\\":false,\\\"count\\\":0,\\\"figures\\\":{\\\"alive\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"dead\\\":{\\\"count\\\":0,\\\"size\\\":0,\\\"deletion\\\":0},\\\"datafiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"journals\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"compactors\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapefiles\\\":{\\\"count\\\":0,\\\"fileSize\\\":0},\\\"shapes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"attributes\\\":{\\\"count\\\":0,\\\"size\\\":0},\\\"indexes\\\":{\\\"count\\\":1,\\\"size\\\":2008},\\\"lastTick\\\":\\\"0\\\",\\\"uncollectedLogfileEntries\\\":0},\\\"status\\\":3,\\\"type\\\":2,\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\nContent-Id: otherId\\r\\n\\r\\nHTTP/1.1 200 OK\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 44\\r\\n\\r\\n{\\\"id\\\":\\\"1426886089\\\",\\\"error\\\":false,\\\"code\\\":200}\\r\\n--SomeBoundaryValue--\"\n



    Sending a batch request, setting the boundary implicitly (the server will in this case try to find the boundary at the beginning of the request body).



    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/batch\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting1 HTTP/1.1\r\n\r\n--SomeBoundaryValue\r\nContent-Type: application/x-arango-batchpart\r\n\r\nDELETE /_api/collection/notexisting2 HTTP/1.1\r\n--SomeBoundaryValue--\r\n\n\nHTTP/1.1 200 OK\nx-arango-errors: 2\n\n\"--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting1'\\\"}\\r\\n--SomeBoundaryValue\\r\\nContent-Type: application/x-arango-batchpart\\r\\n\\r\\nHTTP/1.1 404 Not Found\\r\\nContent-Type: application/json; charset=utf-8\\r\\nContent-Length: 92\\r\\n\\r\\n{\\\"error\\\":true,\\\"code\\\":404,\\\"errorNum\\\":1203,\\\"errorMessage\\\":\\\"unknown collection 'notexisting2'\\\"}\\r\\n--SomeBoundaryValue--\"\n

    ", "nickname": "executesABatchRequest" } ], diff --git a/js/apps/system/aardvark/api-docs/collection.json b/js/apps/system/aardvark/api-docs/collection.json index 2970b7c091..ac641d198b 100644 --- a/js/apps/system/aardvark/api-docs/collection.json +++ b/js/apps/system/aardvark/api-docs/collection.json @@ -19,7 +19,7 @@ "notes": "Creates an new collection with a given name. The request must contain an object with the following attributes.

    • name: The name of the collection.
    • waitForSync (optional, default: false): If true then the data is synchronised to disk before returning from a create or update of a document.
    • doCompact (optional, default is true): whether or not the collection will be compacted.
    • journalSize (optional, default is a configuration parameter): The maximal size of a journal or datafile.
    Note: This also limits the maximal size of a single object. Must be at least 1MB.

    • isSystem (optional, default is false): If true, create a system collection. In this case collection-name should start with an underscore. End users should normally create non-system collections only. API implementors may be required to create system collections in very special occasions, but normally a regular collection will do.
    • isVolatile (optional, default is false): If true then the collection data is kept in-memory only and not made persistent. Unloading the collection will cause the collection data to be discarded. Stopping or re-starting the server will also cause full loss of data in the collection. Setting this option will make the resulting collection be slightly faster than regular collections because ArangoDB does not enforce any synchronisation to disk and does not calculate any CRC checksums for datafiles (as there are no datafiles). This option should threrefore be used for cache-type collections only, and not for data that cannot be re-created otherwise.
    • keyOptions (optional) additional options for key generation. If specified, then keyOptions should be a JSON array containing the following attributes (note: some of them are optional): - type: specifies the type of the key generator. The currently available generators are traditional and autoincrement. - allowUserKeys: if set to true, then it is allowed to supply own key values in the _key attribute of a document. If set to false, then the key generator will solely be responsible for generating keys and supplying own key values in the _key attribute of documents is considered an error. - increment: increment value for autoincrement key generator. Not used for other key generator types. - offset: initial offset value for autoincrement key generator. Not used for other key generator types.
    • type (optional, default is 2): the type of the collection to create. The following values for type are valid: - 2: document collection - 3: edges collection
    • numberOfShards (optional, default is 1): in a cluster, this value determines the number of shards to create for the collection. In a single server setup, this option is meaningless.
    • shardKeys (optional, default is [ \"_key\" ]): in a cluster, this attribute determines which document attributes are used to determine the target shard for documents. Documents are sent to shards based on the values of their shard key attributes. The values of all shard key attributes in a document are hashed, and the hash value is used to determine the target shard.
    Note: Values of shard key attributes cannot be changed once set. This option is meaningless in a single server setup.", "summary": " Create collection", "httpMethod": "POST", - "examples": "



    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionBasics\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionBasics\n\n{ \n  \"id\" : \"890305704\", \n  \"name\" : \"testCollectionBasics\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\nshell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionEdges\",\"type\":3}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionEdges\n\n{ \n  \"id\" : \"890436776\", \n  \"name\" : \"testCollectionEdges\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 3, \n  \"error\" : false, \n  \"code\" : 200 \n}\n





    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionUsers\",\"keyOptions\":{\"type\":\"autoincrement\",\"increment\":5,\"allowUserKeys\":true}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionUsers\n\n{ \n  \"id\" : \"890698920\", \n  \"name\" : \"testCollectionUsers\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



    ", + "examples": "



    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionBasics\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionBasics\n\n{ \n  \"id\" : \"910593481\", \n  \"name\" : \"testCollectionBasics\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\nshell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionEdges\",\"type\":3}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionEdges\n\n{ \n  \"id\" : \"910724553\", \n  \"name\" : \"testCollectionEdges\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 3, \n  \"error\" : false, \n  \"code\" : 200 \n}\n





    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/collection\n{\"name\":\"testCollectionUsers\",\"keyOptions\":{\"type\":\"autoincrement\",\"increment\":5,\"allowUserKeys\":true}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/testCollectionUsers\n\n{ \n  \"id\" : \"910986697\", \n  \"name\" : \"testCollectionUsers\", \n  \"waitForSync\" : false, \n  \"isVolatile\" : false, \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



    ", "nickname": "CreateCollection" } ], @@ -41,7 +41,7 @@ "notes": "Returns an object with an attribute collections containing a list of all collection descriptions. The same information is also available in the names as hash map with the collection names as keys.

    By providing the optional URL parameter excludeSystem with a value of true, all system collections will be excluded from the response.

    ", "summary": "reads all collections", "httpMethod": "GET", - "examples": "

    Return information about all collections:



    shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"id\" : \"883162280\", \n      \"name\" : \"frenchHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"4848808\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2620584\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"798620840\", \n      \"name\" : \"Company\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"5242024\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"859503784\", \n      \"name\" : \"relation\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"888405160\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"799014056\", \n      \"name\" : \"has_bought\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"5635240\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"887487656\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"883031208\", \n      \"name\" : \"frenchCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4717736\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2489512\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"6487208\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4258984\", \n      \"name\" : \"_aal\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"699333800\", \n      \"name\" : \"better-example\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"798489768\", \n      \"name\" : \"friend_of\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"195752\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"859372712\", \n      \"name\" : \"male\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"798882984\", \n      \"name\" : \"Electronics\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"882900136\", \n      \"name\" : \"germanHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"2358440\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"6356136\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"26803368\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"798358696\", \n      \"name\" : \"Customer\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"883293352\", \n      \"name\" : \"internationalHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"2751656\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"859241640\", \n      \"name\" : \"female\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"798751912\", \n      \"name\" : \"Groceries\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"882769064\", \n      \"name\" : \"germanCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"457896\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  ], \n  \"names\" : { \n    \"frenchHighway\" : { \n      \"id\" : \"883162280\", \n      \"name\" : \"frenchHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_statisticsRaw\" : { \n      \"id\" : \"4848808\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_routing\" : { \n      \"id\" : \"2620584\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Company\" : { \n      \"id\" : \"798620840\", \n      \"name\" : \"Company\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statistics\" : { \n      \"id\" : \"5242024\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"relation\" : { \n      \"id\" : \"859503784\", \n      \"name\" : \"relation\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"animals\" : { \n      \"id\" : \"888405160\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"has_bought\" : { \n      \"id\" : \"799014056\", \n      \"name\" : \"has_bought\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_statistics15\" : { \n      \"id\" : \"5635240\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"demo\" : { \n      \"id\" : \"887487656\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"frenchCity\" : { \n      \"id\" : \"883031208\", \n      \"name\" : \"frenchCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_aqlfunctions\" : { \n      \"id\" : \"4717736\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_modules\" : { \n      \"id\" : \"2489512\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_jobs\" : { \n      \"id\" : \"6487208\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_aal\" : { \n      \"id\" : \"4258984\", \n      \"name\" : \"_aal\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"better-example\" : { \n      \"id\" : \"699333800\", \n      \"name\" : \"better-example\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"friend_of\" : { \n      \"id\" : \"798489768\", \n      \"name\" : \"friend_of\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_configuration\" : { \n      \"id\" : \"195752\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"male\" : { \n      \"id\" : \"859372712\", \n      \"name\" : \"male\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Electronics\" : { \n      \"id\" : \"798882984\", \n      \"name\" : \"Electronics\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"germanHighway\" : { \n      \"id\" : \"882900136\", \n      \"name\" : \"germanHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_graphs\" : { \n      \"id\" : \"2358440\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_queues\" : { \n      \"id\" : \"6356136\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_sessions\" : { \n      \"id\" : \"26803368\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Customer\" : { \n      \"id\" : \"798358696\", \n      \"name\" : \"Customer\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"internationalHighway\" : { \n      \"id\" : \"883293352\", \n      \"name\" : \"internationalHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_cluster_kickstarter_plans\" : { \n      \"id\" : \"2751656\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"female\" : { \n      \"id\" : \"859241640\", \n      \"name\" : \"female\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Groceries\" : { \n      \"id\" : \"798751912\", \n      \"name\" : \"Groceries\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"germanCity\" : { \n      \"id\" : \"882769064\", \n      \"name\" : \"germanCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_users\" : { \n      \"id\" : \"457896\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



    ", + "examples": "

    Return information about all collections:



    shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"id\" : \"2723273\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"817860041\", \n      \"name\" : \"Groceries\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"879201737\", \n      \"name\" : \"female\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"429513\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"903187913\", \n      \"name\" : \"frenchCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"26185161\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4820425\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2592201\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"817728969\", \n      \"name\" : \"Company\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"5213641\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"818122185\", \n      \"name\" : \"has_bought\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"903056841\", \n      \"name\" : \"germanHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"879463881\", \n      \"name\" : \"relation\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"5606857\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"903450057\", \n      \"name\" : \"internationalHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"4689353\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"2461129\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"232905\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"4230601\", \n      \"name\" : \"_aal\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"6458825\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"817597897\", \n      \"name\" : \"friend_of\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"719752649\", \n      \"name\" : \"better-example\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"908758473\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"907840969\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"817991113\", \n      \"name\" : \"Electronics\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"902925769\", \n      \"name\" : \"germanCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"879332809\", \n      \"name\" : \"male\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"903318985\", \n      \"name\" : \"frenchHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    { \n      \"id\" : \"2330057\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"6327753\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    { \n      \"id\" : \"817466825\", \n      \"name\" : \"Customer\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  ], \n  \"names\" : { \n    \"_cluster_kickstarter_plans\" : { \n      \"id\" : \"2723273\", \n      \"name\" : \"_cluster_kickstarter_plans\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Groceries\" : { \n      \"id\" : \"817860041\", \n      \"name\" : \"Groceries\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"female\" : { \n      \"id\" : \"879201737\", \n      \"name\" : \"female\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_users\" : { \n      \"id\" : \"429513\", \n      \"name\" : \"_users\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"frenchCity\" : { \n      \"id\" : \"903187913\", \n      \"name\" : \"frenchCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_sessions\" : { \n      \"id\" : \"26185161\", \n      \"name\" : \"_sessions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statisticsRaw\" : { \n      \"id\" : \"4820425\", \n      \"name\" : \"_statisticsRaw\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_routing\" : { \n      \"id\" : \"2592201\", \n      \"name\" : \"_routing\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Company\" : { \n      \"id\" : \"817728969\", \n      \"name\" : \"Company\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_statistics\" : { \n      \"id\" : \"5213641\", \n      \"name\" : \"_statistics\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"has_bought\" : { \n      \"id\" : \"818122185\", \n      \"name\" : \"has_bought\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"germanHighway\" : { \n      \"id\" : \"903056841\", \n      \"name\" : \"germanHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"relation\" : { \n      \"id\" : \"879463881\", \n      \"name\" : \"relation\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_statistics15\" : { \n      \"id\" : \"5606857\", \n      \"name\" : \"_statistics15\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"internationalHighway\" : { \n      \"id\" : \"903450057\", \n      \"name\" : \"internationalHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_aqlfunctions\" : { \n      \"id\" : \"4689353\", \n      \"name\" : \"_aqlfunctions\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_modules\" : { \n      \"id\" : \"2461129\", \n      \"name\" : \"_modules\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_configuration\" : { \n      \"id\" : \"232905\", \n      \"name\" : \"_configuration\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_aal\" : { \n      \"id\" : \"4230601\", \n      \"name\" : \"_aal\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_jobs\" : { \n      \"id\" : \"6458825\", \n      \"name\" : \"_jobs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"friend_of\" : { \n      \"id\" : \"817597897\", \n      \"name\" : \"friend_of\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"better-example\" : { \n      \"id\" : \"719752649\", \n      \"name\" : \"better-example\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"animals\" : { \n      \"id\" : \"908758473\", \n      \"name\" : \"animals\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"demo\" : { \n      \"id\" : \"907840969\", \n      \"name\" : \"demo\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Electronics\" : { \n      \"id\" : \"817991113\", \n      \"name\" : \"Electronics\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"germanCity\" : { \n      \"id\" : \"902925769\", \n      \"name\" : \"germanCity\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"male\" : { \n      \"id\" : \"879332809\", \n      \"name\" : \"male\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"frenchHighway\" : { \n      \"id\" : \"903318985\", \n      \"name\" : \"frenchHighway\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 3 \n    }, \n    \"_graphs\" : { \n      \"id\" : \"2330057\", \n      \"name\" : \"_graphs\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"_queues\" : { \n      \"id\" : \"6327753\", \n      \"name\" : \"_queues\", \n      \"isSystem\" : true, \n      \"status\" : 3, \n      \"type\" : 2 \n    }, \n    \"Customer\" : { \n      \"id\" : \"817466825\", \n      \"name\" : \"Customer\", \n      \"isSystem\" : false, \n      \"status\" : 3, \n      \"type\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



    ", "nickname": "readsAllCollections" } ], @@ -99,7 +99,7 @@ "notes": "In addition to the above, the result will always contain the waitForSync, doCompact, journalSize, and isVolatile attributes. This is achieved by forcing a load of the underlying collection.

    • waitForSync: If true then creating or changing a document will wait until the data has been synchronised to disk.
    • doCompact: Whether or not the collection will be compacted.
    • journalSize: The maximal size setting for journals / datafiles.
    • isVolatile: If true then the collection data will be kept in memory only and ArangoDB will not write or sync the data to disk.
    In a cluster setup, the result will also contain the following attributes:
    • numberOfShards: the number of shards of the collection.
    • shardKeys: contains the names of document attributes that are used to determine the target shard for documents.", "summary": " Read properties of a collection", "httpMethod": "GET", - "examples": "

      Using an identifier:



      shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/890895528/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"890895528\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



      Using a name:



      shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"891092136\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



      ", + "examples": "

      Using an identifier:



      shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/911183305/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"911183305\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



      Using a name:



      shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/properties\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/properties\n\n{ \n  \"id\" : \"911379913\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



      ", "nickname": "ReadPropertiesOfACollection" } ], @@ -130,7 +130,7 @@ "notes": "In addition to the above, the result also contains the number of documents. Note that this will always load the collection into memory.

      • count: The number of documents inside the collection.", "summary": " Return number of documents in a collection", "httpMethod": "GET", - "examples": "

        Requesting the number of documents:



        shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/count\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/count\n\n{ \n  \"id\" : \"891288744\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"count\" : 100, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



        ", + "examples": "

        Requesting the number of documents:



        shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/count\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/count\n\n{ \n  \"id\" : \"911576521\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"count\" : 100, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



        ", "nickname": "ReturnNumberOfDocumentsInACollection" } ], @@ -161,7 +161,7 @@ "notes": "In addition to the above, the result also contains the number of documents and additional statistical information about the collection. Note : This will always load the collection into memory.

        • count: The number of documents currently present in the collection.
        *figures.alive.count: The number of curretly active documents in all datafiles and journals of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.

        *figures.alive.size: The total size in bytes used by all active documents of the collection. Documents that are contained in the write-ahead log only are not reported in this figure.

        • figures.dead.count: The number of dead documents. This includes document versions that have been deleted or replaced by a newer version. Documents deleted or replaced that are contained the write-ahead log only are not reported in this figure.
        *figures.dead.size: The total size in bytes used by all dead documents.

        *figures.dead.deletion: The total number of deletion markers. Deletion markers only contained in the write-ahead log are not reporting in this figure.

        • figures.datafiles.count: The number of datafiles.
        • figures.datafiles.fileSize: The total filesize of datafiles (in bytes).
        • figures.journals.count: The number of journal files.
        • figures.journals.fileSize: The total filesize of all journal files (in bytes).
        • figures.compactors.count: The number of compactor files.
        • figures.compactors.fileSize: The total filesize of all compactor files (in bytes).
        *figures.shapefiles.count: The number of shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 since ArangoDB 2.0 and higher. *figures.shapefiles.fileSize: The total filesize of the shape files. This value is deprecated and kept for compatibility reasons only. The value will always be 0 in ArangoDB 2.0 and higher.

        *figures.shapes.count: The total number of shapes used in the collection. This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure. *figures.shapes.size: The total size of all shapes (in bytes). This includes shapes that are not in use anymore. Shapes that are contained in the write-ahead log only are not reported in this figure.

        *figures.attributes.count: The total number of attributes used in the collection. Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure. *figures.attributes.size: The total size of the attribute data (in bytes). Note: the value includes data of attributes that are not in use anymore. Attributes that are contained in the write-ahead log only are not reported in this figure.

        *figures.indexes.count: The total number of indexes defined for the collection, including the pre-defined indexes (e.g. primary index).

        *figures.indexes.size: The total memory allocated for indexes in bytes.

        *figures.maxTick: The tick of the last marker that was stored in a journal of the collection. This might be 0 if the collection does not yet have a journal.

        *figures.uncollectedLogfileEntries: The number of markers in the write-ahead log for this collection that have not been transferred to journals or datafiles.

        • journalSize: The maximal size of the journal in bytes.
        Note: collection data that are stored in the write-ahead log only are not reported in the results. When the write-ahead log is collected, documents might be added to journals and datafiles of the collection, which may modify the figures of the collection.

        Additionally, the filesizes of collection and index parameter JSON files are not reported. These files should normally have a size of a few bytes each. Please also note that the fileSize values are reported in bytes and reflect the logical file sizes. Some filesystems may use optimisations (e.g. sparse files) so that the actual physical file size is somewhat different. Directories and sub-directories may also require space in the file system, but this space is not reported in the fileSize results.

        That means that the figures reported do not reflect the actual disk usage of the collection with 100% accuracy. The actual disk usage of a collection is normally slightly higher than the sum of the reported fileSize values. Still the sum of the fileSize values can still be used as a lower bound approximation of the disk usage.

        ", "summary": " Return statistics for a collection", "httpMethod": "GET", - "examples": "

        Using an identifier and requesting the figures of the collection:



        shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/figures\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/figures\n\n{ \n  \"id\" : \"911539368\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : false, \n  \"count\" : 1, \n  \"figures\" : { \n    \"alive\" : { \n      \"count\" : 1, \n      \"size\" : 88 \n    }, \n    \"dead\" : { \n      \"count\" : 0, \n      \"size\" : 0, \n      \"deletion\" : 0 \n    }, \n    \"datafiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"journals\" : { \n      \"count\" : 1, \n      \"fileSize\" : 1048576 \n    }, \n    \"compactors\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapefiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapes\" : { \n      \"count\" : 1, \n      \"size\" : 104 \n    }, \n    \"attributes\" : { \n      \"count\" : 1, \n      \"size\" : 48 \n    }, \n    \"indexes\" : { \n      \"count\" : 1, \n      \"size\" : 2008 \n    }, \n    \"lastTick\" : \"911932584\", \n    \"uncollectedLogfileEntries\" : 0 \n  }, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



        ", + "examples": "

        Using an identifier and requesting the figures of the collection:



        shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/figures\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\nlocation: /_db/_system/_api/collection/products/figures\n\n{ \n  \"id\" : \"932220361\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : false, \n  \"count\" : 1, \n  \"figures\" : { \n    \"alive\" : { \n      \"count\" : 1, \n      \"size\" : 88 \n    }, \n    \"dead\" : { \n      \"count\" : 0, \n      \"size\" : 0, \n      \"deletion\" : 0 \n    }, \n    \"datafiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"journals\" : { \n      \"count\" : 1, \n      \"fileSize\" : 1048576 \n    }, \n    \"compactors\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapefiles\" : { \n      \"count\" : 0, \n      \"fileSize\" : 0 \n    }, \n    \"shapes\" : { \n      \"count\" : 1, \n      \"size\" : 104 \n    }, \n    \"attributes\" : { \n      \"count\" : 1, \n      \"size\" : 48 \n    }, \n    \"indexes\" : { \n      \"count\" : 1, \n      \"size\" : 2008 \n    }, \n    \"lastTick\" : \"932613577\", \n    \"uncollectedLogfileEntries\" : 0 \n  }, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



        ", "nickname": "ReturnStatisticsForACollection" } ], @@ -192,7 +192,7 @@ "notes": "In addition to the above, the result will also contain the collection's revision id. The revision id is a server-generated string that clients can use to check whether data in a collection has changed since the last revision check.

        • revision: The collection revision id as a string.", "summary": " Return collection revision id", "httpMethod": "GET", - "examples": "

          Retrieving the revision of a collection



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/revision\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"912915624\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"revision\" : \"0\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          ", + "examples": "

          Retrieving the revision of a collection



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/revision\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"933531081\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"revision\" : \"0\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          ", "nickname": "ReturnCollectionRevisionId" } ], @@ -237,7 +237,7 @@ "notes": "Will calculate a checksum of the meta-data (keys and optionally revision ids) and optionally the document data in the collection.

          The checksum can be used to compare if two collections on different ArangoDB instances contain the same contents. The current revision of the collection is returned too so one can make sure the checksums are calculated for the same state of data.

          By default, the checksum will only be calculated on the _key system attribute of the documents contained in the collection. For edge collections, the system attributes _from and _to will also be included in the calculation.

          By setting the optional URL parameter withRevisions to true, then revision ids (_rev system attributes) are included in the checksumming.

          By providing the optional URL parameter withData with a value of true, the user-defined document attributes will be included in the calculation too. Note: Including user-defined attributes will make the checksumming slower.

          The response is a JSON object with the following attributes:

          • checksum: The calculated checksum as a number.
          • revision: The collection revision id as a string.
          Note: this method is not available in a cluster.

          ", "summary": " Return checksum for the collection", "httpMethod": "GET", - "examples": "

          Retrieving the checksum of a collection:



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/checksum\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"913177768\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 912174629, \n  \"revision\" : \"913505448\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          Retrieving the checksum of a collection including the collection data, but not the revisions:



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/checksum?withRevisions=false&withData=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"913767592\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 375414976, \n  \"revision\" : \"914095272\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          ", + "examples": "

          Retrieving the checksum of a collection:



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/checksum\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"933793225\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 1968594040, \n  \"revision\" : \"934120905\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          Retrieving the checksum of a collection including the collection data, but not the revisions:



          shell> curl --data-binary @- --dump - http://localhost:8529/_api/collection/products/checksum?withRevisions=false&withData=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"934383049\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"checksum\" : 2327871952, \n  \"revision\" : \"934710729\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



          ", "nickname": "ReturnChecksumForTheCollection" } ], @@ -268,7 +268,7 @@ "notes": "Loads a collection into memory. Returns the collection on success.

          The request might optionally contain the following attribute:

          • count: If set, this controls whether the return value should include the number of documents in the collection. Setting count to false may speed up loading a collection. The default value for count is true.
          On success an object with the following attributes is returned:

          • id: The identifier of the collection.
          • name: The name of the collection.
          • count: The number of documents inside the collection. This is only returned if the count input parameters is set to true or has not been specified.
          • status: The status of the collection as number.
          • type: The collection type. Valid types are: - 2: document collection - 3: edges collection", "summary": " Load collection", "httpMethod": "PUT", - "examples": "



            shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/load\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"914357416\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"count\" : 0, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



            ", + "examples": "



            shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/load\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"934972873\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"count\" : 0, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



            ", "nickname": "LoadCollection" } ], @@ -299,7 +299,7 @@ "notes": "Removes a collection from memory. This call does not delete any documents. You can use the collection afterwards; in which case it will be loaded into memory, again. On success an object with the following attributes is returned:

            • id: The identifier of the collection.
            • name: The name of the collection.
            • status: The status of the collection as number.
            • type: The collection type. Valid types are: - 2: document collection - 3: edges collection", "summary": " Unload collection", "httpMethod": "PUT", - "examples": "



              shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/unload\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"914619560\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 4, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", + "examples": "



              shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/unload\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"935235017\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 2, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", "nickname": "UnloadCollection" } ], @@ -321,7 +321,7 @@ "notes": "Removes all documents from the collection, but leaves the indexes intact.

              ", "summary": " Truncate collection", "httpMethod": "PUT", - "examples": "



              shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/truncate\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"914816168\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", + "examples": "



              shell> curl -X PUT --dump - http://localhost:8529/_api/collection/products/truncate\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"935431625\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", "nickname": "TruncateCollection" } ], @@ -343,7 +343,7 @@ "notes": "Changes the properties of a collection. Expects an object with the attribute(s)

              • waitForSync: If true then creating or changing a document will wait until the data has been synchronised to disk.
              • journalSize: Size (in bytes) for new journal files that are created for the collection.
              If returns an object with the attributes

              • id: The identifier of the collection.
              • name: The name of the collection.
              • waitForSync: The new value.
              • journalSize: The new value.
              • status: The status of the collection as number.
              • type: The collection type. Valid types are: - 2: document collection - 3: edges collection
              Note: some other collection properties, such as type, isVolatile, numberOfShards or shardKeys cannot be changed once a collection is created.

              ", "summary": " Change properties of a collection", "httpMethod": "PUT", - "examples": "



              shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products/properties\n{ \n  \"waitForSync\" : true \n}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"915209384\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", + "examples": "



              shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products/properties\n{ \n  \"waitForSync\" : true \n}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"935824841\", \n  \"name\" : \"products\", \n  \"isSystem\" : false, \n  \"doCompact\" : true, \n  \"isVolatile\" : false, \n  \"journalSize\" : 1048576, \n  \"keyOptions\" : { \n    \"type\" : \"traditional\", \n    \"allowUserKeys\" : true \n  }, \n  \"waitForSync\" : true, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



              ", "nickname": "ChangePropertiesOfACollection" } ], @@ -365,7 +365,7 @@ "notes": "Renames a collection. Expects an object with the attribute(s)

              • name: The new name.
              If returns an object with the attributes

              • id: The identifier of the collection.
              • name: The new name of the collection.
              • status: The status of the collection as number.
              • type: The collection type. Valid types are: - 2: document collection - 3: edges collection", "summary": " Rename collection", "httpMethod": "PUT", - "examples": "



                shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products1/rename\n{ \n  \"name\" : \"newname\" \n}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"915471528\", \n  \"name\" : \"newname\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                ", + "examples": "



                shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/collection/products1/rename\n{ \n  \"name\" : \"newname\" \n}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"936086985\", \n  \"name\" : \"newname\", \n  \"isSystem\" : false, \n  \"status\" : 3, \n  \"type\" : 2, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                ", "nickname": "RenameCollection" } ], @@ -427,7 +427,7 @@ "notes": "Deletes a collection identified by collection-name.

                If the collection was successfully deleted then, an object is returned with the following attributes:

                • error: false
                • id: The identifier of the deleted collection.", "summary": " Delete collection", "httpMethod": "DELETE", - "examples": "

                  Using an identifier:



                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/collection/916847784\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"916847784\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  Using a name:



                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/collection/products1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"917044392\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  ", + "examples": "

                  Using an identifier:



                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/collection/937463241\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"937463241\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  Using a name:



                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/collection/products1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"937659849\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  ", "nickname": "DeleteCollection" } ], diff --git a/js/apps/system/aardvark/api-docs/cursor.json b/js/apps/system/aardvark/api-docs/cursor.json index 1b108099d9..7338ca6cdc 100644 --- a/js/apps/system/aardvark/api-docs/cursor.json +++ b/js/apps/system/aardvark/api-docs/cursor.json @@ -33,10 +33,10 @@ "description": "A JSON object describing the query and query parameters.

                  " } ], - "notes": "The query details include the query string plus optional query options and bind parameters. These values need to be passed in a JSON representation in the body of the POST request.

                  The following attributes can be used inside the JSON object:

                  • query: contains the query string to be executed (mandatory)
                  • count: boolean flag that indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result (optional). Calculating the \"count\" attribute might in the future have a performance impact for some queries so this option is turned off by default, and \"count\" is only returned when requested.
                  • batchSize: maximum number of result documents to be transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.
                  • ttl: an optional time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
                  • bindVars: key/value list of bind parameters (optional).
                  • options: key/value list of extra options for the query (optional).
                  The following options are supported at the moment:

                  • fullCount: if set to true and the query contains a LIMIT clause, then the result will contain an extra attribute extra with a sub-attribute fullCount. This sub-attribute will contain the number of documents in the result before the last LIMIT in the query was applied. It can be used to count the number of documents that match certain filter criteria, but only return a subset of them, in one go. It is thus similar to MySQL's SQL_CALC_FOUND_ROWS hint. Note that setting the option will disable a few LIMIT optimizations and may lead to more documents being processed, and thus make queries run longer. Note that the fullCount sub-attribute will only be present in the result if the query has a LIMIT clause and the LIMIT clause is actually used in the query.
                  If the result set can be created by the server, the server will respond with HTTP 201. The body of the response will contain a JSON object with the result set.

                  The returned JSON object has the following properties:

                  • error: boolean flag to indicate that an error occurred (false in this case)
                  • code: the HTTP status code
                  • result: an array of result documents (might be empty if query has no results)
                  • hasMore: a boolean indicator whether there are more results available for the cursor on the server
                  • count: the total number of result documents available (only available if the query was executed with the count attribute set)
                  • id: id of temporary cursor created on the server (optional, see above)
                  • extra: an optional JSON object with extra information about the query result. For data-modification queries, the extra attribute will contain the number of modified documents and the number of documents that could not be modified due to an error (if ignoreErrors query option is specified)
                  If the JSON representation is malformed or the query specification is missing from the request, the server will respond with HTTP 400.

                  The body of the response will contain a JSON object with additional error details. The object has the following attributes:

                  • error: boolean flag to indicate that an error occurred (true in this case)
                  • code: the HTTP status code
                  • errorNum: the server error number
                  • errorMessage: a descriptive error message
                  If the query specification is complete, the server will process the query. If an error occurs during query processing, the server will respond with HTTP 400. Again, the body of the response will contain details about the error.

                  A list of query errors can be found (../ArangoErrors/README.md) here.

                  ", + "notes": "The query details include the query string plus optional query options and bind parameters. These values need to be passed in a JSON representation in the body of the POST request.

                  The following attributes can be used inside the JSON object:

                  • query: contains the query string to be executed (mandatory)
                  • count: boolean flag that indicates whether the number of documents in the result set should be returned in the \"count\" attribute of the result (optional). Calculating the \"count\" attribute might in the future have a performance impact for some queries so this option is turned off by default, and \"count\" is only returned when requested.
                  • batchSize: maximum number of result documents to be transferred from the server to the client in one roundtrip (optional). If this attribute is not set, a server-controlled default value will be used.
                  • ttl: an optional time-to-live for the cursor (in seconds). The cursor will be removed on the server automatically after the specified amount of time. This is useful to ensure garbage collection of cursors that are not fully fetched by clients. If not set, a server-defined value will be used.
                  • bindVars: key/value list of bind parameters (optional).
                  • options: key/value list of extra options for the query (optional).
                  The following options are supported at the moment:

                  • fullCount: if set to true and the query contains a LIMIT clause, then the result will contain an extra attribute extra with a sub-attribute fullCount. This sub-attribute will contain the number of documents in the result before the last LIMIT in the query was applied. It can be used to count the number of documents that match certain filter criteria, but only return a subset of them, in one go. It is thus similar to MySQL's SQL_CALC_FOUND_ROWS hint. Note that setting the option will disable a few LIMIT optimizations and may lead to more documents being processed, and thus make queries run longer. Note that the fullCount sub-attribute will only be present in the result if the query has a LIMIT clause and the LIMIT clause is actually used in the query.
                  • maxPlans: limits the maximum number of plans that are created by the AQL query optimizer.
                  • optimizer.rules: a list of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a -, to enable a rule, prefix it with a +. There is also a pseudo-rule all, which will match all optimizer rules.
                  If the result set can be created by the server, the server will respond with HTTP 201. The body of the response will contain a JSON object with the result set.

                  The returned JSON object has the following properties:

                  • error: boolean flag to indicate that an error occurred (false in this case)
                  • code: the HTTP status code
                  • result: an array of result documents (might be empty if query has no results)
                  • hasMore: a boolean indicator whether there are more results available for the cursor on the server
                  • count: the total number of result documents available (only available if the query was executed with the count attribute set)
                  • id: id of temporary cursor created on the server (optional, see above)
                  • extra: an optional JSON object with extra information about the query result. For data-modification queries, the extra attribute will contain the number of modified documents and the number of documents that could not be modified due to an error (if ignoreErrors query option is specified)
                  If the JSON representation is malformed or the query specification is missing from the request, the server will respond with HTTP 400.

                  The body of the response will contain a JSON object with additional error details. The object has the following attributes:

                  • error: boolean flag to indicate that an error occurred (true in this case)
                  • code: the HTTP status code
                  • errorNum: the server error number
                  • errorMessage: a descriptive error message
                  If the query specification is complete, the server will process the query. If an error occurs during query processing, the server will respond with HTTP 400. Again, the body of the response will contain details about the error.

                  A list of query errors can be found (../ArangoErrors/README.md) here.

                  ", "summary": " Create cursor", "httpMethod": "POST", - "examples": "

                  Executes a query and extract the result in a single go:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 2 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/917896360\", \n      \"_key\" : \"917896360\", \n      \"_rev\" : \"917896360\", \n      \"hello2\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/917568680\", \n      \"_key\" : \"917568680\", \n      \"_rev\" : \"917568680\", \n      \"hello1\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a query and extracts part of the result:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/919796904\", \n      \"_key\" : \"919796904\", \n      \"_rev\" : \"919796904\", \n      \"hello5\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/919141544\", \n      \"_key\" : \"919141544\", \n      \"_rev\" : \"919141544\", \n      \"hello3\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"919993512\", \n  \"count\" : 5, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Using a query option:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR i IN 1..1000 FILTER i > 500 LIMIT 10 RETURN i\",\"count\":true,\"options\":{\"fullCount\":true}}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    501, \n    502, \n    503, \n    504, \n    505, \n    506, \n    507, \n    508, \n    509, \n    510 \n  ], \n  \"hasMore\" : false, \n  \"count\" : 10, \n  \"extra\" : { \n    \"fullCount\" : 500 \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a data-modification query and retrieves the number of modified documents:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products REMOVE p IN products\"}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"operations\" : { \n      \"executed\" : 2, \n      \"ignored\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a data-modification query with option ignoreErrors:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"REMOVE 'bar' IN products OPTIONS { ignoreErrors: true }\"}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"operations\" : { \n      \"executed\" : 0, \n      \"ignored\" : 1 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Bad queries:

                  Missing body:



                  shell> curl -X POST --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1502, \n  \"errorMessage\" : \"query is empty\" \n}\n



                  Unknown collection:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR u IN unknowncoll LIMIT 2 RETURN u\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1203, \n  \"errorMessage\" : \"cannot execute query: collection not found: 'unknowncoll'\" \n}\n



                  Executes a data-modification query that attempts to remove a non-existing document:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"REMOVE 'foo' IN products\"}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1202, \n  \"errorMessage\" : \"document not found\" \n}\n





                  ", + "examples": "

                  Executes a query and extract the result in a single go:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 2 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/938184137\", \n      \"_key\" : \"938184137\", \n      \"_rev\" : \"938184137\", \n      \"hello1\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/938511817\", \n      \"_key\" : \"938511817\", \n      \"_rev\" : \"938511817\", \n      \"hello2\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 2, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a query and extracts part of the result:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/940084681\", \n      \"_key\" : \"940084681\", \n      \"_rev\" : \"940084681\", \n      \"hello4\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/939429321\", \n      \"_key\" : \"939429321\", \n      \"_rev\" : \"939429321\", \n      \"hello2\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"940608969\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Using query option \"fullCount\":



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR i IN 1..1000 FILTER i > 500 LIMIT 10 RETURN i\",\"count\":true,\"options\":{\"fullCount\":true}}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    501, \n    502, \n    503, \n    504, \n    505, \n    506, \n    507, \n    508, \n    509, \n    510 \n  ], \n  \"hasMore\" : false, \n  \"count\" : 10, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0, \n      \"fullCount\" : 500 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Enabling and disabling optimizer rules:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR i IN 1..10 LET a = 1 LET b = 2 FILTER a + b == 3 RETURN i\",\"count\":true,\"options\":{\"maxPlans\":1,\"optimizer\":{\"rules\":[\"-all\",\"+remove-unnecessary-filters\"]}}}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    1, \n    2, \n    3, \n    4, \n    5, \n    6, \n    7, \n    8, \n    9, \n    10 \n  ], \n  \"hasMore\" : false, \n  \"count\" : 10, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a data-modification query and retrieves the number of modified documents:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products REMOVE p IN products\"}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 2, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 2, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Executes a data-modification query with option ignoreErrors:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"REMOVE 'bar' IN products OPTIONS { ignoreErrors: true }\"}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 1, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                  Bad queries:

                  Missing body:



                  shell> curl -X POST --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1502, \n  \"errorMessage\" : \"query is empty\" \n}\n



                  Unknown collection:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR u IN unknowncoll LIMIT 2 RETURN u\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1203, \n  \"errorMessage\" : \"collection not found (unknowncoll)\" \n}\n



                  Executes a data-modification query that attempts to remove a non-existing document:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"REMOVE 'foo' IN products\"}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1202, \n  \"errorMessage\" : \"document not found (while executing)\" \n}\n





                  ", "nickname": "CreateCursor" } ], @@ -71,7 +71,7 @@ "notes": "

                  If the cursor is still alive, returns an object with the following attributes.

                  • id: the cursor-identifier
                  • result: a list of documents for the current batch
                  • hasMore: false if this was the last batch
                  • count: if present the total number of elements
                  Note that even if hasMore returns true, the next call might still return no documents. If, however, hasMore is false, then the cursor is exhausted. Once the hasMore attribute has a value of false, the client can stop.

                  ", "summary": " Read next batch from cursor", "httpMethod": "PUT", - "examples": "

                  Valid request for next batch:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/cursor/924777640\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/923597992\", \n      \"_key\" : \"923597992\", \n      \"_rev\" : \"923597992\", \n      \"hello2\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/924253352\", \n      \"_key\" : \"924253352\", \n      \"_rev\" : \"924253352\", \n      \"hello4\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"924777640\", \n  \"count\" : 5, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  Missing identifier



                  shell> curl -X PUT --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 400, \n  \"errorMessage\" : \"bad parameter\" \n}\n



                  Unknown identifier



                  shell> curl -X PUT --dump - http://localhost:8529/_api/cursor/123123\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1600, \n  \"errorMessage\" : \"cursor not found\" \n}\n



                  ", + "examples": "

                  Valid request for next batch:



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nshell> curl -X PUT --dump - http://localhost:8529/_api/cursor/945458633\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/944278985\", \n      \"_key\" : \"944278985\", \n      \"_rev\" : \"944278985\", \n      \"hello2\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/945262025\", \n      \"_key\" : \"945262025\", \n      \"_rev\" : \"945262025\", \n      \"hello5\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"945458633\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                  Missing identifier



                  shell> curl -X PUT --dump - http://localhost:8529/_api/cursor\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 400, \n  \"errorMessage\" : \"bad parameter\" \n}\n



                  Unknown identifier



                  shell> curl -X PUT --dump - http://localhost:8529/_api/cursor/123123\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 1600, \n  \"errorMessage\" : \"cursor not found\" \n}\n



                  ", "nickname": "ReadNextBatchFromCursor" } ], @@ -102,7 +102,7 @@ "notes": "Deletes the cursor and frees the resources associated with it.

                  The cursor will automatically be destroyed on the server when the client has retrieved all documents from it. The client can also explicitly destroy the cursor at any earlier time using an HTTP DELETE request. The cursor id must be included as part of the URL.

                  Note: the server will also destroy abandoned cursors automatically after a certain server-controlled timeout to avoid resource leakage.

                  ", "summary": " Delete cursor", "httpMethod": "DELETE", - "examples": "



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/925564072\", \n      \"_key\" : \"925564072\", \n      \"_rev\" : \"925564072\", \n      \"hello2\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/926219432\", \n      \"_key\" : \"926219432\", \n      \"_rev\" : \"926219432\", \n      \"hello4\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"926743720\", \n  \"count\" : 5, \n  \"error\" : false, \n  \"code\" : 201 \n}\nshell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/cursor/926743720\n\n



                  ", + "examples": "



                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/cursor\n{\"query\":\"FOR p IN products LIMIT 5 RETURN p\",\"count\":true,\"batchSize\":2}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/947228105\", \n      \"_key\" : \"947228105\", \n      \"_rev\" : \"947228105\", \n      \"hello5\" : \"world1\" \n    }, \n    { \n      \"_id\" : \"products/946245065\", \n      \"_key\" : \"946245065\", \n      \"_rev\" : \"946245065\", \n      \"hello2\" : \"world1\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"947424713\", \n  \"count\" : 5, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\nshell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/cursor/947424713\n\n



                  ", "nickname": "DeleteCursor" } ], diff --git a/js/apps/system/aardvark/api-docs/database.json b/js/apps/system/aardvark/api-docs/database.json index ee8f009dbb..2ce467c8b7 100644 --- a/js/apps/system/aardvark/api-docs/database.json +++ b/js/apps/system/aardvark/api-docs/database.json @@ -74,7 +74,7 @@ "notes": "Retrieves information about the current database

                  The response is a JSON object with the following attributes:

                  • name: the name of the current database
                  • id: the id of the current database
                  • path: the filesystem path of the current database
                  • isSystem: whether or not the current database is the _system database", "summary": " Information of the database", "httpMethod": "GET", - "examples": "



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/database/current\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"name\" : \"_system\", \n    \"id\" : \"130216\", \n    \"path\" : \"/tmp/vocdir.14793/databases/database-130216\", \n    \"isSystem\" : true \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    ", + "examples": "



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/database/current\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"name\" : \"_system\", \n    \"id\" : \"101833\", \n    \"path\" : \"/tmp/vocdir.19920/databases/database-101833\", \n    \"isSystem\" : true \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    ", "nickname": "InformationOfTheDatabase" } ], diff --git a/js/apps/system/aardvark/api-docs/document.json b/js/apps/system/aardvark/api-docs/document.json index 88d379ed45..5f6a5a62cd 100644 --- a/js/apps/system/aardvark/api-docs/document.json +++ b/js/apps/system/aardvark/api-docs/document.json @@ -57,7 +57,7 @@ "notes": "Creates a new document in the collection named collection. A JSON representation of the document must be passed as the body of the POST request.

                    If the document was created successfully, then the \"Location\" header contains the path to the newly created document. The \"ETag\" header field contains the revision of the document.

                    The body of the response contains a JSON object with the following attributes:

                    • _id contains the document handle of the newly created document
                    • _key contains the document key
                    • _rev contains the document revision
                    If the collection parameter waitForSync is false, then the call returns as soon as the document has been accepted. It will not wait until the document has been synced to disk.

                    Optionally, the URL parameter waitForSync can be used to force synchronisation of the document creation operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronisation of just this specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronisation for collections that have a default waitForSync value of true.

                    ", "summary": "Create document", "httpMethod": "POST", - "examples": "

                    Create a document given a collection named products. Note that the revision identifier might or might not by equal to the auto-generated key.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"1365638312\"\nlocation: /_db/_system/_api/document/products/1365638312\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1365638312\", \n  \"_rev\" : \"1365638312\", \n  \"_key\" : \"1365638312\" \n}\n



                    Create a document in a collection named products with a collection-level waitForSync value of false.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1366162600\"\nlocation: /_db/_system/_api/document/products/1366162600\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1366162600\", \n  \"_rev\" : \"1366162600\", \n  \"_key\" : \"1366162600\" \n}\n



                    Create a document in a collection with a collection-level waitForSync value of false, but using the waitForSync URL parameter.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&waitForSync=true\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"1366686888\"\nlocation: /_db/_system/_api/document/products/1366686888\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1366686888\", \n  \"_rev\" : \"1366686888\", \n  \"_key\" : \"1366686888\" \n}\n



                    Create a document in a new, named collection



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&createCollection=true\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1367211176\"\nlocation: /_db/_system/_api/document/products/1367211176\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1367211176\", \n  \"_rev\" : \"1367211176\", \n  \"_key\" : \"1367211176\" \n}\n



                    Unknown collection name:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n



                    Illegal document:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ 1: \"World\" }\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting attribute name\", \n  \"code\" : 400, \n  \"errorNum\" : 600 \n}\n



                    ", + "examples": "

                    Create a document given a collection named products. Note that the revision identifier might or might not by equal to the auto-generated key.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"1427541449\"\nlocation: /_db/_system/_api/document/products/1427541449\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1427541449\", \n  \"_rev\" : \"1427541449\", \n  \"_key\" : \"1427541449\" \n}\n



                    Create a document in a collection named products with a collection-level waitForSync value of false.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1428065737\"\nlocation: /_db/_system/_api/document/products/1428065737\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1428065737\", \n  \"_rev\" : \"1428065737\", \n  \"_key\" : \"1428065737\" \n}\n



                    Create a document in a collection with a collection-level waitForSync value of false, but using the waitForSync URL parameter.



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&waitForSync=true\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: \"1428590025\"\nlocation: /_db/_system/_api/document/products/1428590025\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1428590025\", \n  \"_rev\" : \"1428590025\", \n  \"_key\" : \"1428590025\" \n}\n



                    Create a document in a new, named collection



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products&createCollection=true\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1429114313\"\nlocation: /_db/_system/_api/document/products/1429114313\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1429114313\", \n  \"_rev\" : \"1429114313\", \n  \"_key\" : \"1429114313\" \n}\n



                    Unknown collection name:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ \"Hello\": \"World\" }\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'products' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n



                    Illegal document:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/document?collection=products\n{ 1: \"World\" }\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"expecting attribute name\", \n  \"code\" : 400, \n  \"errorNum\" : 600 \n}\n



                    ", "nickname": "CreateDocument" } ], @@ -108,7 +108,7 @@ "notes": "Returns the document identified by document-handle. The returned document contains two special attributes: _id containing the document handle and _rev containing the revision.

                    ", "summary": "Read document", "httpMethod": "GET", - "examples": "

                    Use a document handle:



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1367735464\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1367735464\"\n\n{ \n  \"hello\" : \"world\", \n  \"_id\" : \"products/1367735464\", \n  \"_rev\" : \"1367735464\", \n  \"_key\" : \"1367735464\" \n}\n



                    Use a document handle and an etag:



                    shell> curl --header 'If-None-Match: \"1368325288\"' --dump - http://localhost:8529/_api/document/products/1368325288\n\n



                    Unknown document handle:



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/unknownhandle\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/unknownhandle not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    ", + "examples": "

                    Use a document handle:



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1429638601\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1429638601\"\n\n{ \n  \"hello\" : \"world\", \n  \"_id\" : \"products/1429638601\", \n  \"_rev\" : \"1429638601\", \n  \"_key\" : \"1429638601\" \n}\n



                    Use a document handle and an etag:



                    shell> curl --header 'If-None-Match: \"1430228425\"' --dump - http://localhost:8529/_api/document/products/1430228425\n\n



                    Unknown document handle:



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/unknownhandle\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/unknownhandle not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    ", "nickname": "ReadDocument" } ], @@ -146,7 +146,7 @@ "notes": "Returns a list of all keys, ids, or URI paths for all documents in the collection identified by collection. The type of the result list is determined by the type attribute.

                    Note that the results have no defined order and thus the order should not be relied on.

                    ", "summary": "Read all documents", "httpMethod": "GET", - "examples": "

                    Returns all document paths



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=products\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"/_api/document/products/1369636008\", \n    \"/_api/document/products/1368980648\", \n    \"/_api/document/products/1369308328\" \n  ] \n}\n



                    Returns all document keys



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=products&type=key\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"1370225832\", \n    \"1370881192\", \n    \"1370553512\" \n  ] \n}\n



                    Collection does not exist.



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=doesnotexist\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'doesnotexist' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n



                    ", + "examples": "

                    Returns all document paths



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=products\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"/_api/document/products/1431211465\", \n    \"/_api/document/products/1430883785\", \n    \"/_api/document/products/1431539145\" \n  ] \n}\n



                    Returns all document keys



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=products&type=key\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"documents\" : [ \n    \"1432915401\", \n    \"1432260041\", \n    \"1432587721\" \n  ] \n}\n



                    Collection does not exist.



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/document/?collection=doesnotexist\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"collection 'doesnotexist' not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1203 \n}\n



                    ", "nickname": "ReadAllDocuments" } ], @@ -204,7 +204,7 @@ "notes": "Like GET, but only returns the header fields and not the body. You can use this call to get the current revision of a document or check if the document was deleted.

                    ", "summary": "Read document header", "httpMethod": "HEAD", - "examples": "



                    shell> curl -X HEAD --data-binary @- --dump - http://localhost:8529/_api/document/products/1371471016\n\n





                    ", + "examples": "



                    shell> curl -X HEAD --data-binary @- --dump - http://localhost:8529/_api/document/products/1433570761\n\n





                    ", "nickname": "ReadDocumentHeader" } ], @@ -281,7 +281,7 @@ "notes": "Completely updates (i.e. replaces) the document identified by document-handle. If the document exists and can be updated, then a HTTP 201 is returned and the \"ETag\" header field contains the new revision of the document.

                    If the new document passed in the body of the request contains the document-handle in the attribute _id and the revision in _rev, these attributes will be ignored. Only the URI and the \"ETag\" header are relevant in order to avoid confusion when using proxies.

                    Optionally, the URL parameter waitForSync can be used to force synchronisation of the document replacement operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronisation of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronisation for collections that have a default waitForSync value of true.

                    The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated document, the attribute _rev contains the new document revision.

                    If the document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.

                    There are two ways for specifying the targeted document revision id for conditional replacements (i.e. replacements that will only be executed if the revision id found in the database matches the document revision id specified in the request):
                    • specifying the target revision in the rev URL query parameter
                    • specifying the target revision in the if-match HTTP header
                    Specifying a target revision is optional, however, if done, only one of the described mechanisms must be used (either the rev URL parameter or the if-match HTTP header). Regardless which mechanism is used, the parameter needs to contain the target document revision id as returned in the _rev attribute of a document or by an HTTP etag header.

                    For example, to conditionally replace a document based on a specific revision id, you can use the following request:

                    PUT /_api/document/document-handle?rev=etag

                    If a target revision id is provided in the request (e.g. via the etag value in the rev URL query parameter above), ArangoDB will check that the revision id of the document found in the database is equal to the target revision id provided in the request. If there is a mismatch between the revision id, then by default a HTTP 412 conflict is returned and no replacement is performed.

                    The conditional update behavior can be overriden with the policy URL query parameter:

                    PUT /_api/document/document-handle?policy=policy

                    If policy is set to error, then the behavior is as before: replacements will fail if the revision id found in the database does not match the target revision id specified in the request.

                    If policy is set to last, then the replacement will succeed, even if the revision id found in the database does not match the target revision id specified in the request. You can use the last *policy* to force replacements.

                    ", "summary": "Replace document", "httpMethod": "PUT", - "examples": "

                    Using document handle:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1372060840\n{\"Hello\": \"you\"}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1372388520\"\nlocation: /_db/_system/_api/document/products/1372060840\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1372060840\", \n  \"_rev\" : \"1372388520\", \n  \"_key\" : \"1372060840\" \n}\n



                    Unknown document handle:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1372912808\n{}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/1372912808 not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    Produce a revision conflict:



                    shell> curl -X PUT --header 'If-Match: \"1374157992\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/1373830312\n{\"other\":\"content\"}\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1373830312\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1373830312\", \n  \"_rev\" : \"1373830312\", \n  \"_key\" : \"1373830312\" \n}\n



                    Last write wins:



                    shell> curl -X PUT --header 'If-Match: \"1375272104\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/1374944424?policy=last\n{}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1375534248\"\nlocation: /_db/_system/_api/document/products/1374944424\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1374944424\", \n  \"_rev\" : \"1375534248\", \n  \"_key\" : \"1374944424\" \n}\n



                    Alternative to header field:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1376058536?rev=1376386216\n{\"other\":\"content\"}\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1376058536\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1376058536\", \n  \"_rev\" : \"1376058536\", \n  \"_key\" : \"1376058536\" \n}\n



                    ", + "examples": "

                    Using document handle:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1434160585\n{\"Hello\": \"you\"}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1434488265\"\nlocation: /_db/_system/_api/document/products/1434160585\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1434160585\", \n  \"_rev\" : \"1434488265\", \n  \"_key\" : \"1434160585\" \n}\n



                    Unknown document handle:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1435012553\n{}\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/1435012553 not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    Produce a revision conflict:



                    shell> curl -X PUT --header 'If-Match: \"1436257737\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/1435930057\n{\"other\":\"content\"}\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1435930057\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1435930057\", \n  \"_rev\" : \"1435930057\", \n  \"_key\" : \"1435930057\" \n}\n



                    Last write wins:



                    shell> curl -X PUT --header 'If-Match: \"1437371849\"' --data-binary @- --dump - http://localhost:8529/_api/document/products/1437044169?policy=last\n{}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1437633993\"\nlocation: /_db/_system/_api/document/products/1437044169\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1437044169\", \n  \"_rev\" : \"1437633993\", \n  \"_key\" : \"1437044169\" \n}\n



                    Alternative to header field:



                    shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/document/products/1438158281?rev=1438485961\n{\"other\":\"content\"}\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1438158281\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1438158281\", \n  \"_rev\" : \"1438158281\", \n  \"_key\" : \"1438158281\" \n}\n



                    ", "nickname": "ReplaceDocument" } ], @@ -365,7 +365,7 @@ "notes": "Partially updates the document identified by document-handle. The body of the request must contain a JSON document with the attributes to patch (the patch document). All attributes from the patch document will be added to the existing document if they do not yet exist, and overwritten in the existing document if they do exist there.

                    Setting an attribute value to null in the patch document will cause a value of null be saved for the attribute by default.

                    Optionally, the URL parameter waitForSync can be used to force synchronisation of the document update operation to disk even in case that the waitForSync flag had been disabled for the entire collection. Thus, the waitForSync URL parameter can be used to force synchronisation of just specific operations. To use this, set the waitForSync parameter to true. If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronisation for collections that have a default waitForSync value of true.

                    The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the updated document, the attribute _rev contains the new document revision.

                    If the document does not exist, then a HTTP 404 is returned and the body of the response contains an error document.

                    You can conditionally update a document based on a target revision id by using either the rev URL parameter or the if-match HTTP header. To control the update behavior in case there is a revision mismatch, you can use the policy parameter. This is the same as when replacing documents (see replacing documents for details).

                    ", "summary": " Patch document", "httpMethod": "PATCH", - "examples": "

                    patches an existing document with new content.



                    shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1377172648\n{ \n  \"hello\" : \"world\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1377500328\"\nlocation: /_db/_system/_api/document/products/1377172648\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1377172648\", \n  \"_rev\" : \"1377500328\", \n  \"_key\" : \"1377172648\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1377172648\n{ \n  \"numbers\" : { \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"empty\" : null \n  } \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1378090152\"\nlocation: /_db/_system/_api/document/products/1377172648\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1377172648\", \n  \"_rev\" : \"1378090152\", \n  \"_key\" : \"1377172648\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1377172648\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1378090152\"\n\n{ \n  \"one\" : \"world\", \n  \"hello\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3 \n  }, \n  \"_id\" : \"products/1377172648\", \n  \"_rev\" : \"1378090152\", \n  \"_key\" : \"1377172648\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1377172648?keepNull=false\n{ \n  \"hello\" : null, \n  \"numbers\" : { \n    \"four\" : 4 \n  } \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1378548904\"\nlocation: /_db/_system/_api/document/products/1377172648\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1377172648\", \n  \"_rev\" : \"1378548904\", \n  \"_key\" : \"1377172648\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1377172648\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1378548904\"\n\n{ \n  \"one\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"four\" : 4 \n  }, \n  \"_id\" : \"products/1377172648\", \n  \"_rev\" : \"1378548904\", \n  \"_key\" : \"1377172648\" \n}\n



                    ", + "examples": "

                    patches an existing document with new content.



                    shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1439272393\n{ \n  \"hello\" : \"world\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1439600073\"\nlocation: /_db/_system/_api/document/products/1439272393\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1439272393\", \n  \"_rev\" : \"1439600073\", \n  \"_key\" : \"1439272393\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1439272393\n{ \n  \"numbers\" : { \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"empty\" : null \n  } \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1440189897\"\nlocation: /_db/_system/_api/document/products/1439272393\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1439272393\", \n  \"_rev\" : \"1440189897\", \n  \"_key\" : \"1439272393\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1439272393\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1440189897\"\n\n{ \n  \"one\" : \"world\", \n  \"hello\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3 \n  }, \n  \"_id\" : \"products/1439272393\", \n  \"_rev\" : \"1440189897\", \n  \"_key\" : \"1439272393\" \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/document/products/1439272393?keepNull=false\n{ \n  \"hello\" : null, \n  \"numbers\" : { \n    \"four\" : 4 \n  } \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1440648649\"\nlocation: /_db/_system/_api/document/products/1439272393\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1439272393\", \n  \"_rev\" : \"1440648649\", \n  \"_key\" : \"1439272393\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/document/products/1439272393\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1440648649\"\n\n{ \n  \"one\" : \"world\", \n  \"numbers\" : { \n    \"empty\" : null, \n    \"one\" : 1, \n    \"two\" : 2, \n    \"three\" : 3, \n    \"four\" : 4 \n  }, \n  \"_id\" : \"products/1439272393\", \n  \"_rev\" : \"1440648649\", \n  \"_key\" : \"1439272393\" \n}\n



                    ", "nickname": "PatchDocument" } ], @@ -431,7 +431,7 @@ "notes": "The body of the response contains a JSON object with the information about the handle and the revision. The attribute _id contains the known document-handle of the deleted document, the attribute _rev contains the document revision.

                    If the waitForSync parameter is not specified or set to false, then the collection's default waitForSync behavior is applied. The waitForSync URL parameter cannot be used to disable synchronisation for collections that have a default waitForSync value of true.

                    ", "summary": " Deletes document", "httpMethod": "DELETE", - "examples": "

                    Using document handle:



                    shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/document/products/1379138728\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1379138728\", \n  \"_rev\" : \"1379138728\", \n  \"_key\" : \"1379138728\" \n}\n



                    Unknown document handle:



                    shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/document/products/1380252840\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/1380252840 not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    Revision conflict:



                    shell> curl -X DELETE --header 'If-Match: \"1381694632\"' --dump - http://localhost:8529/_api/document/products/1381366952\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1381366952\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1381366952\", \n  \"_rev\" : \"1381366952\", \n  \"_key\" : \"1381366952\" \n}\n



                    ", + "examples": "

                    Using document handle:



                    shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/document/products/1441238473\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : false, \n  \"_id\" : \"products/1441238473\", \n  \"_rev\" : \"1441238473\", \n  \"_key\" : \"1441238473\" \n}\n



                    Unknown document handle:



                    shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/document/products/1441959369\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"errorMessage\" : \"document /_api/document/products/1441959369 not found\", \n  \"code\" : 404, \n  \"errorNum\" : 1202 \n}\n



                    Revision conflict:



                    shell> curl -X DELETE --header 'If-Match: \"1443139017\"' --dump - http://localhost:8529/_api/document/products/1442811337\n\nHTTP/1.1 412 Precondition Failed\ncontent-type: application/json; charset=utf-8\netag: \"1442811337\"\n\n{ \n  \"error\" : true, \n  \"code\" : 412, \n  \"errorNum\" : 1200, \n  \"errorMessage\" : \"precondition failed\", \n  \"_id\" : \"products/1442811337\", \n  \"_rev\" : \"1442811337\", \n  \"_key\" : \"1442811337\" \n}\n



                    ", "nickname": "DeletesDocument" } ], diff --git a/js/apps/system/aardvark/api-docs/edge.json b/js/apps/system/aardvark/api-docs/edge.json index dd75500b4f..581ba680d1 100644 --- a/js/apps/system/aardvark/api-docs/edge.json +++ b/js/apps/system/aardvark/api-docs/edge.json @@ -71,7 +71,7 @@ "notes": "Creates a new edge document in the collection named collection. A JSON representation of the document must be passed as the body of the POST request.

                    The from and to handles are immutable once the edge has been created.

                    In all other respects the method works like POST /document.

                    ", "summary": "Create edge", "httpMethod": "POST", - "examples": "

                    Create an edge and read it back:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/edge/?collection=edges&from=vertices/1&to=vertices/2\n{ \n  \"name\" : \"Emil\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1383988392\"\nlocation: /_db/_system/_api/document/edges/1383988392\n\n{ \n  \"error\" : false, \n  \"_id\" : \"edges/1383988392\", \n  \"_rev\" : \"1383988392\", \n  \"_key\" : \"1383988392\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/edge/edges/1383988392\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1383988392\"\n\n{ \n  \"name\" : \"Emil\", \n  \"_id\" : \"edges/1383988392\", \n  \"_rev\" : \"1383988392\", \n  \"_key\" : \"1383988392\", \n  \"_from\" : \"vertices/1\", \n  \"_to\" : \"vertices/2\" \n}\n



                    ", + "examples": "

                    Create an edge and read it back:



                    shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/edge/?collection=edges&from=vertices/1&to=vertices/2\n{ \n  \"name\" : \"Emil\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: \"1445432777\"\nlocation: /_db/_system/_api/document/edges/1445432777\n\n{ \n  \"error\" : false, \n  \"_id\" : \"edges/1445432777\", \n  \"_rev\" : \"1445432777\", \n  \"_key\" : \"1445432777\" \n}\nshell> curl --data-binary @- --dump - http://localhost:8529/_api/edge/edges/1445432777\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: \"1445432777\"\n\n{ \n  \"name\" : \"Emil\", \n  \"_id\" : \"edges/1445432777\", \n  \"_rev\" : \"1445432777\", \n  \"_key\" : \"1445432777\", \n  \"_from\" : \"vertices/1\", \n  \"_to\" : \"vertices/2\" \n}\n



                    ", "nickname": "CreateEdge" } ], diff --git a/js/apps/system/aardvark/api-docs/edges.json b/js/apps/system/aardvark/api-docs/edges.json index 20b859177f..1284452202 100644 --- a/js/apps/system/aardvark/api-docs/edges.json +++ b/js/apps/system/aardvark/api-docs/edges.json @@ -33,7 +33,7 @@ "notes": "Returns the list of edges starting or ending in the vertex identified by vertex-handle.

                    ", "summary": " Read in- or outbound edges", "httpMethod": "GET", - "examples": "

                    Any direction



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"1046281384\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"1046805672\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"1045757096\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    In edges



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=in\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"1050999976\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"1051524264\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    Out edges



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=out\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"1055194280\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    ", + "examples": "

                    Any direction



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"1094487497\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"1095011785\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"1093963209\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    In edges



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=in\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/6\", \n      \"_key\" : \"6\", \n      \"_rev\" : \"1099206089\", \n      \"_from\" : \"vertices/2\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v2 -> v1\" \n    }, \n    { \n      \"_id\" : \"edges/7\", \n      \"_key\" : \"7\", \n      \"_rev\" : \"1099730377\", \n      \"_from\" : \"vertices/4\", \n      \"_to\" : \"vertices/1\", \n      \"$label\" : \"v4 -> v1\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    Out edges



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/edges/edges?vertex=vertices/1&direction=out\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"edges\" : [ \n    { \n      \"_id\" : \"edges/5\", \n      \"_key\" : \"5\", \n      \"_rev\" : \"1103597001\", \n      \"_from\" : \"vertices/1\", \n      \"_to\" : \"vertices/3\", \n      \"$label\" : \"v1 -> v3\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                    ", "nickname": "ReadIn-OrOutboundEdges" } ], diff --git a/js/apps/system/aardvark/api-docs/endpoint.json b/js/apps/system/aardvark/api-docs/endpoint.json index 829da58cb1..41fa156cf4 100644 --- a/js/apps/system/aardvark/api-docs/endpoint.json +++ b/js/apps/system/aardvark/api-docs/endpoint.json @@ -24,7 +24,7 @@ "notes": "Returns a list of all configured endpoints the server is listening on. For each endpoint, the list of allowed databases is returned too if set.

                    The result is a JSON hash which has the endpoints as keys, and the list of mapped database names as values for each endpoint.

                    If a list of mapped databases is empty, it means that all databases can be accessed via the endpoint. If a list of mapped databases contains more than one database name, this means that any of the databases might be accessed via the endpoint, and the first database in the list will be treated as the default database for the endpoint. The default database will be used when an incoming request does not specify a database name in the request explicitly.

                    Note: retrieving the list of all endpoints is allowed in the system database only. Calling this action in any other database will make the server return an error.

                    ", "summary": " Return list of all endpoints", "httpMethod": "GET", - "examples": "



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/endpoint\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"endpoint\" : \"tcp://127.0.0.1:34793\", \n    \"databases\" : [ ] \n  }, \n  { \n    \"endpoint\" : \"tcp://127.0.0.1:8532\", \n    \"databases\" : [ \n      \"mydb1\", \n      \"mydb2\" \n    ] \n  } \n]\n



                    ", + "examples": "



                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/endpoint\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n[ \n  { \n    \"endpoint\" : \"tcp://127.0.0.1:39920\", \n    \"databases\" : [ ] \n  }, \n  { \n    \"endpoint\" : \"tcp://127.0.0.1:8532\", \n    \"databases\" : [ \n      \"mydb1\", \n      \"mydb2\" \n    ] \n  } \n]\n



                    ", "nickname": "ReturnListOfAllEndpoints" } ], diff --git a/js/apps/system/aardvark/api-docs/explain.json b/js/apps/system/aardvark/api-docs/explain.json index 6b5938fd66..e55a2e82ce 100644 --- a/js/apps/system/aardvark/api-docs/explain.json +++ b/js/apps/system/aardvark/api-docs/explain.json @@ -8,11 +8,11 @@ { "errorResponses": [ { - "reason": "If the query is valid, the server will respond with HTTP 200 and return a list of the individual query execution steps in the \"plan\" attribute of the response.

                    ", + "reason": "If the query is valid, the server will respond with HTTP 200 and return the optimal execution plan in the plan attribute of the response. If option allPlans was set in the request, a list of plans will be returned in the allPlans attribute instead.

                    ", "code": "200" }, { - "reason": "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. Omitting bind variables if the query references any will result also result in an HTTP 400 error.

                    ", + "reason": "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. Omitting bind variables if the query references any will also result in an HTTP 400 error.

                    ", "code": "400" }, { @@ -26,14 +26,14 @@ "paramType": "body", "required": "true", "name": "body", - "description": "The query string needs to be passed in the attribute query of a JSON object as the body of the POST request. If the query references any bind variables, these must also be passed in the attribute bindVars.

                    " + "description": "The query string needs to be passed in the attribute query of a JSON object as the body of the POST request. If the query references any bind variables, these must also be passed in the attribute bindVars. Additional options for the query can be passed in the options attribute.

                    The currently supported options are:
                    • allPlans: if set to true, all possible execution plans will be returned. The default is false, meaning only the optimal plan will be returned.
                    • maxPlans: an optional maximum number of plans that the optimizer is allowed to generate. Setting this attribute to a low value allows to put a cap on the amount of work the optimizer does.
                    • optimizer.rules: a list of to-be-included or to-be-excluded optimizer rules can be put into this attribute, telling the optimizer to include or exclude specific rules. To disable a rule, prefix its name with a -, to enable a rule, prefix it with a +. There is also a pseudo-rule all, which will match all optimizer rules." } ], - "notes": "

                      To explain how an AQL query would be executed on the server, the query string can be sent to the server via an HTTP POST request. The server will then validate the query and create an execution plan for it, but will not execute it.

                      The execution plan that is returned by the server can be used to estimate the probable performance of an AQL query. Though the actual performance will depend on many different factors, the execution plan normally can give some good hint on the amount of work the server needs to do in order to actually run the query.

                      The top-level statements will appear in the result in the same order in which they have been used in the original query. Each result element has at most the following attributes:
                      • id: the row number of the top-level statement, starting at 1
                      • type: the type of the top-level statement (e.g. for, return ...)
                      • loopLevel: the nesting level of the top-level statement, starting at 1
                      Depending on the type of top-level statement, there might be other attributes providing additional information, for example, if and which indexed will be used. Many top-level statements will provide an expression attribute that contains data about the expression they operate on. This is true for FOR, FILTER, SORT, COLLECT, and RETURN statements. The expression attribute has the following sub-attributes:
                      • type: the type of the expression. Some possible values are: - collection: an iteration over documents from a collection. The value attribute will then contain the collection name. The extra attribute will contain information about if and which index is used when accessing the documents from the collection. If no index is used, the accessType sub-attribute of the extra attribute will have the value all, otherwise it will be index. - list: a list of dynamic values. The value attribute will contain the list elements. - const list: a list of constant values. The value attribute will contain the list elements. - reference: a reference to another variable. The value attribute will contain the name of the variable that is referenced.
                      Please note that the structure of the explain result data might change in future versions of ArangoDB without further notice and without maintaining backwards compatibility.

                      ", - "summary": " Explain query", + "notes": "

                      To explain how an AQL query would be executed on the server, the query string can be sent to the server via an HTTP POST request. The server will then validate the query and create an execution plan for it. The execution plan will be returned, but the query will not be executed.

                      The execution plan that is returned by the server can be used to estimate the probable performance of the query. Though the actual performance will depend on many different factors, the execution plan normally can provide some rough estimates on the amount of work the server needs to do in order to actually run the query.

                      By default, the explain operation will return the optimal plan as chosen by the query optimizer The optimal plan is the plan with the lowest total estimated cost. The plan will be returned in the attribute plan of the response object. If the option allPlans is specified in the request, the result will contain all plans created by the optimizer. The plans will then be returned in the attribute plans.

                      The result will also contain an attribute warnings, which is a list of warnings that occurred during optimization or execution plan creation.

                      Each plan in the result is a JSON object with the following attributes:
                      • nodes: the list of execution nodes of the plan. The list of available node types can be found [here](.../Aql/Optimizer.html)
                      • estimatedCost: the total estimated cost for the plan. If there are multiple plans, the optimizer will choose the plan with the lowest total cost.
                      • collections: a list of collections used in the query
                      • rules: a list of rules the optimizer applied. The list of rules can be found [here](../Aql/Optimizer.html)
                      • variables: list of variables used in the query (note: this may contain internal variables created by the optimizer)", + "summary": " Explain an AQL query", "httpMethod": "POST", - "examples": "

                        Valid query:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{ \"query\" : \"FOR p IN products FILTER p.id == @id LIMIT 2 RETURN p.name\", \"bindVars\": { \"id\" : 3 } }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"plan\" : { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ] \n        }, \n        { \n          \"type\" : \"EnumerateCollectionNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 2, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            2 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"attribute access\", \n                \"name\" : \"id\", \n                \"subNodes\" : [ \n                  { \n                    \"type\" : \"reference\", \n                    \"name\" : \"p\", \n                    \"id\" : 0 \n                  } \n                ] \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 3 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"inVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"name\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"2\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"LimitNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"offset\" : 0, \n          \"limit\" : 2 \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            5 \n          ], \n          \"id\" : 7, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"inVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"2\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"move-calculations-up\", \n        \"move-filters-up\", \n        \"move-calculations-up-2\", \n        \"move-filters-up-2\" \n      ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"estimatedCost\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        Invalid query:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{ \"query\" : \"FOR p IN products FILTER p.id == @id LIMIT 2 RETURN p.n\" }\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1551, \n  \"errorMessage\" : \"in state parsing: no value specified for declared bind parameter 'id'\" \n}\n



                        The data returned in the plan attribute of the result contains one element per AQL top-level statement (i.e. FOR, RETURN, FILTER etc.). If the query optimiser removed some unnecessary statements, the result might also contain less elements than there were top-level statements in the AQL query. The following example shows a query with a non-sensible filter condition that the optimiser has removed so that there are less top-level statements:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{ \"query\" : \"FOR i IN [ 1, 2, 3 ] FILTER 1 == 2 RETURN i\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"plan\" : { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ] \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 2, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"expression\" : { \n            \"type\" : \"list\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"value\", \n                \"value\" : 1 \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 2 \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 3 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"NoResultsNode\", \n          \"dependencies\" : [ \n            2 \n          ], \n          \"id\" : 7, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ] \n        }, \n        { \n          \"type\" : \"EnumerateListNode\", \n          \"dependencies\" : [ \n            7 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"inVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          }, \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"i\" \n          } \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 0, \n          \"depth\" : 0, \n          \"varInfoList\" : [ ], \n          \"nrRegs\" : [ ], \n          \"regsToClear\" : [ ], \n          \"inVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"i\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"move-calculations-up\", \n        \"move-filters-up\", \n        \"remove-unnecessary-filters\", \n        \"remove-unnecessary-calculations\" \n      ], \n      \"collections\" : [ ], \n      \"estimatedCost\" : 0 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        ", - "nickname": "ExplainQuery" + "examples": "

                        Valid query:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{\"query\":\"FOR p IN products RETURN p\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1 \n      }, \n      { \n        \"type\" : \"EnumerateCollectionNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 10, \n        \"database\" : \"_system\", \n        \"collection\" : \"products\", \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 10, \n        \"inVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      } \n    ], \n    \"rules\" : [ ], \n    \"collections\" : [ \n      { \n        \"name\" : \"products\", \n        \"type\" : \"read\" \n      } \n    ], \n    \"variables\" : [ \n      { \n        \"id\" : 0, \n        \"name\" : \"p\" \n      } \n    ], \n    \"estimatedCost\" : 10 \n  }, \n  \"warnings\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        A plan with some optimizer rules applied:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{\"query\":\"FOR p IN products LET a = p.id FILTER a == 4 LET name = p.name SORT p.id LIMIT 1 RETURN name\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1 \n      }, \n      { \n        \"type\" : \"IndexRangeNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 11, \n        \"estimatedCost\" : 10, \n        \"database\" : \"_system\", \n        \"collection\" : \"products\", \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        }, \n        \"ranges\" : [ \n          [ ] \n        ], \n        \"index\" : { \n          \"type\" : \"skiplist\", \n          \"id\" : \"1108118985\", \n          \"unique\" : false, \n          \"fields\" : [ \n            \"id\" \n          ] \n        }, \n        \"reverse\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          11 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 20, \n        \"expression\" : { \n          \"type\" : \"attribute access\", \n          \"name\" : \"id\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"a\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 6, \n        \"estimatedCost\" : 40, \n        \"expression\" : { \n          \"type\" : \"attribute access\", \n          \"name\" : \"name\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          6 \n        ], \n        \"id\" : 4, \n        \"estimatedCost\" : 80, \n        \"expression\" : { \n          \"type\" : \"compare ==\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"reference\", \n              \"name\" : \"a\", \n              \"id\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 4 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 3, \n          \"name\" : \"3\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"FilterNode\", \n        \"dependencies\" : [ \n          4 \n        ], \n        \"id\" : 5, \n        \"estimatedCost\" : 88.4, \n        \"inVariable\" : { \n          \"id\" : 3, \n          \"name\" : \"3\" \n        } \n      }, \n      { \n        \"type\" : \"LimitNode\", \n        \"dependencies\" : [ \n          5 \n        ], \n        \"id\" : 9, \n        \"estimatedCost\" : 89.405, \n        \"offset\" : 0, \n        \"limit\" : 1, \n        \"fullCount\" : false \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          9 \n        ], \n        \"id\" : 10, \n        \"estimatedCost\" : 89.405, \n        \"inVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"remove-redundant-calculations\", \n      \"move-calculations-up-2\", \n      \"use-index-for-sort\", \n      \"remove-unnecessary-calculations-2\" \n    ], \n    \"collections\" : [ \n      { \n        \"name\" : \"products\", \n        \"type\" : \"read\" \n      } \n    ], \n    \"variables\" : [ \n      { \n        \"id\" : 4, \n        \"name\" : \"4\" \n      }, \n      { \n        \"id\" : 3, \n        \"name\" : \"3\" \n      }, \n      { \n        \"id\" : 2, \n        \"name\" : \"name\" \n      }, \n      { \n        \"id\" : 1, \n        \"name\" : \"a\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"p\" \n      } \n    ], \n    \"estimatedCost\" : 89.405 \n  }, \n  \"warnings\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        Using some options:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{\"query\":\"FOR p IN products LET a = p.id FILTER a == 4 LET name = p.name SORT p.id LIMIT 1 RETURN name\",\"options\":{\"maxPlans\":2,\"allPlans\":true,\"optimizer\":{\"rules\":[\"-all\",\"+use-index-for-sort\",\"+use-index-range\"]}}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plans\" : [ \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1 \n        }, \n        { \n          \"type\" : \"IndexRangeNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 11, \n          \"estimatedCost\" : 10, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          }, \n          \"ranges\" : [ \n            [ ] \n          ], \n          \"index\" : { \n            \"type\" : \"skiplist\", \n            \"id\" : \"1110674889\", \n            \"unique\" : false, \n            \"fields\" : [ \n              \"id\" \n            ] \n          }, \n          \"reverse\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            11 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 20, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"a\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 40, \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"a\", \n                \"id\" : 1 \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 4 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 3, \n            \"name\" : \"3\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 44.2, \n          \"inVariable\" : { \n            \"id\" : 3, \n            \"name\" : \"3\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            5 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 88.4, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"name\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 7, \n          \"estimatedCost\" : 176.8, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 4, \n            \"name\" : \"4\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"LimitNode\", \n          \"dependencies\" : [ \n            7 \n          ], \n          \"id\" : 9, \n          \"estimatedCost\" : 177.805, \n          \"offset\" : 0, \n          \"limit\" : 1, \n          \"fullCount\" : false \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            9 \n          ], \n          \"id\" : 10, \n          \"estimatedCost\" : 177.805, \n          \"inVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"use-index-for-sort\" \n      ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 4, \n          \"name\" : \"4\" \n        }, \n        { \n          \"id\" : 3, \n          \"name\" : \"3\" \n        }, \n        { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        }, \n        { \n          \"id\" : 1, \n          \"name\" : \"a\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 177.805 \n    }, \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1 \n        }, \n        { \n          \"type\" : \"EnumerateCollectionNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 2, \n          \"estimatedCost\" : 10, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            2 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 20, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"a\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 40, \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"a\", \n                \"id\" : 1 \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 4 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 3, \n            \"name\" : \"3\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 44.2, \n          \"inVariable\" : { \n            \"id\" : 3, \n            \"name\" : \"3\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            5 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 88.4, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"name\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 7, \n          \"estimatedCost\" : 176.8, \n          \"expression\" : { \n            \"type\" : \"attribute access\", \n            \"name\" : \"id\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"reference\", \n                \"name\" : \"p\", \n                \"id\" : 0 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 4, \n            \"name\" : \"4\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"SortNode\", \n          \"dependencies\" : [ \n            7 \n          ], \n          \"id\" : 8, \n          \"estimatedCost\" : 914.9433857559865, \n          \"elements\" : [ \n            { \n              \"inVariable\" : { \n                \"id\" : 4, \n                \"name\" : \"4\" \n              }, \n              \"ascending\" : true \n            } \n          ], \n          \"stable\" : false \n        }, \n        { \n          \"type\" : \"LimitNode\", \n          \"dependencies\" : [ \n            8 \n          ], \n          \"id\" : 9, \n          \"estimatedCost\" : 915.9483857559865, \n          \"offset\" : 0, \n          \"limit\" : 1, \n          \"fullCount\" : false \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            9 \n          ], \n          \"id\" : 10, \n          \"estimatedCost\" : 915.9483857559865, \n          \"inVariable\" : { \n            \"id\" : 2, \n            \"name\" : \"name\" \n          } \n        } \n      ], \n      \"rules\" : [ ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 4, \n          \"name\" : \"4\" \n        }, \n        { \n          \"id\" : 3, \n          \"name\" : \"3\" \n        }, \n        { \n          \"id\" : 2, \n          \"name\" : \"name\" \n        }, \n        { \n          \"id\" : 1, \n          \"name\" : \"a\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 915.9483857559865 \n    } \n  ], \n  \"warnings\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        Returning all plans:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{\"query\":\"FOR p IN products FILTER p.id == 25 RETURN p\",\"options\":{\"allPlans\":true}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plans\" : [ \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1 \n        }, \n        { \n          \"type\" : \"IndexRangeNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 6, \n          \"estimatedCost\" : 0, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          }, \n          \"ranges\" : [ \n            [ \n              { \n                \"variable\" : \"p\", \n                \"attr\" : \"id\", \n                \"lowConst\" : { \n                  \"bound\" : 25, \n                  \"include\" : true, \n                  \"isConstant\" : true \n                }, \n                \"highConst\" : { \n                  \"bound\" : 25, \n                  \"include\" : true, \n                  \"isConstant\" : true \n                }, \n                \"lows\" : [ ], \n                \"highs\" : [ ], \n                \"valid\" : true, \n                \"equality\" : true \n              } \n            ] \n          ], \n          \"index\" : { \n            \"type\" : \"hash\", \n            \"id\" : \"1113230793\", \n            \"unique\" : false, \n            \"fields\" : [ \n              \"id\" \n            ] \n          }, \n          \"reverse\" : false \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            6 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 0, \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"attribute access\", \n                \"name\" : \"id\", \n                \"subNodes\" : [ \n                  { \n                    \"type\" : \"reference\", \n                    \"name\" : \"p\", \n                    \"id\" : 0 \n                  } \n                ] \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 25 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 0, \n          \"inVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          } \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 0, \n          \"inVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        } \n      ], \n      \"rules\" : [ \n        \"use-index-range\" \n      ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 0 \n    }, \n    { \n      \"nodes\" : [ \n        { \n          \"type\" : \"SingletonNode\", \n          \"dependencies\" : [ ], \n          \"id\" : 1, \n          \"estimatedCost\" : 1 \n        }, \n        { \n          \"type\" : \"EnumerateCollectionNode\", \n          \"dependencies\" : [ \n            1 \n          ], \n          \"id\" : 2, \n          \"estimatedCost\" : 0, \n          \"database\" : \"_system\", \n          \"collection\" : \"products\", \n          \"outVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        }, \n        { \n          \"type\" : \"CalculationNode\", \n          \"dependencies\" : [ \n            2 \n          ], \n          \"id\" : 3, \n          \"estimatedCost\" : 0, \n          \"expression\" : { \n            \"type\" : \"compare ==\", \n            \"subNodes\" : [ \n              { \n                \"type\" : \"attribute access\", \n                \"name\" : \"id\", \n                \"subNodes\" : [ \n                  { \n                    \"type\" : \"reference\", \n                    \"name\" : \"p\", \n                    \"id\" : 0 \n                  } \n                ] \n              }, \n              { \n                \"type\" : \"value\", \n                \"value\" : 25 \n              } \n            ] \n          }, \n          \"outVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          }, \n          \"canThrow\" : false \n        }, \n        { \n          \"type\" : \"FilterNode\", \n          \"dependencies\" : [ \n            3 \n          ], \n          \"id\" : 4, \n          \"estimatedCost\" : 0, \n          \"inVariable\" : { \n            \"id\" : 1, \n            \"name\" : \"1\" \n          } \n        }, \n        { \n          \"type\" : \"ReturnNode\", \n          \"dependencies\" : [ \n            4 \n          ], \n          \"id\" : 5, \n          \"estimatedCost\" : 0, \n          \"inVariable\" : { \n            \"id\" : 0, \n            \"name\" : \"p\" \n          } \n        } \n      ], \n      \"rules\" : [ ], \n      \"collections\" : [ \n        { \n          \"name\" : \"products\", \n          \"type\" : \"read\" \n        } \n      ], \n      \"variables\" : [ \n        { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        { \n          \"id\" : 0, \n          \"name\" : \"p\" \n        } \n      ], \n      \"estimatedCost\" : 0 \n    } \n  ], \n  \"warnings\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        A query that produces a warning:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{\"query\":\"FOR i IN 1..10 RETURN 1 / 0\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1 \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 2, \n        \"expression\" : { \n          \"type\" : \"range\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 10 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 4, \n        \"estimatedCost\" : 4, \n        \"expression\" : { \n          \"type\" : \"value\", \n          \"value\" : null \n        }, \n        \"outVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"2\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"EnumerateListNode\", \n        \"dependencies\" : [ \n          4 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 4000, \n        \"inVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 5, \n        \"estimatedCost\" : 4000, \n        \"inVariable\" : { \n          \"id\" : 2, \n          \"name\" : \"2\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"move-calculations-up-2\" \n    ], \n    \"collections\" : [ ], \n    \"variables\" : [ \n      { \n        \"id\" : 2, \n        \"name\" : \"2\" \n      }, \n      { \n        \"id\" : 1, \n        \"name\" : \"1\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"i\" \n      } \n    ], \n    \"estimatedCost\" : 4000 \n  }, \n  \"warnings\" : [ \n    { \n      \"code\" : 1562, \n      \"message\" : \"division by zero\" \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        Invalid query (missing bind parameter):



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{ \n  \"query\" : \"FOR p IN products FILTER p.id == @id LIMIT 2 RETURN p.n\" \n}\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1551, \n  \"errorMessage\" : \"no value specified for declared bind parameter 'id' (while parsing)\" \n}\n



                        The data returned in the plan attribute of the result contains one element per AQL top-level statement (i.e. FOR, RETURN, FILTER etc.). If the query optimiser removed some unnecessary statements, the result might also contain less elements than there were top-level statements in the AQL query. The following example shows a query with a non-sensible filter condition that the optimiser has removed so that there are less top-level statements:



                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/explain\n{ \"query\" : \"FOR i IN [ 1, 2, 3 ] FILTER 1 == 2 RETURN i\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"plan\" : { \n    \"nodes\" : [ \n      { \n        \"type\" : \"SingletonNode\", \n        \"dependencies\" : [ ], \n        \"id\" : 1, \n        \"estimatedCost\" : 1 \n      }, \n      { \n        \"type\" : \"CalculationNode\", \n        \"dependencies\" : [ \n          1 \n        ], \n        \"id\" : 2, \n        \"estimatedCost\" : 2, \n        \"expression\" : { \n          \"type\" : \"list\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 1 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 2 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 3 \n            } \n          ] \n        }, \n        \"outVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        \"canThrow\" : false \n      }, \n      { \n        \"type\" : \"NoResultsNode\", \n        \"dependencies\" : [ \n          2 \n        ], \n        \"id\" : 7, \n        \"estimatedCost\" : 0 \n      }, \n      { \n        \"type\" : \"EnumerateListNode\", \n        \"dependencies\" : [ \n          7 \n        ], \n        \"id\" : 3, \n        \"estimatedCost\" : 0, \n        \"inVariable\" : { \n          \"id\" : 1, \n          \"name\" : \"1\" \n        }, \n        \"outVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      }, \n      { \n        \"type\" : \"ReturnNode\", \n        \"dependencies\" : [ \n          3 \n        ], \n        \"id\" : 6, \n        \"estimatedCost\" : 0, \n        \"inVariable\" : { \n          \"id\" : 0, \n          \"name\" : \"i\" \n        } \n      } \n    ], \n    \"rules\" : [ \n      \"move-calculations-up\", \n      \"move-filters-up\", \n      \"remove-unnecessary-filters\", \n      \"remove-unnecessary-calculations\" \n    ], \n    \"collections\" : [ ], \n    \"variables\" : [ \n      { \n        \"id\" : 2, \n        \"name\" : \"2\" \n      }, \n      { \n        \"id\" : 1, \n        \"name\" : \"1\" \n      }, \n      { \n        \"id\" : 0, \n        \"name\" : \"i\" \n      } \n    ], \n    \"estimatedCost\" : 0 \n  }, \n  \"warnings\" : [ ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        ", + "nickname": "ExplainAnAqlQuery" } ], "path": "/_api/explain" diff --git a/js/apps/system/aardvark/api-docs/graph.json b/js/apps/system/aardvark/api-docs/graph.json index 474753da01..b8e7886c2c 100644 --- a/js/apps/system/aardvark/api-docs/graph.json +++ b/js/apps/system/aardvark/api-docs/graph.json @@ -39,7 +39,7 @@ "notes": "Creates a new graph.

                        Returns an object with an attribute graph containing a list of all graph properties.

                        ", "summary": "create graph", "httpMethod": "POST", - "examples": "

                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/\n{ \n  \"_key\" : \"graph\", \n  \"vertices\" : \"vertices\", \n  \"edges\" : \"edges\" \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: 1058340008\n\n{ \n  \"graph\" : { \n    \"_id\" : \"_graphs/graph\", \n    \"_key\" : \"graph\", \n    \"_rev\" : \"1058340008\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"vertices\" \n        ], \n        \"to\" : [ \n          \"vertices\" \n        ] \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                        ", + "examples": "

                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/\n{ \n  \"_key\" : \"graph\", \n  \"vertices\" : \"vertices\", \n  \"edges\" : \"edges\" \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\netag: 1114738121\n\n{ \n  \"graph\" : { \n    \"_id\" : \"_graphs/graph\", \n    \"_key\" : \"graph\", \n    \"_rev\" : \"1114738121\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"vertices\" \n        ], \n        \"to\" : [ \n          \"vertices\" \n        ] \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                        ", "nickname": "createGraph" } ], @@ -90,7 +90,7 @@ "notes": "

                        If graph-name is specified, returns an object with an attribute graph containing a JSON hash with all properties of the specified graph.

                        If graph-name is not specified, returns a list of graph objects.

                        ", "summary": "get the properties of a specific or all graphs", "httpMethod": "GET", - "examples": "

                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1059650728\n\n{ \n  \"graph\" : { \n    \"_id\" : \"_graphs/graph\", \n    \"_key\" : \"graph\", \n    \"_rev\" : \"1059650728\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"vertices\" \n        ], \n        \"to\" : [ \n          \"vertices\" \n        ] \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        get all graphs



                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"graphs\" : [ \n    { \n      \"_id\" : \"_graphs/graph2\", \n      \"_key\" : \"graph2\", \n      \"_rev\" : \"1062337704\", \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"edges2\", \n          \"from\" : [ \n            \"vertices2\" \n          ], \n          \"to\" : [ \n            \"vertices2\" \n          ] \n        } \n      ] \n    }, \n    { \n      \"_id\" : \"_graphs/graph1\", \n      \"_key\" : \"graph1\", \n      \"_rev\" : \"1061354664\", \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"edges1\", \n          \"from\" : [ \n            \"vertices1\" \n          ], \n          \"to\" : [ \n            \"vertices1\" \n          ] \n        } \n      ] \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                        ", + "examples": "

                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1116048841\n\n{ \n  \"graph\" : { \n    \"_id\" : \"_graphs/graph\", \n    \"_key\" : \"graph\", \n    \"_rev\" : \"1116048841\", \n    \"edgeDefinitions\" : [ \n      { \n        \"collection\" : \"edges\", \n        \"from\" : [ \n          \"vertices\" \n        ], \n        \"to\" : [ \n          \"vertices\" \n        ] \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                        get all graphs



                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"graphs\" : [ \n    { \n      \"_id\" : \"_graphs/graph2\", \n      \"_key\" : \"graph2\", \n      \"_rev\" : \"1118735817\", \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"edges2\", \n          \"from\" : [ \n            \"vertices2\" \n          ], \n          \"to\" : [ \n            \"vertices2\" \n          ] \n        } \n      ] \n    }, \n    { \n      \"_id\" : \"_graphs/graph1\", \n      \"_key\" : \"graph1\", \n      \"_rev\" : \"1117752777\", \n      \"edgeDefinitions\" : [ \n        { \n          \"collection\" : \"edges1\", \n          \"from\" : [ \n            \"vertices1\" \n          ], \n          \"to\" : [ \n            \"vertices1\" \n          ] \n        } \n      ] \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                        ", "nickname": "getThePropertiesOfASpecificOrAllGraphs" } ], @@ -180,7 +180,7 @@ "notes": "Creates a vertex in a graph.

                        Returns an object with an attribute vertex containing a list of all vertex properties.

                        ", "summary": "create vertex", "httpMethod": "POST", - "examples": "

                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex\n{ \n  \"_key\" : \"v1\", \n  \"optional1\" : \"val1\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1066728616\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1066728616\", \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", + "examples": "

                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex\n{ \n  \"_key\" : \"v1\", \n  \"optional1\" : \"val1\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1123323337\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1123323337\", \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", "nickname": "createVertex" } ], @@ -245,7 +245,7 @@ "notes": "Returns an object with an attribute vertex containing a list of all vertex properties.

                        ", "summary": "get vertex", "httpMethod": "GET", - "examples": "

                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1068563624\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1068563624\", \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                        ", + "examples": "

                        shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1125158345\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1125158345\", \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                        ", "nickname": "getVertex" } ], @@ -384,7 +384,7 @@ "notes": "Replaces the vertex properties.

                        Returns an object with an attribute vertex containing a list of all vertex properties.

                        ", "summary": "update vertex", "httpMethod": "PUT", - "examples": "

                        shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : \"val2\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1073347752\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1073347752\", \n    \"optional1\" : \"val2\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", + "examples": "

                        shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : \"val2\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1129942473\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1129942473\", \n    \"optional1\" : \"val2\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", "nickname": "updateVertex" } ], @@ -464,7 +464,7 @@ "notes": "Partially updates the vertex properties.

                        Setting an attribute value to null in the patch document will cause a value of null be saved for the attribute by default. If the intention is to delete existing attributes with the patch command, the URL parameter keepNull can be used with a value of false. This will modify the behavior of the patch command to remove any attributes from the existing document that are contained in the patch document with an attribute value of null.

                        Returns an object with an attribute vertex containing a list of all vertex properties.

                        ", "summary": "update vertex", "httpMethod": "PATCH", - "examples": "

                        shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : \"vertexPatch\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1075707048\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1075707048\", \n    \"optional1\" : \"vertexPatch\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : null \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1076231336\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1076231336\", \n    \"optional1\" : null \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", + "examples": "

                        shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : \"vertexPatch\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1132301769\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1132301769\", \n    \"optional1\" : \"vertexPatch\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\nshell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertex/v1\n{ \n  \"optional1\" : null \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1132826057\n\n{ \n  \"vertex\" : { \n    \"_id\" : \"vertices/v1\", \n    \"_key\" : \"v1\", \n    \"_rev\" : \"1132826057\", \n    \"optional1\" : null \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                        ", "nickname": "updateVertex" } ], @@ -498,7 +498,7 @@ "notes": "Returns a cursor.

                        The call expects a JSON hash array as body to filter the result:

                        • batchSize: the batch size of the returned cursor
                        • limit: limit the result size
                        • count: return the total number of results (default \"false\")
                        • filter: a optional filter
                        The attributes of filter
                        • properties: filter by an array of vertex properties
                        The attributes of a property filter
                        • key: filter the result vertices by a key value pair
                        • value: the value of the key
                        • compare: a compare operator", "summary": "get vertices", "httpMethod": "POST", - "examples": "

                          shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices\n{ \n  \"batchSize\" : 100 \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v3\", \n      \"_key\" : \"v3\", \n      \"_rev\" : \"1078852776\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v2\", \n      \"_key\" : \"v2\", \n      \"_rev\" : \"1078459560\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v5\", \n      \"_key\" : \"v5\", \n      \"_rev\" : \"1079639208\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1079245992\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1078066344\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                          ", + "examples": "

                          shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices\n{ \n  \"batchSize\" : 100 \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v3\", \n      \"_key\" : \"v3\", \n      \"_rev\" : \"1135447497\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v2\", \n      \"_key\" : \"v2\", \n      \"_rev\" : \"1135054281\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v5\", \n      \"_key\" : \"v5\", \n      \"_rev\" : \"1136233929\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1135840713\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1134661065\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 5, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                          ", "nickname": "getVertices" } ], @@ -539,7 +539,7 @@ "notes": "Returns a cursor.

                          The call expects a JSON hash array as body to filter the result:

                          • batchSize: the batch size of the returned cursor
                          • limit: limit the result size
                          • count: return the total number of results (default \"false\")
                          • filter: a optional filter
                          The attributes of filter
                          • direction: Filter for inbound (value \"in\") or outbound (value \"out\") neighbors. Default value is \"any\".
                          • labels: filter by an array of edge labels (empty array means no restriction)
                          • properties: filter neighbors by an array of edge properties
                          The attributes of a property filter
                          • key: filter the result vertices by a key value pair
                          • value: the value of the key
                          • compare: a compare operator", "summary": "get vertices", "httpMethod": "POST", - "examples": "

                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices/v2\n{\"batchSize\" : 100, \"filter\" : {\"direction\" : \"any\", \"properties\":[] }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1099037864\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1100217512\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                            Select vertices by direction and property filter



                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices/v2\n{\"batchSize\" : 100, \"filter\" : {\"direction\" : \"out\", \"properties\":[ { \"key\": \"optional1\", \"value\": \"val2\", \"compare\" : \"==\" }, ] }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1106115752\", \n      \"optional1\" : \"val2\" \n    }, \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1104936104\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                            ", + "examples": "

                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices/v2\n{\"batchSize\" : 100, \"filter\" : {\"direction\" : \"any\", \"properties\":[] }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1147506121\", \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1148685769\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                            Select vertices by direction and property filter



                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/vertices/v2\n{\"batchSize\" : 100, \"filter\" : {\"direction\" : \"out\", \"properties\":[ { \"key\": \"optional1\", \"value\": \"val2\", \"compare\" : \"==\" }, ] }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"vertices/v4\", \n      \"_key\" : \"v4\", \n      \"_rev\" : \"1154584009\", \n      \"optional1\" : \"val2\" \n    }, \n    { \n      \"_id\" : \"vertices/v1\", \n      \"_key\" : \"v1\", \n      \"_rev\" : \"1153404361\", \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                            ", "nickname": "getVertices" } ], @@ -584,7 +584,7 @@ "notes": "Creates an edge in a graph.

                            The call expects a JSON hash array as body with the edge properties:

                            • _key: The name of the edge (optional, if edge collection allows user defined keys).
                            • _from: The name of the from vertex.
                            • _to: The name of the to vertex.
                            • $label: A label for the edge (optional).
                            • further optional attributes.
                            Returns an object with an attribute edge containing the list of all edge properties.

                            ", "summary": "create edge", "httpMethod": "POST", - "examples": "

                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge\n{ \n  \"_key\" : \"edge1\", \n  \"_from\" : \"vert2\", \n  \"_to\" : \"vert1\", \n  \"optional1\" : \"val1\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1111882920\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1111882920\", \n    \"_from\" : \"vertices/vert2\", \n    \"_to\" : \"vertices/vert1\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", + "examples": "

                            shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge\n{ \n  \"_key\" : \"edge1\", \n  \"_from\" : \"vert2\", \n  \"_to\" : \"vert1\", \n  \"optional1\" : \"val1\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1160351177\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1160351177\", \n    \"_from\" : \"vertices/vert2\", \n    \"_to\" : \"vertices/vert1\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", "nickname": "createEdge" } ], @@ -649,7 +649,7 @@ "notes": "Returns an object with an attribute edge containing a list of all edge properties.

                            ", "summary": "get edge", "httpMethod": "GET", - "examples": "

                            shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1114766504\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1114766504\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                            ", + "examples": "

                            shell> curl --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\netag: 1163234761\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1163234761\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n

                            ", "nickname": "getEdge" } ], @@ -788,7 +788,7 @@ "notes": "Replaces the optional edge properties.

                            The call expects a JSON hash array as body with the new edge properties.

                            Returns an object with an attribute edge containing a list of all edge properties.

                            ", "summary": "update edge", "httpMethod": "PUT", - "examples": "

                            shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n{ \n  \"optional1\" : \"val2\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1121778856\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1121778856\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val2\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", + "examples": "

                            shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n{ \n  \"optional1\" : \"val2\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1170247113\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1170247113\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val2\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", "nickname": "updateEdge" } ], @@ -868,7 +868,7 @@ "notes": "Partially updates the edge properties.

                            Setting an attribute value to null in the patch document will cause a value of null be saved for the attribute by default. If the intention is to delete existing attributes with the patch command, the URL parameter keepNull can be used with a value of false. This will modify the behavior of the patch command to remove any attributes from the existing document that are contained in the patch document with an attribute value of null.

                            Returns an object with an attribute edge containing a list of all edge properties.

                            ", "summary": "update edge", "httpMethod": "PATCH", - "examples": "

                            shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n{ \n  \"optional3\" : \"val3\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1125317800\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1125317800\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\", \n    \"optional3\" : \"val3\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", + "examples": "

                            shell> curl -X PATCH --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edge/edge1\n{ \n  \"optional3\" : \"val3\" \n}\n\nHTTP/1.1 202 Accepted\ncontent-type: application/json; charset=utf-8\netag: 1173982665\n\n{ \n  \"edge\" : { \n    \"_id\" : \"edges/edge1\", \n    \"_key\" : \"edge1\", \n    \"_rev\" : \"1173982665\", \n    \"_from\" : \"vertices/vert1\", \n    \"_to\" : \"vertices/vert2\", \n    \"$label\" : null, \n    \"optional1\" : \"val1\", \n    \"optional3\" : \"val3\" \n  }, \n  \"error\" : false, \n  \"code\" : 202 \n}\n

                            ", "nickname": "updateEdge" } ], @@ -902,7 +902,7 @@ "notes": "Returns a cursor.

                            The call expects a JSON hash array as body to filter the result:

                            • batchSize: the batch size of the returned cursor
                            • limit: limit the result size
                            • count: return the total number of results (default \"false\")
                            • filter: a optional filter
                            The attributes of filter
                            • labels: filter by an array of edge labels
                            • properties: filter by an array of edge properties
                            The attributes of a property filter
                            • key: filter the result edges by a key value pair
                            • value: the value of the key
                            • compare: a compare operator", "summary": "get edges", "httpMethod": "POST", - "examples": "

                              shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edges\n{ \n  \"batchSize\" : 100 \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"edges/edge2\", \n      \"_key\" : \"edge2\", \n      \"_rev\" : \"1129970856\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v3\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge3\", \n      \"_key\" : \"edge3\", \n      \"_rev\" : \"1130495144\", \n      \"_from\" : \"vertices/v2\", \n      \"_to\" : \"vertices/v4\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge1\", \n      \"_key\" : \"edge1\", \n      \"_rev\" : \"1129446568\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v2\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge4\", \n      \"_key\" : \"edge4\", \n      \"_rev\" : \"1131019432\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v5\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                              ", + "examples": "

                              shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edges\n{ \n  \"batchSize\" : 100 \n}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"edges/edge2\", \n      \"_key\" : \"edge2\", \n      \"_rev\" : \"1178635721\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v3\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge3\", \n      \"_key\" : \"edge3\", \n      \"_rev\" : \"1179160009\", \n      \"_from\" : \"vertices/v2\", \n      \"_to\" : \"vertices/v4\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge1\", \n      \"_key\" : \"edge1\", \n      \"_rev\" : \"1178111433\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v2\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge4\", \n      \"_key\" : \"edge4\", \n      \"_rev\" : \"1179684297\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v5\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 4, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                              ", "nickname": "getEdges" } ], @@ -943,7 +943,7 @@ "notes": "

                              Returns a cursor.

                              The call expects a JSON hash array as body to filter the result:

                              • batchSize: the batch size of the returned cursor
                              • limit: limit the result size
                              • count: return the total number of results (default \"false\")
                              • filter: a optional filter
                              The attributes of filter
                              • direction: Filter for inbound (value \"in\") or outbound (value \"out\") neighbors. Default value is \"any\".
                              • labels: filter by an array of edge labels
                              • properties: filter neighbors by an array of properties
                              The attributes of a property filter
                              • key: filter the result vertices by a key value pair
                              • value: the value of the key
                              • compare: a compare operator", "summary": "get edges", "httpMethod": "POST", - "examples": "

                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edges/v2\n{\"batchSize\" : 100, \"filter\" : { \"direction\" : \"any\" }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"edges/edge1\", \n      \"_key\" : \"edge1\", \n      \"_rev\" : \"1135344808\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v2\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge3\", \n      \"_key\" : \"edge3\", \n      \"_rev\" : \"1136393384\", \n      \"_from\" : \"vertices/v2\", \n      \"_to\" : \"vertices/v4\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                                ", + "examples": "

                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/graph/graph/edges/v2\n{\"batchSize\" : 100, \"filter\" : { \"direction\" : \"any\" }}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"edges/edge1\", \n      \"_key\" : \"edge1\", \n      \"_rev\" : \"1184009673\", \n      \"_from\" : \"vertices/v1\", \n      \"_to\" : \"vertices/v2\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    }, \n    { \n      \"_id\" : \"edges/edge3\", \n      \"_key\" : \"edge3\", \n      \"_rev\" : \"1185058249\", \n      \"_from\" : \"vertices/v2\", \n      \"_to\" : \"vertices/v4\", \n      \"$label\" : null, \n      \"optional1\" : \"val1\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"extra\" : { \n    \"stats\" : { \n      \"writesExecuted\" : 0, \n      \"writesIgnored\" : 0, \n      \"scannedFull\" : 0, \n      \"scannedIndex\" : 0 \n    }, \n    \"warnings\" : [ ] \n  }, \n  \"error\" : false, \n  \"code\" : 201 \n}\n

                                ", "nickname": "getEdges" } ], diff --git a/js/apps/system/aardvark/api-docs/index.json b/js/apps/system/aardvark/api-docs/index.json index f68f39b5f4..9c284159d7 100644 --- a/js/apps/system/aardvark/api-docs/index.json +++ b/js/apps/system/aardvark/api-docs/index.json @@ -96,7 +96,7 @@ "notes": "

                                Creates a cap constraint for the collection collection-name, if it does not already exist. Expects an object containing the index details.

                                • type: must be equal to \"cap\".
                                • size: The maximal number of documents for the collection. If specified, the value must be greater than zero.
                                • byteSize: The maximal size of the active document data in the collection (in bytes). If specified, the value must be at least 16384.
                                Note: The cap constraint does not index particular attributes of the documents in a collection, but limits the number of documents in the collection to a maximum value. The cap constraint thus does not support attribute names specified in the fields attribute nor uniqueness of any kind via the unique attribute.

                                It is allowed to specify either size or byteSize, or both at the same time. If both are specified, then the automatic document removal will be triggered by the first non-met constraint.

                                ", "summary": " Create cap constraint", "httpMethod": "POST", - "examples": "

                                Creating a cap constraint



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{\"type\":\"cap\",\"size\":10}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1138490536\", \n  \"type\" : \"cap\", \n  \"unique\" : false, \n  \"size\" : 10, \n  \"byteSize\" : 0, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", + "examples": "

                                Creating a cap constraint



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{\"type\":\"cap\",\"size\":10}\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1187155401\", \n  \"type\" : \"cap\", \n  \"unique\" : false, \n  \"size\" : 10, \n  \"byteSize\" : 0, \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", "nickname": "CreateCapConstraint" } ], @@ -138,7 +138,7 @@ "notes": "

                                Creates a geo-spatial index in the collection collection-name, if it does not already exist. Expects an object containing the index details.

                                • type: must be equal to \"geo\".
                                • fields: A list with one or two attribute paths. If it is a list with one attribute path location, then a geo-spatial index on all documents is created using location as path to the coordinates. The value of the attribute must be a list with at least two double values. The list must contain the latitude (first value) and the longitude (second value). All documents, which do not have the attribute path or with value that are not suitable, are ignored. If it is a list with two attribute paths latitude and longitude, then a geo-spatial index on all documents is created using latitude and longitude as paths the latitude and the longitude. The value of the attribute latitude and of the attribute longitude must a double. All documents, which do not have the attribute paths or which values are not suitable, are ignored.
                                • geoJson: If a geo-spatial index on a location is constructed and geoJson is true, then the order within the list is longitude followed by latitude. This corresponds to the format described in http://geojson.org/geojson-spec.html#positions
                                • constraint: If constraint is true, then a geo-spatial constraint is created. The constraint is a non-unique variant of the index. Note: It is also possible to set the unique attribute instead of the constraint attribute.
                                • ignoreNull: If a geo-spatial constraint is created and ignoreNull is true, then documents with a null in location or at least one null in latitude or longitude are ignored.
                                Note: Unique indexes on non-shard keys are not supported in a cluster.

                                ", "summary": " Create geo-spatial index", "httpMethod": "POST", - "examples": "

                                Creating a geo index with a location attribute:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"geo\", \"fields\" : [ \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1139014824\", \n  \"type\" : \"geo1\", \n  \"unique\" : false, \n  \"geoJson\" : false, \n  \"constraint\" : false, \n  \"ignoreNull\" : false, \n  \"fields\" : [ \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                Creating a geo index with latitude and longitude attributes:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"geo\", \"fields\" : [ \"e\", \"f\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1139539112\", \n  \"type\" : \"geo2\", \n  \"unique\" : false, \n  \"constraint\" : false, \n  \"ignoreNull\" : false, \n  \"fields\" : [ \n    \"e\", \n    \"f\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", + "examples": "

                                Creating a geo index with a location attribute:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"geo\", \"fields\" : [ \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1187679689\", \n  \"type\" : \"geo1\", \n  \"unique\" : false, \n  \"geoJson\" : false, \n  \"constraint\" : false, \n  \"ignoreNull\" : false, \n  \"fields\" : [ \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                Creating a geo index with latitude and longitude attributes:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"geo\", \"fields\" : [ \"e\", \"f\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1188203977\", \n  \"type\" : \"geo2\", \n  \"unique\" : false, \n  \"constraint\" : false, \n  \"ignoreNull\" : false, \n  \"fields\" : [ \n    \"e\", \n    \"f\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", "nickname": "CreateGeo-spatialIndex" } ], @@ -184,7 +184,7 @@ "notes": "

                                Creates a hash index for the collection collection-name, if it does not already exist. The call expects an object containing the index details.

                                • type: must be equal to \"hash\".
                                • fields: A list of attribute paths.
                                • unique: If true, then create a unique index.
                                Note: unique indexes on non-shard keys are not supported in a cluster.

                                ", "summary": " Create hash index", "httpMethod": "POST", - "examples": "

                                Creating an unique constraint:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"hash\", \"unique\" : true, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1140063400\", \n  \"type\" : \"hash\", \n  \"unique\" : true, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                Creating a hash index:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"hash\", \"unique\" : false, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1140587688\", \n  \"type\" : \"hash\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", + "examples": "

                                Creating an unique constraint:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"hash\", \"unique\" : true, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1188728265\", \n  \"type\" : \"hash\", \n  \"unique\" : true, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                Creating a hash index:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"hash\", \"unique\" : false, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1189252553\", \n  \"type\" : \"hash\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", "nickname": "CreateHashIndex" } ], @@ -230,7 +230,7 @@ "notes": "

                                Creates a skip-list index for the collection collection-name, if it does not already exist. The call expects an object containing the index details.

                                • type: must be equal to \"skiplist\".
                                • fields: A list of attribute paths.
                                • unique: If true, then create a unique index.
                                Note: unique indexes on non-shard keys are not supported in a cluster.

                                ", "summary": " Create skip list", "httpMethod": "POST", - "examples": "

                                Creating a skiplist:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"skiplist\", \"unique\" : false, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1141111976\", \n  \"type\" : \"skiplist\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", + "examples": "

                                Creating a skiplist:



                                shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\": \"skiplist\", \"unique\" : false, \"fields\" : [ \"a\", \"b\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1189776841\", \n  \"type\" : \"skiplist\", \n  \"unique\" : false, \n  \"fields\" : [ \n    \"a\", \n    \"b\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                ", "nickname": "CreateSkipList" } ], @@ -272,7 +272,7 @@ "notes": "

                                Creates a fulltext index for the collection collection-name, if it does not already exist. The call expects an object containing the index details.

                                • type: must be equal to \"fulltext\".
                                • fields: A list of attribute names. Currently, the list is limited to exactly one attribute, so the value of fields should look like this for example: [ \"text\" ].
                                • minLength: Minimum character length of words to index. Will default to a server-defined value if unspecified. It is thus recommended to set this value explicitly when creating the index.", "summary": " Create fulltext index", "httpMethod": "POST", - "examples": "

                                  Creating a fulltext index:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\" : \"fulltext\", \"fields\" : [ \"text\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1141570728\", \n  \"type\" : \"fulltext\", \n  \"unique\" : false, \n  \"minLength\" : 2, \n  \"fields\" : [ \n    \"text\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                  ", + "examples": "

                                  Creating a fulltext index:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/index?collection=products\n{ \"type\" : \"fulltext\", \"fields\" : [ \"text\" ] }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1190235593\", \n  \"type\" : \"fulltext\", \n  \"unique\" : false, \n  \"minLength\" : 2, \n  \"fields\" : [ \n    \"text\" \n  ], \n  \"isNewlyCreated\" : true, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                  ", "nickname": "CreateFulltextIndex" } ], @@ -349,7 +349,7 @@ "notes": "

                                  Deletes an index with index-handle.

                                  ", "summary": " Delete index", "httpMethod": "DELETE", - "examples": "



                                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/index/products/1142095016\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1142095016\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                  ", + "examples": "



                                  shell> curl -X DELETE --data-binary @- --dump - http://localhost:8529/_api/index/products/1190759881\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"id\" : \"products/1190759881\", \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                  ", "nickname": "DeleteIndex" } ], diff --git a/js/apps/system/aardvark/api-docs/job.json b/js/apps/system/aardvark/api-docs/job.json index 20d94e9ac5..7f7781e078 100644 --- a/js/apps/system/aardvark/api-docs/job.json +++ b/js/apps/system/aardvark/api-docs/job.json @@ -2,5 +2,177 @@ "basePath": "/", "swaggerVersion": "1.1", "apiVersion": "0.1", - "apis": [] + "apis": [ + { + "operations": [ + { + "errorResponses": [ + { + "reason": "is returned if the job requested via job-id is still in the queue of pending (or not yet finished) jobs. In this case, no x-arango-async-id HTTP header will be returned.

                                  ", + "code": "204" + }, + { + "reason": "is returned if no job-id was specified in the request. In this case, no x-arango-async-id HTTP header will be returned.

                                  ", + "code": "400" + }, + { + "reason": "is returned if the job was not found or already deleted or fetched from the job result list. In this case, no x-arango-async-id HTTP header will be returned.

                                  ", + "code": "404" + } + ], + "parameters": [ + { + "dataType": "String", + "paramType": "path", + "required": "true", + "name": "job-id", + "description": "The async job id.

                                  " + } + ], + "notes": "Returns the result of an async job identified by job-id. If the async job result is present on the server, the result will be removed from the list of result. That means this method can be called for each job-id once. The method will return the original job result's headers and body, plus the additional HTTP header x-arango-async-job-id. If this header is present, then the job was found and the response contains the original job's result. If the header is not present, the job was not found and the response contains status information from the job manager.

                                  ", + "summary": " Return result of an async job", + "httpMethod": "PUT", + "examples": "Not providing a job-id:

                                  ```js unix> curl -X PUT --dump - http://localhost:8529/_api/job/

                                  HTTP/1.1 400 Bad Request content-type: application/json; charset=utf-8

                                  {\"error\":true,\"errorMessage\":\"bad parameter\",\"code\":400,\"errorNum\":400} `

                                  Providing a job-id for a non-existing job:

                                  ```js unix> curl -X PUT --dump - http://localhost:8529/_api/job/foobar

                                  HTTP/1.1 404 Not Found content-type: application/json; charset=utf-8

                                  {\"error\":true,\"errorMessage\":\"not found\",\"code\":404,\"errorNum\":404} `

                                  Fetching the result of an HTTP GET job:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 265413601

                                  unix> curl -X PUT --dump - http://localhost:8529/_api/job/265413601

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8 x-arango-async-id: 265413601

                                  {\"server\":\"arango\",\"version\":\"2.1.0\"} `

                                  Fetching the result of an HTTP POST job that failed:

                                  ```js unix> curl -X POST --header 'x-arango-async: store' --data-binary @- --dump - http://localhost:8529/_api/collection {\"name\":\" this name is invalid \"}

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 265479137

                                  unix> curl -X PUT --dump - http://localhost:8529/_api/job/265479137

                                  HTTP/1.1 400 Bad Request content-type: application/json; charset=utf-8 x-arango-async-id: 265479137

                                  {\"error\":true,\"code\":400,\"errorNum\":1208,\"errorMessage\":\"cannot create collection: illegal name\"} `



                                  ", + "nickname": "ReturnResultOfAnAsyncJob" + } + ], + "path": "/_api/job/job-id" + }, + { + "operations": [ + { + "errorResponses": [ + { + "reason": "cancel has been initiated.

                                  ", + "code": "200" + }, + { + "reason": "is returned if no job-id was specified in the request. In this case, no x-arango-async-id HTTP header will be returned.

                                  ", + "code": "400" + }, + { + "reason": "is returned if the job was not found or already deleted or fetched from the job result list. In this case, no x-arango-async-id HTTP header will be returned.

                                  ", + "code": "404" + } + ], + "parameters": [ + { + "dataType": "String", + "paramType": "path", + "required": "true", + "name": "job-id", + "description": "The async job id.

                                  " + } + ], + "notes": "Cancels the currently running job identified by job-id. Note that it still might take some time to actually cancel the running async job.

                                  ", + "summary": " Cancel async job", + "httpMethod": "PUT", + "examples": "

                                  ```js unix> curl -X POST --header 'x-arango-async: store' --data-binary @- --dump - http://localhost:8529/_api/cursor {\"query\": \"FOR i IN 1..10 FOR j IN 1..10 LET x = sleep(1.0) FILTER i == 5 && j == 5 RETURN 42\"}

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 268952545

                                  unix> curl --dump - http://localhost:8529/_api/job/pending

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  [\"268952545\"]

                                  unix> curl -X PUT --dump - http://localhost:8529/_api/job/268952545/cancel

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  {\"result\":true}

                                  unix> curl --dump - http://localhost:8529/_api/job/pending

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  [\"268952545\"] `



                                  ", + "nickname": "CancelAsyncJob" + } + ], + "path": "/_api/job/job-id/cancel" + }, + { + "operations": [ + { + "errorResponses": [ + { + "reason": "is returned if the deletion operation was carried out successfully. This code will also be returned if no results were deleted.

                                  ", + "code": "200" + }, + { + "reason": "is returned if type is not specified or has an invalid value.

                                  ", + "code": "400" + }, + { + "reason": "is returned if type is a job-id but no async job with the specified id was found.

                                  ", + "code": "404" + } + ], + "parameters": [ + { + "dataType": "String", + "paramType": "path", + "required": "true", + "name": "type", + "description": "The type of jobs to delete. type can be: *all: Deletes all jobs results. Currently executing or queued async jobs will not be stopped by this call. *expired: Deletes expired results. To determine the expiration status of a result, pass the stamp URL parameter. stamp needs to be a UNIX timestamp, and all async job results created at a lower timestamp will be deleted. *an actual job-id: In this case, the call will remove the result of the specified async job. If the job is currently executing or queued, it will not be aborted.

                                  @RESTQUERYPARAMS

                                  @RESTPARAM{stamp, number, optional}

                                  A UNIX timestamp specifying the expiration threshold when type is expired.

                                  " + } + ], + "notes": "Deletes either all job results, expired job results, or the result of a specific job. Clients can use this method to perform an eventual garbage collection of job results.

                                  ", + "summary": " Deletes async job", + "httpMethod": "DELETE", + "examples": "

                                  Deleting all jobs:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270132193

                                  unix> curl -X DELETE --dump - http://localhost:8529/_api/job/all

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  { \"result\" : true } `

                                  Deleting expired jobs:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270197729

                                  unix> curl -X DELETE --dump - http://localhost:8529/_api/job/expired?stamp=1401376184

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  { \"result\" : true } `

                                  Deleting the result of a specific job:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270263265

                                  unix> curl -X DELETE --dump - http://localhost:8529/_api/job/270263265

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  { \"result\" : true } `

                                  Deleting the result of a non-existing job:

                                  ```js unix> curl -X DELETE --dump - http://localhost:8529/_api/job/foobar

                                  HTTP/1.1 404 Not Found content-type: application/json; charset=utf-8

                                  { \"error\" : true, \"errorMessage\" : \"not found\", \"code\" : 404, \"errorNum\" : 404 } `



                                  ", + "nickname": "DeletesAsyncJob" + } + ], + "path": "/_api/job/type" + }, + { + "operations": [ + { + "errorResponses": [ + { + "reason": "is returned if the job requested via job-id has been executed successfully and its result is ready to fetch.

                                  ", + "code": "200" + }, + { + "reason": "is returned if the job requested via job-id is still in the queue of pending (or not yet finished) jobs.

                                  ", + "code": "204" + }, + { + "reason": "is returned if the job was not found or already deleted or fetched from the job result list.

                                  ", + "code": "404" + } + ], + "parameters": [ + { + "dataType": "String", + "paramType": "path", + "required": "true", + "name": "job-id", + "description": "The async job id.

                                  " + } + ], + "notes": "Returns the processing status of the specified job. The processing status can be determined by peeking into the HTTP response code of the response.

                                  ", + "summary": " Returns async job", + "httpMethod": "GET", + "examples": "

                                  Querying the status of a done job:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270328801

                                  unix> curl --dump - http://localhost:8529/_api/job/270328801

                                  HTTP/1.1 200 OK content-type: text/plain; charset=utf-8

                                  Querying the status of a pending job:

                                  unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_admin/sleep?duration=3

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270394337

                                  unix> curl --dump - http://localhost:8529/_api/job/270394337

                                  HTTP/1.1 204 No Content content-type: text/plain; charset=utf-8 `



                                  ", + "nickname": "ReturnsAsyncJob" + } + ], + "path": "/_api/job/job-id" + }, + { + "operations": [ + { + "errorResponses": [ + { + "reason": "is returned if the list can be compiled successfully. Note: the list might be empty.

                                  ", + "code": "200" + }, + { + "reason": "is returned if type is not specified or has an invalid value.

                                  ", + "code": "400" + } + ], + "parameters": [ + { + "dataType": "String", + "paramType": "path", + "required": "true", + "name": "type", + "description": "The type of jobs to return. The type can be either done or pending. Setting the type to done will make the method return the ids of already completed async jobs for which results can be fetched. Setting the type to pending will return the ids of not yet finished async jobs.

                                  @RESTQUERYPARAMS

                                  @RESTPARAM{count, number, optional}

                                  The maximum number of ids to return per call. If not specified, a server-defined maximum value will be used.

                                  " + } + ], + "notes": "Returns the list of ids of async jobs with a specific status (either done or pending). The list can be used by the client to get an overview of the job system status and to retrieve completed job results later.

                                  ", + "summary": " Returns list of async job", + "httpMethod": "GET", + "examples": "

                                  Fetching the list of done jobs:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270459873

                                  unix> curl --dump - http://localhost:8529/_api/job/done

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  [ \"270459873\" ] `

                                  Fetching the list of pending jobs:

                                  ```js unix> curl --header 'x-arango-async: store' --dump - http://localhost:8529/_api/version

                                  HTTP/1.1 202 Accepted content-type: text/plain; charset=utf-8 x-arango-async-id: 270525409

                                  unix> curl --dump - http://localhost:8529/_api/job/pending

                                  HTTP/1.1 200 OK content-type: application/json; charset=utf-8

                                  [ ] `



                                  ", + "nickname": "ReturnsListOfAsyncJob" + } + ], + "path": "/_api/job/type" + } + ] } diff --git a/js/apps/system/aardvark/api-docs/query.json b/js/apps/system/aardvark/api-docs/query.json index ebcd436092..930c101f4d 100644 --- a/js/apps/system/aardvark/api-docs/query.json +++ b/js/apps/system/aardvark/api-docs/query.json @@ -8,7 +8,7 @@ { "errorResponses": [ { - "reason": "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.

                                  ", + "reason": "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 a list 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.

                                  ", "code": "200" }, { @@ -22,14 +22,14 @@ "paramType": "body", "required": "true", "name": "query", - "description": "To validate a query string without executing it, the query string can be passed to the server via an HTTP POST request.

                                  These query string needs to be passed in the attribute query of a JSON object as the body of the POST request.

                                  " + "description": "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.

                                  " } ], "notes": "", - "summary": " Parse query", + "summary": " Parse an AQL query", "httpMethod": "POST", - "examples": "

                                  Valid query:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query\n{ \"query\" : \"FOR p IN products FILTER p.name == @name LIMIT 2 RETURN p.n\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"bindVars\" : [ \n    \"name\" \n  ], \n  \"collections\" : [ \n    \"products\" \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                  Invalid query:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query\n{ \"query\" : \"FOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n\" }\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1501, \n  \"errorMessage\" : \"syntax error, unexpected assignment near '= @name LIMIT 2 RETURN p.n' at position 1:33\\nFOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n\\n                               ^^^\\n\" \n}\n



                                  ", - "nickname": "ParseQuery" + "examples": "

                                  Valid query:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query\n{ \"query\" : \"FOR p IN products FILTER p.name == @name LIMIT 2 RETURN p.n\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"bindVars\" : [ \n    \"name\" \n  ], \n  \"collections\" : [ \n    \"products\" \n  ], \n  \"ast\" : [ \n    { \n      \"type\" : \"root\", \n      \"subNodes\" : [ \n        { \n          \"type\" : \"for\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"variable\", \n              \"name\" : \"p\", \n              \"id\" : 0 \n            }, \n            { \n              \"type\" : \"collection\", \n              \"name\" : \"products\" \n            } \n          ] \n        }, \n        { \n          \"type\" : \"filter\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"compare ==\", \n              \"subNodes\" : [ \n                { \n                  \"type\" : \"attribute access\", \n                  \"name\" : \"name\", \n                  \"subNodes\" : [ \n                    { \n                      \"type\" : \"reference\", \n                      \"name\" : \"p\", \n                      \"id\" : 0 \n                    } \n                  ] \n                }, \n                { \n                  \"type\" : \"parameter\", \n                  \"name\" : \"name\" \n                } \n              ] \n            } \n          ] \n        }, \n        { \n          \"type\" : \"limit\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"value\", \n              \"value\" : 0 \n            }, \n            { \n              \"type\" : \"value\", \n              \"value\" : 2 \n            } \n          ] \n        }, \n        { \n          \"type\" : \"return\", \n          \"subNodes\" : [ \n            { \n              \"type\" : \"attribute access\", \n              \"name\" : \"n\", \n              \"subNodes\" : [ \n                { \n                  \"type\" : \"reference\", \n                  \"name\" : \"p\", \n                  \"id\" : 0 \n                } \n              ] \n            } \n          ] \n        } \n      ] \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                  Invalid query:



                                  shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/query\n{ \"query\" : \"FOR p IN products FILTER p.name = @name LIMIT 2 RETURN p.n\" }\n\nHTTP/1.1 400 Bad Request\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 400, \n  \"errorNum\" : 1501, \n  \"errorMessage\" : \"syntax error, unexpected assignment near '= @name LIMIT 2 RETURN p.n' at position 1:33\" \n}\n



                                  ", + "nickname": "ParseAnAqlQuery" } ], "path": "/_api/query" diff --git a/js/apps/system/aardvark/api-docs/replication.json b/js/apps/system/aardvark/api-docs/replication.json index 1716bc0464..9c14f50f84 100644 --- a/js/apps/system/aardvark/api-docs/replication.json +++ b/js/apps/system/aardvark/api-docs/replication.json @@ -24,7 +24,7 @@ "notes": "Returns the current state of the server's replication logger. The state will include information about whether the logger is running and about the last logged tick value. This tick value is important for incremental fetching of data.

                                  The state API can be called regardless of whether the logger is currently running or not.

                                  The body of the response contains a JSON object with the following attributes:

                                  • state: the current logger state as a JSON hash array with the following sub-attributes: - running: whether or not the logger is running - lastLogTick: the tick value of the latest tick the logger has logged. This value can be used for incremental fetching of log data. - totalEvents: total number of events logged since the server was started. The value is not reset between multiple stops and re-starts of the logger. - time: the current date and time on the logger server
                                  • server: a JSON hash with the following sub-attributes: - version: the logger server's version - serverId: the logger server's id", "summary": " Return replication logger state", "httpMethod": "GET", - "examples": "

                                    Returns the state of the replication logger.



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1398799528\", \n    \"totalEvents\" : 7993, \n    \"time\" : \"2014-10-22T08:57:41Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-devel\", \n    \"serverId\" : \"216720906318572\" \n  }, \n  \"clients\" : [ ] \n}\n



                                    ", + "examples": "

                                    Returns the state of the replication logger.



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1459523017\", \n    \"totalEvents\" : 8285, \n    \"time\" : \"2014-11-07T18:37:46Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-beta2\", \n    \"serverId\" : \"186671298607643\" \n  }, \n  \"clients\" : [ ] \n}\n



                                    ", "nickname": "ReturnReplicationLoggerState" } ], @@ -197,7 +197,7 @@ "notes": "Returns data from the server's replication log. This method can be called by replication clients after an initial synchronization of data. The method will return all \"recent\" log entries from the logger server, and the clients can replay and apply these entries locally so they get to the same data state as the logger server.

                                    Clients can call this method repeatedly to incrementally fetch all changes from the logger server. In this case, they should provide the from value so they will only get returned the log events since their last fetch.

                                    When the from URL parameter is not used, the logger server will return log entries starting at the beginning of its replication log. When the from parameter is used, the logger server will only return log entries which have higher tick values than the specified from value (note: the log entry with a tick value equal to from will be excluded). Use the from value when incrementally fetching log data.

                                    The to URL parameter can be used to optionally restrict the upper bound of the result to a certain tick value. If used, the result will contain only log events with tick values up to (including) to. In incremental fetching, there is no need to use the to parameter. It only makes sense in special situations, when only parts of the change log are required.

                                    The chunkSize URL parameter can be used to control the size of the result. It must be specified in bytes. The chunkSize value will only be honored approximately. Otherwise a too low chunkSize value could cause the server to not be able to put just one log entry into the result and return it. Therefore, the chunkSize value will only be consulted after a log entry has been written into the result. If the result size is then bigger than chunkSize, the server will respond with as many log entries as there are in the response already. If the result size is still smaller than chunkSize, the server will try to return more data if there's more data left to return.

                                    If chunkSize is not specified, some server-side default value will be used.

                                    The Content-Type of the result is application/x-arango-dump. This is an easy-to-process format, with all log events going onto separate lines in the response body. Each log event itself is a JSON hash, with at least the following attributes:

                                    • tick: the log event tick value
                                    • type: the log event type
                                    Individual log events will also have additional attributes, depending on the event type. A few common attributes which are used for multiple events types are:

                                    • cid: id of the collection the event was for
                                    • tid: id of the transaction the event was contained in
                                    • key: document key
                                    • rev: document revision id
                                    • data: the original document data
                                    A more detailed description of the individual replication event types and their data structures can be found in the manual.

                                    The response will also contain the following HTTP headers:

                                    • x-arango-replication-active: whether or not the logger is active. Clients can use this flag as an indication for their polling frequency. If the logger is not active and there are no more replication events available, it might be sensible for a client to abort, or to go to sleep for a long time and try again later to check whether the logger has been activated.
                                    • x-arango-replication-lastincluded: the tick value of the last included value in the result. In incremental log fetching, this value can be used as the from value for the following request. Note that if the result is empty, the value will be 0. This value should not be used as from value by clients in the next request (otherwise the server would return the log events from the start of the log again).
                                    • x-arango-replication-lasttick: the last tick value the logger server has logged (not necessarily included in the result). By comparing the the last tick and last included tick values, clients have an approximate indication of how many events there are still left to fetch.
                                    • x-arango-replication-checkmore: whether or not there already exists more log data which the client could fetch immediately. If there is more log data available, the client could call logger-follow again with an adjusted from value to fetch remaining log entries until there are no more. If there isn't any more log data to fetch, the client might decide to go to sleep for a while before calling the logger again.
                                    Note: this method is not supported on a coordinator in a cluster.

                                    ", "summary": " Returns log entries", "httpMethod": "GET", - "examples": "

                                    No log events available:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1398799528\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 0\nx-arango-replication-lasttick: 1398799528\n\n



                                    A few log events:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1398799528\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 1400241320\nx-arango-replication-lasttick: 1400241320\n\n\"{\\\"tick\\\":\\\"1398930600\\\",\\\"type\\\":2000,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"1398865064\\\",\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"1399258280\\\",\\\"type\\\":2300,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1399192744\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"1399192744\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n{\\\"tick\\\":\\\"1399585960\\\",\\\"type\\\":2300,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"1399520424\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"1399520424\\\",\\\"hp\\\":5100,\\\"name\\\":\\\"hybrid hovercraft\\\"}}\\n{\\\"tick\\\":\\\"1399782568\\\",\\\"type\\\":2302,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1399717032\\\"}\\n{\\\"tick\\\":\\\"1399979176\\\",\\\"type\\\":2300,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"1399913640\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"1399913640\\\"}}\\n{\\\"tick\\\":\\\"1400044712\\\",\\\"type\\\":2001,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1398865064\\\"}\\n{\\\"tick\\\":\\\"1400175784\\\",\\\"type\\\":2200,\\\"database\\\":\\\"130216\\\",\\\"tid\\\":\\\"1400110248\\\"}\\n{\\\"tick\\\":\\\"1400241320\\\",\\\"type\\\":2201,\\\"database\\\":\\\"130216\\\",\\\"tid\\\":\\\"1400110248\\\"}\\n\"\n



                                    More events than would fit into the response:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1400241320&chunkSize=400\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: true\nx-arango-replication-lastincluded: 1400700072\nx-arango-replication-lasttick: 1401683112\n\n\"{\\\"tick\\\":\\\"1400372392\\\",\\\"type\\\":2000,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1400306856\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"1400306856\\\",\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"1400700072\\\",\\\"type\\\":2300,\\\"database\\\":\\\"130216\\\",\\\"cid\\\":\\\"1400306856\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1400634536\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"1400634536\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n\"\n



                                    ", + "examples": "

                                    No log events available:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1459523017\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 0\nx-arango-replication-lasttick: 1459523017\n\n



                                    A few log events:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1459523017\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 1461882313\nx-arango-replication-lasttick: 1461882313\n\n\"{\\\"tick\\\":\\\"1459654089\\\",\\\"type\\\":2200,\\\"database\\\":\\\"101833\\\",\\\"tid\\\":\\\"1459588553\\\"}\\n{\\\"tick\\\":\\\"1459981769\\\",\\\"type\\\":2300,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1459457481\\\",\\\"tid\\\":\\\"1459588553\\\",\\\"key\\\":\\\"abc\\\",\\\"rev\\\":\\\"1459916233\\\",\\\"data\\\":{\\\"_key\\\":\\\"abc\\\",\\\"_rev\\\":\\\"1459916233\\\",\\\"value1\\\":25,\\\"value2\\\":\\\"test\\\"}}\\n{\\\"tick\\\":\\\"1460178377\\\",\\\"type\\\":2202,\\\"database\\\":\\\"101833\\\",\\\"tid\\\":\\\"1459588553\\\"}\\n{\\\"tick\\\":\\\"1460243913\\\",\\\"type\\\":2001,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1459457481\\\"}\\n{\\\"tick\\\":\\\"1460374985\\\",\\\"type\\\":2000,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460309449\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"1460309449\\\",\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"1460440521\\\",\\\"type\\\":2001,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460309449\\\"}\\n{\\\"tick\\\":\\\"1460571593\\\",\\\"type\\\":2000,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"1460506057\\\",\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"1460899273\\\",\\\"type\\\":2300,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1460833737\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"1460833737\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n{\\\"tick\\\":\\\"1461226953\\\",\\\"type\\\":2300,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"1461161417\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"1461161417\\\",\\\"hp\\\":5100,\\\"name\\\":\\\"hybrid hovercraft\\\"}}\\n{\\\"tick\\\":\\\"1461423561\\\",\\\"type\\\":2302,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1461358025\\\"}\\n{\\\"tick\\\":\\\"1461620169\\\",\\\"type\\\":2300,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p2\\\",\\\"rev\\\":\\\"1461554633\\\",\\\"data\\\":{\\\"_key\\\":\\\"p2\\\",\\\"_rev\\\":\\\"1461554633\\\"}}\\n{\\\"tick\\\":\\\"1461685705\\\",\\\"type\\\":2001,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1460506057\\\"}\\n{\\\"tick\\\":\\\"1461816777\\\",\\\"type\\\":2200,\\\"database\\\":\\\"101833\\\",\\\"tid\\\":\\\"1461751241\\\"}\\n{\\\"tick\\\":\\\"1461882313\\\",\\\"type\\\":2201,\\\"database\\\":\\\"101833\\\",\\\"tid\\\":\\\"1461751241\\\"}\\n\"\n



                                    More events than would fit into the response:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/logger-follow?from=1461882313&chunkSize=400\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-active: true\nx-arango-replication-checkmore: true\nx-arango-replication-lastincluded: 1462341065\nx-arango-replication-lasttick: 1463324105\n\n\"{\\\"tick\\\":\\\"1462013385\\\",\\\"type\\\":2000,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1461947849\\\",\\\"collection\\\":{\\\"version\\\":5,\\\"type\\\":2,\\\"cid\\\":\\\"1461947849\\\",\\\"deleted\\\":false,\\\"doCompact\\\":true,\\\"maximalSize\\\":1048576,\\\"name\\\":\\\"products\\\",\\\"isVolatile\\\":false,\\\"waitForSync\\\":false}}\\n{\\\"tick\\\":\\\"1462341065\\\",\\\"type\\\":2300,\\\"database\\\":\\\"101833\\\",\\\"cid\\\":\\\"1461947849\\\",\\\"tid\\\":\\\"0\\\",\\\"key\\\":\\\"p1\\\",\\\"rev\\\":\\\"1462275529\\\",\\\"data\\\":{\\\"_key\\\":\\\"p1\\\",\\\"_rev\\\":\\\"1462275529\\\",\\\"name\\\":\\\"flux compensator\\\"}}\\n\"\n



                                    ", "nickname": "ReturnsLogEntries" } ], @@ -232,7 +232,7 @@ "notes": "Returns the list of collections and indexes available on the server. This list can be used by replication clients to initiate an initial sync with the server.

                                    The response will contain a JSON hash array with the collection and state and tick attributes.

                                    collections is a list of collections with the following sub-attributes:

                                    • parameters: the collection properties
                                    • indexes: a list of the indexes of a the collection. Primary indexes and edges indexes are not included in this list.
                                    The state attribute contains the current state of the replication logger. It contains the following sub-attributes:

                                    • running: whether or not the replication logger is currently active
                                    • lastLogTick: the value of the last tick the replication logger has written
                                    • time: the current time on the server
                                    Replication clients should note the lastLogTick value returned. They can then fetch collections' data using the dump method up to the value of lastLogTick, and query the continuous replication log for log events after this tick value.

                                    To create a full copy of the collections on the logger server, a replication client can execute these steps:

                                    • call the /inventory API method. This returns the lastLogTick value and the list of collections and indexes from the logger server.
                                    • for each collection returned by /inventory, create the collection locally and call /dump to stream the collection data to the client, up to the value of lastLogTick. After that, the client can create the indexes on the collections as they were reported by /inventory.
                                    If the clients wants to continuously stream replication log events from the logger server, the following additional steps need to be carried out:

                                    • the client should call /logger-follow initially to fetch the first batch of replication events that were logged after the client's call to /inventory. The call to /logger-follow should use a from parameter with the value of the lastLogTick as reported by /inventory. The call to /logger-follow will return the x-arango-replication-lastincluded which will contain the last tick value included in the response.
                                    • the client can then continuously call /logger-follow to incrementally fetch new replication events that occurred after the last transfer. Calls should use a from parameter with the value of the x-arango-replication-lastincluded header of the previous response. If there are no more replication events, the response will be empty and clients can go to sleep for a while and try again later.
                                    Note: on a coordinator, this request must have the URL parameter DBserver which must be an ID of a DBserver. The very same request is forwarded synchronously to that DBserver. It is an error if this attribute is not bound in the coordinator case.

                                    ", "summary": " Return inventory of collections and indexes", "httpMethod": "GET", - "examples": "



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"888405160\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"699333800\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"better-example\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798620840\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Company\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798358696\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Customer\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"887487656\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798882984\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Electronics\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1361509544\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"female\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1272446120\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1272183976\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798751912\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Groceries\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1361640616\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"male\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1297415336\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"otherVertices\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1060764840\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"vertices1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1062141096\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"edges2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272577192\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"798489768\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"friend_of\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272315048\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"799014056\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"has_bought\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272708264\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"internationalHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1361771688\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"relation\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1401683112\", \n    \"totalEvents\" : 8017, \n    \"time\" : \"2014-10-22T08:57:43Z\" \n  }, \n  \"tick\" : \"1401683112\" \n}\n



                                    With some additional indexes:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"888405160\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"699333800\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"better-example\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798620840\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Company\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798358696\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Customer\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"887487656\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798882984\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Electronics\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1361509544\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"female\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1272446120\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1272183976\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"798751912\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Groceries\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1401748648\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"1402010792\", \n          \"type\" : \"hash\", \n          \"unique\" : false, \n          \"fields\" : [ \n            \"name\" \n          ] \n        }, \n        { \n          \"id\" : \"1402338472\", \n          \"type\" : \"skiplist\", \n          \"unique\" : true, \n          \"fields\" : [ \n            \"a\", \n            \"b\" \n          ] \n        }, \n        { \n          \"id\" : \"1402535080\", \n          \"type\" : \"cap\", \n          \"unique\" : false, \n          \"size\" : 500, \n          \"byteSize\" : 0 \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1402731688\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"1402993832\", \n          \"type\" : \"fulltext\", \n          \"unique\" : false, \n          \"minLength\" : 10, \n          \"fields\" : [ \n            \"text\" \n          ] \n        }, \n        { \n          \"id\" : \"1403255976\", \n          \"type\" : \"skiplist\", \n          \"unique\" : false, \n          \"fields\" : [ \n            \"a\" \n          ] \n        }, \n        { \n          \"id\" : \"1403452584\", \n          \"type\" : \"cap\", \n          \"unique\" : false, \n          \"size\" : 0, \n          \"byteSize\" : 1048576 \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1361640616\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"male\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1297415336\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"otherVertices\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1060764840\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"vertices1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1062141096\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"edges2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272577192\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"798489768\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"friend_of\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272315048\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"799014056\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"has_bought\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1272708264\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"internationalHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1361771688\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"relation\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1402797224\", \n    \"totalEvents\" : 8030, \n    \"time\" : \"2014-10-22T08:57:43Z\" \n  }, \n  \"tick\" : \"1403583656\" \n}\n



                                    ", + "examples": "



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"908758473\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"719752649\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"better-example\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817728969\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Company\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817466825\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Customer\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"907840969\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817991113\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Electronics\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1423412681\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"female\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1332907465\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1332645321\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817860041\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Groceries\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1423543753\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"male\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1358073289\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"otherVertices\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1117162953\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"vertices1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1118539209\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"edges2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1333038537\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"817597897\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"friend_of\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1332776393\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"818122185\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"has_bought\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1333169609\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"internationalHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1423674825\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"relation\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1463324105\", \n    \"totalEvents\" : 8309, \n    \"time\" : \"2014-11-07T18:37:48Z\" \n  }, \n  \"tick\" : \"1463324105\" \n}\n



                                    With some additional indexes:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/inventory\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"collections\" : [ \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"908758473\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"animals\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"719752649\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"better-example\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817728969\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Company\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817466825\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Customer\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"907840969\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"demo\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817991113\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Electronics\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1423412681\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"female\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1332907465\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1332645321\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanCity\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"817860041\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"Groceries\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1463586249\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"1463848393\", \n          \"type\" : \"hash\", \n          \"unique\" : false, \n          \"fields\" : [ \n            \"name\" \n          ] \n        }, \n        { \n          \"id\" : \"1464176073\", \n          \"type\" : \"skiplist\", \n          \"unique\" : true, \n          \"fields\" : [ \n            \"a\", \n            \"b\" \n          ] \n        }, \n        { \n          \"id\" : \"1464372681\", \n          \"type\" : \"cap\", \n          \"unique\" : false, \n          \"size\" : 500, \n          \"byteSize\" : 0 \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1464569289\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"IndexedCollection2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ \n        { \n          \"id\" : \"1464831433\", \n          \"type\" : \"fulltext\", \n          \"unique\" : false, \n          \"minLength\" : 10, \n          \"fields\" : [ \n            \"text\" \n          ] \n        }, \n        { \n          \"id\" : \"1465093577\", \n          \"type\" : \"skiplist\", \n          \"unique\" : false, \n          \"fields\" : [ \n            \"a\" \n          ] \n        }, \n        { \n          \"id\" : \"1465290185\", \n          \"type\" : \"cap\", \n          \"unique\" : false, \n          \"size\" : 0, \n          \"byteSize\" : 1048576 \n        } \n      ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1423543753\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"male\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1358073289\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"otherVertices\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 2, \n        \"cid\" : \"1117162953\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"vertices1\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1118539209\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"edges2\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1333038537\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"frenchHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"817597897\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"friend_of\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1332776393\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"germanHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"818122185\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"has_bought\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1333169609\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"internationalHighway\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    }, \n    { \n      \"parameters\" : { \n        \"version\" : 5, \n        \"type\" : 3, \n        \"cid\" : \"1423674825\", \n        \"deleted\" : false, \n        \"doCompact\" : true, \n        \"maximalSize\" : 1048576, \n        \"name\" : \"relation\", \n        \"isVolatile\" : false, \n        \"waitForSync\" : false \n      }, \n      \"indexes\" : [ ] \n    } \n  ], \n  \"state\" : { \n    \"running\" : true, \n    \"lastLogTick\" : \"1463324105\", \n    \"totalEvents\" : 8324, \n    \"time\" : \"2014-11-07T18:37:49Z\" \n  }, \n  \"tick\" : \"1465421257\" \n}\n



                                    ", "nickname": "ReturnInventoryOfCollectionsAndIndexes" } ], @@ -338,7 +338,7 @@ "notes": "Returns the data from the collection for the requested range.

                                    When the from URL parameter is not used, collection events are returned from the beginning. When the from parameter is used, the result will only contain collection entries which have higher tick values than the specified from value (note: the log entry with a tick value equal to from will be excluded).

                                    The to URL parameter can be used to optionally restrict the upper bound of the result to a certain tick value. If used, the result will only contain collection entries with tick values up to (including) to.

                                    The chunkSize URL parameter can be used to control the size of the result. It must be specified in bytes. The chunkSize value will only be honored approximately. Otherwise a too low chunkSize value could cause the server to not be able to put just one entry into the result and return it. Therefore, the chunkSize value will only be consulted after an entry has been written into the result. If the result size is then bigger than chunkSize, the server will respond with as many entries as there are in the response already. If the result size is still smaller than chunkSize, the server will try to return more data if there's more data left to return.

                                    If chunkSize is not specified, some server-side default value will be used.

                                    The Content-Type of the result is application/x-arango-dump. This is an easy-to-process format, with all entries going onto separate lines in the response body.

                                    Each line itself is a JSON hash, with at least the following attributes:

                                    • tick: the operation's tick attribute
                                    • key: the key of the document/edge or the key used in the deletion operation
                                    • rev: the revision id of the document/edge or the deletion operation
                                    • data: the actual document/edge data for types 2300 and 2301. The full document/edge data will be returned even for updates.
                                    • type: the type of entry. Possible values for type are: - 2300: document insertion/update - 2301: edge insertion/update - 2302: document/edge deletion
                                    Note: there will be no distinction between inserts and updates when calling this method.

                                    ", "summary": " Return data of a collection", "httpMethod": "GET", - "examples": "

                                    Empty collection:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 0\n\n



                                    Non-empty collection:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 1406205096\n\n\"{\\\"tick\\\":\\\"1405549736\\\",\\\"type\\\":2300,\\\"key\\\":\\\"123456\\\",\\\"rev\\\":\\\"1405484200\\\",\\\"data\\\":{\\\"_key\\\":\\\"123456\\\",\\\"_rev\\\":\\\"1405484200\\\",\\\"c\\\":false,\\\"b\\\":1,\\\"d\\\":\\\"additional value\\\"}}\\n{\\\"tick\\\":\\\"1406008488\\\",\\\"type\\\":2302,\\\"key\\\":\\\"foobar\\\",\\\"rev\\\":\\\"1405942952\\\"}\\n{\\\"tick\\\":\\\"1406205096\\\",\\\"type\\\":2302,\\\"key\\\":\\\"abcdef\\\",\\\"rev\\\":\\\"1406139560\\\"}\\n\"\n



                                    ", + "examples": "

                                    Empty collection:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 204 No Content\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 0\n\n



                                    Non-empty collection:



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/dump?collection=testCollection\n\nHTTP/1.1 200 OK\ncontent-type: application/x-arango-dump; charset=utf-8\nx-arango-replication-checkmore: false\nx-arango-replication-lastincluded: 1468894665\n\n\"{\\\"tick\\\":\\\"1468239305\\\",\\\"type\\\":2300,\\\"key\\\":\\\"123456\\\",\\\"rev\\\":\\\"1468173769\\\",\\\"data\\\":{\\\"_key\\\":\\\"123456\\\",\\\"_rev\\\":\\\"1468173769\\\",\\\"c\\\":false,\\\"b\\\":1,\\\"d\\\":\\\"additional value\\\"}}\\n{\\\"tick\\\":\\\"1468698057\\\",\\\"type\\\":2302,\\\"key\\\":\\\"foobar\\\",\\\"rev\\\":\\\"1468632521\\\"}\\n{\\\"tick\\\":\\\"1468894665\\\",\\\"type\\\":2302,\\\"key\\\":\\\"abcdef\\\",\\\"rev\\\":\\\"1468829129\\\"}\\n\"\n



                                    ", "nickname": "ReturnDataOfACollection" } ], @@ -408,7 +408,7 @@ "notes": "Returns the servers id. The id is also returned by other replication API methods, and this method is an easy means of determining a server's id.

                                    The body of the response is a JSON hash with the attribute serverId. The server id is returned as a string.

                                    ", "summary": " Return server id", "httpMethod": "GET", - "examples": "



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/server-id\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"serverId\" : \"216720906318572\" \n}\n



                                    ", + "examples": "



                                    shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/server-id\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"serverId\" : \"186671298607643\" \n}\n



                                    ", "nickname": "ReturnServerId" } ], @@ -513,7 +513,7 @@ "notes": "Starts the replication applier. This will return immediately if the replication applier is already running.

                                    If the replication applier is not already running, the applier configuration will be checked, and if it is complete, the applier will be started in a background thread. This means that even if the applier will encounter any errors while running, they will not be reported in the response to this method.

                                    To detect replication applier errors after the applier was started, use the /_api/replication/applier-state API instead.

                                    ", "summary": " Start replication applier", "httpMethod": "PUT", - "examples": "



                                    shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-start\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-10-22T08:57:16Z\", \n      \"message\" : \"applier created\", \n      \"failedConnects\" : 0 \n    }, \n    \"totalRequests\" : 0, \n    \"totalFailedConnects\" : 0, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2014-10-22T08:57:45Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-devel\", \n    \"serverId\" : \"216720906318572\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                    ", + "examples": "



                                    shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-start\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-11-07T18:35:09Z\", \n      \"message\" : \"applier created\", \n      \"failedConnects\" : 0 \n    }, \n    \"totalRequests\" : 0, \n    \"totalFailedConnects\" : 0, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2014-11-07T18:37:54Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-beta2\", \n    \"serverId\" : \"186671298607643\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                    ", "nickname": "StartReplicationApplier" } ], @@ -540,7 +540,7 @@ "notes": "Stops the replication applier. This will return immediately if the replication applier is not running.

                                    ", "summary": " Stop replication applier", "httpMethod": "PUT", - "examples": "



                                    shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-stop\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-10-22T08:57:45Z\", \n      \"message\" : \"applier shut down\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2014-10-22T08:57:45Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2014-10-22T08:57:45Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-devel\", \n    \"serverId\" : \"216720906318572\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                    ", + "examples": "



                                    shell> curl -X PUT --dump - http://localhost:8529/_api/replication/applier-stop\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-11-07T18:37:54Z\", \n      \"message\" : \"fetching master state information\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2014-11-07T18:37:54Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2014-11-07T18:37:54Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-beta2\", \n    \"serverId\" : \"186671298607643\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                    ", "nickname": "StopReplicationApplier" } ], @@ -567,7 +567,7 @@ "notes": "Returns the state of the replication applier, regardless of whether the applier is currently running or not.

                                    The response is a JSON hash with the following attributes:

                                    • state: a JSON hash with the following sub-attributes: - running: whether or not the applier is active and running - lastAppliedContinuousTick: the last tick value from the continuous replication log the applier has applied. - lastProcessedContinuousTick: the last tick value from the continuous replication log the applier has processed. Regularly, the last applied and last processed tick values should be identical. For transactional operations, the replication applier will first process incoming log events before applying them, so the processed tick value might be higher than the applied tick value. This will be the case until the applier encounters the transaction commit log event for the transaction. - lastAvailableContinuousTick: the last tick value the logger server can provide. - time: the time on the applier server. - totalRequests: the total number of requests the applier has made to the endpoint. - totalFailedConnects: the total number of failed connection attempts the applier has made. - totalEvents: the total number of log events the applier has processed. - progress: a JSON hash with details about the replication applier progress. It contains the following sub-attributes if there is progress to report: - message: a textual description of the progress - time: the date and time the progress was logged - failedConnects: the current number of failed connection attempts - lastError: a JSON hash with details about the last error that happened on the applier. It contains the following sub-attributes if there was an error: - errorNum: a numerical error code - errorMessage: a textual error description - time: the date and time the error occurred In case no error has occurred, lastError will be empty.
                                    • server: a JSON hash with the following sub-attributes: - version: the applier server's version - serverId: the applier server's id
                                    • endpoint: the endpoint the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)
                                    • database: the name of the database the applier is connected to (if applier is active) or will connect to (if applier is currently inactive)", "summary": " State of the replication applier", "httpMethod": "GET", - "examples": "

                                      Fetching the state of an inactive applier:



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-10-22T08:57:45Z\", \n      \"message\" : \"applier shut down\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2014-10-22T08:57:45Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2014-10-22T08:57:45Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-devel\", \n    \"serverId\" : \"216720906318572\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                      Fetching the state of an active applier:



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-10-22T08:57:45Z\", \n      \"message\" : \"fetching master state information\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 3, \n    \"totalFailedConnects\" : 3, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2014-10-22T08:57:45Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-devel\", \n    \"serverId\" : \"216720906318572\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                      ", + "examples": "

                                      Fetching the state of an inactive applier:



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : false, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-11-07T18:37:54Z\", \n      \"message\" : \"fetching master state information\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"time\" : \"2014-11-07T18:37:54Z\", \n      \"errorMessage\" : \"could not connect to master at tcp://127.0.0.1:8529: Could not connect\", \n      \"errorNum\" : 1412 \n    }, \n    \"time\" : \"2014-11-07T18:37:54Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-beta2\", \n    \"serverId\" : \"186671298607643\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                      Fetching the state of an active applier:



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_api/replication/applier-state\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"state\" : { \n    \"running\" : true, \n    \"lastAppliedContinuousTick\" : null, \n    \"lastProcessedContinuousTick\" : null, \n    \"lastAvailableContinuousTick\" : null, \n    \"progress\" : { \n      \"time\" : \"2014-11-07T18:37:54Z\", \n      \"message\" : \"fetching master state information\", \n      \"failedConnects\" : 1 \n    }, \n    \"totalRequests\" : 2, \n    \"totalFailedConnects\" : 2, \n    \"totalEvents\" : 0, \n    \"lastError\" : { \n      \"errorNum\" : 0 \n    }, \n    \"time\" : \"2014-11-07T18:37:54Z\" \n  }, \n  \"server\" : { \n    \"version\" : \"2.3.0-beta2\", \n    \"serverId\" : \"186671298607643\" \n  }, \n  \"endpoint\" : \"tcp://127.0.0.1:8529\", \n  \"database\" : \"_system\" \n}\n



                                      ", "nickname": "StateOfTheReplicationApplier" } ], diff --git a/js/apps/system/aardvark/api-docs/simple.json b/js/apps/system/aardvark/api-docs/simple.json index 4232d60d0d..9a56be05c1 100644 --- a/js/apps/system/aardvark/api-docs/simple.json +++ b/js/apps/system/aardvark/api-docs/simple.json @@ -3,41 +3,6 @@ "swaggerVersion": "1.1", "apiVersion": "0.1", "apis": [ - { - "operations": [ - { - "errorResponses": [ - { - "reason": "is returned if the query was executed successfully.

                                      ", - "code": "201" - }, - { - "reason": "is returned if the body does not contain a valid JSON representation of a query. The response body contains an error document in this case.

                                      ", - "code": "400" - }, - { - "reason": "is returned if the collection specified by collection is unknown. The response body contains an error document in this case. The same error code is also returned if an invalid index id or type is used.

                                      ", - "code": "404" - } - ], - "parameters": [ - { - "dataType": "String", - "paramType": "body", - "required": "true", - "name": "query", - "description": "Contains the query specification.

                                      " - } - ], - "notes": "

                                      This will find all documents matching a given example, using the specified hash index.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • index: The id of the index to be used for the query. The index must exist and must be of type hash.
                                      • example: an example document. The example must contain a value for each attribute in the index.
                                      • skip: The number of documents to skip in the query. (optional)
                                      • limit: The maximal number of documents to return. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", - "summary": " Hash index", - "httpMethod": "PUT", - "examples": "", - "nickname": "HashIndex" - } - ], - "path": "/_api/simple/by-example-hash" - }, { "operations": [ { @@ -137,7 +102,7 @@ "notes": "

                                      Returns all documents of a collections. The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • skip: The number of documents to skip in the query (optional).
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Return all", "httpMethod": "PUT", - "examples": "

                                      Limit the amount of documents using limit



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all\n{ \"collection\": \"products\", \"skip\": 2, \"limit\" : 2 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1144061096\", \n      \"_key\" : \"1144061096\", \n      \"_rev\" : \"1144061096\", \n      \"Hello5\" : \"World5\" \n    }, \n    { \n      \"_id\" : \"products/1143733416\", \n      \"_key\" : \"1143733416\", \n      \"_rev\" : \"1143733416\", \n      \"Hello4\" : \"World4\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Using a batchSize value



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all\n{ \"collection\": \"products\", \"batchSize\" : 3 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1146027176\", \n      \"_key\" : \"1146027176\", \n      \"_rev\" : \"1146027176\", \n      \"Hello5\" : \"World5\" \n    }, \n    { \n      \"_id\" : \"products/1145044136\", \n      \"_key\" : \"1145044136\", \n      \"_rev\" : \"1145044136\", \n      \"Hello2\" : \"World2\" \n    }, \n    { \n      \"_id\" : \"products/1145371816\", \n      \"_key\" : \"1145371816\", \n      \"_rev\" : \"1145371816\", \n      \"Hello3\" : \"World3\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"1146223784\", \n  \"count\" : 5, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "

                                      Limit the amount of documents using limit



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all\n{ \"collection\": \"products\", \"skip\": 2, \"limit\" : 2 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1192267209\", \n      \"_key\" : \"1192267209\", \n      \"_rev\" : \"1192267209\", \n      \"Hello3\" : \"World3\" \n    }, \n    { \n      \"_id\" : \"products/1192922569\", \n      \"_key\" : \"1192922569\", \n      \"_rev\" : \"1192922569\", \n      \"Hello5\" : \"World5\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Using a batchSize value



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/all\n{ \"collection\": \"products\", \"batchSize\" : 3 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1193577929\", \n      \"_key\" : \"1193577929\", \n      \"_rev\" : \"1193577929\", \n      \"Hello1\" : \"World1\" \n    }, \n    { \n      \"_id\" : \"products/1194560969\", \n      \"_key\" : \"1194560969\", \n      \"_rev\" : \"1194560969\", \n      \"Hello4\" : \"World4\" \n    }, \n    { \n      \"_id\" : \"products/1193905609\", \n      \"_key\" : \"1193905609\", \n      \"_rev\" : \"1193905609\", \n      \"Hello2\" : \"World2\" \n    } \n  ], \n  \"hasMore\" : true, \n  \"id\" : \"1195085257\", \n  \"count\" : 5, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "ReturnAll" } ], @@ -172,7 +137,7 @@ "notes": "

                                      Returns a random document from a collection. The call expects a JSON object as body with the following attributes:

                                      • collection: The identifier or name of the collection to query.
                                      Returns a JSON object with the document stored in the attribute document if the collection contains at least one document. If the collection is empty, the document attrbute contains null.

                                      ", "summary": " Random document", "httpMethod": "PUT", - "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/any\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/1147665576\", \n    \"_key\" : \"1147665576\", \n    \"_rev\" : \"1147665576\", \n    \"Hello4\" : \"World4\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", + "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/any\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/1195871689\", \n    \"_key\" : \"1195871689\", \n    \"_rev\" : \"1195871689\", \n    \"Hello2\" : \"World2\" \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", "nickname": "RandomDocument" } ], @@ -207,7 +172,7 @@ "notes": "

                                      The default will find at most 100 documents near the given coordinate. The returned list is sorted according to the distance, with the nearest document being first in the list. If there are near documents of equal distance, documents are chosen randomly from this set until the limit is reached.

                                      In order to use the near operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more then one geo-spatial index, you can use the geo field to select a particular index.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • latitude: The latitude of the coordinate.
                                      • longitude: The longitude of the coordinate.
                                      • distance: If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
                                      • skip: The number of documents to skip in the query. (optional)
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
                                      • geo: If given, the identifier of the geo-index to use. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Near query", "httpMethod": "PUT", - "examples": "

                                      Without distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 2 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1150090408\", \n      \"_key\" : \"1150090408\", \n      \"_rev\" : \"1150090408\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/1149697192\", \n      \"_key\" : \"1149697192\", \n      \"_rev\" : \"1149697192\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      With distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 3, \"distance\" : \"distance\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1152711848\", \n      \"_key\" : \"1152711848\", \n      \"_rev\" : \"1152711848\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1153105064\", \n      \"_key\" : \"1153105064\", \n      \"_rev\" : \"1153105064\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1152515240\", \n      \"_key\" : \"1152515240\", \n      \"_rev\" : \"1152515240\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "

                                      Without distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 2 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1198951881\", \n      \"_key\" : \"1198951881\", \n      \"_rev\" : \"1198951881\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/1198558665\", \n      \"_key\" : \"1198558665\", \n      \"_rev\" : \"1198558665\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      With distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 3, \"distance\" : \"distance\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1201769929\", \n      \"_key\" : \"1201769929\", \n      \"_rev\" : \"1201769929\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1202163145\", \n      \"_key\" : \"1202163145\", \n      \"_rev\" : \"1202163145\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1201573321\", \n      \"_key\" : \"1201573321\", \n      \"_rev\" : \"1201573321\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "NearQuery" } ], @@ -242,7 +207,7 @@ "notes": "

                                      This will find all documents within a given radius around the coordinate (latitude, longitude). The returned list is sorted by distance.

                                      In order to use the within operator, a geo index must be defined for the collection. This index also defines which attribute holds the coordinates for the document. If you have more then one geo-spatial index, you can use the geo field to select a particular index.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • latitude: The latitude of the coordinate.
                                      • longitude: The longitude of the coordinate.
                                      • radius: The maximal radius (in meters).
                                      • distance: If given, the attribute key used to return the distance to the given coordinate. (optional). If specified, distances are returned in meters.
                                      • skip: The number of documents to skip in the query. (optional)
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. The default is 100. (optional)
                                      • geo: If given, the identifier of the geo-index to use. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Within query", "httpMethod": "PUT", - "examples": "

                                      Without distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 2, \"radius\" : 500 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1156119720\", \n      \"_key\" : \"1156119720\", \n      \"_rev\" : \"1156119720\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/1155726504\", \n      \"_key\" : \"1155726504\", \n      \"_rev\" : \"1155726504\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      With distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 3, \"distance\" : \"distance\", \"radius\" : 300 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1158741160\", \n      \"_key\" : \"1158741160\", \n      \"_rev\" : \"1158741160\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1159134376\", \n      \"_key\" : \"1159134376\", \n      \"_rev\" : \"1159134376\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1158544552\", \n      \"_key\" : \"1158544552\", \n      \"_rev\" : \"1158544552\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "

                                      Without distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 2, \"radius\" : 500 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1205177801\", \n      \"_key\" : \"1205177801\", \n      \"_rev\" : \"1205177801\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ] \n    }, \n    { \n      \"_id\" : \"products/1204784585\", \n      \"_key\" : \"1204784585\", \n      \"_rev\" : \"1204784585\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ] \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      With distance:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/near\n{ \"collection\": \"products\", \"latitude\" : 0, \"longitude\" : 0, \"skip\" : 1, \"limit\" : 3, \"distance\" : \"distance\", \"radius\" : 300 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1207995849\", \n      \"_key\" : \"1207995849\", \n      \"_rev\" : \"1207995849\", \n      \"name\" : \"Name/-0.002/\", \n      \"loc\" : [ \n        -0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1208389065\", \n      \"_key\" : \"1208389065\", \n      \"_rev\" : \"1208389065\", \n      \"name\" : \"Name/0.002/\", \n      \"loc\" : [ \n        0.002, \n        0 \n      ], \n      \"distance\" : 222.38985328911744 \n    }, \n    { \n      \"_id\" : \"products/1207799241\", \n      \"_key\" : \"1207799241\", \n      \"_rev\" : \"1207799241\", \n      \"name\" : \"Name/-0.004/\", \n      \"loc\" : [ \n        -0.004, \n        0 \n      ], \n      \"distance\" : 444.779706578235 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 3, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "WithinQuery" } ], @@ -274,10 +239,10 @@ "description": "Contains the query.

                                      " } ], - "notes": "

                                      This will find all documents from the collection that match the fulltext query specified in query.

                                      In order to use the fulltext operator, a fulltext index must be defined for the collection and the specified attribute.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • attribute: The attribute that contains the texts.
                                      • query: The fulltext query.
                                      • skip: The number of documents to skip in the query (optional).
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
                                      • index: The identifier of the fulltext-index to use.
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", + "notes": "

                                      This will find all documents from the collection that match the fulltext query specified in query.

                                      In order to use the fulltext operator, a fulltext index must be defined for the collection and the specified attribute.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • attribute: The attribute that contains the texts.
                                      • query: The fulltext query. Please refer to [Fulltext queries](../SimpleQueries/FulltextQueries.html) for details.
                                      • skip: The number of documents to skip in the query (optional).
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
                                      • index: The identifier of the fulltext-index to use.
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Fulltext index query", "httpMethod": "PUT", - "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/fulltext\n{ \"collection\": \"products\", \"attribute\" : \"text\", \"query\" : \"word\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1160838312\", \n      \"_key\" : \"1160838312\", \n      \"_rev\" : \"1160838312\", \n      \"text\" : \"this text contains word\" \n    }, \n    { \n      \"_id\" : \"products/1161034920\", \n      \"_key\" : \"1161034920\", \n      \"_rev\" : \"1161034920\", \n      \"text\" : \"this text also has a word\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/fulltext\n{ \"collection\": \"products\", \"attribute\" : \"text\", \"query\" : \"word\" }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1210093001\", \n      \"_key\" : \"1210093001\", \n      \"_rev\" : \"1210093001\", \n      \"text\" : \"this text also has a word\" \n    }, \n    { \n      \"_id\" : \"products/1209896393\", \n      \"_key\" : \"1209896393\", \n      \"_rev\" : \"1209896393\", \n      \"text\" : \"this text contains word\" \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "FulltextIndexQuery" } ], @@ -312,7 +277,7 @@ "notes": "

                                      This will find all documents matching a given example.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • example: The example document.
                                      • skip: The number of documents to skip in the query (optional).
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Simple query by-example", "httpMethod": "PUT", - "examples": "

                                      Matching an attribute:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" :  { \"i\" : 1 }  }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1163001000\", \n      \"_key\" : \"1163001000\", \n      \"_rev\" : \"1163001000\", \n      \"i\" : 1 \n    }, \n    { \n      \"_id\" : \"products/1162411176\", \n      \"_key\" : \"1162411176\", \n      \"_rev\" : \"1162411176\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1162738856\", \n      \"_key\" : \"1162738856\", \n      \"_rev\" : \"1162738856\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1163197608\", \n      \"_key\" : \"1163197608\", \n      \"_rev\" : \"1163197608\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 4, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Matching an attribute which is a sub-document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" : { \"a.j\" : 1 } }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1164377256\", \n      \"_key\" : \"1164377256\", \n      \"_rev\" : \"1164377256\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1164704936\", \n      \"_key\" : \"1164704936\", \n      \"_rev\" : \"1164704936\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Matching an attribute within a sub-document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" : { \"a\" : { \"j\" : 1 } } }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1166671016\", \n      \"_key\" : \"1166671016\", \n      \"_rev\" : \"1166671016\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 1, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "

                                      Matching an attribute:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" :  { \"i\" : 1 }  }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1211796937\", \n      \"_key\" : \"1211796937\", \n      \"_rev\" : \"1211796937\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1212255689\", \n      \"_key\" : \"1212255689\", \n      \"_rev\" : \"1212255689\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    }, \n    { \n      \"_id\" : \"products/1212059081\", \n      \"_key\" : \"1212059081\", \n      \"_rev\" : \"1212059081\", \n      \"i\" : 1 \n    }, \n    { \n      \"_id\" : \"products/1211469257\", \n      \"_key\" : \"1211469257\", \n      \"_rev\" : \"1211469257\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 4, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Matching an attribute which is a sub-document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" : { \"a.j\" : 1 } }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1213763017\", \n      \"_key\" : \"1213763017\", \n      \"_rev\" : \"1213763017\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1213435337\", \n      \"_key\" : \"1213435337\", \n      \"_rev\" : \"1213435337\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      Matching an attribute within a sub-document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/by-example\n{ \"collection\": \"products\", \"example\" : { \"a\" : { \"j\" : 1 } } }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1215729097\", \n      \"_key\" : \"1215729097\", \n      \"_rev\" : \"1215729097\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 1, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "SimpleQueryBy-example" } ], @@ -347,7 +312,7 @@ "notes": "

                                      This will return the first document matching a given example.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • example: The example document.
                                      Returns a result containing the document or HTTP 404 if no document matched the example.

                                      If more than one document in the collection matches the specified example, only one of these documents will be returned, and it is undefined which of the matching documents is returned.

                                      ", "summary": " Document matching an example", "httpMethod": "PUT", - "examples": "

                                      If a matching document was found:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example\n{ \"collection\": \"products\", \"example\" :  { \"i\" : 1 }  }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/1168899240\", \n    \"_key\" : \"1168899240\", \n    \"_rev\" : \"1168899240\", \n    \"i\" : 1 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      If no document was found:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example\n{ \"collection\": \"products\", \"example\" :  { \"l\" : 1 }  }\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 404, \n  \"errorMessage\" : \"no match\" \n}\n



                                      ", + "examples": "

                                      If a matching document was found:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example\n{ \"collection\": \"products\", \"example\" :  { \"i\" : 1 }  }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"document\" : { \n    \"_id\" : \"products/1218350537\", \n    \"_key\" : \"1218350537\", \n    \"_rev\" : \"1218350537\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 2, \n      \"j\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      If no document was found:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first-example\n{ \"collection\": \"products\", \"example\" :  { \"l\" : 1 }  }\n\nHTTP/1.1 404 Not Found\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 404, \n  \"errorNum\" : 404, \n  \"errorMessage\" : \"no match\" \n}\n



                                      ", "nickname": "DocumentMatchingAnExample" } ], @@ -382,7 +347,7 @@ "notes": "

                                      This will return the first document(s) from the collection, in the order of insertion/update time. When the count argument is supplied, the result will be a list of documents, with the \"oldest\" document being first in the result list. If the count argument is not supplied, the result is the \"oldest\" document of the collection, or null if the collection is empty.

                                      The request body must be a JSON object with the following attributes:
                                      • collection: the name of the collection
                                      • count: the number of documents to return at most. Specifiying count is optional. If it is not specified, it defaults to 1.
                                      Note: this method is not supported for sharded collections with more than one shard.

                                      ", "summary": " First document of a collection", "httpMethod": "PUT", - "examples": "

                                      Retrieving the first n documents:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first\n{ \"collection\": \"products\", \"count\" : 2 }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1172110504\", \n      \"_key\" : \"1172110504\", \n      \"_rev\" : \"1172110504\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1172438184\", \n      \"_key\" : \"1172438184\", \n      \"_rev\" : \"1172438184\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      Retrieving the first document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/1173748904\", \n    \"_key\" : \"1173748904\", \n    \"_rev\" : \"1173748904\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 1, \n      \"j\" : 1 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", + "examples": "

                                      Retrieving the first n documents:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first\n{ \"collection\": \"products\", \"count\" : 2 }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1221561801\", \n      \"_key\" : \"1221561801\", \n      \"_rev\" : \"1221561801\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 1, \n        \"j\" : 1 \n      } \n    }, \n    { \n      \"_id\" : \"products/1221889481\", \n      \"_key\" : \"1221889481\", \n      \"_rev\" : \"1221889481\", \n      \"i\" : 1, \n      \"a\" : { \n        \"j\" : 1 \n      } \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      Retrieving the first document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/first\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/1223200201\", \n    \"_key\" : \"1223200201\", \n    \"_rev\" : \"1223200201\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 1, \n      \"j\" : 1 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", "nickname": "FirstDocumentOfACollection" } ], @@ -417,7 +382,7 @@ "notes": "

                                      This will return the last documents from the collection, in the order of insertion/update time. When the count argument is supplied, the result will be a list of documents, with the \"latest\" document being first in the result list.

                                      The request body must be a JSON object with the following attributes:
                                      • collection: the name of the collection
                                      • count: the number of documents to return at most. Specifiying count is optional. If it is not specified, it defaults to 1.
                                      If the count argument is not supplied, the result is the \"latest\" document of the collection, or null if the collection is empty.

                                      Note: this method is not supported for sharded collections with more than one shard.

                                      ", "summary": " Last document of a collection", "httpMethod": "PUT", - "examples": "

                                      Retrieving the last n documents:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last\n{ \"collection\": \"products\", \"count\" : 2 }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1176173736\", \n      \"_key\" : \"1176173736\", \n      \"_rev\" : \"1176173736\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    }, \n    { \n      \"_id\" : \"products/1175977128\", \n      \"_key\" : \"1175977128\", \n      \"_rev\" : \"1175977128\", \n      \"i\" : 1 \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      Retrieving the first document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/1177812136\", \n    \"_key\" : \"1177812136\", \n    \"_rev\" : \"1177812136\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 2, \n      \"j\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", + "examples": "

                                      Retrieving the last n documents:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last\n{ \"collection\": \"products\", \"count\" : 2 }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1225625033\", \n      \"_key\" : \"1225625033\", \n      \"_rev\" : \"1225625033\", \n      \"i\" : 1, \n      \"a\" : { \n        \"k\" : 2, \n        \"j\" : 2 \n      } \n    }, \n    { \n      \"_id\" : \"products/1225428425\", \n      \"_key\" : \"1225428425\", \n      \"_rev\" : \"1225428425\", \n      \"i\" : 1 \n    } \n  ], \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      Retrieving the first document:



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/last\n{ \"collection\": \"products\" }\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"_id\" : \"products/1227263433\", \n    \"_key\" : \"1227263433\", \n    \"_rev\" : \"1227263433\", \n    \"i\" : 1, \n    \"a\" : { \n      \"k\" : 2, \n      \"j\" : 2 \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", "nickname": "LastDocumentOfACollection" } ], @@ -452,7 +417,7 @@ "notes": "

                                      This will find all documents within a given range. In order to execute a range query, a skip-list index on the queried attribute must be present.

                                      The call expects a JSON object as body with the following attributes:

                                      • collection: The name of the collection to query.
                                      • attribute: The attribute path to check.
                                      • left: The lower bound.
                                      • right: The upper bound.
                                      • closed: If true, use interval including left and right, otherwise exclude right, but include left.
                                      • skip: The number of documents to skip in the query (optional).
                                      • limit: The maximal amount of documents to return. The skip is applied before the limit restriction. (optional)
                                      Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.

                                      ", "summary": " Simple range query", "httpMethod": "PUT", - "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/range\n{ \"collection\": \"products\", \"attribute\" : \"i\", \"left\" : 2, \"right\" : 4 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1178795176\", \n      \"_key\" : \"1178795176\", \n      \"_rev\" : \"1178795176\", \n      \"i\" : 2 \n    }, \n    { \n      \"_id\" : \"products/1178991784\", \n      \"_key\" : \"1178991784\", \n      \"_rev\" : \"1178991784\", \n      \"i\" : 3 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", + "examples": "



                                      shell> curl -X PUT --data-binary @- --dump - http://localhost:8529/_api/simple/range\n{ \"collection\": \"products\", \"attribute\" : \"i\", \"left\" : 2, \"right\" : 4 }\n\nHTTP/1.1 201 Created\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : [ \n    { \n      \"_id\" : \"products/1228443081\", \n      \"_key\" : \"1228443081\", \n      \"_rev\" : \"1228443081\", \n      \"i\" : 2 \n    }, \n    { \n      \"_id\" : \"products/1228639689\", \n      \"_key\" : \"1228639689\", \n      \"_rev\" : \"1228639689\", \n      \"i\" : 3 \n    } \n  ], \n  \"hasMore\" : false, \n  \"count\" : 2, \n  \"error\" : false, \n  \"code\" : 201 \n}\n



                                      ", "nickname": "SimpleRangeQuery" } ], diff --git a/js/apps/system/aardvark/api-docs/system.json b/js/apps/system/aardvark/api-docs/system.json index 46e90f9228..5ff5f3e51c 100644 --- a/js/apps/system/aardvark/api-docs/system.json +++ b/js/apps/system/aardvark/api-docs/system.json @@ -214,7 +214,7 @@ "notes": "

                                      Returns the statistics information. The returned object contains the statistics figures grouped together according to the description returned by _admin/statistics-description. For instance, to access a figure userTime from the group system, you first select the sub-object describing the group stored in system and in that sub-object the value for userTime is stored in the attribute of the same name.

                                      In case of a distribution, the returned object contains the total count in count and the distribution list in counts. The sum (or total) of the individual values is returned in sum.

                                      ", "summary": " Read the statistics", "httpMethod": "GET", - "examples": "



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_admin/statistics\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"time\" : 1413968258.626262, \n  \"system\" : { \n    \"minorPageFaults\" : 145185, \n    \"majorPageFaults\" : 2179, \n    \"userTime\" : 6.69533, \n    \"systemTime\" : 4.061218, \n    \"numberOfThreads\" : 19, \n    \"residentSize\" : 187953152, \n    \"residentSizePercent\" : 0.021880626678466797, \n    \"virtualSize\" : 5231443968 \n  }, \n  \"client\" : { \n    \"httpConnections\" : 1, \n    \"connectionTime\" : { \n      \"sum\" : 0.0009860992431640625, \n      \"count\" : 1, \n      \"counts\" : [ \n        1, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"totalTime\" : { \n      \"sum\" : 13.294313192367554, \n      \"count\" : 8784, \n      \"counts\" : [ \n        8676, \n        96, \n        4, \n        4, \n        1, \n        3, \n        0 \n      ] \n    }, \n    \"requestTime\" : { \n      \"sum\" : 12.3034508228302, \n      \"count\" : 8784, \n      \"counts\" : [ \n        8680, \n        92, \n        4, \n        4, \n        1, \n        3, \n        0 \n      ] \n    }, \n    \"queueTime\" : { \n      \"sum\" : 0.16509556770324707, \n      \"count\" : 8784, \n      \"counts\" : [ \n        8784, \n        0, \n        0, \n        0, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"ioTime\" : { \n      \"sum\" : 0.8257668018341064, \n      \"count\" : 8784, \n      \"counts\" : [ \n        8784, \n        0, \n        0, \n        0, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"bytesSent\" : { \n      \"sum\" : 3264611, \n      \"count\" : 8784, \n      \"counts\" : [ \n        2666, \n        5978, \n        10, \n        8, \n        122, \n        0 \n      ] \n    }, \n    \"bytesReceived\" : { \n      \"sum\" : 2079017, \n      \"count\" : 8784, \n      \"counts\" : [ \n        6564, \n        2220, \n        0, \n        0, \n        0, \n        0 \n      ] \n    } \n  }, \n  \"http\" : { \n    \"requestsTotal\" : 8784, \n    \"requestsAsync\" : 0, \n    \"requestsGet\" : 3650, \n    \"requestsHead\" : 295, \n    \"requestsPost\" : 3165, \n    \"requestsPut\" : 685, \n    \"requestsPatch\" : 31, \n    \"requestsDelete\" : 958, \n    \"requestsOptions\" : 0, \n    \"requestsOther\" : 0 \n  }, \n  \"server\" : { \n    \"uptime\" : 22.03459119796753, \n    \"physicalMemory\" : 8589934592 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", + "examples": "



                                      shell> curl --data-binary @- --dump - http://localhost:8529/_admin/statistics\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"time\" : 1415385452.993082, \n  \"system\" : { \n    \"minorPageFaults\" : 292830, \n    \"majorPageFaults\" : 2296, \n    \"userTime\" : 12.196963, \n    \"systemTime\" : 6.109562, \n    \"numberOfThreads\" : 19, \n    \"residentSize\" : 95592448, \n    \"residentSizePercent\" : 0.022256851196289062, \n    \"virtualSize\" : 5232513024 \n  }, \n  \"client\" : { \n    \"httpConnections\" : 1, \n    \"connectionTime\" : { \n      \"sum\" : 0.03389310836791992, \n      \"count\" : 1, \n      \"counts\" : [ \n        1, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"totalTime\" : { \n      \"sum\" : 114.02063083648682, \n      \"count\" : 8842, \n      \"counts\" : [ \n        7864, \n        547, \n        142, \n        141, \n        130, \n        12, \n        6 \n      ] \n    }, \n    \"requestTime\" : { \n      \"sum\" : 112.08691906929016, \n      \"count\" : 8842, \n      \"counts\" : [ \n        7874, \n        539, \n        141, \n        141, \n        130, \n        11, \n        6 \n      ] \n    }, \n    \"queueTime\" : { \n      \"sum\" : 0.20596933364868164, \n      \"count\" : 8842, \n      \"counts\" : [ \n        8842, \n        0, \n        0, \n        0, \n        0, \n        0, \n        0 \n      ] \n    }, \n    \"ioTime\" : { \n      \"sum\" : 1.7277424335479736, \n      \"count\" : 8842, \n      \"counts\" : [ \n        8840, \n        0, \n        1, \n        0, \n        0, \n        1, \n        0 \n      ] \n    }, \n    \"bytesSent\" : { \n      \"sum\" : 3327712, \n      \"count\" : 8842, \n      \"counts\" : [ \n        2652, \n        6041, \n        12, \n        10, \n        127, \n        0 \n      ] \n    }, \n    \"bytesReceived\" : { \n      \"sum\" : 1889636, \n      \"count\" : 8842, \n      \"counts\" : [ \n        7062, \n        1780, \n        0, \n        0, \n        0, \n        0 \n      ] \n    } \n  }, \n  \"http\" : { \n    \"requestsTotal\" : 8843, \n    \"requestsAsync\" : 0, \n    \"requestsGet\" : 3657, \n    \"requestsHead\" : 295, \n    \"requestsPost\" : 3211, \n    \"requestsPut\" : 686, \n    \"requestsPatch\" : 31, \n    \"requestsDelete\" : 963, \n    \"requestsOptions\" : 0, \n    \"requestsOther\" : 0 \n  }, \n  \"server\" : { \n    \"uptime\" : 152.82532405853271, \n    \"physicalMemory\" : 4294967296 \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                      ", "nickname": "ReadTheStatistics" } ], diff --git a/js/apps/system/aardvark/api-docs/traversal.json b/js/apps/system/aardvark/api-docs/traversal.json index eb3af97df6..95bd45f646 100644 --- a/js/apps/system/aardvark/api-docs/traversal.json +++ b/js/apps/system/aardvark/api-docs/traversal.json @@ -36,7 +36,7 @@ "notes": "Starts a traversal starting from a given vertex and following. edges contained in a given edgeCollection. The request must contain the following attributes.

                                      • startVertex: id of the startVertex, e.g. \"users/foo\".
                                      • edgeCollection: (optional) name of the collection that contains the edges.
                                      • graphName: (optional) name of the graph that contains the edges. Either edgeCollection or graphName has to be given. In case both values are set the graphName is prefered.
                                      • filter (optional, default is to include all nodes): body (JavaScript code) of custom filter function function signature: (config, vertex, path) -> mixed can return four different string values: - \"exclude\" -> this vertex will not be visited. - \"prune\" -> the edges of this vertex will not be followed. - \"\" or undefined -> visit the vertex and follow it's edges. - Array -> containing any combination of the above. If there is at least one \"exclude\" or \"prune\" respectivly is contained, it's effect will occur.
                                      • minDepth (optional, ANDed with any existing filters): visits only nodes in at least the given depth
                                      • maxDepth (optional, ANDed with any existing filters): visits only nodes in at most the given depth
                                      • visitor (optional): body (JavaScript) code of custom visitor function function signature: (config, result, vertex, path) -> void visitor function can do anything, but its return value is ignored. To populate a result, use the result variable by reference
                                      • direction (optional): direction for traversal - if set, must be either \"outbound\", \"inbound\", or \"any\" - if not set, the expander attribute must be specified
                                      • init (optional): body (JavaScript) code of custom result initialisation function function signature: (config, result) -> void initialise any values in result with what is required
                                      • expander (optional): body (JavaScript) code of custom expander function must be set if direction attribute is not set function signature: (config, vertex, path) -> array expander must return an array of the connections for vertex each connection is an object with the attributes edge and vertex
                                      • sort (optional): body (JavaScript) code of a custom comparison function for the edges. The signature of this function is (l, r) -> integer (where l and r are edges) and must return -1 if l is smaller than, +1 if l is greater than, and 0 if l and r are equal. The reason for this is the following: The order of edges returned for a certain vertex is undefined. This is because there is no natural order of edges for a vertex with multiple connected edges. To explicitly define the order in which edges on the vertex are followed, you can specify an edge comparator function with this attribute. Note that the value here has to be a string to conform to the JSON standard, which in turn is parsed as function body on the server side. Furthermore note that this attribute is only used for the standard expanders. If you use your custom expander you have to do the sorting yourself within the expander code.
                                      • strategy (optional): traversal strategy can be \"depthfirst\" or \"breadthfirst\"
                                      • order (optional): traversal order can be \"preorder\" or \"postorder\"
                                      • itemOrder (optional): item iteration order can be \"forward\" or \"backward\"
                                      • uniqueness (optional): specifies uniqueness for vertices and edges visited if set, must be an object like this: \"uniqueness\": {\"vertices\": \"none\"|\"global\"|path\", \"edges\": \"none\"|\"global\"|\"path\"}
                                      • maxIterations (optional): Maximum number of iterations in each traversal. This number can be set to prevent endless loops in traversal of cyclic graphs. When a traversal performs as many iterations as the maxIterations value, the traversal will abort with an error. If maxIterations is not set, a server-defined value may be used.
                                      If the Traversal is successfully executed HTTP 200 will be returned. Additionally the result object will be returned by the traversal.

                                      For successful traversals, the returned JSON object has the following properties:

                                      • error: boolean flag to indicate if an error occurred (false in this case)
                                      • code: the HTTP status code
                                      • result: the return value of the traversal
                                      If the traversal specification is either missing or malformed, the server will respond with HTTP 400.

                                      The body of the response will then contain a JSON object with additional error details. The object has the following attributes:

                                      • error: boolean flag to indicate that an error occurred (true in this case)
                                      • code: the HTTP status code
                                      • errorNum: the server error number
                                      • errorMessage: a descriptive error message", "summary": "executes a traversal", "httpMethod": "POST", - "examples": "

                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1197866152\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1198062760\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1198324904\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1198521512\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1197866152\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1198980264\", \n              \"_key\" : \"1198980264\", \n              \"_rev\" : \"1198980264\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1197866152\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1198062760\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1198980264\", \n              \"_key\" : \"1198980264\", \n              \"_rev\" : \"1198980264\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1199176872\", \n              \"_key\" : \"1199176872\", \n              \"_rev\" : \"1199176872\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1197866152\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1198062760\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1198324904\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1198980264\", \n              \"_key\" : \"1198980264\", \n              \"_rev\" : \"1198980264\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1199373480\", \n              \"_key\" : \"1199373480\", \n              \"_rev\" : \"1199373480\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1197866152\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1198062760\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1198521512\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow only inbound edges:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"inbound\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1202322600\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1203174568\", \n          \"name\" : \"Eve\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1202322600\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1204026536\", \n              \"_key\" : \"1204026536\", \n              \"_rev\" : \"1204026536\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1202322600\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1203174568\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow any direction of edges:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"global\"}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1206516904\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1207368872\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1206713512\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1206516904\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1206975656\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1207172264\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1208220840\", \n              \"_key\" : \"1208220840\", \n              \"_rev\" : \"1208220840\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1207368872\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1208220840\", \n              \"_key\" : \"1208220840\", \n              \"_rev\" : \"1208220840\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1208417448\", \n              \"_key\" : \"1208417448\", \n              \"_rev\" : \"1208417448\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1207368872\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1206713512\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1208220840\", \n              \"_key\" : \"1208220840\", \n              \"_rev\" : \"1208220840\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1208417448\", \n              \"_key\" : \"1208417448\", \n              \"_rev\" : \"1208417448\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1207631016\", \n              \"_key\" : \"1207631016\", \n              \"_rev\" : \"1207631016\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1207368872\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1206713512\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1208220840\", \n              \"_key\" : \"1208220840\", \n              \"_rev\" : \"1208220840\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1208417448\", \n              \"_key\" : \"1208417448\", \n              \"_rev\" : \"1208417448\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1207827624\", \n              \"_key\" : \"1207827624\", \n              \"_rev\" : \"1207827624\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1207368872\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1206713512\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1206975656\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1208220840\", \n              \"_key\" : \"1208220840\", \n              \"_rev\" : \"1208220840\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1208417448\", \n              \"_key\" : \"1208417448\", \n              \"_rev\" : \"1208417448\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1208024232\", \n              \"_key\" : \"1208024232\", \n              \"_rev\" : \"1208024232\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1206516904\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1207368872\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1206713512\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1207172264\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Excluding Charlie and Bob:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"filter\" : \"if (vertex.name === \\\"Bob\\\" || vertex.name === \\\"Charlie\\\") {return \\\"exclude\\\";}return;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1211694248\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1212349608\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1211694248\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1212808360\", \n              \"_key\" : \"1212808360\", \n              \"_rev\" : \"1212808360\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1213201576\", \n              \"_key\" : \"1213201576\", \n              \"_rev\" : \"1213201576\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1211694248\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1211890856\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1212349608\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Do not follow edges from Bob:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"filter\" : \"if (vertex.name === \\\"Bob\\\") {return \\\"prune\\\";}return;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1216150696\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1216347304\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1216150696\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1217264808\", \n              \"_key\" : \"1217264808\", \n              \"_rev\" : \"1217264808\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1216150696\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1216347304\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Visit only nodes in a depth of at least 2:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"minDepth\" : 2}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1220934824\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1221131432\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1221590184\", \n              \"_key\" : \"1221590184\", \n              \"_rev\" : \"1221590184\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1221786792\", \n              \"_key\" : \"1221786792\", \n              \"_rev\" : \"1221786792\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1220476072\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1220672680\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1220934824\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1221590184\", \n              \"_key\" : \"1221590184\", \n              \"_rev\" : \"1221590184\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1221983400\", \n              \"_key\" : \"1221983400\", \n              \"_rev\" : \"1221983400\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1220476072\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1220672680\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1221131432\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Visit only nodes in a depth of at most 1:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"maxDepth\" : 1}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1224932520\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1225129128\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1224932520\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1226046632\", \n              \"_key\" : \"1226046632\", \n              \"_rev\" : \"1226046632\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1224932520\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1225129128\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Count all visited nodes and return a list of nodes only:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"init\" : \"result.visited = 0; result.myVertices = [ ];\", \"visitor\" : \"result.visited++; result.myVertices.push(vertex);\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : 4, \n    \"myVertices\" : [ \n      { \n        \"_id\" : \"persons/alice\", \n        \"_key\" : \"alice\", \n        \"_rev\" : \"1229061288\", \n        \"name\" : \"Alice\" \n      }, \n      { \n        \"_id\" : \"persons/bob\", \n        \"_key\" : \"bob\", \n        \"_rev\" : \"1229257896\", \n        \"name\" : \"Bob\" \n      }, \n      { \n        \"_id\" : \"persons/charlie\", \n        \"_key\" : \"charlie\", \n        \"_rev\" : \"1229520040\", \n        \"name\" : \"Charlie\" \n      }, \n      { \n        \"_id\" : \"persons/dave\", \n        \"_key\" : \"dave\", \n        \"_rev\" : \"1229716648\", \n        \"name\" : \"Dave\" \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Expand only inbound edges of Alice and outbound edges of Eve:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"expander\":\"var connections = [ ];if (vertex.name === \\\"Alice\\\") {config.datasource.getInEdges(vertex).forEach(function (e) {connections.push({ vertex: require(\\\"internal\\\").db._document(e._from), edge: e});});}if (vertex.name === \\\"Eve\\\") {config.datasource.getOutEdges(vertex).forEach(function (e) {connections.push({vertex: require(\\\"internal\\\").db._document(e._to), edge: e});});}return connections;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1233517736\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1234369704\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1233714344\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1233517736\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1235221672\", \n              \"_key\" : \"1235221672\", \n              \"_rev\" : \"1235221672\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1233517736\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1234369704\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1235221672\", \n              \"_key\" : \"1235221672\", \n              \"_rev\" : \"1235221672\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1235418280\", \n              \"_key\" : \"1235418280\", \n              \"_rev\" : \"1235418280\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1233517736\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1234369704\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1233714344\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow the depthfirst strategy:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"strategy\":\"depthfirst\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1237843112\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1238695080\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1238039720\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1237843112\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1238301864\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1238498472\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1238039720\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1238695080\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1237843112\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1238301864\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1238498472\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239153832\", \n              \"_key\" : \"1239153832\", \n              \"_rev\" : \"1239153832\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1238301864\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239350440\", \n              \"_key\" : \"1239350440\", \n              \"_rev\" : \"1239350440\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1238498472\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239743656\", \n              \"_key\" : \"1239743656\", \n              \"_rev\" : \"1239743656\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239547048\", \n              \"_key\" : \"1239547048\", \n              \"_rev\" : \"1239547048\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1238695080\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239153832\", \n              \"_key\" : \"1239153832\", \n              \"_rev\" : \"1239153832\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1238301864\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1238957224\", \n              \"_key\" : \"1238957224\", \n              \"_rev\" : \"1238957224\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1239350440\", \n              \"_key\" : \"1239350440\", \n              \"_rev\" : \"1239350440\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1237843112\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1238039720\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1238498472\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Using postorder ordering:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"order\":\"postorder\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1244003496\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1244462248\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1244658856\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1244200104\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1244855464\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1244003496\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1244855464\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1244462248\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1244658856\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1244200104\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1244003496\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245314216\", \n              \"_key\" : \"1245314216\", \n              \"_rev\" : \"1245314216\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1244462248\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245510824\", \n              \"_key\" : \"1245510824\", \n              \"_rev\" : \"1245510824\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1244658856\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245707432\", \n              \"_key\" : \"1245707432\", \n              \"_rev\" : \"1245707432\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245904040\", \n              \"_key\" : \"1245904040\", \n              \"_rev\" : \"1245904040\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1244855464\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245314216\", \n              \"_key\" : \"1245314216\", \n              \"_rev\" : \"1245314216\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1244462248\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1245510824\", \n              \"_key\" : \"1245510824\", \n              \"_rev\" : \"1245510824\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1244658856\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1245117608\", \n              \"_key\" : \"1245117608\", \n              \"_rev\" : \"1245117608\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1244200104\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1244003496\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Using backward item-ordering:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"itemOrder\":\"backward\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1250163880\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1250360488\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1250819240\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1250622632\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1251015848\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1250163880\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1251015848\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1250360488\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1250819240\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1250622632\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1250163880\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251671208\", \n              \"_key\" : \"1251671208\", \n              \"_rev\" : \"1251671208\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1250819240\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251474600\", \n              \"_key\" : \"1251474600\", \n              \"_rev\" : \"1251474600\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1250622632\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251671208\", \n              \"_key\" : \"1251671208\", \n              \"_rev\" : \"1251671208\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1250819240\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251474600\", \n              \"_key\" : \"1251474600\", \n              \"_rev\" : \"1251474600\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1250622632\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1251867816\", \n              \"_key\" : \"1251867816\", \n              \"_rev\" : \"1251867816\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1252064424\", \n              \"_key\" : \"1252064424\", \n              \"_rev\" : \"1252064424\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1251277992\", \n              \"_key\" : \"1251277992\", \n              \"_rev\" : \"1251277992\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1251015848\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1250360488\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1250163880\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Edges should only be included once globally, but nodes are included every time they are visited:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"global\"}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1256324264\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1257176232\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1256520872\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1256324264\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1256783016\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1256979624\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258028200\", \n              \"_key\" : \"1258028200\", \n              \"_rev\" : \"1258028200\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1257176232\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258028200\", \n              \"_key\" : \"1258028200\", \n              \"_rev\" : \"1258028200\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1258224808\", \n              \"_key\" : \"1258224808\", \n              \"_rev\" : \"1258224808\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1257176232\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1256520872\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258028200\", \n              \"_key\" : \"1258028200\", \n              \"_rev\" : \"1258028200\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1258224808\", \n              \"_key\" : \"1258224808\", \n              \"_rev\" : \"1258224808\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1257438376\", \n              \"_key\" : \"1257438376\", \n              \"_rev\" : \"1257438376\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1257176232\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1256520872\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258028200\", \n              \"_key\" : \"1258028200\", \n              \"_rev\" : \"1258028200\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1258224808\", \n              \"_key\" : \"1258224808\", \n              \"_rev\" : \"1258224808\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1257634984\", \n              \"_key\" : \"1257634984\", \n              \"_rev\" : \"1257634984\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1257176232\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1256520872\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1256783016\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258028200\", \n              \"_key\" : \"1258028200\", \n              \"_rev\" : \"1258028200\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1258224808\", \n              \"_key\" : \"1258224808\", \n              \"_rev\" : \"1258224808\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1257831592\", \n              \"_key\" : \"1257831592\", \n              \"_rev\" : \"1257831592\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1256324264\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1257176232\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1256520872\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1256979624\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        If the underlying graph is cyclic, maxIterations should be set:

                                        The underlying graph has two vertices Alice and Bob. With the directed edges:
                                        • Alice knows Bob
                                        _ Bob knows Alice





                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"none\"},\"maxIterations\":5}\n\nHTTP/1.1 500 Internal Error\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 500, \n  \"errorNum\" : 1909, \n  \"errorMessage\" : \"too many iterations\" \n}\n





                                        ", + "examples": "

                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1257541065\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1257737673\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1257999817\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1258196425\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1257541065\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258655177\", \n              \"_key\" : \"1258655177\", \n              \"_rev\" : \"1258655177\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1257541065\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1257737673\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258655177\", \n              \"_key\" : \"1258655177\", \n              \"_rev\" : \"1258655177\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1258851785\", \n              \"_key\" : \"1258851785\", \n              \"_rev\" : \"1258851785\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1257541065\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1257737673\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1257999817\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1258655177\", \n              \"_key\" : \"1258655177\", \n              \"_rev\" : \"1258655177\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1259048393\", \n              \"_key\" : \"1259048393\", \n              \"_rev\" : \"1259048393\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1257541065\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1257737673\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1258196425\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow only inbound edges:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"inbound\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1261997513\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1262849481\", \n          \"name\" : \"Eve\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1261997513\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1263701449\", \n              \"_key\" : \"1263701449\", \n              \"_rev\" : \"1263701449\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1261997513\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1262849481\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow any direction of edges:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"global\"}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1266388425\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1267240393\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1266585033\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1266388425\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1266847177\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1267043785\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1268092361\", \n              \"_key\" : \"1268092361\", \n              \"_rev\" : \"1268092361\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1267240393\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1268092361\", \n              \"_key\" : \"1268092361\", \n              \"_rev\" : \"1268092361\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1268288969\", \n              \"_key\" : \"1268288969\", \n              \"_rev\" : \"1268288969\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1267240393\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1266585033\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1268092361\", \n              \"_key\" : \"1268092361\", \n              \"_rev\" : \"1268092361\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1268288969\", \n              \"_key\" : \"1268288969\", \n              \"_rev\" : \"1268288969\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1267502537\", \n              \"_key\" : \"1267502537\", \n              \"_rev\" : \"1267502537\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1267240393\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1266585033\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1268092361\", \n              \"_key\" : \"1268092361\", \n              \"_rev\" : \"1268092361\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1268288969\", \n              \"_key\" : \"1268288969\", \n              \"_rev\" : \"1268288969\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1267699145\", \n              \"_key\" : \"1267699145\", \n              \"_rev\" : \"1267699145\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1267240393\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1266585033\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1266847177\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1268092361\", \n              \"_key\" : \"1268092361\", \n              \"_rev\" : \"1268092361\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1268288969\", \n              \"_key\" : \"1268288969\", \n              \"_rev\" : \"1268288969\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1267895753\", \n              \"_key\" : \"1267895753\", \n              \"_rev\" : \"1267895753\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1266388425\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1267240393\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1266585033\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1267043785\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Excluding Charlie and Bob:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"filter\" : \"if (vertex.name === \\\"Bob\\\" || vertex.name === \\\"Charlie\\\") {return \\\"exclude\\\";}return;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1271565769\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1272221129\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1271565769\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1272679881\", \n              \"_key\" : \"1272679881\", \n              \"_rev\" : \"1272679881\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1273073097\", \n              \"_key\" : \"1273073097\", \n              \"_rev\" : \"1273073097\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1271565769\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1271762377\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1272221129\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Do not follow edges from Bob:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"filter\" : \"if (vertex.name === \\\"Bob\\\") {return \\\"prune\\\";}return;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1276022217\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1276218825\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1276022217\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1277136329\", \n              \"_key\" : \"1277136329\", \n              \"_rev\" : \"1277136329\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1276022217\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1276218825\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Visit only nodes in a depth of at least 2:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"minDepth\" : 2}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1280806345\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1281002953\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1281461705\", \n              \"_key\" : \"1281461705\", \n              \"_rev\" : \"1281461705\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1281658313\", \n              \"_key\" : \"1281658313\", \n              \"_rev\" : \"1281658313\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1280347593\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1280544201\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1280806345\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1281461705\", \n              \"_key\" : \"1281461705\", \n              \"_rev\" : \"1281461705\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1281854921\", \n              \"_key\" : \"1281854921\", \n              \"_rev\" : \"1281854921\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1280347593\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1280544201\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1281002953\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Visit only nodes in a depth of at most 1:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"maxDepth\" : 1}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1284804041\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1285000649\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1284804041\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1285918153\", \n              \"_key\" : \"1285918153\", \n              \"_rev\" : \"1285918153\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1284804041\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1285000649\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Count all visited nodes and return a list of nodes only:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{ \"startVertex\": \"persons/alice\", \"graphName\" : \"knows_graph\", \"direction\" : \"outbound\", \"init\" : \"result.visited = 0; result.myVertices = [ ];\", \"visitor\" : \"result.visited++; result.myVertices.push(vertex);\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : 4, \n    \"myVertices\" : [ \n      { \n        \"_id\" : \"persons/alice\", \n        \"_key\" : \"alice\", \n        \"_rev\" : \"1288932809\", \n        \"name\" : \"Alice\" \n      }, \n      { \n        \"_id\" : \"persons/bob\", \n        \"_key\" : \"bob\", \n        \"_rev\" : \"1289129417\", \n        \"name\" : \"Bob\" \n      }, \n      { \n        \"_id\" : \"persons/charlie\", \n        \"_key\" : \"charlie\", \n        \"_rev\" : \"1289391561\", \n        \"name\" : \"Charlie\" \n      }, \n      { \n        \"_id\" : \"persons/dave\", \n        \"_key\" : \"dave\", \n        \"_rev\" : \"1289588169\", \n        \"name\" : \"Dave\" \n      } \n    ] \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Expand only inbound edges of Alice and outbound edges of Eve:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"expander\":\"var connections = [ ];if (vertex.name === \\\"Alice\\\") {config.datasource.getInEdges(vertex).forEach(function (e) {connections.push({ vertex: require(\\\"internal\\\").db._document(e._from), edge: e});});}if (vertex.name === \\\"Eve\\\") {config.datasource.getOutEdges(vertex).forEach(function (e) {connections.push({vertex: require(\\\"internal\\\").db._document(e._to), edge: e});});}return connections;\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1293389257\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1294241225\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1293585865\", \n          \"name\" : \"Bob\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1293389257\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1295093193\", \n              \"_key\" : \"1295093193\", \n              \"_rev\" : \"1295093193\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1293389257\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1294241225\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1295093193\", \n              \"_key\" : \"1295093193\", \n              \"_rev\" : \"1295093193\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1295289801\", \n              \"_key\" : \"1295289801\", \n              \"_rev\" : \"1295289801\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1293389257\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1294241225\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1293585865\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Follow the depthfirst strategy:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"strategy\":\"depthfirst\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1297714633\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1298566601\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1297911241\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1297714633\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1298173385\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1298369993\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1297911241\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1298566601\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1297714633\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1298173385\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1298369993\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299025353\", \n              \"_key\" : \"1299025353\", \n              \"_rev\" : \"1299025353\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1298173385\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299221961\", \n              \"_key\" : \"1299221961\", \n              \"_rev\" : \"1299221961\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1298369993\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299615177\", \n              \"_key\" : \"1299615177\", \n              \"_rev\" : \"1299615177\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299418569\", \n              \"_key\" : \"1299418569\", \n              \"_rev\" : \"1299418569\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1298566601\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299025353\", \n              \"_key\" : \"1299025353\", \n              \"_rev\" : \"1299025353\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1298173385\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1298828745\", \n              \"_key\" : \"1298828745\", \n              \"_rev\" : \"1298828745\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1299221961\", \n              \"_key\" : \"1299221961\", \n              \"_rev\" : \"1299221961\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1297714633\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1297911241\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1298369993\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Using postorder ordering:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"order\":\"postorder\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1304071625\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1304530377\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1304726985\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1304268233\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1304923593\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1304071625\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1304923593\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1304530377\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1304726985\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1304268233\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1304071625\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305382345\", \n              \"_key\" : \"1305382345\", \n              \"_rev\" : \"1305382345\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1304530377\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305578953\", \n              \"_key\" : \"1305578953\", \n              \"_rev\" : \"1305578953\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1304726985\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305775561\", \n              \"_key\" : \"1305775561\", \n              \"_rev\" : \"1305775561\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305972169\", \n              \"_key\" : \"1305972169\", \n              \"_rev\" : \"1305972169\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1304923593\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305382345\", \n              \"_key\" : \"1305382345\", \n              \"_rev\" : \"1305382345\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1304530377\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1305578953\", \n              \"_key\" : \"1305578953\", \n              \"_rev\" : \"1305578953\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1304726985\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1305185737\", \n              \"_key\" : \"1305185737\", \n              \"_rev\" : \"1305185737\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1304268233\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1304071625\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Using backward item-ordering:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"itemOrder\":\"backward\"}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1310232009\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1310428617\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1310887369\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1310690761\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1311083977\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1310232009\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1311083977\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1310428617\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1310887369\", \n          \"name\" : \"Dave\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1310690761\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1310232009\", \n          \"name\" : \"Alice\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311739337\", \n              \"_key\" : \"1311739337\", \n              \"_rev\" : \"1311739337\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1310887369\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311542729\", \n              \"_key\" : \"1311542729\", \n              \"_rev\" : \"1311542729\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1310690761\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311739337\", \n              \"_key\" : \"1311739337\", \n              \"_rev\" : \"1311739337\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1310887369\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311542729\", \n              \"_key\" : \"1311542729\", \n              \"_rev\" : \"1311542729\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1310690761\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1311935945\", \n              \"_key\" : \"1311935945\", \n              \"_rev\" : \"1311935945\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1312132553\", \n              \"_key\" : \"1312132553\", \n              \"_rev\" : \"1312132553\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1311346121\", \n              \"_key\" : \"1311346121\", \n              \"_rev\" : \"1311346121\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1311083977\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1310428617\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1310232009\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        Edges should only be included once globally, but nodes are included every time they are visited:



                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"global\"}}\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"result\" : { \n    \"visited\" : { \n      \"vertices\" : [ \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1316589001\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/eve\", \n          \"_key\" : \"eve\", \n          \"_rev\" : \"1317440969\", \n          \"name\" : \"Eve\" \n        }, \n        { \n          \"_id\" : \"persons/bob\", \n          \"_key\" : \"bob\", \n          \"_rev\" : \"1316785609\", \n          \"name\" : \"Bob\" \n        }, \n        { \n          \"_id\" : \"persons/alice\", \n          \"_key\" : \"alice\", \n          \"_rev\" : \"1316589001\", \n          \"name\" : \"Alice\" \n        }, \n        { \n          \"_id\" : \"persons/charlie\", \n          \"_key\" : \"charlie\", \n          \"_rev\" : \"1317047753\", \n          \"name\" : \"Charlie\" \n        }, \n        { \n          \"_id\" : \"persons/dave\", \n          \"_key\" : \"dave\", \n          \"_rev\" : \"1317244361\", \n          \"name\" : \"Dave\" \n        } \n      ], \n      \"paths\" : [ \n        { \n          \"edges\" : [ ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1318292937\", \n              \"_key\" : \"1318292937\", \n              \"_rev\" : \"1318292937\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1317440969\", \n              \"name\" : \"Eve\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1318292937\", \n              \"_key\" : \"1318292937\", \n              \"_rev\" : \"1318292937\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1318489545\", \n              \"_key\" : \"1318489545\", \n              \"_rev\" : \"1318489545\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1317440969\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1316785609\", \n              \"name\" : \"Bob\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1318292937\", \n              \"_key\" : \"1318292937\", \n              \"_rev\" : \"1318292937\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1318489545\", \n              \"_key\" : \"1318489545\", \n              \"_rev\" : \"1318489545\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1317703113\", \n              \"_key\" : \"1317703113\", \n              \"_rev\" : \"1317703113\", \n              \"_from\" : \"persons/alice\", \n              \"_to\" : \"persons/bob\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1317440969\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1316785609\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1318292937\", \n              \"_key\" : \"1318292937\", \n              \"_rev\" : \"1318292937\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1318489545\", \n              \"_key\" : \"1318489545\", \n              \"_rev\" : \"1318489545\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1317899721\", \n              \"_key\" : \"1317899721\", \n              \"_rev\" : \"1317899721\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/charlie\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1317440969\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1316785609\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/charlie\", \n              \"_key\" : \"charlie\", \n              \"_rev\" : \"1317047753\", \n              \"name\" : \"Charlie\" \n            } \n          ] \n        }, \n        { \n          \"edges\" : [ \n            { \n              \"_id\" : \"knows/1318292937\", \n              \"_key\" : \"1318292937\", \n              \"_rev\" : \"1318292937\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/alice\" \n            }, \n            { \n              \"_id\" : \"knows/1318489545\", \n              \"_key\" : \"1318489545\", \n              \"_rev\" : \"1318489545\", \n              \"_from\" : \"persons/eve\", \n              \"_to\" : \"persons/bob\" \n            }, \n            { \n              \"_id\" : \"knows/1318096329\", \n              \"_key\" : \"1318096329\", \n              \"_rev\" : \"1318096329\", \n              \"_from\" : \"persons/bob\", \n              \"_to\" : \"persons/dave\" \n            } \n          ], \n          \"vertices\" : [ \n            { \n              \"_id\" : \"persons/alice\", \n              \"_key\" : \"alice\", \n              \"_rev\" : \"1316589001\", \n              \"name\" : \"Alice\" \n            }, \n            { \n              \"_id\" : \"persons/eve\", \n              \"_key\" : \"eve\", \n              \"_rev\" : \"1317440969\", \n              \"name\" : \"Eve\" \n            }, \n            { \n              \"_id\" : \"persons/bob\", \n              \"_key\" : \"bob\", \n              \"_rev\" : \"1316785609\", \n              \"name\" : \"Bob\" \n            }, \n            { \n              \"_id\" : \"persons/dave\", \n              \"_key\" : \"dave\", \n              \"_rev\" : \"1317244361\", \n              \"name\" : \"Dave\" \n            } \n          ] \n        } \n      ] \n    } \n  }, \n  \"error\" : false, \n  \"code\" : 200 \n}\n



                                        If the underlying graph is cyclic, maxIterations should be set:

                                        The underlying graph has two vertices Alice and Bob. With the directed edges:
                                        • Alice knows Bob
                                        _ Bob knows Alice





                                        shell> curl -X POST --data-binary @- --dump - http://localhost:8529/_api/traversal\n{\"startVertex\":\"persons/alice\",\"graphName\":\"knows_graph\",\"direction\":\"any\",\"uniqueness\":{\"vertices\":\"none\",\"edges\":\"none\"},\"maxIterations\":5}\n\nHTTP/1.1 500 Internal Error\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"error\" : true, \n  \"code\" : 500, \n  \"errorNum\" : 1909, \n  \"errorMessage\" : \"too many iterations\" \n}\n





                                        ", "nickname": "executesATraversal" } ], diff --git a/js/apps/system/aardvark/api-docs/version.json b/js/apps/system/aardvark/api-docs/version.json index cf5ca535ac..b36b24c7ec 100644 --- a/js/apps/system/aardvark/api-docs/version.json +++ b/js/apps/system/aardvark/api-docs/version.json @@ -24,7 +24,7 @@ "notes": "Returns the server name and version number. The response is a JSON object with the following attributes:

                                        • server: will always contain arango
                                        • version: the server version string. The string has the format \"major.*minor.*sub\". major and minor will be numeric, and sub may contain a number or a textual version.
                                        • details: an optional JSON object with additional details. This is returned only if the details URL parameter is set to true in the request.", "summary": " Return server version", "httpMethod": "GET", - "examples": "

                                          Returns the version information.



                                          shell> curl --data-binary @- --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.3.0-devel\" \n}\n



                                          Returns the version information with details.



                                          shell> curl --data-binary @- --dump - http://localhost:8529/_api/version?details=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.3.0-devel\", \n  \"details\" : { \n    \"build-date\" : \"2014-10-02 15:22:34\", \n    \"configure\" : \"'./configure' '--enable-all-in-one-icu' '--enable-maintainer-mode' '--enable-relative'\", \n    \"icu-version\" : \"49.1.2\", \n    \"libev-version\" : \"4.11\", \n    \"openssl-version\" : \"OpenSSL 0.9.8za 5 Jun 2014\", \n    \"repository-version\" : \"heads/devel-0-g5e7bbf3470e18b0391f8f3da42c7afa5fac91e20-dirty\", \n    \"server-version\" : \"2.3.0-devel\", \n    \"sizeof int\" : \"4\", \n    \"sizeof void*\" : \"8\", \n    \"v8-version\" : \"3.16.14\" \n  } \n}\n



                                          ", + "examples": "

                                          Returns the version information.



                                          shell> curl --data-binary @- --dump - http://localhost:8529/_api/version\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.3.0-beta2\" \n}\n



                                          Returns the version information with details.



                                          shell> curl --data-binary @- --dump - http://localhost:8529/_api/version?details=true\n\nHTTP/1.1 200 OK\ncontent-type: application/json; charset=utf-8\n\n{ \n  \"server\" : \"arango\", \n  \"version\" : \"2.3.0-beta2\", \n  \"details\" : { \n    \"architecture\" : \"64bit\", \n    \"build-date\" : \"2014-11-07 19:20:48\", \n    \"configure\" : \"'./configure' '--enable-all-in-one-v8' '--enable-all-in-one-libev' '--enable-all-in-one-icu' '--enable-maintainer-mode' '--disable-mruby'\", \n    \"icu-version\" : \"52.1\", \n    \"libev-version\" : \"4.11\", \n    \"maintainer-mode\" : \"true\", \n    \"openssl-version\" : \"OpenSSL 0.9.8za 5 Jun 2014\", \n    \"repository-version\" : \"heads/2.3-0-g39cc250436a6279e0aa28079b33fed95994cf9ff-dirty\", \n    \"server-version\" : \"2.3.0-beta2\", \n    \"sizeof int\" : \"4\", \n    \"sizeof void*\" : \"8\", \n    \"v8-version\" : \"3.16.14\" \n  } \n}\n



                                          ", "nickname": "ReturnServerVersion" } ], diff --git a/js/apps/system/aardvark/frontend/js/bootstrap/errors.js b/js/apps/system/aardvark/frontend/js/bootstrap/errors.js index 97962f6fa9..1a95092f2a 100644 --- a/js/apps/system/aardvark/frontend/js/bootstrap/errors.js +++ b/js/apps/system/aardvark/frontend/js/bootstrap/errors.js @@ -177,6 +177,7 @@ "ERROR_QUERY_COMPILE_TIME_OPTIONS" : { "code" : 1575, "message" : "query options must be readable at query compile time" }, "ERROR_QUERY_EXCEPTION_OPTIONS" : { "code" : 1576, "message" : "query options expected" }, "ERROR_QUERY_COLLECTION_USED_IN_EXPRESSION" : { "code" : 1577, "message" : "collection '%s' used as expression operand" }, + "ERROR_QUERY_DISALLOWED_DYNAMIC_CALL" : { "code" : 1578, "message" : "disallowed dynamic call to '%s'" }, "ERROR_QUERY_FUNCTION_INVALID_NAME" : { "code" : 1580, "message" : "invalid user function name" }, "ERROR_QUERY_FUNCTION_INVALID_CODE" : { "code" : 1581, "message" : "invalid user function code" }, "ERROR_QUERY_FUNCTION_NOT_FOUND" : { "code" : 1582, "message" : "user function '%s()' not found" }, @@ -222,7 +223,7 @@ "ERROR_GRAPH_COLLECTION_MULTI_USE" : { "code" : 1920, "message" : "multi use of edge collection in edge def" }, "ERROR_GRAPH_COLLECTION_USE_IN_MULTI_GRAPHS" : { "code" : 1921, "message" : "edge collection already used in edge def" }, "ERROR_GRAPH_CREATE_MISSING_NAME" : { "code" : 1922, "message" : "missing graph name" }, - "ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION" : { "code" : 1923, "message" : "malformed edge def" }, + "ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION" : { "code" : 1923, "message" : "malformed edge definition" }, "ERROR_GRAPH_NOT_FOUND" : { "code" : 1924, "message" : "graph not found" }, "ERROR_GRAPH_DUPLICATE" : { "code" : 1925, "message" : "graph already exists" }, "ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST" : { "code" : 1926, "message" : "collection does not exist" }, diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/graph/eventLibrary.js b/js/apps/system/aardvark/frontend/js/graphViewer/graph/eventLibrary.js index 70b6fd218c..8a32ef0192 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/graph/eventLibrary.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/graph/eventLibrary.js @@ -55,7 +55,7 @@ function EventLibrary() { this.checkExpandConfig = function(config) { if (config.startCallback === undefined) { - throw "A callback to the Start-method has to be defined"; + throw "A callback to the start-method has to be defined"; } if (config.adapter === undefined || config.adapter.explore === undefined) { throw "An adapter to load data has to be defined"; @@ -99,7 +99,7 @@ function EventLibrary() { throw "An adapter has to be defined"; } if (config.shaper === undefined) { - throw "A Node Shaper has to be defined"; + throw "A node shaper has to be defined"; } return true; }; @@ -109,7 +109,7 @@ function EventLibrary() { throw "An adapter has to be defined"; } if (config.shaper === undefined) { - throw "An Edge Shaper has to be defined"; + throw "An edge Shaper has to be defined"; } return true; }; diff --git a/js/apps/system/aardvark/frontend/js/lib/swagger-ui.js b/js/apps/system/aardvark/frontend/js/lib/swagger-ui.js index 79ab04c66f..348ba74840 100644 --- a/js/apps/system/aardvark/frontend/js/lib/swagger-ui.js +++ b/js/apps/system/aardvark/frontend/js/lib/swagger-ui.js @@ -550,7 +550,10 @@ helpers = helpers || Handlebars.helpers; data = data || {}; if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); } else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } buffer += escapeExpression(stack1) - + "'); return false;\">\n Expand\n \n
                                        • \n
                                        \n\n
                                          \n Expand\n \n \n "; + + buffer += "
                                        • \n Raw \n
                                        • \n "; + buffer += "
                                        \n\n
                                          ) renames a collection ' + "\n" + ' getIndexes() return defined indexes ' + "\n" + diff --git a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/general-graph.js b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/general-graph.js index e8fe1e809a..2a0d84159e 100644 --- a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/general-graph.js +++ b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/general-graph.js @@ -110,6 +110,17 @@ var findOrCreateCollectionsByEdgeDefinitions = function (edgeDefinitions, noCrea var vertexCollections = {}, edgeCollections = {}; edgeDefinitions.forEach(function (e) { + if (! e.hasOwnProperty('collection') || + ! e.hasOwnProperty('from') || + ! e.hasOwnProperty('to') || + ! Array.isArray(e.from) || + ! Array.isArray(e.to)) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION.code; + err.errorMessage = arangodb.errors.ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION.message; + throw err; + } + e.from.concat(e.to).forEach(function (v) { findOrCreateCollectionByName(v, ArangoCollection.TYPE_DOCUMENT, noCreate); vertexCollections[v] = db[v]; @@ -1022,9 +1033,12 @@ AQLGenerator.prototype._getLastRestrictableStatementInfo = function() { //////////////////////////////////////////////////////////////////////////////// AQLGenerator.prototype.restrict = function(restrictions) { + var rest = stringToArray(restrictions); + if (rest.length === 0) { + return this; + } this._addToPrint("restrict", restrictions); this._clearCursor(); - var rest = stringToArray(restrictions); var lastQueryInfo = this._getLastRestrictableStatementInfo(); var lastQuery = lastQueryInfo.statement; var opts = lastQueryInfo.options; @@ -1175,6 +1189,7 @@ AQLGenerator.prototype.execute = function() { AQLGenerator.prototype.toArray = function() { this._createCursor(); + return this.cursor.toArray(); }; @@ -1867,6 +1882,17 @@ var bindEdgeCollections = function(self, edgeCollections) { // save var old_save = wrap.save; wrap.save = function(from, to, data) { + if (typeof from !== 'string' || + from.indexOf('/') === -1 || + typeof to !== 'string' || + to.indexOf('/') === -1) { + // invalid from or to value + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } + //check, if edge is allowed self.__edgeDefinitions.forEach( function(edgeDefinition) { @@ -1889,7 +1915,6 @@ var bindEdgeCollections = function(self, edgeCollections) { // remove wrap.remove = function(edgeId, options) { - var result; //if _key make _id (only on 1st call) if (edgeId.indexOf("/") === -1) { edgeId = key + "/" + edgeId; @@ -1901,6 +1926,7 @@ var bindEdgeCollections = function(self, edgeCollections) { collections: { write: self.__collectionsToLock }, + embed: true, action: function (params) { var db = require("internal").db; params.ids.forEach( @@ -1918,13 +1944,15 @@ var bindEdgeCollections = function(self, edgeCollections) { options: options } }); - result = true; } catch (e) { - result = false; + self.__idsToRemove = []; + self.__collectionsToLock = []; + throw e; } self.__idsToRemove = []; self.__collectionsToLock = []; - return result; + + return true; }; self[key] = wrap; @@ -1934,7 +1962,6 @@ var bindEdgeCollections = function(self, edgeCollections) { var bindVertexCollections = function(self, vertexCollections) { _.each(vertexCollections, function(key) { var obj = db._collection(key); - var result; var wrap = wrapCollection(obj); wrap.remove = function(vertexId, options) { //delete all edges using the vertex in all graphs @@ -1976,6 +2003,7 @@ var bindVertexCollections = function(self, vertexCollections) { collections: { write: self.__collectionsToLock }, + embed: true, action: function (params) { var db = require("internal").db; params.ids.forEach( @@ -1999,14 +2027,15 @@ var bindVertexCollections = function(self, vertexCollections) { vertexId: vertexId } }); - result = true; } catch (e) { - result = false; + self.__idsToRemove = []; + self.__collectionsToLock = []; + throw e; } self.__idsToRemove = []; self.__collectionsToLock = []; - return result; + return true; }; self[key] = wrap; }); @@ -2740,6 +2769,13 @@ Graph.prototype._vertices = function(example) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype._fromVertex = function(edgeId) { + if (typeof edgeId !== 'string' || + edgeId.indexOf('/') === -1) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } var edgeCollection = this._getEdgeCollectionByName(edgeId.split("/")[0]); var document = edgeCollection.document(edgeId); if (document) { @@ -2775,6 +2811,13 @@ Graph.prototype._fromVertex = function(edgeId) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype._toVertex = function(edgeId) { + if (typeof edgeId !== 'string' || + edgeId.indexOf('/') === -1) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } var edgeCollection = this._getEdgeCollectionByName(edgeId.split("/")[0]); var document = edgeCollection.document(edgeId); if (document) { @@ -2813,7 +2856,6 @@ Graph.prototype._getVertexCollectionByName = function(name) { throw err; }; - //////////////////////////////////////////////////////////////////////////////// /// @startDocuBlock JSF_general_graph_neighbors /// @brief Get all neighbors of the vertices defined by the example @@ -2863,6 +2905,7 @@ Graph.prototype._getVertexCollectionByName = function(name) { /// @endDocuBlock // //////////////////////////////////////////////////////////////////////////////// + Graph.prototype._neighbors = function(vertexExample, options) { var AQLStmt = new AQLGenerator(this); // If no direction is specified all edges are duplicated. @@ -4448,6 +4491,98 @@ Graph.prototype._removeVertexCollection = function(vertexCollectionName, dropCol }; +//////////////////////////////////////////////////////////////////////////////// +/// @startDocuBlock JSF_general_graph_connectingEdges +/// @brief Get all connecting edges between 2 groups of vertices defined by the examples +/// +/// `graph._connectingEdges(vertexExample, vertexExample2, options)` +/// +/// The function accepts an id, an example, a list of examples or even an empty +/// example as parameter for vertexExample. +/// +/// @PARAMS +/// +/// @PARAM{vertexExample1, object, optional} +/// See [Definition of examples](#definition_of_examples) +/// @PARAM{vertexExample2, object, optional} +/// See [Definition of examples](#definition_of_examples) +/// @PARAM{options, object, optional} +/// An object defining further options. Can have the following values: +/// * *edgeExamples*: Filter the edges, see [Definition of examples](#definition_of_examples) +/// * *edgeCollectionRestriction* : One or a list of edge-collection names that should be +/// considered to be on the path. +/// * *vertex1CollectionRestriction* : One or a list of vertex-collection names that should be +/// considered on the intermediate vertex steps. +/// * *vertex2CollectionRestriction* : One or a list of vertex-collection names that should be +/// considered on the intermediate vertex steps. +/// +/// @EXAMPLES +/// +/// A route planner example, all neighbors of capitals. +/// +/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphModuleNeighbors1} +/// var examples = require("org/arangodb/graph-examples/example-graph.js"); +/// var graph = examples.loadGraph("routeplanner"); +/// graph._neighbors({isCapital : true}); +/// @END_EXAMPLE_ARANGOSH_OUTPUT +/// +/// A route planner example, all outbound neighbors of Hamburg. +/// +/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphModuleNeighbors2} +/// var examples = require("org/arangodb/graph-examples/example-graph.js"); +/// var graph = examples.loadGraph("routeplanner"); +/// graph._neighbors('germanCity/Hamburg', {direction : 'outbound', maxDepth : 2}); +/// @END_EXAMPLE_ARANGOSH_OUTPUT +/// +/// @endDocuBlock +// +//////////////////////////////////////////////////////////////////////////////// + +Graph.prototype._getConnectingEdges = function(vertexExample1, vertexExample2, options) { + + if (!options) { + options = {}; + } + + var opts = { + }; + + if (options.vertex1CollectionRestriction) { + opts.startVertexCollectionRestriction = options.vertex1CollectionRestriction; + } + + if (options.vertex2CollectionRestriction) { + opts.endVertexCollectionRestriction = options.vertex2CollectionRestriction; + } + + if (options.edgeCollectionRestriction) { + opts.edgeCollectionRestriction = options.edgeCollectionRestriction; + } + + if (options.edgeExamples) { + opts.edgeExamples = options.edgeExamples; + } + + if (vertexExample2) { + opts.neighborExamples = vertexExample2; + } + + var query = "RETURN" + + " GRAPH_EDGES(@graphName" + + ',@vertexExample' + + ',@options' + + ')'; + options = options || {}; + var bindVars = { + "graphName": this.__name, + "vertexExample": vertexExample1, + "options": opts + }; + var result = db._query(query, bindVars).toArray(); + return result[0]; +}; + + //////////////////////////////////////////////////////////////////////////////// diff --git a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query-common.js b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query-common.js index 56939193e1..9adcda7b6f 100644 --- a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query-common.js +++ b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query-common.js @@ -37,6 +37,7 @@ var ArangoError = arangodb.ArangoError; var SimpleQueryArray; var SimpleQueryNear; var SimpleQueryWithin; +var SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- GENERAL ARRAY CURSOR @@ -990,6 +991,14 @@ SimpleQueryGeo.prototype.within = function (lat, lon, radius) { return new SimpleQueryWithin(this._collection, lat, lon, radius, this._index); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructs a within-rectangle query for an index +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryGeo.prototype.withinRectangle = function (lat1, lon1, lat2, lon2) { + return new SimpleQueryWithinRectangle(this._collection, lat1, lon1, lat2, lon2, this._index); +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY NEAR // ----------------------------------------------------------------------------- @@ -1214,10 +1223,6 @@ SimpleQueryWithin.prototype._PRINT = function (context) { context.output += text; }; -// ----------------------------------------------------------------------------- -// --SECTION-- public methods -// ----------------------------------------------------------------------------- - //////////////////////////////////////////////////////////////////////////////// /// @brief adds the distance attribute //////////////////////////////////////////////////////////////////////////////// @@ -1237,6 +1242,112 @@ SimpleQueryWithin.prototype.distance = function (attribute) { return clone; }; +// ----------------------------------------------------------------------------- +// --SECTION-- SIMPLE QUERY WITHINRECTANGLE +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// --SECTION-- constructors and destructors +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle = function (collection, latitude1, longitude1, latitude2, longitude2, iid) { + var idx; + var i; + + this._collection = collection; + this._latitude1 = latitude1; + this._longitude1 = longitude1; + this._latitude2 = latitude2; + this._longitude2 = longitude2; + this._index = (iid === undefined ? null : iid); + + if (iid === undefined) { + idx = collection.getIndexes(); + + for (i = 0; i < idx.length; ++i) { + var index = idx[i]; + + if (index.type === "geo1" || index.type === "geo2") { + if (this._index === null) { + this._index = index.id; + } + else if (index.id < this._index) { + this._index = index.id; + } + } + } + } + + if (this._index === null) { + var err = new ArangoError(); + err.errorNum = arangodb.ERROR_QUERY_GEO_INDEX_MISSING; + err.errorMessage = arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message; + throw err; + } +}; + +SimpleQueryWithinRectangle.prototype = new SimpleQuery(); +SimpleQueryWithinRectangle.prototype.constructor = SimpleQueryWithinRectangle; + +// ----------------------------------------------------------------------------- +// --SECTION-- private methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief clones a within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype.clone = function () { + var query; + + query = new SimpleQueryWithinRectangle(this._collection, + this._latitude1, + this._longitude1, + this._latitude2, + this._longitude2, + this._index); + query._skip = this._skip; + query._limit = this._limit; + + return query; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints a within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype._PRINT = function (context) { + var text; + + text = "SimpleQueryWithinRectangle(" + + this._collection.name() + + ", " + + this._latitude1 + + ", " + + this._longitude1 + + ", " + + this._latitude1 + + ", " + + this._longitude2 + + ", " + + this._index + + ")"; + + if (this._skip !== null && this._skip !== 0) { + text += ".skip(" + this._skip + ")"; + } + + if (this._limit !== null) { + text += ".limit(" + this._limit + ")"; + } + + context.output += text; +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY FULLTEXT // ----------------------------------------------------------------------------- @@ -1342,6 +1453,7 @@ exports.SimpleQueryRange = SimpleQueryRange; exports.SimpleQueryGeo = SimpleQueryGeo; exports.SimpleQueryNear = SimpleQueryNear; exports.SimpleQueryWithin = SimpleQueryWithin; +exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle; exports.SimpleQueryFulltext = SimpleQueryFulltext; // ----------------------------------------------------------------------------- diff --git a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query.js b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query.js index 2b947793fa..90126d9758 100644 --- a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query.js +++ b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/simple-query.js @@ -45,6 +45,7 @@ var SimpleQueryGeo = sq.SimpleQueryGeo; var SimpleQueryNear = sq.SimpleQueryNear; var SimpleQueryRange = sq.SimpleQueryRange; var SimpleQueryWithin = sq.SimpleQueryWithin; +var SimpleQueryWithinRectangle = sq.SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY ALL @@ -382,6 +383,65 @@ SimpleQueryWithin.prototype.execute = function (batchSize) { } }; +// ----------------------------------------------------------------------------- +// --SECTION-- SIMPLE QUERY WITHINRECTANGLE +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes a withinRectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype.execute = function (batchSize) { + if (this._execution === null) { + if (batchSize !== undefined && batchSize > 0) { + this._batchSize = batchSize; + } + + var data = { + collection: this._collection.name(), + latitude1: this._latitude1, + longitude1: this._longitude1, + latitude2: this._latitude2, + longitude2: this._longitude2 + }; + + if (this._limit !== null) { + data.limit = this._limit; + } + + if (this._skip !== null) { + data.skip = this._skip; + } + + if (this._index !== null) { + data.geo = this._index; + } + + if (this._distance !== null) { + data.distance = this._distance; + } + + if (this._batchSize !== null) { + data.batchSize = this._batchSize; + } + + var requestResult = this._collection._database._connection.PUT( + "/_api/simple/within-rectangle", JSON.stringify(data)); + + arangosh.checkRequestResult(requestResult); + + this._execution = new ArangoQueryCursor(this._collection._database, requestResult); + + if (requestResult.hasOwnProperty("count")) { + this._countQuery = requestResult.count; + } + } +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY FULLTEXT // ----------------------------------------------------------------------------- @@ -449,6 +509,7 @@ exports.SimpleQueryGeo = SimpleQueryGeo; exports.SimpleQueryNear = SimpleQueryNear; exports.SimpleQueryRange = SimpleQueryRange; exports.SimpleQueryWithin = SimpleQueryWithin; +exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE diff --git a/js/apps/system/aardvark/frontend/js/views/graphManagementView.js b/js/apps/system/aardvark/frontend/js/views/graphManagementView.js index e7005cd802..21d33192fc 100644 --- a/js/apps/system/aardvark/frontend/js/views/graphManagementView.js +++ b/js/apps/system/aardvark/frontend/js/views/graphManagementView.js @@ -430,7 +430,18 @@ name = "", edgeDefinitions = [{collection : "", from : "", to :""}], orphanCollections = "", - title; + title, + sorter = function(l, r) { + l = l.toLowerCase(); + r = r.toLowerCase(); + if (l < r) { + return -1; + } + if (l > r) { + return 1; + } + return 0; + }; this.eCollList = []; this.removedECollList = []; @@ -504,13 +515,13 @@ "newEdgeDefinitions" + self.counter, "Edge definitions", edgeDefinition.collection, - "An Edge Definition defines a relations of the graph", + "An edge definition defines a relation of the graph", "Edge definitions", true, false, true, 1, - self.eCollList + self.eCollList.sort(sorter) ) ); } else { @@ -519,13 +530,13 @@ "newEdgeDefinitions" + self.counter, "Edge definitions", edgeDefinition.collection, - "An Edge Definition defines a relations of the graph", + "An edge definition defines a relation of the graph", "Edge definitions", false, true, false, 1, - self.eCollList + self.eCollList.sort(sorter) ) ); } @@ -534,13 +545,13 @@ "fromCollections" + self.counter, "fromCollections", edgeDefinition.from, - "The collection that contain the start vertices of the relation.", + "The collections that contain the start vertices of the relation.", "fromCollections", true, false, false, 10, - collList + collList.sort(sorter) ) ); tableContent.push( @@ -548,13 +559,13 @@ "toCollections" + self.counter, "toCollections", edgeDefinition.to, - "The collection that contain the end vertices of the relation.", + "The collections that contain the end vertices of the relation.", "toCollections", true, false, false, 10, - collList + collList.sort(sorter) ) ); self.counter++; @@ -566,13 +577,13 @@ "newVertexCollections", "Vertex collections", orphanCollections, - "Collections, that are part of a graph, but not used in an edge definition", + "Collections that are part of a graph but not used in an edge definition", "Vertex Collections", false, false, false, 10, - collList + collList.sort(sorter) ) ); diff --git a/js/apps/system/aardvark/frontend/js/views/queryView.js b/js/apps/system/aardvark/frontend/js/views/queryView.js index f53f7e7da7..63a19f8b37 100644 --- a/js/apps/system/aardvark/frontend/js/views/queryView.js +++ b/js/apps/system/aardvark/frontend/js/views/queryView.js @@ -589,7 +589,6 @@ "Query is operating..." ); - $.ajax({ type: "POST", url: "/_api/cursor", @@ -598,7 +597,7 @@ processData: false, success: function (data) { var warnings = ""; - if (data.extra.warnings.length > 0) { + if (data.extra && data.extra.warnings && data.extra.warnings.length > 0) { warnings += "Warnings:" + "\r\n\r\n"; data.extra.warnings.forEach(function(w) { warnings += "[" + w.code + "], '" + w.message + "'\r\n"; diff --git a/js/client/modules/org/arangodb/arango-collection.js b/js/client/modules/org/arangodb/arango-collection.js index c24f69eb92..bcba5e135f 100644 --- a/js/client/modules/org/arangodb/arango-collection.js +++ b/js/client/modules/org/arangodb/arango-collection.js @@ -208,7 +208,7 @@ var helpArangoCollection = arangosh.createHelpHeadline("ArangoCollection help") ' truncate() delete all documents ' + "\n" + ' properties() show collection properties ' + "\n" + ' drop() delete a collection ' + "\n" + - ' load() load a collection into memeory ' + "\n" + + ' load() load a collection into memory ' + "\n" + ' unload() unload a collection from memory ' + "\n" + ' rename() renames a collection ' + "\n" + ' getIndexes() return defined indexes ' + "\n" + diff --git a/js/client/modules/org/arangodb/simple-query.js b/js/client/modules/org/arangodb/simple-query.js index 1de1f04d91..501b8fbd76 100644 --- a/js/client/modules/org/arangodb/simple-query.js +++ b/js/client/modules/org/arangodb/simple-query.js @@ -44,6 +44,7 @@ var SimpleQueryGeo = sq.SimpleQueryGeo; var SimpleQueryNear = sq.SimpleQueryNear; var SimpleQueryRange = sq.SimpleQueryRange; var SimpleQueryWithin = sq.SimpleQueryWithin; +var SimpleQueryWithinRectangle = sq.SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY ALL @@ -381,6 +382,65 @@ SimpleQueryWithin.prototype.execute = function (batchSize) { } }; +// ----------------------------------------------------------------------------- +// --SECTION-- SIMPLE QUERY WITHINRECTANGLE +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes a withinRectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype.execute = function (batchSize) { + if (this._execution === null) { + if (batchSize !== undefined && batchSize > 0) { + this._batchSize = batchSize; + } + + var data = { + collection: this._collection.name(), + latitude1: this._latitude1, + longitude1: this._longitude1, + latitude2: this._latitude2, + longitude2: this._longitude2 + }; + + if (this._limit !== null) { + data.limit = this._limit; + } + + if (this._skip !== null) { + data.skip = this._skip; + } + + if (this._index !== null) { + data.geo = this._index; + } + + if (this._distance !== null) { + data.distance = this._distance; + } + + if (this._batchSize !== null) { + data.batchSize = this._batchSize; + } + + var requestResult = this._collection._database._connection.PUT( + "/_api/simple/within-rectangle", JSON.stringify(data)); + + arangosh.checkRequestResult(requestResult); + + this._execution = new ArangoQueryCursor(this._collection._database, requestResult); + + if (requestResult.hasOwnProperty("count")) { + this._countQuery = requestResult.count; + } + } +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY FULLTEXT // ----------------------------------------------------------------------------- @@ -448,6 +508,7 @@ exports.SimpleQueryGeo = SimpleQueryGeo; exports.SimpleQueryNear = SimpleQueryNear; exports.SimpleQueryRange = SimpleQueryRange; exports.SimpleQueryWithin = SimpleQueryWithin; +exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index 97962f6fa9..1a95092f2a 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -177,6 +177,7 @@ "ERROR_QUERY_COMPILE_TIME_OPTIONS" : { "code" : 1575, "message" : "query options must be readable at query compile time" }, "ERROR_QUERY_EXCEPTION_OPTIONS" : { "code" : 1576, "message" : "query options expected" }, "ERROR_QUERY_COLLECTION_USED_IN_EXPRESSION" : { "code" : 1577, "message" : "collection '%s' used as expression operand" }, + "ERROR_QUERY_DISALLOWED_DYNAMIC_CALL" : { "code" : 1578, "message" : "disallowed dynamic call to '%s'" }, "ERROR_QUERY_FUNCTION_INVALID_NAME" : { "code" : 1580, "message" : "invalid user function name" }, "ERROR_QUERY_FUNCTION_INVALID_CODE" : { "code" : 1581, "message" : "invalid user function code" }, "ERROR_QUERY_FUNCTION_NOT_FOUND" : { "code" : 1582, "message" : "user function '%s()' not found" }, @@ -222,7 +223,7 @@ "ERROR_GRAPH_COLLECTION_MULTI_USE" : { "code" : 1920, "message" : "multi use of edge collection in edge def" }, "ERROR_GRAPH_COLLECTION_USE_IN_MULTI_GRAPHS" : { "code" : 1921, "message" : "edge collection already used in edge def" }, "ERROR_GRAPH_CREATE_MISSING_NAME" : { "code" : 1922, "message" : "missing graph name" }, - "ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION" : { "code" : 1923, "message" : "malformed edge def" }, + "ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION" : { "code" : 1923, "message" : "malformed edge definition" }, "ERROR_GRAPH_NOT_FOUND" : { "code" : 1924, "message" : "graph not found" }, "ERROR_GRAPH_DUPLICATE" : { "code" : 1925, "message" : "graph already exists" }, "ERROR_GRAPH_VERTEX_COL_DOES_NOT_EXIST" : { "code" : 1926, "message" : "collection does not exist" }, diff --git a/js/common/modules/org/arangodb/arango-collection-common.js b/js/common/modules/org/arangodb/arango-collection-common.js index b7493c1d90..8680cc5305 100644 --- a/js/common/modules/org/arangodb/arango-collection-common.js +++ b/js/common/modules/org/arangodb/arango-collection-common.js @@ -45,6 +45,7 @@ var SimpleQueryRange = simple.SimpleQueryRange; var SimpleQueryGeo = simple.SimpleQueryGeo; var SimpleQueryNear = simple.SimpleQueryNear; var SimpleQueryWithin = simple.SimpleQueryWithin; +var SimpleQueryWithinRectangle = simple.SimpleQueryWithinRectangle; var SimpleQueryFulltext = simple.SimpleQueryFulltext; // ----------------------------------------------------------------------------- @@ -739,6 +740,10 @@ ArangoCollection.prototype.within = function (lat, lon, radius) { return new SimpleQueryWithin(this, lat, lon, radius); }; +ArangoCollection.prototype.withinRectangle = function (lat1, lon1, lat2, lon2) { + return new SimpleQueryWithinRectangle(this, lat1, lon1, lat2, lon2); +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief constructs a fulltext query for a collection /// @startDocuBlock collectionFulltext diff --git a/js/common/modules/org/arangodb/general-graph.js b/js/common/modules/org/arangodb/general-graph.js index d0d0769406..84772a206f 100644 --- a/js/common/modules/org/arangodb/general-graph.js +++ b/js/common/modules/org/arangodb/general-graph.js @@ -109,6 +109,17 @@ var findOrCreateCollectionsByEdgeDefinitions = function (edgeDefinitions, noCrea var vertexCollections = {}, edgeCollections = {}; edgeDefinitions.forEach(function (e) { + if (! e.hasOwnProperty('collection') || + ! e.hasOwnProperty('from') || + ! e.hasOwnProperty('to') || + ! Array.isArray(e.from) || + ! Array.isArray(e.to)) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION.code; + err.errorMessage = arangodb.errors.ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION.message; + throw err; + } + e.from.concat(e.to).forEach(function (v) { findOrCreateCollectionByName(v, ArangoCollection.TYPE_DOCUMENT, noCreate); vertexCollections[v] = db[v]; @@ -1021,9 +1032,12 @@ AQLGenerator.prototype._getLastRestrictableStatementInfo = function() { //////////////////////////////////////////////////////////////////////////////// AQLGenerator.prototype.restrict = function(restrictions) { + var rest = stringToArray(restrictions); + if (rest.length === 0) { + return this; + } this._addToPrint("restrict", restrictions); this._clearCursor(); - var rest = stringToArray(restrictions); var lastQueryInfo = this._getLastRestrictableStatementInfo(); var lastQuery = lastQueryInfo.statement; var opts = lastQueryInfo.options; @@ -1174,6 +1188,7 @@ AQLGenerator.prototype.execute = function() { AQLGenerator.prototype.toArray = function() { this._createCursor(); + return this.cursor.toArray(); }; @@ -1866,6 +1881,17 @@ var bindEdgeCollections = function(self, edgeCollections) { // save var old_save = wrap.save; wrap.save = function(from, to, data) { + if (typeof from !== 'string' || + from.indexOf('/') === -1 || + typeof to !== 'string' || + to.indexOf('/') === -1) { + // invalid from or to value + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } + //check, if edge is allowed self.__edgeDefinitions.forEach( function(edgeDefinition) { @@ -1888,7 +1914,6 @@ var bindEdgeCollections = function(self, edgeCollections) { // remove wrap.remove = function(edgeId, options) { - var result; //if _key make _id (only on 1st call) if (edgeId.indexOf("/") === -1) { edgeId = key + "/" + edgeId; @@ -1900,6 +1925,7 @@ var bindEdgeCollections = function(self, edgeCollections) { collections: { write: self.__collectionsToLock }, + embed: true, action: function (params) { var db = require("internal").db; params.ids.forEach( @@ -1917,13 +1943,15 @@ var bindEdgeCollections = function(self, edgeCollections) { options: options } }); - result = true; } catch (e) { - result = false; + self.__idsToRemove = []; + self.__collectionsToLock = []; + throw e; } self.__idsToRemove = []; self.__collectionsToLock = []; - return result; + + return true; }; self[key] = wrap; @@ -1933,7 +1961,6 @@ var bindEdgeCollections = function(self, edgeCollections) { var bindVertexCollections = function(self, vertexCollections) { _.each(vertexCollections, function(key) { var obj = db._collection(key); - var result; var wrap = wrapCollection(obj); wrap.remove = function(vertexId, options) { //delete all edges using the vertex in all graphs @@ -1975,6 +2002,7 @@ var bindVertexCollections = function(self, vertexCollections) { collections: { write: self.__collectionsToLock }, + embed: true, action: function (params) { var db = require("internal").db; params.ids.forEach( @@ -1998,14 +2026,15 @@ var bindVertexCollections = function(self, vertexCollections) { vertexId: vertexId } }); - result = true; } catch (e) { - result = false; + self.__idsToRemove = []; + self.__collectionsToLock = []; + throw e; } self.__idsToRemove = []; self.__collectionsToLock = []; - return result; + return true; }; self[key] = wrap; }); @@ -2739,6 +2768,13 @@ Graph.prototype._vertices = function(example) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype._fromVertex = function(edgeId) { + if (typeof edgeId !== 'string' || + edgeId.indexOf('/') === -1) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } var edgeCollection = this._getEdgeCollectionByName(edgeId.split("/")[0]); var document = edgeCollection.document(edgeId); if (document) { @@ -2774,6 +2810,13 @@ Graph.prototype._fromVertex = function(edgeId) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype._toVertex = function(edgeId) { + if (typeof edgeId !== 'string' || + edgeId.indexOf('/') === -1) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code; + err.errorMessage = arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message; + throw err; + } var edgeCollection = this._getEdgeCollectionByName(edgeId.split("/")[0]); var document = edgeCollection.document(edgeId); if (document) { @@ -2812,7 +2855,6 @@ Graph.prototype._getVertexCollectionByName = function(name) { throw err; }; - //////////////////////////////////////////////////////////////////////////////// /// @startDocuBlock JSF_general_graph_neighbors /// @brief Get all neighbors of the vertices defined by the example @@ -2862,6 +2904,7 @@ Graph.prototype._getVertexCollectionByName = function(name) { /// @endDocuBlock // //////////////////////////////////////////////////////////////////////////////// + Graph.prototype._neighbors = function(vertexExample, options) { var AQLStmt = new AQLGenerator(this); // If no direction is specified all edges are duplicated. @@ -4447,6 +4490,98 @@ Graph.prototype._removeVertexCollection = function(vertexCollectionName, dropCol }; +//////////////////////////////////////////////////////////////////////////////// +/// @startDocuBlock JSF_general_graph_connectingEdges +/// @brief Get all connecting edges between 2 groups of vertices defined by the examples +/// +/// `graph._connectingEdges(vertexExample, vertexExample2, options)` +/// +/// The function accepts an id, an example, a list of examples or even an empty +/// example as parameter for vertexExample. +/// +/// @PARAMS +/// +/// @PARAM{vertexExample1, object, optional} +/// See [Definition of examples](#definition_of_examples) +/// @PARAM{vertexExample2, object, optional} +/// See [Definition of examples](#definition_of_examples) +/// @PARAM{options, object, optional} +/// An object defining further options. Can have the following values: +/// * *edgeExamples*: Filter the edges, see [Definition of examples](#definition_of_examples) +/// * *edgeCollectionRestriction* : One or a list of edge-collection names that should be +/// considered to be on the path. +/// * *vertex1CollectionRestriction* : One or a list of vertex-collection names that should be +/// considered on the intermediate vertex steps. +/// * *vertex2CollectionRestriction* : One or a list of vertex-collection names that should be +/// considered on the intermediate vertex steps. +/// +/// @EXAMPLES +/// +/// A route planner example, all neighbors of capitals. +/// +/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphModuleNeighbors1} +/// var examples = require("org/arangodb/graph-examples/example-graph.js"); +/// var graph = examples.loadGraph("routeplanner"); +/// graph._neighbors({isCapital : true}); +/// @END_EXAMPLE_ARANGOSH_OUTPUT +/// +/// A route planner example, all outbound neighbors of Hamburg. +/// +/// @EXAMPLE_ARANGOSH_OUTPUT{generalGraphModuleNeighbors2} +/// var examples = require("org/arangodb/graph-examples/example-graph.js"); +/// var graph = examples.loadGraph("routeplanner"); +/// graph._neighbors('germanCity/Hamburg', {direction : 'outbound', maxDepth : 2}); +/// @END_EXAMPLE_ARANGOSH_OUTPUT +/// +/// @endDocuBlock +// +//////////////////////////////////////////////////////////////////////////////// + +Graph.prototype._getConnectingEdges = function(vertexExample1, vertexExample2, options) { + + if (!options) { + options = {}; + } + + var opts = { + }; + + if (options.vertex1CollectionRestriction) { + opts.startVertexCollectionRestriction = options.vertex1CollectionRestriction; + } + + if (options.vertex2CollectionRestriction) { + opts.endVertexCollectionRestriction = options.vertex2CollectionRestriction; + } + + if (options.edgeCollectionRestriction) { + opts.edgeCollectionRestriction = options.edgeCollectionRestriction; + } + + if (options.edgeExamples) { + opts.edgeExamples = options.edgeExamples; + } + + if (vertexExample2) { + opts.neighborExamples = vertexExample2; + } + + var query = "RETURN" + + " GRAPH_EDGES(@graphName" + + ',@vertexExample' + + ',@options' + + ')'; + options = options || {}; + var bindVars = { + "graphName": this.__name, + "vertexExample": vertexExample1, + "options": opts + }; + var result = db._query(query, bindVars).toArray(); + return result[0]; +}; + + //////////////////////////////////////////////////////////////////////////////// diff --git a/js/common/modules/org/arangodb/simple-query-common.js b/js/common/modules/org/arangodb/simple-query-common.js index 2ce4788f02..a5cad4d797 100644 --- a/js/common/modules/org/arangodb/simple-query-common.js +++ b/js/common/modules/org/arangodb/simple-query-common.js @@ -36,6 +36,7 @@ var ArangoError = arangodb.ArangoError; var SimpleQueryArray; var SimpleQueryNear; var SimpleQueryWithin; +var SimpleQueryWithinRectangle; // ----------------------------------------------------------------------------- // --SECTION-- GENERAL ARRAY CURSOR @@ -989,6 +990,14 @@ SimpleQueryGeo.prototype.within = function (lat, lon, radius) { return new SimpleQueryWithin(this._collection, lat, lon, radius, this._index); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructs a within-rectangle query for an index +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryGeo.prototype.withinRectangle = function (lat1, lon1, lat2, lon2) { + return new SimpleQueryWithinRectangle(this._collection, lat1, lon1, lat2, lon2, this._index); +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY NEAR // ----------------------------------------------------------------------------- @@ -1213,10 +1222,6 @@ SimpleQueryWithin.prototype._PRINT = function (context) { context.output += text; }; -// ----------------------------------------------------------------------------- -// --SECTION-- public methods -// ----------------------------------------------------------------------------- - //////////////////////////////////////////////////////////////////////////////// /// @brief adds the distance attribute //////////////////////////////////////////////////////////////////////////////// @@ -1236,6 +1241,112 @@ SimpleQueryWithin.prototype.distance = function (attribute) { return clone; }; +// ----------------------------------------------------------------------------- +// --SECTION-- SIMPLE QUERY WITHINRECTANGLE +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// --SECTION-- constructors and destructors +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle = function (collection, latitude1, longitude1, latitude2, longitude2, iid) { + var idx; + var i; + + this._collection = collection; + this._latitude1 = latitude1; + this._longitude1 = longitude1; + this._latitude2 = latitude2; + this._longitude2 = longitude2; + this._index = (iid === undefined ? null : iid); + + if (iid === undefined) { + idx = collection.getIndexes(); + + for (i = 0; i < idx.length; ++i) { + var index = idx[i]; + + if (index.type === "geo1" || index.type === "geo2") { + if (this._index === null) { + this._index = index.id; + } + else if (index.id < this._index) { + this._index = index.id; + } + } + } + } + + if (this._index === null) { + var err = new ArangoError(); + err.errorNum = arangodb.ERROR_QUERY_GEO_INDEX_MISSING; + err.errorMessage = arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message; + throw err; + } +}; + +SimpleQueryWithinRectangle.prototype = new SimpleQuery(); +SimpleQueryWithinRectangle.prototype.constructor = SimpleQueryWithinRectangle; + +// ----------------------------------------------------------------------------- +// --SECTION-- private methods +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief clones a within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype.clone = function () { + var query; + + query = new SimpleQueryWithinRectangle(this._collection, + this._latitude1, + this._longitude1, + this._latitude2, + this._longitude2, + this._index); + query._skip = this._skip; + query._limit = this._limit; + + return query; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints a within-rectangle query +//////////////////////////////////////////////////////////////////////////////// + +SimpleQueryWithinRectangle.prototype._PRINT = function (context) { + var text; + + text = "SimpleQueryWithinRectangle(" + + this._collection.name() + + ", " + + this._latitude1 + + ", " + + this._longitude1 + + ", " + + this._latitude1 + + ", " + + this._longitude2 + + ", " + + this._index + + ")"; + + if (this._skip !== null && this._skip !== 0) { + text += ".skip(" + this._skip + ")"; + } + + if (this._limit !== null) { + text += ".limit(" + this._limit + ")"; + } + + context.output += text; +}; + // ----------------------------------------------------------------------------- // --SECTION-- SIMPLE QUERY FULLTEXT // ----------------------------------------------------------------------------- @@ -1341,6 +1452,7 @@ exports.SimpleQueryRange = SimpleQueryRange; exports.SimpleQueryGeo = SimpleQueryGeo; exports.SimpleQueryNear = SimpleQueryNear; exports.SimpleQueryWithin = SimpleQueryWithin; +exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle; exports.SimpleQueryFulltext = SimpleQueryFulltext; // ----------------------------------------------------------------------------- diff --git a/js/common/tests/replication.js b/js/common/tests/replication.js index 24837e4f61..97073bfff3 100644 --- a/js/common/tests/replication.js +++ b/js/common/tests/replication.js @@ -1420,10 +1420,7 @@ function ReplicationLoggerSuite () { assertTrue(actual); var entry = getLogEntries(tick, [ 2200, 2201, 2202 ]); - assertEqual(2, entry.length); - assertEqual(2200, entry[0].type); - assertEqual(2201, entry[1].type); - assertEqual(entry[0].tid, entry[1].tid); + assertEqual(0, entry.length); }, //////////////////////////////////////////////////////////////////////////////// @@ -1533,6 +1530,7 @@ function ReplicationLoggerSuite () { action: function (params) { var c2 = require("internal").db._collection(params.cn2); + // we're using a wrong collection here c2.save({ "test" : 2, "_key": "abc" }); }, params: { @@ -1545,12 +1543,7 @@ function ReplicationLoggerSuite () { } var entry = getLogEntries(tick, [ 2200, 2201, 2202, 2300 ]); - assertEqual(2, entry.length); - - assertEqual(2200, entry[0].type); - assertEqual(2202, entry[1].type); - - assertEqual(entry[0].tid, entry[1].tid); + assertEqual(0, entry.length); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/common/tests/shell-general-graph.js b/js/common/tests/shell-general-graph.js index 0af7bdffec..3b71833bb0 100644 --- a/js/common/tests/shell-general-graph.js +++ b/js/common/tests/shell-general-graph.js @@ -1894,6 +1894,41 @@ function EdgesAndVerticesSuite() { graph._drop(unitTestGraphName, true); }, + + test_connectingEdges : function () { + fillCollections(); + var res = g._getConnectingEdges({first_name: "Tam"}, {first_name: "Tem"}, {}); + assertTrue(res.length == 3); + }, + + test_connectingEdgesWithEdgeCollectionRestriction : function () { + fillCollections(); + var res = g._getConnectingEdges({first_name: "Tam"}, null, {}); + assertTrue(res.length == 13); + var res = g._getConnectingEdges({first_name: "Tam"}, null, {edgeCollectionRestriction : "unitTestEdgeCollection2"}); + assertTrue(res.length == 5); + }, + + test_connectingEdgesWithVertexCollectionRestriction : function () { + fillCollections(); + var res = g._getConnectingEdges(null, null, {}); + assertTrue(res.length == 13); + var res = g._getConnectingEdges(null, null, {vertex1CollectionRestriction : "unitTestVertexCollection1"}); + assertTrue(res.length == 13); + var res = g._getConnectingEdges(null, null, { + vertex1CollectionRestriction : "unitTestVertexCollection1", + vertex2CollectionRestriction : "unitTestVertexCollection3" + }); + assertTrue(res.length == 5); + }, + + test_connectingEdgesWithIds : function () { + var ids = fillCollections(); + var res = g._getConnectingEdges(ids.vId11, ids.vId13, {}); + assertTrue(res.length == 2); + }, + + test_dropGraph1 : function () { var myGraphName = unitTestGraphName + "2"; var myEdgeColName = "unitTestEdgeCollection4711"; @@ -1940,6 +1975,22 @@ function EdgesAndVerticesSuite() { assertTrue(db._collection(vc1) !== null); assertTrue(db._collection(ec1) !== null); }, + + test_createGraphWithMalformedEdgeDefinitions : function () { + var myGraphName = unitTestGraphName + "2"; + try { + graph._create( + myGraphName, + [ "foo" ] + ); + } catch (e) { + assertEqual( + e.errorMessage, + arangodb.errors.ERROR_GRAPH_CREATE_MALFORMED_EDGE_DEFINITION.message + ); + } + assertFalse(graph._exists(myGraphName)); + }, test_createGraphWithCollectionDuplicateNOK1 : function () { var myGraphName = unitTestGraphName + "2"; @@ -2293,6 +2344,21 @@ function EdgesAndVerticesSuite() { graph._drop(gN3, true); graph._drop(gN4, true); }, + + test_eC_malformedId : function() { + [ null, "foo", [ ] ].forEach(function(v) { + try { + var x= g[ec2].save(v, v, {}); + fail(); + } + catch (e) { + assertEqual( + e.errorMessage, + arangodb.errors.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.message + ); + } + }); + }, test_getInVertex : function() { var ids = fillCollections(); diff --git a/js/node/node_modules/foxx_generator/.jshintrc b/js/node/node_modules/foxx_generator/.jshintrc new file mode 100644 index 0000000000..d19dfe9189 --- /dev/null +++ b/js/node/node_modules/foxx_generator/.jshintrc @@ -0,0 +1,84 @@ +{ + "maxerr" : 50, // {int} Maximum error before stopping + + // Enforcing + "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) + "camelcase" : true, // true: Identifiers must be in camelCase + "curly" : true, // true: Require {} for every new block or scope + "eqeqeq" : true, // true: Require triple equals (===) for comparison + "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. + "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() + "immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` + "indent" : 2, // {int} Number of spaces to use for indentation + "latedef" : true, // true: Require variables/functions to be defined before being used + "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()` + "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` + "noempty" : true, // true: Prohibit use of empty blocks + "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. + "nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment) + "plusplus" : false, // true: Prohibit use of `++` & `--` + "quotmark" : "single", // Quotation mark consistency: + // false : do nothing (default) + // true : ensure whatever is used is consistent + // "single" : require single quotes + // "double" : require double quotes + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : "vars", // "vars": Require all defined variables be used, but not parameters + "strict" : true, // true: Requires all functions run in ES5 Strict Mode + "maxparams" : false, // {int} Max number of formal params allowed per function + "maxdepth" : 2, // {int} Max depth of nested blocks (within functions) + "maxstatements" : false, // {int} Max number statements per function + "maxcomplexity" : 5, // {int} Max cyclomatic complexity per function + "maxlen" : 120, // {int} Max number of characters per line + + // Relaxing + "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) + "boss" : false, // true: Tolerate assignments where comparisons would be expected + "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. + "eqnull" : false, // true: Tolerate use of `== null` + "es5" : false, // true: Allow ES5 syntax (ex: getters and setters) + "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`) + "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) + // (ex: `for each`, multiple try/catch, function expression…) + "evil" : false, // true: Tolerate use of `eval` and `new Function()` + "expr" : false, // true: Tolerate `ExpressionStatement` as Programs + "funcscope" : false, // true: Tolerate defining variables inside control statements + "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') + "iterator" : false, // true: Tolerate using the `__iterator__` property + "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block + "laxbreak" : false, // true: Tolerate possibly unsafe line breakings + "laxcomma" : false, // true: Tolerate comma-first style coding + "loopfunc" : false, // true: Tolerate functions being defined in loops + "multistr" : false, // true: Tolerate multi-line strings + "noyield" : false, // true: Tolerate generator functions with no yield statement in them. + "notypeof" : false, // true: Tolerate invalid typeof operator values + "proto" : false, // true: Tolerate using the `__proto__` property + "scripturl" : false, // true: Tolerate script-targeted URLs + "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` + "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation + "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` + "validthis" : false, // true: Tolerate using this in a non-constructor function + + // Environments + "browser" : false, // Web Browser (window, document, etc) + "browserify" : false, // Browserify (node.js code in the browser) + "couch" : false, // CouchDB + "devel" : false, // Development/debugging (alert, confirm, etc) + "dojo" : false, // Dojo Toolkit + "jasmine" : false, // Jasmine + "jquery" : false, // jQuery + "mocha" : false, // Mocha + "mootools" : false, // MooTools + "node" : true, // Node.js + "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) + "prototypejs" : false, // Prototype and Scriptaculous + "qunit" : false, // QUnit + "rhino" : false, // Rhino + "shelljs" : false, // ShellJS + "worker" : false, // Web Workers + "wsh" : false, // Windows Scripting Host + "yui" : false, // Yahoo User Interface + + // Custom Globals + "globals" : {} // additional predefined global variables +} diff --git a/js/node/node_modules/foxx_generator/.npmignore b/js/node/node_modules/foxx_generator/.npmignore new file mode 100644 index 0000000000..f928a64038 --- /dev/null +++ b/js/node/node_modules/foxx_generator/.npmignore @@ -0,0 +1,3 @@ +.DS_STORE +node_modules +npm-debug.log diff --git a/js/node/node_modules/foxx_generator/LICENSE b/js/node/node_modules/foxx_generator/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/js/node/node_modules/foxx_generator/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/js/node/node_modules/foxx_generator/README.md b/js/node/node_modules/foxx_generator/README.md new file mode 100644 index 0000000000..0ab1dcfb84 --- /dev/null +++ b/js/node/node_modules/foxx_generator/README.md @@ -0,0 +1,163 @@ +# FoxxGenerator + +FoxxGenerator is a declarative JavaScript framework that allows developers to describe the API in terms of the domain using statecharts. This declarative approach is based upon a combination of Richardson and Amundsen's design approach described in their book [RESTful Web APIs](http://restfulwebapis.com), Eric Evans' ideas from his book [domain driven design](http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215) and the Harel's statecharts introduced in his paper *Statecharts: A Visual Formalism For Complex Systems*. + +To create an API with FoxxGenerator, first draw a statechart that represents your API. In this statechart, your states can have one of the following types: + +* Entity: This state represents something that has an identity and an arbitrary number of (optionally nested) attributes. +* Repository: A repository can store entities. +* Service: A service can do something. What it can do is defined via a JavaScript function that you can define. A service does not have a state. + +Connect these states with transitions. When you have modeled your statechart in a way that it can fulfill all your use cases, it is time to classify your transitions. For every transition you have to decide which of the following type it follows: + +* `follow`: This is a transition that you can just follow from one state to the next. +* `connect`: This is a point of extension where you can create a transition at runtime. In order to be able to follow this transition, you have to add a `follow` transition as well. +* `disconnect`: With this transition you can remove a transition created with `connect`. +* `modify`: This is a transition that can only be created from an entity to itself. It is used to modify the state of this entity. + +You can now translate this annotated statechart into the DSL of FoxxGenerator to create your API. + +## Setting up a Foxx application with FoxxGenerator. + +First, create a Foxx application as described in [Foxx's manual](http://docs.arangodb.org/Foxx/README.html). In the folder of your Foxx app, you can now install FoxxGenerator with `npm install foxx_generator`. In the same way you would add a controller to your Foxx application, you can now add a FoxxGenerator to your application: In the file that would normally contain your FoxxController, add the following: + +```js +var FoxxGenerator = require('foxx_generator').Generator, + Joi = require('joi'), + generator; + +generator = new FoxxGenerator('name_of_your_app', { + // To learn more about media types, see below + mediaType: 'application/vnd.siren+json', + applicationContext: applicationContext, +}); + +// Insert transition definitions here + +// Insert states here + +generator.generate(); +``` + +For more information on how to choose a media type, see the section about Media types. Now you can define the transitions you used in your statechart and then add the states and the transitions between them. + +## Defining the transitions + +Every transition needs the following attributes: + +* A name for the transition that you can use when you want to add a transition of this type. +* `type`: One of the types described above. +* `to`: Is the target of this transition one or more states? For a `connect` transition this for example determines if you can only connect one state to it or more than that. Acceptable values are `one` and `many`. + +You can also add a documentation block (a JavaScript comment starting with `/**`) that will be used for the documentation. The first line should be a short summary, all other lines will be used for a long description. An example for that would be the following transition definition: + +```js +/** Show details for a particular item + * + * Show all information about this particular item. + */ +generator.defineTransition('showDetail', { + type: 'follow', + to: 'one' +}); +``` + +For a `connect` and `disconnect` transition you additionally have to determine which `follow` transition can be used to follow the created transition. This is done with `as` and the name of the transition. + +You can also add `parameters` to the transition, if in the transition process you need additional information from the user of the API. Each of the parameters needs to be a value object defined with [Joi](https://github.com/hapijs/joi). For example: + +```js +/** Modify the title of the entity + * + */ +generator.defineTransition('changeTitle', { + type: 'modify', + to: 'one', + + parameters: { + title: Joi.string() + } +}); +``` + +You can also define a `condition` for a transition. This is a JavaScript function that takes the parameters of the HTTP request as its argument and returns either true or false. If it is true, the transition can be executed. If it is false, the transition can not be executed and the link to execute it will be hidden from the representation. This can for example be used for user authorization. + +## Adding states and transitions + +Now you can add states and transitions to your API. Every state has a name, a type and a number of outgoing transitions. The type is one of the above described ones – either `entity`, `repository` or `service`. Every transition needs information about where it leads to and via which transition type. The transition type needs to be defined as described above. Simple example: + +```js +generator.addState('ideas', { + type: 'repository', + contains: 'idea', + + transitions: [ + { to: 'idea', via: 'showDetail' } + ] +}); +``` + +Some states take additional information: Entities need to know which repository they are contained in (via `containedIn`) and repositories need to know which entities they contain (via `contains`). + +### Entity + +An entity can be `parameterized` (by setting its attribute `parameterized` to `true`) which means that there is not only one state of that type, but there can be an arbitrary amount – each of them is identified by a parameter. This is usually the case with entities that are stored in a repository. + +It also takes an object of attributes which describe the representation of the entity. Each of the attributes needs to be a value object defined with [Joi](https://github.com/hapijs/joi). + +Example for an entity: + +```js +generator.addState('idea', { + type: 'entity', + parameterized: true, + containedIn: 'ideas', + + attributes: { + description: Joi.string().required(), + title: Joi.string().required() + }, + + transitions: [ + { to: 'idea', via: 'relatedIdea' } + ] +}); +``` + +### Service + +A service needs to describe what it does, this is done with an `action` which is a function that takes a request and a response in the [same way that a FoxxController route does](http://docs.arangodb.org/Foxx/FoxxController.html). The default HTTP verb for a service is a `post`, it can be changed by setting the `verb`. Example: + +```js +generator.addState('title', { + type: 'service', + verb: 'get', + + action: function (req, res) { + var entity = req.params('entity'); + res.json({ title: entity.get('title') }); + } +}); +``` + +## Media types + +FoxxGenerator currently only supports [siren](https://github.com/kevinswiber/siren) which is a media type without application semantics. Use the media type `application/vnd.siren+json`. We plan to support HAL with an extension for forms in the near future. + +## Interactive Documentation + +During your development, FoxxGenerator will generate an interactive documentation alongside the API. You can use this in an iterative development style to check after each step if the API is as you expected it to be. The documentation allows you to try out each of the generated endpoints. The API documentation can be found in the admin interface of ArangoDB and looks a little like this: + +![Overview](screenshots/overview.png) + +If you click on one of the routes, you can try it out: + +![Try it out](screenshots/try_it_out.png) + +## Examples + +* An example for a Siren API generated with FoxxGenerator can be found [here](https://github.com/moonglum/siren) + +## Linting + +To check the project for linting errors, run `npm run jshint`. diff --git a/js/node/node_modules/foxx_generator/foxx_generator.js b/js/node/node_modules/foxx_generator/foxx_generator.js new file mode 100644 index 0000000000..b4502e6884 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator.js @@ -0,0 +1,54 @@ +(function () { + 'use strict'; + var Foxx = require('org/arangodb/foxx'), + _ = require('underscore'), + Graph = require('./foxx_generator/graph').Graph, + Generator, + StateFactory = require('./foxx_generator/state_factory').StateFactory, + TransitionFactory = require('./foxx_generator/transition_factory').TransitionFactory, + configureStates = require('./foxx_generator/configure_states').configureStates, + mediaTypes; + + mediaTypes = { + 'application/vnd.siren+json': require('./foxx_generator/siren').mediaType + }; + + Generator = function (name, options) { + var applicationContext = options.applicationContext, + graph = new Graph(name, applicationContext), + strategies = mediaTypes[options.mediaType].strategies; + + this.controller = new Foxx.Controller(applicationContext, options); + + this.states = {}; + this.transitions = []; + + this.stateFactory = new StateFactory(graph, this.transitions, this.states); + this.transitionFactory = new TransitionFactory(applicationContext, graph, this.controller, strategies); + }; + + _.extend(Generator.prototype, { + addStartState: function (opts) { + var name = '', + options = _.defaults({ type: 'start', controller: this.controller }, opts); + + this.states[name] = this.stateFactory.create(name, options); + }, + + addState: function (name, opts) { + this.states[name] = this.stateFactory.create(name, opts); + }, + + defineTransition: function (name, opts) { + this.transitions[name] = this.transitionFactory.create(name, opts); + }, + + generate: function () { + configureStates(this.states); + _.each(this.states, function (state) { state.prepareTransitions(this.transitions, this.states); }, this); + _.each(this.states, function (state) { state.applyTransitions(); }, this); + } + }); + + exports.Generator = Generator; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/condition_not_fulfilled.js b/js/node/node_modules/foxx_generator/foxx_generator/condition_not_fulfilled.js new file mode 100644 index 0000000000..49591725d2 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/condition_not_fulfilled.js @@ -0,0 +1,13 @@ +(function () { + 'use strict'; + var ConditionNotFulfilled; + + ConditionNotFulfilled = function (msg) { + this.name = 'ConditionNotFulfilled'; + this.msg = msg; + }; + + ConditionNotFulfilled.prototype = Error.prototype; + + exports.ConditionNotFulfilled = ConditionNotFulfilled; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/configure_states.js b/js/node/node_modules/foxx_generator/foxx_generator/configure_states.js new file mode 100644 index 0000000000..dcbd6e9ceb --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/configure_states.js @@ -0,0 +1,103 @@ +(function () { + 'use strict'; + var _ = require('underscore'), + R = require('ramda'), + Repository = require('./repository_with_graph').RepositoryWithGraph, + Model = require('./model').Model, + configureStates, + typeIs, + determineSuperstate, + prepareStartState, + prepareServiceState, + determinePrefix, + prependPrefix, + appendIdPlaceholder, + isParameterized, + hasUrlTemplate, + appendIdPlaceholderForParameterizedState, + determineUrlTemplate, + determineUrlTemplateIfNotDetermined, + prepareEntityState, + prepareRepositoryState, + copyInfoFromRepositoryState; + + typeIs = R.curry(function (type, state) { + return state.type === type; + }); + + determineSuperstate = R.curry(function (states, state) { + if (state.superstate) { + state.superstate = states[state.superstate]; + } + }); + + prepareStartState = R.curry(R.func('setAsStart')); + prepareServiceState = R.curry(R.func('addService')); + + determinePrefix = function (state) { + var prefix = '/'; + + if (state.superstate) { + // First determine the entire chain + determineUrlTemplateIfNotDetermined(state.superstate); + prefix = state.superstate.urlTemplate + '/'; + } + + return prefix; + }; + + prependPrefix = function (state) { + state.urlTemplate = R.concat(determinePrefix(state), state.name); + return state; + }; + + appendIdPlaceholder = function(state) { + state.urlTemplate = R.concat(state.urlTemplate, '/:id'); + return state; + }; + + isParameterized = R.prop('parameterized'); + hasUrlTemplate = R.prop('urlTemplate'); + appendIdPlaceholderForParameterizedState = R.cond(isParameterized, appendIdPlaceholder, R.identity); + determineUrlTemplate = R.pipe(prependPrefix, appendIdPlaceholderForParameterizedState); + determineUrlTemplateIfNotDetermined = R.cond(hasUrlTemplate, R.identity, determineUrlTemplate); + + prepareEntityState = R.curry(function (states, entity) { + var repositoryState = states[entity.options.containedIn]; + entity.repositoryState = repositoryState; + entity.addModel(Model); + }); + + prepareRepositoryState = R.curry(function (states, repository) { + var entityState = states[repository.options.contains]; + repository.entityState = entityState; + repository.model = entityState.model; + repository.addRepository(Repository); + }); + + copyInfoFromRepositoryState = function (entity) { + var repositoryState = entity.repositoryState, + repository = repositoryState.repository; + entity.collectionName = repositoryState.collectionName; + entity.collection = repositoryState.collection; + entity.repository = repositoryState.repository; + repository.relations = entity.relations; + }; + + configureStates = function (states) { + var entities = _.filter(states, typeIs('entity')), + repositories = _.filter(states, typeIs('repository')), + services = _.filter(states, typeIs('service')), + starts = _.filter(states, typeIs('start')); + + _.each(states, determineSuperstate(states)); + _.each(states, determineUrlTemplateIfNotDetermined); + _.each(starts, prepareStartState); + _.each(services, prepareServiceState); + _.each(entities, prepareEntityState(states)); + _.each(repositories, prepareRepositoryState(states)); + _.each(entities, copyInfoFromRepositoryState); + }; + + exports.configureStates = configureStates; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/construct_route.js b/js/node/node_modules/foxx_generator/foxx_generator/construct_route.js new file mode 100644 index 0000000000..ba47b65d54 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/construct_route.js @@ -0,0 +1,52 @@ +(function () { + 'use strict'; + var Foxx = require('org/arangodb/foxx'), + ConditionNotFulfilled = require('./condition_not_fulfilled').ConditionNotFulfilled, + VertexNotFound = require('./vertex_not_found').VertexNotFound, + wrapServiceAction = require('./wrap_service_action').wrapServiceAction, + constructBodyParams, + joi = require('joi'), + constructRoute; + + constructBodyParams = function (relation) { + return Foxx.Model.extend({ schema: relation.parameters }); + }; + + constructRoute = function (opts) { + var route, + controller = opts.controller, + // from = opts.from, + // graph = opts.graph, + to = opts.to, + verb, + url = opts.url || to.urlTemplate, + action, + relation = opts.relation; + + if (to.type === 'service') { + verb = to.verb; + action = wrapServiceAction(to); + } else { + verb = opts.verb; + action = opts.action; + } + + route = controller[verb](url, action) + .errorResponse(VertexNotFound, 404, 'The vertex could not be found') + .errorResponse(ConditionNotFulfilled, 403, 'The condition could not be fulfilled') + .onlyIf(relation.condition) + .summary(relation.summary) + .notes(relation.notes); + + if (url.indexOf(':') > 0) { + route.pathParam('id', joi.string().description('ID of the entity')); + } + + if (opts.body) { + route.bodyParam(opts.body.name, 'TODO', constructBodyParams(relation)); + } + }; + + exports.constructRoute = constructRoute; +}()); + diff --git a/js/node/node_modules/foxx_generator/foxx_generator/context.js b/js/node/node_modules/foxx_generator/foxx_generator/context.js new file mode 100644 index 0000000000..313a3a354c --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/context.js @@ -0,0 +1,34 @@ +(function () { + 'use strict'; + var Context, + _ = require('underscore'), + extend = require('org/arangodb/extend').extend; + + /*jshint maxlen: 200 */ + Context = function (from, to, relation) { + from.relations.push(relation); + + this.from = from; + this.to = to; + this.relation = relation; + this.strategy = _.find(this.strategies, function (maybeStrategy) { + return maybeStrategy.executable(relation.type, from.type, to.type, relation.cardinality); + }); + + if (_.isUndefined(this.strategy)) { + require('console').log('Couldn\'t find a strategy for semantic %s from %s to %s (%s)', relation.type, from.type, to.type, relation.cardinality); + throw 'Could not find strategy'; + } + }; + /*jshint maxlen: 100 */ + + _.extend(Context.prototype, { + execute: function (controller, graph) { + this.strategy.execute(controller, graph, this.relation, this.from, this.to); + } + }); + + Context.extend = extend; + + exports.Context = Context; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/documentation.js b/js/node/node_modules/foxx_generator/foxx_generator/documentation.js new file mode 100644 index 0000000000..8a109b942c --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/documentation.js @@ -0,0 +1,19 @@ +(function () { + 'use strict'; + + var Documentation = function (applicationContext) { + this.summary = ''; + this.notes = ''; + + if (applicationContext.comments.length > 0) { + do { + this.summary = applicationContext.comments.shift(); + } while (this.summary === ''); + this.notes = applicationContext.comments.join('\n'); + } + + applicationContext.clearComments(); + }; + + exports.Documentation = Documentation; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/graph.js b/js/node/node_modules/foxx_generator/foxx_generator/graph.js new file mode 100644 index 0000000000..e17edb1553 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/graph.js @@ -0,0 +1,125 @@ +(function () { + 'use strict'; + var graphModule = require('org/arangodb/general-graph'), + ArangoError = require('internal').ArangoError, + _ = require('underscore'), + report = require('./reporter').report, + Graph, + VertexNotFound = require('./vertex_not_found').VertexNotFound, + tryAndHandleArangoError, + alreadyExists; + + tryAndHandleArangoError = function (func, errHandler) { + try { + func(); + } catch (e) { + if (e instanceof ArangoError) { + errHandler(); + } else { + throw e; + } + } + }; + + alreadyExists = function (type, name) { + return function () { + report('%s "%s" already added. Leaving it untouched.', type, name); + }; + }; + + Graph = function (name, appContext) { + var that = this; + this.appContext = appContext; + + tryAndHandleArangoError(function () { + that.graph = graphModule._graph(name); + }, function () { + that.graph = graphModule._create(name); + }); + }; + + _.extend(Graph.prototype, { + extendEdgeDefinitions: function (rawEdgeCollectionName, from, to) { + var vertexCollections, edgeCollectionName, edgeDefinition, graph; + edgeCollectionName = this.appContext.collectionName(rawEdgeCollectionName); + + if (from.type === 'entity' && to.type === 'entity' && from.collectionName && to.collectionName) { + vertexCollections = [ from.collectionName, to.collectionName ]; + edgeDefinition = graphModule._undirectedRelation(edgeCollectionName, vertexCollections); + graph = this.graph; + + tryAndHandleArangoError(function () { + graph._extendEdgeDefinitions(edgeDefinition); + }, alreadyExists('EdgeDefinition', edgeCollectionName)); + } else { + report('Invalid edge definition for "%s" and "%s"', from.collectionName, to.collectionName); + } + + return edgeCollectionName; + }, + + addVertexCollection: function (collectionName) { + var prefixedCollectionName = this.appContext.collectionName(collectionName), + graph = this.graph; + + tryAndHandleArangoError(function () { + graph._addVertexCollection(prefixedCollectionName, true); + }, alreadyExists('Collection', prefixedCollectionName)); + + return this.graph[prefixedCollectionName]; + }, + + neighbors: function (id, options) { + return this.graph._neighbors(id, options); + }, + + edges: function (id, options) { + return this.graph._vertices(id).edges().restrict(options.edgeCollectionRestriction).toArray(); + }, + + removeEdges: function (options) { + var graph = this.graph, + vertexId = options.vertexId, + edgeCollectionName = options.edgeCollectionName, + edges; + + edges = this.edges(vertexId, { + edgeCollectionRestriction: [edgeCollectionName], + }); + + _.each(edges, function (edge) { + graph[edgeCollectionName].remove(edge._id); + }); + }, + + checkIfVerticesExist: function (ids) { + if (!_.every(ids, this.hasVertex, this)) { + throw new VertexNotFound(); + } + }, + + hasVertex: function (id) { + return this.graph._vertices(id).count() > 0; + }, + + areConnected: function (sourceId, destinationId) { + return this.graph._edges([ + { _from: sourceId, _to: destinationId }, + { _from: destinationId, _to: sourceId } + ]).count() > 0; + }, + + createEdge: function (options) { + var sourceId = options.sourceId, + destinationId = options.destinationId, + edgeCollectionName = options.edgeCollectionName, + edgeCollection = this.graph[edgeCollectionName]; + + if (!this.areConnected(sourceId, destinationId)) { + edgeCollection.save(sourceId, destinationId, {}); + } + } + }); + + exports.Graph = Graph; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/model.js b/js/node/node_modules/foxx_generator/foxx_generator/model.js new file mode 100644 index 0000000000..e99e617f2d --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/model.js @@ -0,0 +1,18 @@ +(function () { + 'use strict'; + var Foxx = require('org/arangodb/foxx'), + Model; + + Model = Foxx.Model.extend({ + forClient: function () { + var properties = Foxx.Model.prototype.forClient.call(this); + + return { + properties: properties, + links: [] + }; + } + }); + + exports.Model = Model; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/relation_repository.js b/js/node/node_modules/foxx_generator/foxx_generator/relation_repository.js new file mode 100644 index 0000000000..09887cc62d --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/relation_repository.js @@ -0,0 +1,48 @@ +(function () { + 'use strict'; + var RelationRepository, + _ = require('underscore'); + + RelationRepository = function (from, to, relation, graph) { + this.edgeCollectionName = relation.edgeCollectionName; + this.fromId = function (key) { return from.collectionName + '/' + key; }; + this.toId = function (key) { return to.collectionName + '/' + key; }; + this.graph = graph; + }; + + _.extend(RelationRepository.prototype, { + replaceRelation: function (sourceKey, destinationKey) { + var sourceId = this.fromId(sourceKey), + destinationId = this.toId(destinationKey), + edgeCollectionName = this.edgeCollectionName, + graph = this.graph; + + graph.checkIfVerticesExist([destinationId, sourceId]); + graph.removeEdges({ vertexId: sourceId, edgeCollectionName: edgeCollectionName, throwError: false }); + graph.createEdge({ edgeCollectionName: edgeCollectionName, sourceId: sourceId, destinationId: destinationId }); + }, + + addRelations: function (sourceKey, destinationKeys) { + var sourceId = this.fromId(sourceKey), + destinationIds = _.map(destinationKeys, this.toId, this), + edgeCollectionName = this.edgeCollectionName, + graph = this.graph; + + graph.checkIfVerticesExist(_.union(sourceId, destinationIds)); + _.each(destinationIds, function (destinationId) { + graph.createEdge({ edgeCollectionName: edgeCollectionName, sourceId: sourceId, destinationId: destinationId }); + }); + }, + + deleteRelation: function (sourceKey) { + var sourceId = this.fromId(sourceKey), + edgeCollectionName = this.edgeCollectionName, + graph = this.graph; + + graph.checkIfVerticesExist([sourceId]); + graph.removeEdges({ vertexId: sourceId, edgeCollectionName: edgeCollectionName }); + } + }); + + exports.RelationRepository = RelationRepository; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/reporter.js b/js/node/node_modules/foxx_generator/foxx_generator/reporter.js new file mode 100644 index 0000000000..d47afcf834 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/reporter.js @@ -0,0 +1,13 @@ +(function () { + 'use strict'; + var report, + developmentMode = false; + + report = function () { + if (developmentMode) { + require('console').log.apply(this, arguments); + } + }; + + exports.report = report; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/repository_with_graph.js b/js/node/node_modules/foxx_generator/foxx_generator/repository_with_graph.js new file mode 100644 index 0000000000..2b92255371 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/repository_with_graph.js @@ -0,0 +1,48 @@ +(function () { + 'use strict'; + var Foxx = require('org/arangodb/foxx'), + _ = require('underscore'), + RepositoryWithGraph; + + RepositoryWithGraph = Foxx.Repository.extend({ + allWithNeighbors: function (options) { + var results = this.all(options); + _.each(results, function (result) { + this.addLinks(result); + }, this); + return results; + }, + + byIdWithNeighbors: function (key) { + var result = this.byId(key); + this.addLinks(result); + return result; + }, + + removeByKey: function (key) { + this.collection.remove(key); + }, + + addLinks: function (model) { + var links = {}, + graph = this.graph, + relations = _.filter(this.relations, function (relation) { return relation.type === 'follow'; }); + + _.each(relations, function (relation) { + var neighbors = graph.neighbors(model.get('_id'), { + edgeCollectionRestriction: [relation.edgeCollectionName] + }); + + if (relation.cardinality === 'one' && neighbors.length > 0) { + links[relation.name] = neighbors[0]._key; + } else if (relation.cardinality === 'many') { + links[relation.name] = _.pluck(neighbors, '_key'); + } + }); + + model.set('links', links); + } + }); + + exports.RepositoryWithGraph = RepositoryWithGraph; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/siren.js b/js/node/node_modules/foxx_generator/foxx_generator/siren.js new file mode 100644 index 0000000000..4fcd498a8d --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/siren.js @@ -0,0 +1,304 @@ +(function () { + 'use strict'; + var RelationRepository = require('./relation_repository').RelationRepository, + Strategy = require('./strategy').Strategy, + constructRoute = require('./construct_route').constructRoute, + ModifyAnEntity, + AddEntityToRepository, + ConnectRepoWithEntity, + ConnectStartWithRepository, + ConnectToService, + DisconnectTwoEntities, + DisconnectTwoEntitiesToMany, + ConnectEntityToService, + ConnectTwoEntities, + ConnectTwoEntitiesToMany, + FollowToEntity, + FollowToEntityToMany, + FollowFromRepositoryToService; + + ConnectEntityToService = Strategy.extend({ + type: 'follow', + from: 'entity', + to: 'service', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + constructRoute({ + controller: controller, + graph: graph, + from: from, + to: to, + relation: relation + }); + } + }); + + ModifyAnEntity = Strategy.extend({ + type: 'modify', + from: 'entity', + to: 'entity', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + constructRoute({ + controller: controller, + graph: graph, + verb: 'patch', + url: from.urlTemplate, + action: function (req, res) { + var id = req.params('id'), + patch = req.params(from.name), + result; + + from.repository.updateById(id, patch.forDB()); + result = from.repository.byIdWithNeighbors(id); + + res.json(result.forClient()); + }, + from: from, + to: to, + relation: relation, + body: from + }); + } + }); + + ConnectTwoEntities = Strategy.extend({ + type: 'connect', + from: 'entity', + to: 'entity', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + var relationRepository = new RelationRepository(from, to, relation, graph); + + constructRoute({ + controller: controller, + graph: graph, + verb: 'post', + url: from.urlForRelation(relation), + action: function (req, res) { + relationRepository.replaceRelation(req.params('id'), req.body()[relation.name]); + res.status(204); + }, + from: from, + to: to, + relation: relation + }); + } + }); + + ConnectTwoEntitiesToMany = Strategy.extend({ + type: 'connect', + from: 'entity', + to: 'entity', + cardinality: 'many', + + execute: function (controller, graph, relation, from, to) { + var relationRepository = new RelationRepository(from, to, relation, graph); + + constructRoute({ + controller: controller, + graph: graph, + verb: 'post', + url: from.urlForRelation(relation), + action: function (req, res) { + relationRepository.addRelations(req.params('id'), req.body()[relation.name]); + res.status(204); + }, + from: from, + to: to, + relation: relation + }); + } + }); + + DisconnectTwoEntities = Strategy.extend({ + type: 'disconnect', + from: 'entity', + to: 'entity', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + var relationRepository = new RelationRepository(from, to, relation, graph); + + constructRoute({ + controller: controller, + graph: graph, + verb: 'delete', + url: from.urlForRelation(relation), + action: function (req, res) { + relationRepository.deleteRelation(req.params('id')); + res.status(204); + }, + from: from, + to: to, + relation: relation + }); + } + }); + + DisconnectTwoEntitiesToMany = Strategy.extend({ + type: 'disconnect', + from: 'entity', + to: 'entity', + cardinality: 'many' + }); + + + FollowToEntity = Strategy.extend({ + type: 'follow', + from: 'entity', + to: 'entity', + cardinality: 'one' + }); + + FollowToEntityToMany = Strategy.extend({ + type: 'follow', + from: 'entity', + to: 'entity', + cardinality: 'many' + }); + + AddEntityToRepository = Strategy.extend({ + type: 'connect', + from: 'repository', + to: 'entity', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + from.addActionWithMethodForRelation('POST', relation); + + constructRoute({ + controller: controller, + graph: graph, + verb: 'post', + url: from.urlTemplate, + action: function (req, res) { + var data = {}, + model = req.params(to.name); + + data[to.name] = from.repository.save(model).forClient(); + res.status(201); + res.json(data); + }, + from: from, + to: to, + relation: relation, + body: to + }); + } + }); + + ConnectRepoWithEntity = Strategy.extend({ + type: 'follow', + from: 'repository', + to: 'entity', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + constructRoute({ + controller: controller, + graph: graph, + verb: 'get', + action: function (req, res) { + var id = req.params('id'), + entry = from.repository.byIdWithNeighbors(id); + + res.json(entry.forClient()); + }, + from: from, + to: to, + relation: relation + }); + + from.addLinkToEntities(relation, to); + } + }); + + ConnectStartWithRepository = Strategy.extend({ + type: 'follow', + from: 'start', + to: 'repository', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + from.addLinkViaTransitionTo(relation, to); + + constructRoute({ + controller: controller, + graph: graph, + verb: 'get', + action: function (req, res) { + res.json({ + properties: to.properties(), + entities: to.entities(), + links: to.filteredLinks(req), + actions: to.filteredActions(req) + }); + }, + from: from, + to: to, + relation: relation + }); + } + }); + + ConnectToService = Strategy.extend({ + type: 'follow', + from: 'start', + to: 'service', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + from.addLinkViaTransitionTo(relation, to); + + constructRoute({ + controller: controller, + graph: graph, + from: from, + to: to, + relation: relation, + body: to + }); + } + }); + + FollowFromRepositoryToService = Strategy.extend({ + type: 'follow', + from: 'repository', + to: 'service', + cardinality: 'one', + + execute: function (controller, graph, relation, from, to) { + from.addLinkViaTransitionTo(relation, to); + + constructRoute({ + controller: controller, + graph: graph, + from: from, + to: to, + relation: relation + }); + } + }); + + exports.mediaType = { + strategies: [ + new ModifyAnEntity(), + new ConnectTwoEntities(), + new DisconnectTwoEntities(), + new DisconnectTwoEntitiesToMany(), + new FollowToEntity(), + new FollowToEntityToMany(), + new AddEntityToRepository(), + new ConnectRepoWithEntity(), + new ConnectEntityToService(), + new ConnectToService(), + new ConnectTwoEntitiesToMany(), + new ConnectStartWithRepository(), + new FollowFromRepositoryToService() + ] + }; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/state.js b/js/node/node_modules/foxx_generator/foxx_generator/state.js new file mode 100644 index 0000000000..2a73022625 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/state.js @@ -0,0 +1,203 @@ +(function () { + 'use strict'; + + var stateTypes = ['entity', 'repository', 'service', 'start'], + extend = require('org/arangodb/extend').extend, + _ = require('underscore'), + constructFields, + State; + + constructFields = function (relation) { + return _.map(relation.parameters, function (joi, name) { + var fieldDescription = { name: name, type: joi._type }; + + if (!_.isNull(joi._description)) { + fieldDescription.description = joi._description; + } + + if (!_.isUndefined(joi._flags.default)) { + fieldDescription.value = joi._flags.default; + } + + return fieldDescription; + }); + }; + + State = function (name, graph, options) { + this.name = name; + this.graph = graph; + this.options = options; + this.parameterized = this.options.parameterized; + this.superstate = this.options.superstate; + this.type = this.options.type; + + if (!_.contains(stateTypes, this.type)) { + require('console').log('Unknown state type "' + options.type + '"'); + throw 'Unknown State Type'; + } + + this.links = []; + this.actions = []; + this.childLinks = []; + this.relations = []; + }; + + _.extend(State.prototype, { + prepareTransitions: function (definitions, states) { + this.transitions = _.map(this.options.transitions, function (transitionDescription) { + var transition = definitions[transitionDescription.via], + to = states[transitionDescription.to]; + + return { + transition: transition, + to: to + }; + }, this); + }, + + applyTransitions: function () { + _.each(this.transitions, function (transitionDescription) { + transitionDescription.transition.apply(this, transitionDescription.to); + }, this); + }, + + properties: function () { + return {}; + }, + + setAsStart: function () { + var that = this; + + this.options.controller.get('/', function (req, res) { + res.json({ + properties: {}, + links: that.filteredLinks(req), + actions: that.filteredActions(req) + }); + }).summary('Billboard URL') + .notes('This is the starting point for using the API'); + }, + + addRepository: function (Repository) { + this.collection = this.graph.addVertexCollection(this.name); + this.collectionName = this.collection.name(); + + this.repository = new Repository(this.collection, { + model: this.model, + graph: this.graph + }); + }, + + addModel: function (Model) { + this.model = Model.extend({ + schema: _.extend(this.options.attributes, { links: { type: 'object' } }) + }, { + state: this, + }); + }, + + addService: function () { + this.action = this.options.action; + this.verb = this.options.verb.toLowerCase(); + }, + + urlForEntity: function (selector) { + if (!this.parameterized) { + throw 'This is not a paremeterized state'; + } + + return this.urlTemplate.replace(':id', selector); + }, + + urlForRelation: function (relation) { + return this.urlTemplate + '/links/' + relation.name; + }, + + entities: function () { + var entities = []; + + if (this.type === 'repository') { + entities = _.map(this.repository.all(), function (entity) { + var result = entity.forClient(); + + _.each(this.childLinks, function (link) { + result.links.push({ + rel: link.rel, + href: link.target.urlForEntity(entity.get('_key')), + title: link.title + }); + }); + return result; + }, this); + } + + return entities; + }, + + filteredLinks: function (req) { + return _.filter(this.links, function (link) { + return link.precondition(req); + }); + }, + + filteredActions: function (req) { + return _.filter(this.actions, function (action) { + return action.precondition(req); + }); + }, + + addLink: function (rel, href, title, precondition) { + this.links.push({ + precondition: precondition, + rel: rel, + href: href, + title: title + }); + }, + + addLinkViaTransitionTo: function (relation, to) { + this.addLink([relation.name], to.urlTemplate, relation.summary, relation.precondition); + }, + + addLinkToEntities: function (relation, to) { + var rel = relation.name, + href = to.urlTemplate, + title = relation.summary, + target = to; + + this.childLinks.push({ + rel: rel, + href: href, + title: title, + target: target + }); + }, + + addAction: function (name, method, href, title, fields, precondition) { + this.actions.push({ + precondition: precondition, + name: name, + // class: ?, + method: method, + href: href, + title: title, + type: 'application/json', + fields: fields + }); + }, + + addActionWithMethodForRelation: function (method, relation) { + var name = relation.name, + urlTemplate = this.urlTemplate, + summary = relation.summary, + fields = constructFields(relation), + precondition = relation.precondition; + + this.addAction(name, method, urlTemplate, summary, fields, precondition); + } + }); + + State.extend = extend; + + exports.State = State; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/state_factory.js b/js/node/node_modules/foxx_generator/foxx_generator/state_factory.js new file mode 100644 index 0000000000..3b4b5b2e17 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/state_factory.js @@ -0,0 +1,32 @@ +(function () { + 'use strict'; + var _ = require('underscore'), + State = require('./state').State, + defaultsForStateOptions, + StateFactory; + + defaultsForStateOptions = { + parameterized: false, + superstate: false, + verb: 'post', + maxFailures: 1, + queue: 'defaultQueue' + }; + + StateFactory = function (graph, transitions, states) { + this.graph = graph; + this.transitions = transitions; + this.states = states; + }; + + _.extend(StateFactory.prototype, { + create: function (name, opts) { + var options = _.defaults(opts, defaultsForStateOptions), + state = new State(name, this.graph, options); + + return state; + } + }); + + exports.StateFactory = StateFactory; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/strategy.js b/js/node/node_modules/foxx_generator/foxx_generator/strategy.js new file mode 100644 index 0000000000..b7b64d1499 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/strategy.js @@ -0,0 +1,27 @@ +(function () { + 'use strict'; + var Strategy, + _ = require('underscore'), + extend = require('org/arangodb/extend').extend; + + Strategy = function () { + }; + + _.extend(Strategy.prototype, { + executable: function (type, from, to, cardinality) { + return type === this.type && from === this.from && to === this.to && cardinality === this.cardinality; + }, + + execute: function () { + require('console').log('Nothing to do for strategy type "%s" from "%s" to "%s" with cardinality "%s"', + this.type, + this.from, + this.to, + this.cardinality); + } + }); + + Strategy.extend = extend; + + exports.Strategy = Strategy; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/transition.js b/js/node/node_modules/foxx_generator/foxx_generator/transition.js new file mode 100644 index 0000000000..db915676e7 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/transition.js @@ -0,0 +1,54 @@ +(function () { + 'use strict'; + var extend = require('org/arangodb/extend').extend, + ConditionNotFulfilled = require('./condition_not_fulfilled').ConditionNotFulfilled, + _ = require('underscore'), + Transition; + + Transition = function (graph, controller) { + this.graph = graph; + this.controller = controller; + }; + + _.extend(Transition.prototype, { + extendEdgeDefinitions: function(from, to) { + var edgeCollectionName = this.collectionBaseName + '_' + from.name + '_' + to.name; + return this.graph.extendEdgeDefinitions(edgeCollectionName, from, to); + }, + + wrappedCondition: function () { + var condition = this.condition; + + return function (req) { + if (!condition(req)) { + throw new ConditionNotFulfilled('Condition was not fulfilled'); + } + }; + }, + + createContext: function(from, to) { + var context = new this.Context(from, to, { + name: this.relationName, + edgeCollectionName: this.extendEdgeDefinitions(from, to), + cardinality: this.cardinality, + type: this.type, + parameters: this.parameters, + summary: this.summary, + notes: this.notes, + condition: this.wrappedCondition(), + precondition: this.precondition, + to: to + }); + + return context; + }, + + apply: function (from, to) { + this.createContext(from, to).execute(this.controller, this.graph); + } + }); + + Transition.extend = extend; + + exports.Transition = Transition; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/transition_factory.js b/js/node/node_modules/foxx_generator/foxx_generator/transition_factory.js new file mode 100644 index 0000000000..f81825ae4a --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/transition_factory.js @@ -0,0 +1,62 @@ +(function () { + 'use strict'; + var _ = require('underscore'), + defaultsForTransitionOptions, + parseOptions, + Transition = require('./transition').Transition, + BaseContext = require('./context').Context, + Documentation = require('./documentation').Documentation; + + defaultsForTransitionOptions = { + type: 'follow', + to: 'one', + condition: function () { return true; } + }; + + parseOptions = function (name, opts, applicationContext) { + var options, + documentation = new Documentation(applicationContext); + + opts = opts || {}; + options = _.defaults(opts, defaultsForTransitionOptions); + options.precondition = options.precondition || options.condition; + + return _.extend(options, { + collectionBaseName: options.as || name, + relationName: name, + cardinality: options.to, + summary: documentation.summary, + notes: documentation.notes + }); + }; + + var TransitionFactory = function (applicationContext, graph, controller, strategies) { + this.applicationContext = applicationContext; + this.graph = graph; + this.controller = controller; + + var Context = BaseContext.extend({ + strategies: strategies + }); + + this.Transition = Transition.extend({ + Context: Context + }); + }; + + _.extend(TransitionFactory.prototype, { + create: function (name, opts) { + var Transition, + options = parseOptions(name, opts, this.applicationContext), + transition; + + Transition = this.Transition.extend(options); + + transition = new Transition(this.graph, this.controller); + + return transition; + } + }); + + exports.TransitionFactory = TransitionFactory; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/vertex_not_found.js b/js/node/node_modules/foxx_generator/foxx_generator/vertex_not_found.js new file mode 100644 index 0000000000..6bd6e12046 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/vertex_not_found.js @@ -0,0 +1,12 @@ +(function () { + 'use strict'; + var VertexNotFound; + + VertexNotFound = function () { + this.name = 'VertexNotFound'; + this.message = 'The vertex could not be found'; + }; + VertexNotFound.prototype = Error.prototype; + + exports.VertexNotFound = VertexNotFound; +}()); diff --git a/js/node/node_modules/foxx_generator/foxx_generator/wrap_service_action.js b/js/node/node_modules/foxx_generator/foxx_generator/wrap_service_action.js new file mode 100644 index 0000000000..16cbcfdb28 --- /dev/null +++ b/js/node/node_modules/foxx_generator/foxx_generator/wrap_service_action.js @@ -0,0 +1,53 @@ +(function () { + 'use strict'; + var wrapEntity, + wrapRepository, + selectByStateType, + wrapServiceAction; + + wrapEntity = function (state) { + return function (req) { + var id = req.params('id'); + return { + superstate: { + repository: state.repository, + entity: state.repository.byId(id) + } + }; + }; + }; + + wrapRepository = function (state) { + return function () { + return { + superstate: { + repository: state.repository + } + }; + }; + }; + + selectByStateType = function (state) { + var wrapper; + + if (!state) { + return function () { return {}; }; + } + + if (state.type === 'entity') { + wrapper = wrapEntity; + } else if (state.type === 'repository') { + wrapper = wrapRepository; + } + + return wrapper(state); + }; + + wrapServiceAction = function (serviceState) { + return function (req, res) { + serviceState.action(req, res, selectByStateType(serviceState.superstate)(req)); + }; + }; + + exports.wrapServiceAction = wrapServiceAction; +}()); diff --git a/js/node/node_modules/foxx_generator/package.json b/js/node/node_modules/foxx_generator/package.json new file mode 100644 index 0000000000..1cfd5c89b1 --- /dev/null +++ b/js/node/node_modules/foxx_generator/package.json @@ -0,0 +1,34 @@ +{ + "name": "foxx_generator", + "version": "0.5.0", + "description": "Generate Foxx APIs using Statecharts and Domain Driven Design", + "main": "foxx_generator.js", + "scripts": { + "jshint": "jshint -c .jshintrc foxx_generator.js foxx_generator/*.js" + }, + "repository": { + "type": "git", + "url": "git@github.com/moonglum/foxx_generator.git" + }, + "keywords": [ + "foxx", + "arangodb", + "generator", + "hypermedia" + ], + "author": { + "name": "Lucas Dohmen", + "email": "lucas@arangodb.org" + }, + "license": "Apache License Version 2.0", + "bugs": { + "url": "https://github.com/moonglum/foxx_generator/issues" + }, + "homepage": "https://github.com/moonglum/foxx_generator", + "gitHead": "d6e918d0dd7fbe00f8faa4a96a01790cdae07833", + "readme": "# FoxxGenerator\n\nFoxxGenerator is a declarative JavaScript framework that allows developers to describe the API in terms of the domain using statecharts. This declarative approach is based upon a combination of Richardson and Amundsen's design approach described in their book [RESTful Web APIs](http://restfulwebapis.com), Eric Evans' ideas from his book [domain driven design](http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215) and the Harel's statecharts introduced in his paper *Statecharts: A Visual Formalism For Complex Systems*.\n\nTo create an API with FoxxGenerator, first draw a statechart that represents your API. In this statechart, your states can have one of the following types:\n\n* Entity: This state represents something that has an identity and an arbitrary number of (optionally nested) attributes.\n* Repository: A repository can store entities.\n* Service: A service can do something. What it can do is defined via a JavaScript function that you can define. A service does not have a state.\n\nConnect these states with transitions. When you have modeled your statechart in a way that it can fulfill all your use cases, it is time to classify your transitions. For every transition you have to decide which of the following type it follows:\n\n* `follow`: This is a transition that you can just follow from one state to the next.\n* `connect`: This is a point of extension where you can create a transition at runtime. In order to be able to follow this transition, you have to add a `follow` transition as well.\n* `disconnect`: With this transition you can remove a transition created with `connect`.\n* `modify`: This is a transition that can only be created from an entity to itself. It is used to modify the state of this entity.\n\nYou can now translate this annotated statechart into the DSL of FoxxGenerator to create your API.\n\n## Setting up a Foxx application with FoxxGenerator.\n\nFirst, create a Foxx application as described in [Foxx's manual](http://docs.arangodb.org/Foxx/README.html). In the folder of your Foxx app, you can now install FoxxGenerator with `npm install foxx_generator`. In the same way you would add a controller to your Foxx application, you can now add a FoxxGenerator to your application: In the file that would normally contain your FoxxController, add the following:\n\n```js\nvar FoxxGenerator = require('foxx_generator').Generator,\n Joi = require('joi'),\n generator;\n\ngenerator = new FoxxGenerator('name_of_your_app', {\n // To learn more about media types, see below\n mediaType: 'application/vnd.siren+json',\n applicationContext: applicationContext,\n});\n\n// Insert transition definitions here\n\n// Insert states here\n\ngenerator.generate();\n```\n\nFor more information on how to choose a media type, see the section about Media types. Now you can define the transitions you used in your statechart and then add the states and the transitions between them.\n\n## Defining the transitions\n\nEvery transition needs the following attributes:\n\n* A name for the transition that you can use when you want to add a transition of this type.\n* `type`: One of the types described above.\n* `to`: Is the target of this transition one or more states? For a `connect` transition this for example determines if you can only connect one state to it or more than that. Acceptable values are `one` and `many`.\n\nYou can also add a documentation block (a JavaScript comment starting with `/**`) that will be used for the documentation. The first line should be a short summary, all other lines will be used for a long description. An example for that would be the following transition definition:\n\n```js\n/** Show details for a particular item\n * \n * Show all information about this particular item.\n */\ngenerator.defineTransition('showDetail', {\n type: 'follow',\n to: 'one'\n});\n```\n\nFor a `connect` and `disconnect` transition you additionally have to determine which `follow` transition can be used to follow the created transition. This is done with `as` and the name of the transition.\n\nYou can also add `parameters` to the transition, if in the transition process you need additional information from the user of the API. Each of the parameters needs to be a value object defined with [Joi](https://github.com/hapijs/joi). For example:\n\n```js\n/** Modify the title of the entity\n *\n */\ngenerator.defineTransition('changeTitle', {\n type: 'modify',\n to: 'one',\n\n parameters: {\n title: Joi.string()\n }\n});\n```\n\nYou can also define a `condition` for a transition. This is a JavaScript function that takes the parameters of the HTTP request as its argument and returns either true or false. If it is true, the transition can be executed. If it is false, the transition can not be executed and the link to execute it will be hidden from the representation. This can for example be used for user authorization.\n\n## Adding states and transitions\n\nNow you can add states and transitions to your API. Every state has a name, a type and a number of outgoing transitions. The type is one of the above described ones – either `entity`, `repository` or `service`. Every transition needs information about where it leads to and via which transition type. The transition type needs to be defined as described above. Simple example:\n\n```js\ngenerator.addState('ideas', {\n type: 'repository',\n contains: 'idea',\n\n transitions: [\n { to: 'idea', via: 'showDetail' }\n ]\n});\n```\n\nSome states take additional information: Entities need to know which repository they are contained in (via `containedIn`) and repositories need to know which entities they contain (via `contains`).\n\n### Entity\n\nAn entity can be `parameterized` (by setting its attribute `parameterized` to `true`) which means that there is not only one state of that type, but there can be an arbitrary amount – each of them is identified by a parameter. This is usually the case with entities that are stored in a repository.\n\nIt also takes an object of attributes which describe the representation of the entity. Each of the attributes needs to be a value object defined with [Joi](https://github.com/hapijs/joi).\n\nExample for an entity:\n\n```js\ngenerator.addState('idea', {\n type: 'entity',\n parameterized: true,\n containedIn: 'ideas',\n\n attributes: {\n description: Joi.string().required(),\n title: Joi.string().required()\n },\n\n transitions: [\n { to: 'idea', via: 'relatedIdea' }\n ]\n});\n```\n\n### Service\n\nA service needs to describe what it does, this is done with an `action` which is a function that takes a request and a response in the [same way that a FoxxController route does](http://docs.arangodb.org/Foxx/FoxxController.html). The default HTTP verb for a service is a `post`, it can be changed by setting the `verb`. Example:\n\n```js\ngenerator.addState('title', {\n type: 'service',\n verb: 'get',\n\n action: function (req, res) {\n var entity = req.params('entity');\n res.json({ title: entity.get('title') });\n }\n});\n```\n\n## Media types\n\nFoxxGenerator currently only supports [siren](https://github.com/kevinswiber/siren) which is a media type without application semantics. Use the media type `application/vnd.siren+json`. We plan to support HAL with an extension for forms in the near future.\n\n## Interactive Documentation\n\nDuring your development, FoxxGenerator will generate an interactive documentation alongside the API. You can use this in an iterative development style to check after each step if the API is as you expected it to be. The documentation allows you to try out each of the generated endpoints. The API documentation can be found in the admin interface of ArangoDB and looks a little like this:\n\n![Overview](screenshots/overview.png)\n\nIf you click on one of the routes, you can try it out:\n\n![Try it out](screenshots/try_it_out.png)\n\n## Examples\n\n* An example for a Siren API generated with FoxxGenerator can be found [here](https://github.com/moonglum/siren)\n\n## Linting\n\nTo check the project for linting errors, run `npm run jshint`.\n", + "readmeFilename": "README.md", + "_id": "foxx_generator@0.5.0", + "_shasum": "ae854ef1a78b7f2925469e0a6e155926e52fdabc", + "_from": "foxx_generator@*" +} diff --git a/js/node/node_modules/foxx_generator/screenshots/overview.png b/js/node/node_modules/foxx_generator/screenshots/overview.png new file mode 100644 index 0000000000..72d36bb5ee Binary files /dev/null and b/js/node/node_modules/foxx_generator/screenshots/overview.png differ diff --git a/js/node/node_modules/foxx_generator/screenshots/try_it_out.png b/js/node/node_modules/foxx_generator/screenshots/try_it_out.png new file mode 100644 index 0000000000..53d1f9c0a9 Binary files /dev/null and b/js/node/node_modules/foxx_generator/screenshots/try_it_out.png differ diff --git a/js/node/node_modules/joi/.c9/.nakignore b/js/node/node_modules/joi/.c9/.nakignore new file mode 100644 index 0000000000..6d30aa67b4 --- /dev/null +++ b/js/node/node_modules/joi/.c9/.nakignore @@ -0,0 +1,17 @@ +*~backup-* +.c9revisions +.c9 +.git +.svn +.DS_Store +.bzr +.cdv +~.dep +~.dot +~.nib +~.plst +.hg +.pc +*.min.js +.nakignore +/dev diff --git a/js/node/node_modules/joi/.c9/metadata/tab0 b/js/node/node_modules/joi/.c9/metadata/tab0 new file mode 100644 index 0000000000..011ec571b9 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/tab0 @@ -0,0 +1 @@ +{"filter":false,"title":"bash - \"marsup-joi-1072366\"","tooltip":"bash - \"marsup-joi-1072366\"","undoManager":{"mark":0,"position":-1,"stack":[]},"terminal":{"id":"marsup@joi_498","cwd":"","width":1861,"height":386,"scrollTop":19842.22318649292},"timestamp":1415008774854,"hash":"da39a3ee5e6b4b0d3255bfef95601890afd80709"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/.c9/project.settings b/js/node/node_modules/joi/.c9/metadata/workspace/.c9/project.settings new file mode 100644 index 0000000000..5575c908f4 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/.c9/project.settings @@ -0,0 +1 @@ +{"changed":false,"filter":false,"title":"project.settings","tooltip":"/.c9/project.settings","value":"{\n \"run\": {\n \"@path\": \"/.c9/runners\",\n \"configs\": {\n \"json()\": {},\n \"@inited\": true\n }\n },\n \"share\": {\n \"@preview\": false,\n \"@app\": false,\n \"@useOwnerSettings\": false\n },\n \"ace\": {\n \"@newLineMode\": \"unix\",\n \"@tabSize\": \"4\",\n \"@useSoftTabs\": true,\n \"@guessTabSize\": true\n },\n \"find.nak\": {\n \"@searchLimit\": 100\n },\n \"language\": {\n \"@warnLevel\": \"info\",\n \"@instanceHighlight\": true,\n \"@undeclaredVars\": true,\n \"@unusedFunctionArgs\": false\n },\n \"build\": {\n \"@path\": \"/.c9/builders\",\n \"@saveall\": true,\n \"@builder\": \"auto\"\n }\n}","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"customSyntax":"javascript","scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415392221976} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/.travis.yml b/js/node/node_modules/joi/.c9/metadata/workspace/.travis.yml new file mode 100644 index 0000000000..13b32e3565 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/.travis.yml @@ -0,0 +1 @@ +{"filter":false,"title":".travis.yml","tooltip":"/.travis.yml","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":8},"end":{"row":4,"column":8},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"hash":"b26c436ff30d2ac8013ba767826e7adb0ab17e59","timestamp":1415572979000} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/README.md b/js/node/node_modules/joi/.c9/metadata/workspace/README.md new file mode 100644 index 0000000000..68dc5117e4 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/README.md @@ -0,0 +1 @@ +{"filter":false,"title":"README.md","tooltip":"/README.md","undoManager":{"mark":22,"position":22,"stack":[[{"group":"doc","deltas":[{"start":{"row":38,"column":25},"end":{"row":38,"column":30},"action":"remove","lines":["value"]},{"start":{"row":38,"column":25},"end":{"row":38,"column":26},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":26},"end":{"row":38,"column":27},"action":"insert","lines":["n"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":27},"end":{"row":38,"column":28},"action":"insert","lines":["a"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":28},"end":{"row":38,"column":29},"action":"insert","lines":["b"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":29},"end":{"row":38,"column":30},"action":"insert","lines":["l"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":30},"end":{"row":38,"column":31},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":31},"end":{"row":38,"column":32},"action":"insert","lines":["d"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":48},"end":{"row":38,"column":53},"action":"remove","lines":["value"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":48},"end":{"row":38,"column":49},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":49},"end":{"row":38,"column":50},"action":"insert","lines":["n"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":50},"end":{"row":38,"column":51},"action":"insert","lines":["a"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":51},"end":{"row":38,"column":52},"action":"insert","lines":["b"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":52},"end":{"row":38,"column":53},"action":"insert","lines":["l"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":53},"end":{"row":38,"column":54},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":54},"end":{"row":38,"column":55},"action":"insert","lines":["d"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":32},"end":{"row":477,"column":37},"action":"remove","lines":["value"]},{"start":{"row":477,"column":32},"end":{"row":477,"column":33},"action":"insert","lines":["e"]},{"start":{"row":475,"column":19},"end":{"row":475,"column":24},"action":"remove","lines":["value"]},{"start":{"row":475,"column":19},"end":{"row":475,"column":20},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":33},"end":{"row":477,"column":34},"action":"insert","lines":["n"]},{"start":{"row":475,"column":20},"end":{"row":475,"column":21},"action":"insert","lines":["n"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":34},"end":{"row":477,"column":35},"action":"insert","lines":["a"]},{"start":{"row":475,"column":21},"end":{"row":475,"column":22},"action":"insert","lines":["a"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":35},"end":{"row":477,"column":36},"action":"insert","lines":["b"]},{"start":{"row":475,"column":22},"end":{"row":475,"column":23},"action":"insert","lines":["b"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":36},"end":{"row":477,"column":37},"action":"insert","lines":["l"]},{"start":{"row":475,"column":23},"end":{"row":475,"column":24},"action":"insert","lines":["l"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":37},"end":{"row":477,"column":38},"action":"insert","lines":["e"]},{"start":{"row":475,"column":24},"end":{"row":475,"column":25},"action":"insert","lines":["e"]}]}],[{"group":"doc","deltas":[{"start":{"row":477,"column":38},"end":{"row":477,"column":39},"action":"insert","lines":["d"]},{"start":{"row":475,"column":25},"end":{"row":475,"column":26},"action":"insert","lines":["d"]}]}],[{"group":"doc","deltas":[{"start":{"row":38,"column":0},"end":{"row":39,"column":0},"action":"remove","lines":[" - [`array.sparse(enabled)`](#arraysparseenabled)",""]},{"start":{"row":465,"column":58},"end":{"row":465,"column":158},"action":"remove","lines":[" Note that undefined values inside arrays are not allowed by default but can be by using `sparse()`."]},{"start":{"row":474,"column":0},"end":{"row":483,"column":0},"action":"remove","lines":["#### `array.sparse(enabled)`","","Allow this array to be sparse. `enabled` can be used with a falsy value to go back to the default behavior.","","```javascript","var schema = Joi.array().sparse(); // undefined values are now allowed","schema = schema.sparse(false); // undefined values are now denied","```","",""]}]}]]},"ace":{"folds":[],"scrolltop":7634.833927154541,"scrollleft":0,"selection":{"start":{"row":475,"column":0},"end":{"row":475,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":457,"state":"jscode-start","mode":"ace/mode/markdown"}},"timestamp":1416252877680,"hash":"076bd672386ca6ec7222cfa8e4ba11891bc8b126"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/any.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/any.js new file mode 100644 index 0000000000..9854c85194 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/any.js @@ -0,0 +1 @@ +{"filter":false,"title":"any.js","tooltip":"/lib/any.js","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":2741,"scrollleft":0,"selection":{"start":{"row":166,"column":23},"end":{"row":166,"column":29},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":342,"state":"no_regex","mode":"ace/mode/javascript"}},"timestamp":1415180399000,"hash":"d449170dc0ccedd5fb7ea7e7d29c106d7ef2e0aa"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/array.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/array.js new file mode 100644 index 0000000000..3420946251 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/array.js @@ -0,0 +1 @@ +{"filter":false,"title":"array.js","tooltip":"/lib/array.js","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":20,"column":0},"end":{"row":20,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"hash":"176896676455afc62f6b48334611800d8237ac1d","timestamp":1415020417000} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/binary.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/binary.js new file mode 100644 index 0000000000..18fa95149a --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/binary.js @@ -0,0 +1 @@ +{"filter":false,"title":"binary.js","tooltip":"/lib/binary.js","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1416236566829,"hash":"9b6f08844af759e97c3dc73e09a8a4a4803dca81"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/boolean.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/boolean.js new file mode 100644 index 0000000000..ee49b64b9e --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/boolean.js @@ -0,0 +1 @@ +{"filter":false,"title":"boolean.js","tooltip":"/lib/boolean.js","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1416236563023,"hash":"b849990b16d670ccebd0b62734526e3e96da529d"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/cast.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/cast.js new file mode 100644 index 0000000000..6962abd209 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/cast.js @@ -0,0 +1 @@ +{"filter":false,"title":"cast.js","tooltip":"/lib/cast.js","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":360,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":19,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1416236557657,"hash":"82dad8939f72d5509c7b793cfbb9b00d323feb97"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/date.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/date.js new file mode 100644 index 0000000000..d537474938 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/date.js @@ -0,0 +1 @@ +{"filter":false,"title":"date.js","tooltip":"/lib/date.js","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415531927767,"hash":"d81dae2c22a8b314858ca762f8396c170fc5ef5f"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/errors.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/errors.js new file mode 100644 index 0000000000..4329c674e1 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/errors.js @@ -0,0 +1 @@ +{"filter":false,"title":"errors.js","tooltip":"/lib/errors.js","ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":3,"column":12},"end":{"row":3,"column":15},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":64,"state":"no_regex","mode":"ace/mode/javascript"}},"hash":"8ec3b723af76103ad758b0c1768a644c726078f2","undoManager":{"mark":0,"position":-1,"stack":[]},"timestamp":1415008722000} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/function.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/function.js new file mode 100644 index 0000000000..1fabb731b6 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/function.js @@ -0,0 +1 @@ +{"filter":false,"title":"function.js","tooltip":"/lib/function.js","undoManager":{"mark":-1,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1416236549420,"hash":"5843085394e4320bf0f313b4c036753a5a83aaef"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/index.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/index.js new file mode 100644 index 0000000000..1c97b57b47 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/index.js @@ -0,0 +1 @@ +{"filter":false,"title":"index.js","tooltip":"/lib/index.js","ace":{"folds":[],"scrolltop":1182,"scrollleft":0,"selection":{"start":{"row":90,"column":12},"end":{"row":90,"column":12},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":64,"state":"start","mode":"ace/mode/javascript"}},"hash":"00bb491ce725f98a9dacc5f5b6d5e43e6cca1de2","undoManager":{"mark":0,"position":-1,"stack":[]},"timestamp":1415027201704} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/language.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/language.js new file mode 100644 index 0000000000..b1684f784c --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/language.js @@ -0,0 +1 @@ +{"filter":false,"title":"language.js","tooltip":"/lib/language.js","ace":{"folds":[],"scrolltop":1041.5,"scrollleft":0,"selection":{"start":{"row":85,"column":8},"end":{"row":85,"column":13},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":56,"state":"start","mode":"ace/mode/javascript"},"cleansed":true},"hash":"81def83792799ed9455989cbffda57ce89855dea","undoManager":{"mark":0,"position":-1,"stack":[]},"timestamp":1415026883404} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/number.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/number.js new file mode 100644 index 0000000000..661da83541 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/number.js @@ -0,0 +1 @@ +{"filter":false,"title":"number.js","tooltip":"/lib/number.js","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":720,"scrollleft":0,"selection":{"start":{"row":29,"column":26},"end":{"row":29,"column":26},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":39,"state":"start","mode":"ace/mode/javascript"}},"hash":"14221f57f58b982df19c7c5440af9b1ca2917a1d","timestamp":1415025086901} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/object.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/object.js new file mode 100644 index 0000000000..b8ab89d7c8 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/object.js @@ -0,0 +1 @@ +{"filter":false,"title":"object.js","tooltip":"/lib/object.js","ace":{"folds":[],"scrolltop":840,"scrollleft":0,"selection":{"start":{"row":0,"column":0},"end":{"row":0,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":45,"state":"no_regex","mode":"ace/mode/javascript"}},"hash":"f734ae6b59414c86058f9b6677193fe129e45f57","undoManager":{"mark":0,"position":-1,"stack":[]},"timestamp":1415707992000} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/lib/string.js b/js/node/node_modules/joi/.c9/metadata/workspace/lib/string.js new file mode 100644 index 0000000000..9bd3991b4a --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/lib/string.js @@ -0,0 +1 @@ +{"filter":false,"title":"string.js","tooltip":"/lib/string.js","ace":{"folds":[],"scrolltop":1860,"scrollleft":0,"selection":{"start":{"row":128,"column":20},"end":{"row":128,"column":28},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":52,"state":"start","mode":"ace/mode/javascript"},"cleansed":true},"hash":"d060ff9793fc40243c1f3107316eeecf8a246158","undoManager":{"mark":0,"position":-1,"stack":[]},"timestamp":1415026562330} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/package.json b/js/node/node_modules/joi/.c9/metadata/workspace/package.json new file mode 100644 index 0000000000..ebc47e8094 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/package.json @@ -0,0 +1 @@ +{"filter":false,"title":"package.json","tooltip":"/package.json","undoManager":{"mark":7,"position":7,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":20,"column":0},"end":{"row":20,"column":21}},"text":" \"code\": \"^1.2.1\","},{"action":"insertText","range":{"start":{"row":20,"column":21},"end":{"row":21,"column":0}},"text":"\n"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":20,"column":13},"end":{"row":20,"column":14}},"text":"^"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":20,"column":15},"end":{"row":20,"column":16}},"text":"2"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":20,"column":15},"end":{"row":20,"column":16}},"text":"x"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":20,"column":17},"end":{"row":20,"column":18}},"text":"1"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":20,"column":17},"end":{"row":20,"column":18}},"text":"x"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":21,"column":12},"end":{"row":21,"column":13}},"text":"4"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":21,"column":12},"end":{"row":21,"column":13}},"text":"5"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":21,"column":13},"end":{"row":21,"column":13},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365338150,"hash":"c470323e0beca2fbe4a637b0c204cb4b9205c53e"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/alternatives.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/alternatives.js new file mode 100644 index 0000000000..fa88dbfb9b --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/alternatives.js @@ -0,0 +1 @@ +{"filter":false,"title":"alternatives.js","tooltip":"/test/alternatives.js","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":20,"column":25},"end":{"row":20,"column":25},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1416218382000,"hash":"133eeb46c87f4ed9015e0509e19c91816114f6fa"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/any.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/any.js new file mode 100644 index 0000000000..6ee6267bb3 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/any.js @@ -0,0 +1 @@ +{"filter":false,"title":"any.js","tooltip":"/test/any.js","undoManager":{"mark":2,"position":2,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}],[{"group":"doc","deltas":[{"action":"removeLines","range":{"start":{"row":3,"column":0},"end":{"row":4,"column":0}},"nl":"\n","lines":["var Code = require('code');"]},{"action":"removeText","range":{"start":{"row":19,"column":13},"end":{"row":19,"column":16}},"text":"Lab"},{"action":"insertText","range":{"start":{"row":19,"column":13},"end":{"row":19,"column":17}},"text":"Code"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":21},"end":{"row":4,"column":21},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365464947,"hash":"0362f0c6f4552d5b32636a598ab65f82552b279b"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/array.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/array.js new file mode 100644 index 0000000000..96e51c95cd --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/array.js @@ -0,0 +1 @@ +{"filter":false,"title":"array.js","tooltip":"/test/array.js","undoManager":{"mark":0,"position":-1,"stack":[]},"ace":{"folds":[],"scrolltop":60,"scrollleft":0,"selection":{"start":{"row":16,"column":4},"end":{"row":16,"column":10},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":2,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1415365471618,"hash":"2a0d28e1d987c72c625911280278a4224e6cd1c7"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/binary.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/binary.js new file mode 100644 index 0000000000..24dbcde9ee --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/binary.js @@ -0,0 +1 @@ +{"filter":false,"title":"binary.js","tooltip":"/test/binary.js","undoManager":{"mark":1,"position":1,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":93,"column":0},"end":{"row":93,"column":8}},"text":" "},{"action":"removeText","range":{"start":{"row":97,"column":0},"end":{"row":97,"column":16}},"text":" "}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365485882,"hash":"827a2ceee11041e1aca3503df80a33cbc9593167"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/boolean.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/boolean.js new file mode 100644 index 0000000000..477684ffea --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/boolean.js @@ -0,0 +1 @@ +{"filter":false,"title":"boolean.js","tooltip":"/test/boolean.js","undoManager":{"mark":0,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365548431,"hash":"a7fb14e44c2f95f2d36b397f9f592e2a3f544330"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/date.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/date.js new file mode 100644 index 0000000000..b9badd470d --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/date.js @@ -0,0 +1 @@ +{"filter":false,"title":"date.js","tooltip":"/test/date.js","undoManager":{"mark":10,"position":10,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":106,"column":25},"end":{"row":106,"column":26}},"text":"b"},{"action":"removeText","range":{"start":{"row":83,"column":25},"end":{"row":83,"column":26}},"text":"b"},{"action":"removeText","range":{"start":{"row":71,"column":29},"end":{"row":71,"column":30}},"text":"b"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":106,"column":25},"end":{"row":106,"column":26}},"text":"e"},{"action":"removeText","range":{"start":{"row":83,"column":25},"end":{"row":83,"column":26}},"text":"e"},{"action":"removeText","range":{"start":{"row":71,"column":29},"end":{"row":71,"column":30}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":25},"end":{"row":106,"column":26}},"text":"d"},{"action":"insertText","range":{"start":{"row":83,"column":25},"end":{"row":83,"column":26}},"text":"d"},{"action":"insertText","range":{"start":{"row":71,"column":29},"end":{"row":71,"column":30}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":26},"end":{"row":106,"column":27}},"text":"e"},{"action":"insertText","range":{"start":{"row":83,"column":26},"end":{"row":83,"column":27}},"text":"e"},{"action":"insertText","range":{"start":{"row":71,"column":30},"end":{"row":71,"column":31}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":27},"end":{"row":106,"column":28}},"text":"e"},{"action":"insertText","range":{"start":{"row":83,"column":27},"end":{"row":83,"column":28}},"text":"e"},{"action":"insertText","range":{"start":{"row":71,"column":31},"end":{"row":71,"column":32}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":28},"end":{"row":106,"column":29}},"text":"p"},{"action":"insertText","range":{"start":{"row":83,"column":28},"end":{"row":83,"column":29}},"text":"p"},{"action":"insertText","range":{"start":{"row":71,"column":32},"end":{"row":71,"column":33}},"text":"p"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":32},"end":{"row":106,"column":33}},"text":"u"},{"action":"insertText","range":{"start":{"row":83,"column":32},"end":{"row":83,"column":33}},"text":"u"},{"action":"insertText","range":{"start":{"row":71,"column":36},"end":{"row":71,"column":37}},"text":"u"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":106,"column":33},"end":{"row":106,"column":34}},"text":"a"},{"action":"insertText","range":{"start":{"row":83,"column":33},"end":{"row":83,"column":34}},"text":"a"},{"action":"insertText","range":{"start":{"row":71,"column":37},"end":{"row":71,"column":38}},"text":"a"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":213,"column":43},"end":{"row":213,"column":44}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":218,"column":43},"end":{"row":218,"column":44}},"text":"."}]}]]},"ace":{"folds":[],"scrolltop":3309.5,"scrollleft":0,"selection":{"start":{"row":218,"column":44},"end":{"row":218,"column":44},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":182,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1415365908261,"hash":"3c27814a5dce2d63f072d6a96a9238f32aa3b4bf"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/errors.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/errors.js new file mode 100644 index 0000000000..fb3d53c50e --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/errors.js @@ -0,0 +1 @@ +{"filter":false,"title":"errors.js","tooltip":"/test/errors.js","undoManager":{"mark":0,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365550196,"hash":"88bb55a14ca905983a57df59f589201567b45e92"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/function.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/function.js new file mode 100644 index 0000000000..9ed70cdf09 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/function.js @@ -0,0 +1 @@ +{"filter":false,"title":"function.js","tooltip":"/test/function.js","undoManager":{"mark":0,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365550902,"hash":"f2e9d088641e291868d10970f0182d5df19a15ab"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/helper.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/helper.js new file mode 100644 index 0000000000..6654811d00 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/helper.js @@ -0,0 +1 @@ +{"filter":false,"title":"helper.js","tooltip":"/test/helper.js","undoManager":{"mark":0,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365551639,"hash":"63dd3f704c76bf668e4b1f2e1e6aad24e3eb6336"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/index.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/index.js new file mode 100644 index 0000000000..7664c904e5 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/index.js @@ -0,0 +1 @@ +{"filter":false,"title":"index.js","tooltip":"/test/index.js","undoManager":{"mark":7,"position":7,"stack":[[{"group":"doc","deltas":[{"start":{"row":579,"column":34},"end":{"row":579,"column":36},"action":"insert","lines":["()"]},{"start":{"row":582,"column":38},"end":{"row":582,"column":40},"action":"insert","lines":["()"]},{"start":{"row":594,"column":50},"end":{"row":594,"column":52},"action":"insert","lines":["()"]},{"start":{"row":597,"column":54},"end":{"row":597,"column":56},"action":"insert","lines":["()"]},{"start":{"row":616,"column":34},"end":{"row":616,"column":36},"action":"insert","lines":["()"]},{"start":{"row":665,"column":38},"end":{"row":665,"column":40},"action":"insert","lines":["()"]},{"start":{"row":670,"column":42},"end":{"row":670,"column":44},"action":"insert","lines":["()"]},{"start":{"row":697,"column":38},"end":{"row":697,"column":40},"action":"insert","lines":["()"]},{"start":{"row":701,"column":46},"end":{"row":701,"column":48},"action":"insert","lines":["()"]},{"start":{"row":707,"column":46},"end":{"row":707,"column":48},"action":"insert","lines":["()"]},{"start":{"row":763,"column":34},"end":{"row":763,"column":36},"action":"insert","lines":["()"]},{"start":{"row":767,"column":38},"end":{"row":767,"column":40},"action":"insert","lines":["()"]},{"start":{"row":782,"column":34},"end":{"row":782,"column":36},"action":"insert","lines":["()"]},{"start":{"row":786,"column":38},"end":{"row":786,"column":40},"action":"insert","lines":["()"]},{"start":{"row":967,"column":34},"end":{"row":967,"column":36},"action":"insert","lines":["()"]},{"start":{"row":1070,"column":34},"end":{"row":1070,"column":36},"action":"insert","lines":["()"]},{"start":{"row":1113,"column":34},"end":{"row":1113,"column":36},"action":"insert","lines":["()"]},{"start":{"row":1134,"column":34},"end":{"row":1134,"column":36},"action":"insert","lines":["()"]},{"start":{"row":1139,"column":38},"end":{"row":1139,"column":40},"action":"insert","lines":["()"]},{"start":{"row":1162,"column":34},"end":{"row":1162,"column":36},"action":"insert","lines":["()"]},{"start":{"row":1167,"column":38},"end":{"row":1167,"column":40},"action":"insert","lines":["()"]}]}],[{"group":"doc","deltas":[{"start":{"row":1225,"column":39},"end":{"row":1225,"column":41},"action":"insert","lines":["()"]}]}],[{"group":"doc","deltas":[{"start":{"row":1225,"column":40},"end":{"row":1225,"column":40},"action":"insert","lines":[""]}]}],[{"group":"doc","deltas":[{"start":{"row":1225,"column":41},"end":{"row":1225,"column":42},"action":"insert","lines":[";"]}]}],[{"group":"doc","deltas":[{"start":{"row":1226,"column":40},"end":{"row":1226,"column":42},"action":"insert","lines":["()"]}]}],[{"group":"doc","deltas":[{"start":{"row":1226,"column":41},"end":{"row":1226,"column":41},"action":"insert","lines":[""]}]}],[{"group":"doc","deltas":[{"start":{"row":1226,"column":42},"end":{"row":1226,"column":43},"action":"insert","lines":[";"]}]}],[{"group":"doc","deltas":[{"start":{"row":579,"column":34},"end":{"row":579,"column":36},"action":"remove","lines":["()"]},{"start":{"row":580,"column":0},"end":{"row":580,"column":0},"action":"insert","lines":[""]},{"start":{"row":582,"column":38},"end":{"row":582,"column":40},"action":"remove","lines":["()"]},{"start":{"row":594,"column":50},"end":{"row":594,"column":52},"action":"remove","lines":["()"]},{"start":{"row":597,"column":54},"end":{"row":597,"column":56},"action":"remove","lines":["()"]},{"start":{"row":616,"column":34},"end":{"row":616,"column":36},"action":"remove","lines":["()"]},{"start":{"row":665,"column":38},"end":{"row":665,"column":40},"action":"remove","lines":["()"]},{"start":{"row":670,"column":42},"end":{"row":670,"column":44},"action":"remove","lines":["()"]},{"start":{"row":697,"column":38},"end":{"row":697,"column":40},"action":"remove","lines":["()"]},{"start":{"row":701,"column":46},"end":{"row":701,"column":48},"action":"remove","lines":["()"]},{"start":{"row":707,"column":46},"end":{"row":707,"column":48},"action":"remove","lines":["()"]},{"start":{"row":763,"column":34},"end":{"row":763,"column":36},"action":"remove","lines":["()"]},{"start":{"row":767,"column":38},"end":{"row":767,"column":40},"action":"remove","lines":["()"]},{"start":{"row":782,"column":34},"end":{"row":782,"column":36},"action":"remove","lines":["()"]},{"start":{"row":786,"column":38},"end":{"row":786,"column":40},"action":"remove","lines":["()"]},{"start":{"row":967,"column":34},"end":{"row":967,"column":36},"action":"remove","lines":["()"]},{"start":{"row":1070,"column":34},"end":{"row":1070,"column":36},"action":"remove","lines":["()"]},{"start":{"row":1113,"column":34},"end":{"row":1113,"column":36},"action":"remove","lines":["()"]},{"start":{"row":1134,"column":34},"end":{"row":1134,"column":36},"action":"remove","lines":["()"]},{"start":{"row":1139,"column":38},"end":{"row":1139,"column":40},"action":"remove","lines":["()"]},{"start":{"row":1162,"column":34},"end":{"row":1162,"column":36},"action":"remove","lines":["()"]},{"start":{"row":1167,"column":38},"end":{"row":1167,"column":40},"action":"remove","lines":["()"]},{"start":{"row":1225,"column":39},"end":{"row":1225,"column":42},"action":"remove","lines":["();"]},{"start":{"row":1226,"column":40},"end":{"row":1226,"column":43},"action":"remove","lines":["();"]}]}]]},"ace":{"folds":[],"scrolltop":20239.668224334717,"scrollleft":0,"selection":{"start":{"row":1226,"column":40},"end":{"row":1226,"column":40},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":342,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1416252619504,"hash":"3d0e779687e0a732014ca99bdb18192738d5ae38"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/number.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/number.js new file mode 100644 index 0000000000..d20923a486 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/number.js @@ -0,0 +1 @@ +{"filter":false,"title":"number.js","tooltip":"/test/number.js","undoManager":{"mark":0,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365553045,"hash":"fb307b8890979629fcf9436f28e0d707eb9753e5"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/object.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/object.js new file mode 100644 index 0000000000..761ecd91d1 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/object.js @@ -0,0 +1 @@ +{"filter":false,"title":"object.js","tooltip":"/test/object.js","undoManager":{"mark":69,"position":69,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":23},"end":{"row":569,"column":24}},"text":"O"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":24},"end":{"row":569,"column":25}},"text":"b"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":25},"end":{"row":569,"column":26}},"text":"j"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":26},"end":{"row":569,"column":27}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":27},"end":{"row":569,"column":28}},"text":"c"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":28},"end":{"row":569,"column":29}},"text":"t"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":29},"end":{"row":569,"column":30}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":30},"end":{"row":569,"column":31}},"text":"k"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":31},"end":{"row":569,"column":32}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":32},"end":{"row":569,"column":33}},"text":"y"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":33},"end":{"row":569,"column":34}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":34},"end":{"row":569,"column":35}},"text":"("}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":40},"end":{"row":569,"column":41}},"text":")"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":569,"column":46},"end":{"row":569,"column":50}},"text":"have"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":569,"column":46},"end":{"row":569,"column":47}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":569,"column":46},"end":{"row":569,"column":50}},"text":"keys"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":46},"end":{"row":569,"column":47}},"text":"i"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":47},"end":{"row":569,"column":48}},"text":"n"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":48},"end":{"row":569,"column":49}},"text":"c"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":49},"end":{"row":569,"column":50}},"text":"l"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":50},"end":{"row":569,"column":51}},"text":"u"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":51},"end":{"row":569,"column":52}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":569,"column":52},"end":{"row":569,"column":53}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":569,"column":54},"end":{"row":569,"column":55}},"text":"["}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":569,"column":57},"end":{"row":569,"column":58}},"text":"]"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":19},"end":{"row":597,"column":20}},"text":"O"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":20},"end":{"row":597,"column":21}},"text":"b"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":21},"end":{"row":597,"column":22}},"text":"j"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":22},"end":{"row":597,"column":23}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":23},"end":{"row":597,"column":24}},"text":"c"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":24},"end":{"row":597,"column":25}},"text":"t"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":25},"end":{"row":597,"column":26}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":26},"end":{"row":597,"column":27}},"text":"k"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":27},"end":{"row":597,"column":28}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":28},"end":{"row":597,"column":29}},"text":"y"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":29},"end":{"row":597,"column":30}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":30},"end":{"row":597,"column":31}},"text":"("}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":51},"end":{"row":597,"column":52}},"text":")"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":597,"column":62},"end":{"row":597,"column":69}},"text":"contain"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":597,"column":62},"end":{"row":597,"column":63}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":597,"column":62},"end":{"row":597,"column":65}},"text":"key"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":62},"end":{"row":597,"column":63}},"text":"i"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":63},"end":{"row":597,"column":64}},"text":"n"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":64},"end":{"row":597,"column":65}},"text":"c"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":65},"end":{"row":597,"column":66}},"text":"l"},{"action":"insertText","range":{"start":{"row":597,"column":66},"end":{"row":597,"column":67}},"text":"u"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":67},"end":{"row":597,"column":68}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":597,"column":68},"end":{"row":597,"column":69}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":19},"end":{"row":598,"column":20}},"text":"O"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":20},"end":{"row":598,"column":21}},"text":"b"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":21},"end":{"row":598,"column":22}},"text":"j"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":22},"end":{"row":598,"column":23}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":23},"end":{"row":598,"column":24}},"text":"c"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":24},"end":{"row":598,"column":25}},"text":"t"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":25},"end":{"row":598,"column":26}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":26},"end":{"row":598,"column":27}},"text":"k"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":27},"end":{"row":598,"column":28}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":28},"end":{"row":598,"column":29}},"text":"y"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":29},"end":{"row":598,"column":30}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":30},"end":{"row":598,"column":31}},"text":"("}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":49},"end":{"row":598,"column":50}},"text":")"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":598,"column":54},"end":{"row":598,"column":61}},"text":"contain"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":598,"column":54},"end":{"row":598,"column":55}},"text":"."}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":598,"column":54},"end":{"row":598,"column":57}},"text":"key"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":54},"end":{"row":598,"column":55}},"text":"i"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":55},"end":{"row":598,"column":56}},"text":"n"},{"action":"insertText","range":{"start":{"row":598,"column":56},"end":{"row":598,"column":57}},"text":"c"},{"action":"insertText","range":{"start":{"row":598,"column":57},"end":{"row":598,"column":58}},"text":"l"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":58},"end":{"row":598,"column":59}},"text":"u"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":59},"end":{"row":598,"column":60}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":598,"column":60},"end":{"row":598,"column":61}},"text":"e"}]}],[{"group":"doc","deltas":[{"action":"removeText","range":{"start":{"row":45,"column":8},"end":{"row":45,"column":15}},"text":"should "},{"action":"insertText","range":{"start":{"row":45,"column":16},"end":{"row":45,"column":17}},"text":"s"},{"action":"insertText","range":{"start":{"row":55,"column":0},"end":{"row":55,"column":75}},"text":" it('return object reference when no rules specified', function (done) {"},{"action":"insertText","range":{"start":{"row":55,"column":75},"end":{"row":56,"column":0}},"text":"\n"},{"action":"insertLines","range":{"start":{"row":56,"column":0},"end":{"row":69,"column":0}},"lines":[""," var schema = Joi.object({"," a: Joi.object()"," });",""," var item = { x: 5 };"," schema.validate({ a: item }, function (err, value) {",""," expect(value.a).to.equal(item);"," done();"," });"," });",""]}]}]]},"ace":{"folds":[],"scrolltop":10470,"scrollleft":0,"selection":{"start":{"row":590,"column":4},"end":{"row":590,"column":24},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":182,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1415365932943,"hash":"f2d969780fb6f9875439f049d433d3a2b9ab8971"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/ref.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/ref.js new file mode 100644 index 0000000000..b3ca5843fb --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/ref.js @@ -0,0 +1 @@ +{"filter":false,"title":"ref.js","tooltip":"/test/ref.js","undoManager":{"mark":2,"position":2,"stack":[[{"group":"doc","deltas":[{"start":{"row":355,"column":52},"end":{"row":355,"column":54},"action":"insert","lines":["()"]}]}],[{"group":"doc","deltas":[{"start":{"row":355,"column":53},"end":{"row":355,"column":53},"action":"insert","lines":[""]}]}],[{"group":"doc","deltas":[{"start":{"row":355,"column":52},"end":{"row":355,"column":54},"action":"remove","lines":["()"]}]}]]},"ace":{"folds":[],"scrolltop":5720.16711807251,"scrollleft":0,"selection":{"start":{"row":355,"column":52},"end":{"row":355,"column":52},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":{"row":342,"state":"start","mode":"ace/mode/javascript"}},"timestamp":1416252630421,"hash":"c2e3bbcb46a736408d213db793eb4b6b3612cacf"} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/metadata/workspace/test/string.js b/js/node/node_modules/joi/.c9/metadata/workspace/test/string.js new file mode 100644 index 0000000000..6149c5d654 --- /dev/null +++ b/js/node/node_modules/joi/.c9/metadata/workspace/test/string.js @@ -0,0 +1 @@ +{"changed":true,"filter":false,"title":"string.js","tooltip":"/test/string.js","value":"// Load modules\n\nvar Lab = require('lab');\nvar Code = require('code');\nvar Joi = require('../lib');\nvar Helper = require('./helper');\n\n\n// Declare internals\n\nvar internals = {};\n\n\n// Test shortcuts\n\nvar lab = exports.lab = Lab.script();\nvar before = lab.before;\nvar after = lab.after;\nvar describe = lab.describe;\nvar it = lab.it;\nvar expect = Code.expect;\n\n\ndescribe('string', function () {\n\n it('fails on boolean', function (done) {\n\n var schema = Joi.string();\n Helper.validate(schema, [\n [true, false],\n [false, false]\n ], done);\n });\n\n describe('#valid', function () {\n\n it('should throw error on input not matching type', function (done) {\n\n expect(function () {\n\n Joi.string().valid({});\n }).to.throw();\n done();\n });\n\n it('should not throw on input matching type', function (done) {\n\n expect(function () {\n\n Joi.string().valid('joi');\n }).to.not.throw();\n done();\n });\n\n it('validates case sensitive values', function (done) {\n\n Helper.validate(Joi.string().valid('a', 'b'), [\n ['a', true],\n ['b', true],\n ['A', false],\n ['B', false]\n ], done);\n });\n\n it('validates case insensitive values', function (done) {\n\n Helper.validate(Joi.string().valid('a', 'b').insensitive(), [\n ['a', true],\n ['b', true],\n ['A', true],\n ['B', true],\n [4, false]\n ], done);\n });\n\n it('validates case insensitive values with non-strings', function (done) {\n\n Helper.validate(Joi.string().valid('a', 'b', 5).insensitive(), [\n ['a', true],\n ['b', true],\n ['A', true],\n ['B', true],\n [4, false],\n [5, true]\n ], done);\n });\n });\n\n describe('#invalid', function () {\n\n it('should throw error on input not matching type', function (done) {\n\n expect(function () {\n\n Joi.string().invalid({});\n }).to.throw();\n done();\n });\n\n it('should not throw on input matching type', function (done) {\n\n expect(function () {\n\n Joi.string().invalid('joi');\n }).to.not.throw();\n done();\n });\n\n it('invalidates case sensitive values', function (done) {\n\n Helper.validate(Joi.string().invalid('a', 'b'), [\n ['a', false],\n ['b', false],\n ['A', true],\n ['B', true]\n ], done);\n });\n\n it('invalidates case insensitive values', function (done) {\n\n Helper.validate(Joi.string().invalid('a', 'b').insensitive(), [\n ['a', false],\n ['b', false],\n ['A', false],\n ['B', false]\n ], done);\n });\n });\n\n describe('#min', function () {\n\n it('throws when limit is not a number', function (done) {\n\n expect(function () {\n\n Joi.string().min('a');\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('throws when limit is not an integer', function (done) {\n\n expect(function () {\n\n Joi.string().min(1.2);\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('enforces a limit using byte count', function (done) {\n\n var schema = Joi.string().min(2, 'utf8');\n Helper.validate(schema, [\n ['\\u00bd', true],\n ['a', false]\n ], done);\n });\n });\n\n describe('#max', function () {\n\n it('throws when limit is not a number', function (done) {\n\n expect(function () {\n\n Joi.string().max('a');\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('throws when limit is not an integer', function (done) {\n\n expect(function () {\n\n Joi.string().max(1.2);\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('enforces a limit using byte count', function (done) {\n\n var schema = Joi.string().max(1, 'utf8');\n Helper.validate(schema, [\n ['\\u00bd', false],\n ['a', true]\n ], done);\n });\n });\n\n describe('#creditCard', function () {\n\n it('should validate credit card', function (done) {\n\n var t = Joi.string().creditCard();\n t.validate('4111111111111112', function (err, value) {\n\n expect(err.message).to.equal('value must be a credit card');\n\n Helper.validate(t, [\n ['378734493671000', true], // american express\n ['371449635398431', true], // american express\n ['378282246310005', true], // american express\n ['341111111111111', true], // american express\n ['5610591081018250', true], // australian bank\n ['5019717010103742', true], // dankort pbs\n ['38520000023237', true], // diners club\n ['30569309025904', true], // diners club\n ['6011000990139424', true], // discover\n ['6011111111111117', true], // discover\n ['6011601160116611', true], // discover\n ['3566002020360505', true], // jbc\n ['3530111333300000', true], // jbc\n ['5105105105105100', true], // mastercard\n ['5555555555554444', true], // mastercard\n ['5431111111111111', true], // mastercard\n ['6331101999990016', true], // switch/solo paymentech\n ['4222222222222', true], // visa\n ['4012888888881881', true], // visa\n ['4111111111111111', true], // visa\n ['4111111111111112', false],\n [null, false],\n ], done);\n });\n });\n });\n\n describe('#length', function () {\n\n it('throws when limit is not a number', function (done) {\n\n expect(function () {\n\n Joi.string().length('a');\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('throws when limit is not an integer', function (done) {\n\n expect(function () {\n\n Joi.string().length(1.2);\n }).to.throw('limit must be a positive integer');\n done();\n });\n\n it('enforces a limit using byte count', function (done) {\n\n var schema = Joi.string().length(2, 'utf8');\n Helper.validate(schema, [\n ['\\u00bd', true],\n ['a', false]\n ], done);\n });\n });\n\n describe('#hostname', function () {\n\n it('validates hostnames', function (done) {\n\n var schema = Joi.string().hostname();\n Helper.validate(schema, [\n ['www.example.com', true],\n ['domain.local', true],\n ['3domain.local', true],\n ['hostname', true],\n ['host:name', false],\n ['-', false],\n ['2387628', true],\n ['01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', false],\n ['::1', true],\n ['0:0:0:0:0:0:0:1', true],\n ['0:?:0:0:0:0:0:1', false]\n ], done);\n });\n });\n\n describe('#lowercase', function () {\n\n it('only allows strings that are entirely lowercase', function (done) {\n\n var schema = Joi.string().lowercase();\n Helper.validateOptions(schema, [\n ['this is all lowercase', true],\n ['5', true],\n ['lower\\tcase', true],\n ['Uppercase', false],\n ['MixEd cAsE', false],\n [1, false]\n ], { convert: false }, done);\n });\n\n it('coerce string to lowercase before validation', function (done) {\n\n var schema = Joi.string().lowercase();\n schema.validate('UPPER TO LOWER', function (err, value) {\n\n expect(err).to.not.exist;\n expect(value).to.equal('upper to lower');\n done();\n });\n });\n\n it('should work in combination with a trim', function (done) {\n\n var schema = Joi.string().lowercase().trim();\n Helper.validate(schema, [\n [' abc', true],\n [' ABC', true],\n ['ABC', true],\n [1, false]\n ], done);\n });\n });\n\n describe('#uppercase', function () {\n\n it('only allow strings that are entirely uppercase', function (done) {\n\n var schema = Joi.string().uppercase();\n Helper.validateOptions(schema, [\n ['THIS IS ALL UPPERCASE', true],\n ['5', true],\n ['UPPER\\nCASE', true],\n ['lOWERCASE', false],\n ['MixEd cAsE', false],\n [1, false]\n ], { convert: false }, done);\n });\n\n it('coerce string to uppercase before validation', function (done) {\n\n var schema = Joi.string().uppercase();\n schema.validate('lower to upper', function (err, value) {\n\n expect(err).to.not.exist;\n expect(value).to.equal('LOWER TO UPPER');\n done();\n });\n });\n\n it('works in combination with a forced trim', function (done) {\n\n var schema = Joi.string().uppercase().trim();\n Helper.validate(schema, [\n [' abc', true],\n [' ABC', true],\n ['ABC', true],\n [1, false]\n ], done);\n });\n });\n\n describe('#trim', function () {\n\n it('only allow strings that have no leading or trailing whitespace', function (done) {\n\n var schema = Joi.string().trim();\n Helper.validateOptions(schema, [\n [' something', false],\n ['something ', false],\n ['something\\n', false],\n ['some thing', true],\n ['something', true]\n ], { convert: false }, done);\n });\n\n it('removes leading and trailing whitespace before validation', function (done) {\n\n var schema = Joi.string().trim();\n schema.validate(' trim this ', function (err, value) {\n\n expect(err).to.not.exist;\n expect(value).to.equal('trim this');\n done();\n });\n });\n\n it('removes leading and trailing whitespace before validation', function (done) {\n\n var schema = Joi.string().trim().allow('');\n schema.validate(' ', function (err, value) {\n\n expect(err).to.not.exist;\n expect(value).to.equal('');\n done();\n });\n });\n\n it('should work in combination with min', function (done) {\n\n var schema = Joi.string().min(4).trim();\n Helper.validate(schema, [\n [' a ', false],\n ['abc ', false],\n ['abcd ', true]\n ], done);\n });\n\n it('should work in combination with max', function (done) {\n\n var schema = Joi.string().max(4).trim();\n Helper.validate(schema, [\n [' abcde ', false],\n ['abc ', true],\n ['abcd ', true]\n ], done);\n });\n\n it('should work in combination with length', function (done) {\n\n var schema = Joi.string().length(4).trim();\n Helper.validate(schema, [\n [' ab ', false],\n ['abc ', false],\n ['abcd ', true]\n ], done);\n });\n\n it('should work in combination with a case change', function (done) {\n\n var schema = Joi.string().trim().lowercase();\n Helper.validate(schema, [\n [' abc', true],\n [' ABC', true],\n ['ABC', true]\n ], done);\n });\n });\n\n describe('#regex', function () {\n\n it('should not include a pattern name by default', function (done) {\n\n var schema = Joi.string().regex(/[a-z]+/).regex(/[0-9]+/);\n schema.validate('abcd', function (err, value) {\n\n expect(err.message).to.contain('required pattern');\n done();\n });\n });\n\n it('should include a pattern name if specified', function (done) {\n\n var schema = Joi.string().regex(/[a-z]+/, 'letters').regex(/[0-9]+/, 'numbers');\n schema.validate('abcd', function (err, value) {\n\n expect(err.message).to.contain('numbers pattern');\n done();\n });\n });\n });\n\n describe('#validate', function () {\n\n it('should, by default, allow undefined, deny empty string', function (done) {\n\n Helper.validate(Joi.string(), [\n [undefined, true],\n ['', false]\n ], done);\n });\n\n it('should, when .required(), deny undefined, deny empty string', function (done) {\n\n Helper.validate(Joi.string().required(), [\n [undefined, false],\n ['', false]\n ], done);\n });\n\n it('should, when .required(), print a friend error message for an empty string', function (done) {\n\n var schema = Joi.string().required();\n Joi.compile(schema).validate('', function (err, value) {\n\n expect(err.message).to.contain('be empty');\n done();\n });\n });\n\n it('should, when .required(), validate non-empty strings', function (done) {\n\n var schema = Joi.string().required();\n Helper.validate(schema, [\n ['test', true],\n ['0', true],\n [null, false]\n ], done);\n });\n\n it('validates invalid values', function (done) {\n\n var schema = Joi.string().invalid('a', 'b', 'c');\n Helper.validate(schema, [\n ['x', true],\n ['a', false],\n ['c', false]\n ], done);\n });\n\n it('should invalidate invalid values', function (done) {\n\n var schema = Joi.string().valid('a', 'b', 'c');\n Helper.validate(schema, [\n ['x', false],\n ['a', true],\n ['c', true]\n ], done);\n });\n\n it('validates array arguments correctly', function (done) {\n\n var schema = Joi.string().valid(['a', 'b', 'c']);\n Helper.validate(schema, [\n ['x', false],\n ['a', true],\n ['c', true]\n ], done);\n });\n\n it('validates minimum length when min is used', function (done) {\n\n var schema = Joi.string().min(3);\n Helper.validate(schema, [\n ['test', true],\n ['0', false],\n [null, false]\n ], done);\n });\n\n it('validates minimum length when min is 0', function (done) {\n\n var schema = Joi.string().min(0).required();\n Helper.validate(schema, [\n ['0', true],\n [null, false],\n [undefined, false]\n ], done);\n });\n\n it('should return false with minimum length and a null value passed in', function (done) {\n\n var schema = Joi.string().min(3);\n Helper.validate(schema, [\n [null, false]\n ], done);\n });\n\n it('null allowed overrides min length requirement', function (done) {\n\n var schema = Joi.string().min(3).allow(null);\n Helper.validate(schema, [\n [null, true]\n ], done);\n });\n\n it('validates maximum length when max is used', function (done) {\n\n var schema = Joi.string().max(3);\n Helper.validate(schema, [\n ['test', false],\n ['0', true],\n [null, false]\n ], done);\n });\n\n it('should return true with max and not required when value is undefined', function (done) {\n\n var schema = Joi.string().max(3);\n Helper.validate(schema, [\n [undefined, true]\n ], done);\n });\n\n it('validates length requirements', function (done) {\n\n var schema = Joi.string().length(3);\n Helper.validate(schema, [\n ['test', false],\n ['0', false],\n [null, false],\n ['abc', true]\n ], done);\n });\n\n it('validates regex', function (done) {\n\n var schema = Joi.string().regex(/^[0-9][-][a-z]+$/);\n Helper.validate(schema, [\n ['van', false],\n ['0-www', true]\n ], done);\n });\n\n it('validates regex (ignoring global flag)', function (done) {\n\n var schema = Joi.string().regex(/a/g);\n Helper.validate(schema, [\n ['ab', true],\n ['ac', true]\n ], done);\n });\n\n it('validates token', function (done) {\n\n var schema = Joi.string().token();\n Helper.validate(schema, [\n ['w0rld_of_w4lm4rtl4bs', true],\n ['w0rld of_w4lm4rtl4bs', false],\n ['abcd#f?h1j orly?', false]\n ], done);\n });\n\n it('validates alphanum', function (done) {\n\n var schema = Joi.string().alphanum();\n Helper.validate(schema, [\n ['w0rld of w4lm4rtl4bs', false],\n ['w0rldofw4lm4rtl4bs', true],\n ['abcd#f?h1j orly?', false]\n ], done);\n });\n\n it('validates email', function (done) {\n\n var schema = Joi.string().email();\n Helper.validate(schema, [\n ['joe@example.com', true],\n ['\"joe\"@example.com', true],\n ['@iaminvalid.com', false],\n ['joe@[IPv6:2a00:1450:4001:c02::1b]', true],\n ['12345678901234567890123456789012345678901234567890123456789012345@walmartlabs.com', false],\n ['123456789012345678901234567890123456789012345678901234567890@12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345.toolong.com', false]\n ], done);\n });\n\n it('validates email with a friendly error message', function (done) {\n\n var schema = { item: Joi.string().email() };\n Joi.compile(schema).validate({ item: 'something' }, function (err, value) {\n\n expect(err.message).to.contain('must be a valid email');\n done();\n });\n });\n\n it('should return false for denied value', function (done) {\n\n var text = Joi.string().invalid('joi');\n text.validate('joi', function (err, value) {\n\n expect(err).to.exist;\n done();\n });\n });\n\n it('should return true for allowed value', function (done) {\n\n var text = Joi.string().allow('hapi');\n text.validate('result', function (err, value) {\n\n expect(err).to.not.exist;\n done();\n });\n });\n\n it('validates with one validator (min)', function (done) {\n\n var text = Joi.string().min(3);\n text.validate('joi', function (err, value) {\n\n expect(err).to.not.exist;\n done();\n });\n });\n\n it('validates with two validators (min, required)', function (done) {\n\n var text = Joi.string().min(3).required();\n text.validate('joi', function (err, value) {\n\n expect(err).to.not.exist;\n\n text.validate('', function (err, value) {\n\n expect(err).to.exist;\n done();\n });\n });\n });\n\n it('validates null with allow(null)', function (done) {\n\n Helper.validate(Joi.string().allow(null), [\n [null, true]\n ], done);\n });\n\n it('validates \"\" (empty string) with allow(\\'\\')', function (done) {\n\n Helper.validate(Joi.string().allow(''), [\n ['', true],\n ['', true]\n ], done);\n });\n\n it('validates combination of required and min', function (done) {\n\n var rule = Joi.string().required().min(3);\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of required and max', function (done) {\n\n var rule = Joi.string().required().max(3);\n Helper.validate(rule, [\n ['x', true],\n ['123', true],\n ['1234', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of allow(\\'\\') and min', function (done) {\n\n var rule = Joi.string().allow('').min(3);\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', true],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of allow(\\'\\') and max', function (done) {\n\n var rule = Joi.string().allow('').max(3);\n Helper.validate(rule, [\n ['x', true],\n ['123', true],\n ['1234', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of null allowed and max', function (done) {\n var rule = Joi.string().allow(null).max(3);\n Helper.validate(rule, [\n ['x', true],\n ['123', true],\n ['1234', false],\n ['', false],\n [null, true]\n ], done);\n });\n\n it('validates combination of min and max', function (done) {\n\n var rule = Joi.string().min(2).max(3);\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().min(2).max(3).allow('');\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, and required', function (done) {\n\n var rule = Joi.string().min(2).max(3).required();\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, and regex', function (done) {\n\n var rule = Joi.string().min(2).max(3).regex(/^a/);\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, regex, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().min(2).max(3).regex(/^a/).allow('');\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, regex, and required', function (done) {\n\n var rule = Joi.string().min(2).max(3).regex(/^a/).required();\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, and alphanum', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum();\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['*ab', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, alphanum, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum().allow('');\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['*ab', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, alphanum, and required', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum().required();\n Helper.validate(rule, [\n ['x', false],\n ['123', true],\n ['1234', false],\n ['12', true],\n ['ab', true],\n ['abc', true],\n ['abcd', false],\n ['*ab', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, alphanum, and regex', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum().regex(/^a/);\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['a2c', true],\n ['abcd', false],\n ['*ab', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, alphanum, required, and regex', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum().required().regex(/^a/);\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['a2c', true],\n ['abcd', false],\n ['*ab', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of min, max, alphanum, allow(\\'\\'), and regex', function (done) {\n\n var rule = Joi.string().min(2).max(3).alphanum().allow('').regex(/^a/);\n Helper.validate(rule, [\n ['x', false],\n ['123', false],\n ['1234', false],\n ['12', false],\n ['ab', true],\n ['abc', true],\n ['a2c', true],\n ['abcd', false],\n ['*ab', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email and min', function (done) {\n\n var rule = Joi.string().email().min(8);\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', true],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, and max', function (done) {\n\n var rule = Joi.string().email().min(8).max(10);\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', true],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, and invalid', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).invalid('123@x.com');\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, and allow', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com');\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', true],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, allow, and invalid', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com');\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, allow, invalid, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').allow('');\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, allow, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com').allow('');\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', true],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, allow, invalid, and regex', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/);\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, allow, invalid, regex, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/).allow('');\n Helper.validate(rule, [\n ['x@x.com', true],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).allow('');\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', true],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, and regex', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).regex(/^1234/);\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, regex, and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).regex(/^1234/).allow('');\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of email, min, max, regex, and required', function (done) {\n\n var rule = Joi.string().email().min(8).max(10).regex(/^1234/).required();\n Helper.validate(rule, [\n ['x@x.com', false],\n ['123@x.com', false],\n ['1234@x.com', true],\n ['12345@x.com', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates isoDate', function (done) {\n\n Helper.validate(Joi.string().isoDate(), [\n ['2013-06-07T14:21:46.295Z', true],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', true],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', true],\n ['2013-06-07T14:21:46-07:00', true],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', true],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', true],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false]\n ], done);\n });\n\n it('validates isoDate with a friendly error message', function (done) {\n\n var schema = { item: Joi.string().isoDate() };\n Joi.compile(schema).validate({ item: 'something' }, function (err, value) {\n\n expect(err.message).to.contain('must be a valid ISO 8601 date');\n done();\n });\n });\n\n it('validates combination of isoDate and min', function (done) {\n\n var rule = Joi.string().isoDate().min(23);\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', true],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', true],\n ['2013-06-07T14:21:46Z', false],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', true],\n ['2013-06-07T14:21:46-07:00', true],\n ['2013-06-07T14:21Z', false],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min and max', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23);\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', true],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max and invalid', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).invalid('2013-06-07T14:21+07:00');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max and allow', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', true],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, allow and invalid', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21+07:00');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, allow, invalid and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21+07:00').allow('');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, allow, invalid and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').allow('');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', true],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, allow, invalid and regex', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21Z').regex(/Z$/);\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', false],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, allow, invalid, regex and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21Z').regex(/Z$/).allow('');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', true],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', false],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).allow('');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', true],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', true],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max and regex', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).regex(/Z$/);\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, regex and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).regex(/Z$/).allow('');\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of isoDate, min, max, regex and required', function (done) {\n\n var rule = Joi.string().isoDate().min(17).max(23).regex(/Z$/).required();\n Helper.validate(rule, [\n ['2013-06-07T14:21:46.295Z', false],\n ['2013-06-07T14:21:46.295Z0', false],\n ['2013-06-07T14:21:46.295+07:00', false],\n ['2013-06-07T14:21:46.295+07:000', false],\n ['2013-06-07T14:21:46.295-07:00', false],\n ['2013-06-07T14:21:46Z', true],\n ['2013-06-07T14:21:46Z0', false],\n ['2013-06-07T14:21:46+07:00', false],\n ['2013-06-07T14:21:46-07:00', false],\n ['2013-06-07T14:21Z', true],\n ['2013-06-07T14:21+07:00', false],\n ['2013-06-07T14:21+07:000', false],\n ['2013-06-07T14:21-07:00', false],\n ['2013-06-07T14:21Z+7:00', false],\n ['2013-06-07', false],\n ['2013-06-07T', false],\n ['2013-06-07T14:21', false],\n ['1-1-2013', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates guid', function (done) {\n\n Helper.validate(Joi.string().guid(), [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', true],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', true],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', true],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', true],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', true],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false]\n ], done);\n });\n\n it('validates guid with a friendly error message', function (done) {\n\n var schema = { item: Joi.string().guid() };\n Joi.compile(schema).validate({ item: 'something' }, function (err, value) {\n\n expect(err.message).to.contain('must be a valid GUID');\n done();\n });\n });\n\n it('validates combination of guid and min', function (done) {\n\n var rule = Joi.string().guid().min(36);\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', true],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', true],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', true],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', false],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', true],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min and max', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34);\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', true],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max and invalid', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).invalid('b4b2fb69c6244e5eb0698e0c6ec66618');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max and allow', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', true],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, allow and invalid', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').invalid('b4b2fb69c6244e5eb0698e0c6ec66618');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, allow, invalid and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').allow('');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, allow and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').allow('');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', true],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, allow, invalid and regex', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/);\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, allow, invalid, regex and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/).allow('');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08', true],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).allow('');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', true],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', true],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', true],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max and regex', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).regex(/^{7e9081/i);\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, regex and allow(\\'\\')', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).regex(/^{7e9081/i).allow('');\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', true],\n [null, false]\n ], done);\n });\n\n it('validates combination of guid, min, max, regex and required', function (done) {\n\n var rule = Joi.string().guid().min(32).max(34).regex(/^{7e9081/i).required();\n Helper.validate(rule, [\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['{B59511BD6A5F4DF09ECF562A108D8A2E}', false],\n ['69593D62-71EA-4548-85E4-04FC71357423', false],\n ['677E2553DD4D43B09DA77414DB1EB8EA', false],\n ['{5ba3bba3-729a-4717-88c1-b7c4b7ba80db}', false],\n ['{7e9081b59a6d4cc1a8c347f69fb4198d}', true],\n ['0c74f13f-fa83-4c48-9b33-68921dd72463', false],\n ['b4b2fb69c6244e5eb0698e0c6ec66618', false],\n ['{283B67B2-430F-4E6F-97E6-19041992-C1B0}', false],\n ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D', false],\n ['D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],\n ['', false],\n [null, false]\n ], done);\n });\n });\n});\n","undoManager":{"mark":-1,"position":0,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":3,"column":0},"end":{"row":3,"column":27}},"text":"var Code = require('code');"},{"action":"insertText","range":{"start":{"row":3,"column":27},"end":{"row":4,"column":0}},"text":"\n"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":4,"column":0},"end":{"row":4,"column":0},"isBackwards":true},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1415365529437} \ No newline at end of file diff --git a/js/node/node_modules/joi/.c9/project.settings b/js/node/node_modules/joi/.c9/project.settings new file mode 100644 index 0000000000..f95eafa687 --- /dev/null +++ b/js/node/node_modules/joi/.c9/project.settings @@ -0,0 +1,34 @@ +{ + "run": { + "@path": "/.c9/runners", + "configs": { + "json()": {}, + "@inited": "true" + } + }, + "share": { + "@preview": false, + "@app": false, + "@useOwnerSettings": false + }, + "ace": { + "@newLineMode": "unix", + "@tabSize": "4", + "@useSoftTabs": "true", + "@guessTabSize": "true" + }, + "find.nak": { + "@searchLimit": 100 + }, + "language": { + "@warnLevel": "info", + "@instanceHighlight": "true", + "@undeclaredVars": "true", + "@unusedFunctionArgs": "false" + }, + "build": { + "@path": "/.c9/builders", + "@saveall": "true", + "@builder": "auto" + } +} \ No newline at end of file diff --git a/js/node/node_modules/joi/.travis.yml b/js/node/node_modules/joi/.travis.yml index 047f7e3d5e..5e7286f853 100755 --- a/js/node/node_modules/joi/.travis.yml +++ b/js/node/node_modules/joi/.travis.yml @@ -2,4 +2,5 @@ language: node_js node_js: - 0.10 + - 0.11 diff --git a/js/node/node_modules/joi/AUTHORS b/js/node/node_modules/joi/AUTHORS deleted file mode 100644 index 93b7813e9e..0000000000 --- a/js/node/node_modules/joi/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Van Nguyen -Eran Hammer (http://hueniverse.com) -Wyatt Preul (http://jsgeek.com) \ No newline at end of file diff --git a/js/node/node_modules/joi/CONTRIBUTING.md b/js/node/node_modules/joi/CONTRIBUTING.md old mode 100644 new mode 100755 index f62b5e92d7..c6b9dfafd8 --- a/js/node/node_modules/joi/CONTRIBUTING.md +++ b/js/node/node_modules/joi/CONTRIBUTING.md @@ -2,13 +2,13 @@ We welcome contributions from the community and are pleased to have them. Please follow this guide when logging issues or making code changes. ## Logging Issues -All issues should be created using the [new issue form](https://github.com/spumko/joi/issues/new). Clearly describe the issue including steps to reproduce if there are any. Also, make sure to indicate the earliest version that has the issue being reported. +All issues should be created using the [new issue form](https://github.com/hapijs/joi/issues/new). Clearly describe the issue including steps to reproduce if there are any. Also, make sure to indicate the earliest version that has the issue being reported. ## Patching Code Code changes are welcome and should follow the guidelines below. * Fork the repository on GitHub. -* Fix the issue ensuring that your code follows the [style guide](https://github.com/spumko/hapi/blob/master/docs/Style.md). +* Fix the issue ensuring that your code follows the [style guide](https://github.com/hapijs/hapi/blob/master/docs/Style.md). * Add tests for your new code ensuring that you have 100% code coverage (we can help you reach 100% but will not merge without it). * Run `npm test` to generate a report of test coverage -* [Pull requests](http://help.github.com/send-pull-requests/) should be made to the [master branch](https://github.com/spumko/joi/tree/master). \ No newline at end of file +* [Pull requests](http://help.github.com/send-pull-requests/) should be made to the [master branch](https://github.com/hapijs/joi/tree/master). \ No newline at end of file diff --git a/js/node/node_modules/joi/LICENSE b/js/node/node_modules/joi/LICENSE index 911b97ee67..03afbde32a 100755 --- a/js/node/node_modules/joi/LICENSE +++ b/js/node/node_modules/joi/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2013, Walmart. +Copyright (c) 2012-2014, Walmart and other contributors. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -8,17 +8,21 @@ modification, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Walmart nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * The names of any contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * * * + +The complete list of contributors can be found at: https://github.com/hapijs/joi/graphs/contributors \ No newline at end of file diff --git a/js/node/node_modules/joi/README.md b/js/node/node_modules/joi/README.md index bb094a7478..f69ea6a329 100755 --- a/js/node/node_modules/joi/README.md +++ b/js/node/node_modules/joi/README.md @@ -1,22 +1,21 @@ - -![joi Logo](https://raw.github.com/spumko/joi/master/images/joi.png) +![joi Logo](https://raw.github.com/hapijs/joi/master/images/joi.png) Object schema description language and validator for JavaScript objects. -Current version: **4.6.x** +Current version: **4.7.x** -[![Build Status](https://secure.travis-ci.org/spumko/joi.png)](http://travis-ci.org/spumko/joi) +[![Build Status](https://secure.travis-ci.org/hapijs/joi.png)](http://travis-ci.org/hapijs/joi) -[![Browser Support](https://ci.testling.com/spumko/joi.png)](https://ci.testling.com/spumko/joi) +Lead Maintainer: [Nicolas Morel](https://github.com/marsup) ## Table of Contents - + - [Example](#example) - [Usage](#usage) - - [`validate(value, schema, [options], callback)`](#validatevalue-schema-options-callback) + - [`validate(value, schema, [options], [callback])`](#validatevalue-schema-options-callback) - [`compile(schema)`](#compileschema) - - [`assert(value, schema)`](#assertvalue-schema) + - [`assert(value, schema, [message])`](#assertvalue-schema-message) - [`any`](#any) - [`any.allow(value)`](#anyallowvalue) - [`any.valid(value)`](#anyvalidvalue) @@ -35,12 +34,14 @@ Current version: **4.6.x** - [`any.default(value)`](#anydefaultvalue) - [`any.concat(schema)`](#anyconcatschema) - [`any.when(ref, options)`](#anywhenref-options) + - [`any.label(name)`](#anylabelname) - [`array`](#array) - [`array.includes(type)`](#arrayincludestype) - [`array.excludes(type)`](#arrayexcludestype) - [`array.min(limit)`](#arrayminlimit) - [`array.max(limit)`](#arraymaxlimit) - [`array.length(limit)`](#arraylengthlimit) + - [`array.unique()`](#arrayunique) - [`binary`](#binary) - [`binary.encoding(encoding)`](#binaryencodingencoding) - [`binary.min(limit)`](#binaryminlimit) @@ -50,11 +51,16 @@ Current version: **4.6.x** - [`date`](#date) - [`date.min(date)`](#datemindate) - [`date.max(date)`](#datemaxdate) + - [`date.format(format)`](#dateformatformat) + - [`date.iso()`](#dateiso) - [`func`](#func) - [`number`](#number) - [`number.min(limit)`](#numberminlimit) - [`number.max(limit)`](#numbermaxlimit) + - [`number.greater(limit)`](#numbergreaterlimit) + - [`number.less(limit)`](#numberlesslimit) - [`number.integer()`](#numberinteger) + - [`number.precision(limit)`](#numberprecisionlimit) - [`object`](#object) - [`object.keys([schema])`](#objectkeysschema) - [`object.min(limit)`](#objectminlimit) @@ -62,24 +68,26 @@ Current version: **4.6.x** - [`object.length(limit)`](#objectlengthlimit) - [`object.pattern(regex, schema)`](#objectpatternregex-schema) - [`object.and(peers)`](#objectandpeers) + - [`object.nand(peers)`](#objectnandpeers) - [`object.or(peers)`](#objectorpeers) - [`object.xor(peers)`](#objectxorpeers) - [`object.with(key, peers)`](#objectwithkey-peers) - [`object.without(key, peers)`](#objectwithoutkey-peers) - [`object.rename(from, to, [options])`](#objectrenamefrom-to-options) - - [`object.assert(ref, schema, message)`](#objectassertref-schema-message) + - [`object.assert(ref, schema, [message])`](#objectassertref-schema-message) - [`object.unknown([allow])`](#objectunknownallow) + - [`object.type(constructor, [name])`](#objecttypeconstructorname) - [`string`](#string) - [`string.insensitive()`](#stringinsensitive) - [`string.min(limit, [encoding])`](#stringminlimit-encoding) - [`string.max(limit, [encoding])`](#stringmaxlimit-encoding) + - [`string.creditCard()`](#stringcreditCard) - [`string.length(limit, [encoding])`](#stringlengthlimit-encoding) - - [`string.regex(pattern)`](#stringregexpattern) + - [`string.regex(pattern, [name])`](#stringregexpattern) - [`string.alphanum()`](#stringalphanum) - [`string.token()`](#stringtoken) - [`string.email()`](#stringemail) - [`string.guid()`](#stringguid) - - [`string.isoDate()`](#stringisodate) - [`string.hostname()`](#stringhostname) - [`string.lowercase()`](#stringlowercase) - [`string.uppercase()`](#stringuppercase) @@ -163,7 +171,7 @@ When validating a schema: * Strings are utf-8 encoded by default. * Rules are defined in an additive fashion and evaluated in order after whitelist and blacklist checks. -### `validate(value, schema, [options], callback)` +### `validate(value, schema, [options], [callback])` Validates a value using the given schema and options where: - `value` - the value being validated. @@ -174,13 +182,16 @@ Validates a value using the given schema and options where: - `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`. - `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`. - `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`. - - `language` - overrides individual error messages. Defaults to no override (`{}`). + - `language` - overrides individual error messages, when `'label'` is set, it overrides the key name in the error message. Defaults to no override (`{}`). + - `presence` - sets the default presence requirements. Supported modes: `'optional'`, `'required'`, and `'forbidden'`. + Defaults to `'optional'`. - `context` - provides an external data set to be used in [references](#refkey-options). Can only be set as an external option to `validate()` and not using `any.options()`. -- `callback` - the synchronous callback method using the signature `function(err, value)` where: +- `callback` - the optional synchronous callback method using the signature `function(err, value)` where: - `err` - if validation failed, the error reason, otherwise `null`. - `value` - the validated value with any type conversions and other modifiers applied (the input is left unchanged). `value` can be - incomplete if validation failed and `abortEarly` is `true`. + incomplete if validation failed and `abortEarly` is `true`. If callback is not provided, then returns an object with error + and value properties. ```javascript var schema = { @@ -194,6 +205,11 @@ var value = { Joi.validate(value, schema, function (err, value) { }); // err -> null // value.a -> 123 (number, not string) + +// or +var result = Joi.validate(value, schema); +// result.error -> null +// result.value -> { "a" : 123 } ``` ### `compile(schema)` @@ -220,11 +236,12 @@ var schema = Joi.alternatives().try([ ]); ``` -### `assert(value, schema)` +### `assert(value, schema, [message])` Validates a value against a schema and throws if validation fails where: - `value` - the value to validate. - `schema` - the schema object. +- `message` - optional message sting prefix added in front of the error message. ```javascript Joi.assert('x', Joi.number()); @@ -303,7 +320,7 @@ Marks a key as forbidden which will not allow any value except `undefined`. Used ```javascript var schema = { - a: Joi.any.forbidden() + a: Joi.any().forbidden() }; ``` @@ -423,6 +440,27 @@ var schema = { }; ``` +Alternatively, if you want to specify a specific type such as `string`, `array`, etc, you can do so like this: + +```javascript +var schema = { + a: Joi.valid('a', 'b', 'other'), + other: Joi.string() + .when('a', { is: 'other', then: Joi.required() }), +}; +``` + +#### `any.label(name)` + +Overrides the key name in error messages. +- `name` - the name of the key. + +```javascript +var schema = { + first_name: Joi.string().label('First Name') +}; +``` + ### `array` Generates a schema object that matches an array data type. @@ -479,6 +517,14 @@ Specifies the exact number of items in the array where: var schema = Joi.array().length(5); ``` +#### `array.unique()` + +Requires the array values to be unique. Only works for literals (numbers and strings), all other types are ignored. + +```javascript +var schema = Joi.array().unique(); +``` + ### `boolean` Generates a schema object that matches a boolean data type (as well as the strings 'true', 'false', 'yes', and 'no'). Can also be called via `bool()`. @@ -556,6 +602,12 @@ Specifies the oldest date allowed where: var schema = Joi.date().min('1-1-1974'); ``` +Note: `'now'` can be passed in lieu of `date` so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future. + +```javascript +var schema = Joi.date().min('now'); +``` + #### `date.max(date)` Specifies the latest date allowed where: @@ -565,6 +617,29 @@ Specifies the latest date allowed where: var schema = Joi.date().max('12-31-2020'); ``` +Note: `'now'` can be passed in lieu of `date` so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future. + +```javascript +var schema = Joi.date().max('now'); +``` + +#### `date.format(format)` + +Specifies the allowed date format: +- `format` - string or array of strings that follow the `moment.js` [format](http://momentjs.com/docs/#/parsing/string-format/). + +```javascript +var schema = Joi.date().format('YYYY/MM/DD'); +``` + +#### `date.iso()` + +Requires the string value to be in valid ISO 8601 date format. + +```javascript +var schema = Joi.date().iso(); +``` + ### `func` Generates a schema object that matches a function type. @@ -605,6 +680,22 @@ Specifies the maximum value where: var schema = Joi.number().max(10); ``` +#### `number.greater(limit)` + +Specifies that the value must be greater than `limit`. + +```javascript +var schema = Joi.number().greater(5); +``` + +#### `number.less(limit)` + +Specifies that the value must be less than `limit`. + +```javascript +var schema = Joi.number().less(10); +``` + #### `number.integer()` Requires the number to be an integer (no floating point). @@ -613,6 +704,15 @@ Requires the number to be an integer (no floating point). var schema = Joi.number().integer(); ``` +#### `number.precision(limit)` + +Specifies the maximum number of decimal places where: +- `limit` - the maximum number of decimal places allowed. + +```javascript +var schema = Joi.number().precision(2); +``` + ### `object` Generates a schema object that matches an object data type (as well as JSON strings that parsed into objects). Defaults @@ -631,17 +731,21 @@ object.validate({ a: 5 }, function (err, value) { }); #### `object.keys([schema])` -Sets the allowed object keys where: -- `schema` - optional object where each key is assinged a **joi** type object. If `schema` is `{}` no keys allowed. +Sets or extends the allowed object keys where: +- `schema` - optional object where each key is assigned a **joi** type object. If `schema` is `{}` no keys allowed. If `schema` is `null` or `undefined`, any key allowed. If `schema` is an object with keys, the keys are added to any previously defined keys (but narrows the selection if all keys previously allowed). Defaults to 'undefined' which allows any child key. ```javascript -var object = Joi.object().keys({ - a: Joi.number() +var base = Joi.object().keys({ + a: Joi.number(), b: Joi.string() }); +// Validate keys a, b and c. +var extended = base.keys({ + c: Joi.boolean() +}); ``` #### `object.min(limit)` @@ -697,6 +801,20 @@ var schema = Joi.object().keys({ }).and('a', 'b'); ``` +#### `object.nand(peers)` + +Defines a relationship between keys where not all peers can be present at the +same time where: +- `peers` - the key names of which if one present, the others may not all be present. `peers` can be a single string value, an + array of string values, or each peer provided as an argument. + +```javascript +var schema = Joi.object().keys({ + a: Joi.any(), + b: Joi.any() +}).nand('a', 'b'); +``` + #### `object.or(peers)` Defines a relationship between keys where one of the peers is required (and more than one is allowed) where: @@ -772,13 +890,13 @@ var object = Joi.object().keys({ object.validate({ b: 5 }, function (err, value) { }); ``` -#### `object.assert(ref, schema, message)` +#### `object.assert(ref, schema, [message])` Verifies an assertion where: - `ref` - the key name or [reference](#refkey-options). - `schema` - the validation rules required to satisfy the assertion. If the `schema` includes references, they are resolved against the object value, not the value of the `ref` target. -- `message` - human-readable message used when the assertion fails. +- `message` - optional human-readable message used when the assertion fails. Defaults to 'failed to pass the assertion test'. ```javascript var schema = Joi.object().keys({ @@ -798,7 +916,17 @@ Overrides the handling of unknown keys for the scope of the current object only - `allow` - if `false`, unknown keys are not allowed, otherwise unknown keys are ignored. ```javascript -var schema = Joi.Object({ a: Joi.any() }).unknown(); +var schema = Joi.object({ a: Joi.any() }).unknown(); +``` + +#### `object.type(constructor, [name])` + +Requires the object to be an instance of a given constructor where: +- `constructor` - the constructor function that the object must be an instance of. +- `name` - an alternate name to use in validation errors. This is useful when the constructor function does not have a name. + +```javascript +var schema = Joi.object().type(RegExp); ``` ### `string` @@ -840,6 +968,15 @@ Specifies the maximum number of string characters where: var schema = Joi.string().max(10); ``` +#### `string.creditCard()` + +Requires the number to be a credit card number (Using [Lunh +Algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm)). + +```javascript +var schema = Joi.string().creditCard(); +``` + #### `string.length(limit, [encoding])` Specifies the exact string length required where: @@ -850,10 +987,11 @@ Specifies the exact string length required where: var schema = Joi.string().length(5); ``` -#### `string.regex(pattern)` +#### `string.regex(pattern, [name])` Defines a regular expression rule where: - `pattern` - a regular expression object the string value must match against. +- `name` - optional name for patterns (useful with multiple patterns). Defaults to 'required'. ```javascript var schema = Joi.string().regex(/^[abc]+$/); @@ -891,14 +1029,6 @@ Requires the string value to be a valid GUID. var schema = Joi.string().guid(); ``` -#### `string.isoDate()` - -Requires the string value to be in valid ISO 8601 date format. - -```javascript -var schema = Joi.string().isoDate(); -``` - #### `string.hostname()` Requires the string value to be a valid hostname as per [RFC1123](http://tools.ietf.org/html/rfc1123). @@ -948,7 +1078,7 @@ var alt = Joi.alternatives().try(Joi.number(), Joi.string()); // Same as [Joi.number(), Joi.string()] ``` -#### `alternatives.try(schemas)`` +#### `alternatives.try(schemas)` Adds an alternative schema type for attempting to match against the validated value where: - `schema` - an array of alternative **joi** types. Also supports providing each type as a separate argument. @@ -1004,8 +1134,8 @@ var schema = { Generates a reference to the value of the named key. References are resolved at validation time and in order of dependency so that if one key validation depends on another, the dependent key is validated second after the reference is validated. References support the following arguments: -- `key` - the reference target. References cannot point up the object tree, only to siebling keys, but they can point to - their siebling's children (e.g. 'a.b.c') using the `.` separator. If a `key` starts with `$` is signifies a context reference +- `key` - the reference target. References cannot point up the object tree, only to sibling keys, but they can point to + their siblings' children (e.g. 'a.b.c') using the `.` separator. If a `key` starts with `$` is signifies a context reference which is looked up in the `context` option object. - `options` - optional settings: - `separator` - overrides the default `.` hierarchy separator. diff --git a/js/node/node_modules/joi/examples/conditionalRequire.js b/js/node/node_modules/joi/examples/conditionalRequire.js new file mode 100644 index 0000000000..8ed0a6a6e3 --- /dev/null +++ b/js/node/node_modules/joi/examples/conditionalRequire.js @@ -0,0 +1,43 @@ +// This is an example of a survey to obtain the reputation of Parisians +// It contains examples of how to conditionally require keys based on values of other keys + +var Joi = require("../"); + +// This is a valid value for integer rating 1 - 5 +var intRating = Joi.number().integer().min(1).max(5); + +var schema = Joi.object().keys({ + // Do you know any French people? yes or no (required) + q1: Joi.boolean().required(), + // Do you know any Parisians? yes or no (required if answered yes in q1) + q2: Joi.boolean() + .when('q1', { is: true, then: Joi.required() }), + // How many french in paris do you know? 1-6, 6-10, 11-50 or 50+ (required if answered yes in q2) + q3: Joi.string() + .when('q2', { is: true, then: Joi.valid('1-5', '6-10', '11-50', '50+').required() }), + // Rate 20% of most friendly Parisians, from how many people you know answered in q3, individually on 1-5 rating + q4: Joi.array() + .when('q3', {is: '1-5', then: Joi.array().min(0).max(1).includes(intRating).required() }) + .when('q3', {is: '6-10', then: Joi.array().min(1).max(2).includes(intRating).required() }) + .when('q3', {is: '11-50', then: Joi.array().min(2).max(10).includes(intRating).required() }) + .when('q3', {is: '50+' , then: Joi.array().min(10).includes(intRating).required() }), + // Rate remaining 80% of Parisians, from how many people you know answered in q3, individually on 1-5 rating + q5: Joi.array() + .when('q3', {is: '1-5', then: Joi.array().min(1).max(4).includes(intRating).required() }) + .when('q3', {is: '6-10', then: Joi.array().min(4).max(8).includes(intRating).required() }) + .when('q3', {is: '11-50', then: Joi.array().min(8).max(40).includes(intRating).required() }) + .when('q3', {is: '50+' , then: Joi.array().min(40).includes(intRating).required().required() }), + // Rate the reputation of Parisians in general, 1-5 rating + q6: intRating.required() +}); + +var response = { + q1: true, + q2: true, + q3: '1-5', + q4: [5], + q4: [1], + q6: 2 +}; + +Joi.assert(response, schema); diff --git a/js/node/node_modules/joi/examples/customMessage.js b/js/node/node_modules/joi/examples/customMessage.js new file mode 100755 index 0000000000..38cd28ac3b --- /dev/null +++ b/js/node/node_modules/joi/examples/customMessage.js @@ -0,0 +1,22 @@ +var Joi = require('../'); + + +var schema = Joi.object().options({ abortEarly: false }).keys({ + email: Joi.string().email().required().label('User Email'), + password: Joi.string().min(8).required(), + password_confirmation: Joi.any().valid(Joi.ref('password')).required().options({ language: { any: { allowOnly: 'must match password' }, label: 'Password Confirmation' } }).label('This label is not used because language.label takes precedence'), + first_name: Joi.string().required(), + last_name: Joi.string().required(), + company: Joi.string().optional() +}); + + +var data = { + email: 'not_a_valid_email_to_show_custom_label', + password: 'abcd1234', + password_confirmation: 'abc1', + first_name: 'Joe', + last_name: 'Doe' +}; + +Joi.assert(data, schema); diff --git a/js/node/node_modules/joi/examples/multipleWhen.js b/js/node/node_modules/joi/examples/multipleWhen.js new file mode 100755 index 0000000000..b13cba9ce1 --- /dev/null +++ b/js/node/node_modules/joi/examples/multipleWhen.js @@ -0,0 +1,17 @@ +var Joi = require('../'); + + +var schema = { + type: Joi.string().required(), + subtype: Joi.alternatives() + .when('type', {is: 'video', then: Joi.valid('mp4', 'wav')}) + .when('type', {is: 'audio', then: Joi.valid('mp3')}) + .when('type', {is: 'image', then: Joi.valid('jpg', 'png')}) + .when('type', {is: 'pdf' , then: Joi.valid('document')}) +}; + + +Joi.assert({ type: 'video', subtype: 'mp4' }, schema); // Pass +Joi.assert({ type: 'video', subtype: 'wav' }, schema); // Pass +Joi.assert({ type: 'other', subtype: 'something' }, schema); // Fail +Joi.assert({ type: 'audio', subtype: 'mp4' }, schema); // Fail diff --git a/js/node/node_modules/joi/lib/any.js b/js/node/node_modules/joi/lib/any.js old mode 100755 new mode 100644 index 003d2e5e56..d28a8f2cc2 --- a/js/node/node_modules/joi/lib/any.js +++ b/js/node/node_modules/joi/lib/any.js @@ -19,7 +19,8 @@ internals.defaults = { allowUnknown: false, skipFunctions: false, stripUnknown: false, - language: {} + language: {}, + presence: 'optional' // context: null }; @@ -43,7 +44,7 @@ module.exports = internals.Any = function () { insensitive: false, trim: false, case: undefined // upper, lower - */}; + */ }; this._description = null; this._unit = null; @@ -61,8 +62,7 @@ internals.Any.prototype.isImmutable = true; // Prevents Hoek from deep cloni internals.Any.prototype.clone = function () { - var obj = {}; - obj.__proto__ = Object.getPrototypeOf(this); + var obj = Object.create(Object.getPrototypeOf(this)); obj.isJoi = true; obj._type = this._type; @@ -207,7 +207,15 @@ internals.Any.prototype.required = internals.Any.prototype.exist = function () { internals.Any.prototype.optional = function () { var obj = this.clone(); - delete obj._flags.presence; // Defaults to 'optional' + obj._flags.presence = 'optional'; + return obj; +}; + + +internals.Any.prototype.forbidden = function () { + + var obj = this.clone(); + obj._flags.presence = 'forbidden'; return obj; }; @@ -221,14 +229,6 @@ internals.Any.prototype.default = function (value) { }; -internals.Any.prototype.forbidden = function () { - - var obj = this.clone(); - obj._flags.presence = 'forbidden'; - return obj; -}; - - internals.Any.prototype.when = function (ref, options) { Hoek.assert(options && typeof options === 'object', 'Invalid options'); @@ -329,27 +329,26 @@ internals.Any.prototype._validate = function (value, state, options, reference) // Check presence requirements - if (this._flags.presence) { // 'required', 'forbidden', or 'ignore' - if (this._flags.presence === 'required' && - value === undefined) { - - errors.push(Errors.create('any.required', null, state, options)); - return finish(); - } - else if (this._flags.presence === 'forbidden') { - if (value === undefined) { - return finish(); - } - - errors.push(Errors.create('any.unknown', null, state, options)); - return finish(); - } - } - else { // 'optional' + var presence = this._flags.presence || options.presence; + if (presence === 'optional') { if (value === undefined) { return finish(); } } + else if (presence === 'required' && + value === undefined) { + + errors.push(Errors.create('any.required', null, state, options)); + return finish(); + } + else if (presence === 'forbidden') { + if (value === undefined) { + return finish(); + } + + errors.push(Errors.create('any.unknown', null, state, options)); + return finish(); + } // Check allowed and denied values using the original value @@ -496,7 +495,7 @@ internals.Any.prototype.describe = function () { for (var i = 0, il = this._tests.length; i < il; ++i) { var validator = this._tests[i]; var item = { name: validator.name }; - if (validator.arg) { + if (validator.arg !== void 0) { item.arg = validator.arg; } description.rules.push(item); @@ -509,6 +508,18 @@ internals.Any.prototype.describe = function () { return description; }; +internals.Any.prototype.label = function (name) { + + Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string'); + + var obj = this.clone(); + var options = { language: { label: name } }; + + // If language.label is set, it should override this label + obj._settings = internals.concatSettings(options, obj._settings); + return obj; +}; + // Set diff --git a/js/node/node_modules/joi/lib/array.js b/js/node/node_modules/joi/lib/array.js index b1643838bb..c4f0b9091a 100755 --- a/js/node/node_modules/joi/lib/array.js +++ b/js/node/node_modules/joi/lib/array.js @@ -1,6 +1,5 @@ // Load modules -var Sys = require('sys'); var Any = require('./any'); var Cast = require('./cast'); var Errors = require('./errors'); @@ -190,4 +189,29 @@ internals.Array.prototype.length = function (limit) { }; +internals.Array.prototype.unique = function () { + + return this._test('unique', undefined, function (value, state, options) { + + var found = { + string: {}, + number: {} + }; + + for (var i = 0, il = value.length; i < il; ++i) { + var item = value[i]; + var type = typeof item; + var records = found[type]; + if (records) { + if (records[item]) { + return Errors.create('array.unique', { pos: i }, state, options); + } + + records[item] = true; + } + } + }); +}; + + module.exports = new internals.Array(); diff --git a/js/node/node_modules/joi/lib/date.js b/js/node/node_modules/joi/lib/date.js index b1462682ed..7ab90c45e7 100755 --- a/js/node/node_modules/joi/lib/date.js +++ b/js/node/node_modules/joi/lib/date.js @@ -3,12 +3,15 @@ var Any = require('./any'); var Errors = require('./errors'); var Hoek = require('hoek'); +var Moment = require('moment'); // Declare internals var internals = {}; +internals.isoDate = /^((\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\d))$/; +internals.invalidDate = new Date(''); internals.Date = function () { @@ -22,15 +25,21 @@ Hoek.inherits(internals.Date, Any); internals.Date.prototype._base = function (value, state, options) { var result = { - value: (options.convert && internals.toDate(value)) || value + value: (options.convert && internals.toDate(value, this._flags.format)) || value }; - result.errors = (result.value instanceof Date && !isNaN(result.value.getTime())) ? null : Errors.create('date.base', null, state, options); + if (result.value instanceof Date && !isNaN(result.value.getTime())) { + result.errors = null; + } + else { + result.errors = Errors.create(this._flags.format === internals.isoDate ? 'date.isoDate' : 'date.base', null, state, options); + } + return result; }; -internals.toDate = function (value) { +internals.toDate = function (value, format) { if (value instanceof Date) { return value; @@ -40,12 +49,25 @@ internals.toDate = function (value) { Hoek.isInteger(value)) { if (typeof value === 'string' && - /^\d+$/.test(value)) { + /^[+-]?\d+$/.test(value)) { value = parseInt(value, 10); } - var date = new Date(value); + var date; + if (format) { + if (format === internals.isoDate) { + date = format.test(value) ? new Date(value) : internals.invalidDate; + } + else { + date = Moment(value, format, true); + date = date.isValid() ? date.toDate() : internals.invalidDate; + } + } + else { + date = new Date(value); + } + if (!isNaN(date.getTime())) { return date; } @@ -57,12 +79,17 @@ internals.toDate = function (value) { internals.Date.prototype.min = function (date) { - date = internals.toDate(date); + var isNow = date === 'now'; + + if (!isNow) { + date = internals.toDate(date); + } + Hoek.assert(date, 'Invalid date format'); return this._test('min', date, function (value, state, options) { - if (value.getTime() >= date.getTime()) { + if (value.getTime() >= (isNow ? Date.now() : date.getTime())) { return null; } @@ -73,12 +100,17 @@ internals.Date.prototype.min = function (date) { internals.Date.prototype.max = function (date) { - date = internals.toDate(date); + var isNow = date === 'now'; + + if (!isNow) { + date = internals.toDate(date); + } + Hoek.assert(date, 'Invalid date format'); return this._test('max', date, function (value, state, options) { - if (value.getTime() <= date.getTime()) { + if (value.getTime() <= (isNow ? Date.now() : date.getTime())) { return null; } @@ -86,5 +118,28 @@ internals.Date.prototype.max = function (date) { }); }; +internals.Date.prototype.format = function (format) { + + Hoek.assert(typeof format === 'string' || (Array.isArray(format) && format.every(function (f) { + + return typeof f === 'string'; + })), 'Invalid format.'); + + var obj = this.clone(); + obj._flags.format = format; + return obj; +}; + +internals.Date.prototype.iso = function () { + + var obj = this.clone(); + obj._flags.format = internals.isoDate; + return obj; +} + +internals.Date.prototype._isIsoDate = function (value) { + + return internals.isoDate.test(value); +}; module.exports = new internals.Date(); diff --git a/js/node/node_modules/joi/lib/errors.js b/js/node/node_modules/joi/lib/errors.js index cac3a69074..d5b24c6c96 100755 --- a/js/node/node_modules/joi/lib/errors.js +++ b/js/node/node_modules/joi/lib/errors.js @@ -24,7 +24,7 @@ internals.Err.prototype.toString = function () { var self = this; var localized = this.options.language; - this.context.key = this.context.key || localized.root || Language.errors.root; + this.context.key = localized.label || this.context.key || localized.root || Language.errors.root; var format = Hoek.reach(localized, this.type) || Hoek.reach(Language.errors, this.type); var hasKey = /\{\{\!?key\}\}/.test(format); @@ -57,7 +57,7 @@ exports.process = function (errors, object) { var item = errors[i]; details.push({ message: item.toString(), - path: item.path || item.context.key, + path: internals.getPath(item), type: item.type }); } @@ -79,6 +79,22 @@ exports.process = function (errors, object) { }; +internals.getPath = function (item) { + + var recursePath = function (it) { + + var reachedItem = Hoek.reach(it, 'context.reason.0'); + if (reachedItem && reachedItem.context) { + return recursePath(reachedItem); + } + + return it.path; + }; + + return recursePath(item) || item.context.key; +}; + + internals.annotate = function () { var obj = Hoek.clone(this._object || {}); diff --git a/js/node/node_modules/joi/lib/index.js b/js/node/node_modules/joi/lib/index.js index 9890dd0264..2db8d5dc4b 100755 --- a/js/node/node_modules/joi/lib/index.js +++ b/js/node/node_modules/joi/lib/index.js @@ -113,11 +113,12 @@ internals.root = function () { return Cast.schema(schema); }; - root.assert = function (value, schema) { + root.assert = function (value, schema, message) { + message = (message ? message + ' ' : ''); var error = root.validate(value, schema).error; if (error) { - throw new Error(error.annotate()); + throw new Error(message + error.annotate()); } }; diff --git a/js/node/node_modules/joi/lib/language.js b/js/node/node_modules/joi/lib/language.js index a0619efb8a..047aadcdb1 100755 --- a/js/node/node_modules/joi/lib/language.js +++ b/js/node/node_modules/joi/lib/language.js @@ -25,7 +25,8 @@ exports.errors = { excludes: 'position {{pos}} contains an excluded value', min: 'must contain at least {{limit}} items', max: 'must contain less than or equal to {{limit}} items', - length: 'must contain {{limit}} items' + length: 'must contain {{limit}} items', + unique: 'position {{pos}} contains a duplicate value' }, boolean: { base: 'must be a boolean' @@ -39,7 +40,8 @@ exports.errors = { date: { base: 'must be a number of milliseconds or valid date string', min: 'must be larger than or equal to {{limit}}', - max: 'must be less than or equal to {{limit}}' + max: 'must be less than or equal to {{limit}}', + isoDate: 'must be a valid ISO 8601 date' }, function: { base: 'must be a Function' @@ -56,20 +58,25 @@ exports.errors = { xor: 'contains a conflict between exclusive peers {{peers}}', or: 'must contain at least one of {{peers}}', and: 'contains {{present}} without its required peers {{missing}}', + nand: '{{main}} must not exist simultaneously with {{peers}}', assert: 'validation failed because {{ref}} failed to {{message}}', rename: { multiple: 'cannot rename child {{from}} because multiple renames are disabled and another key was already renamed to {{to}}', override: 'cannot rename child {{from}} because override is disabled and target {{to}} exists' - } + }, + type: 'must be an instance of {{type}}' }, number: { base: 'must be a number', min: 'must be larger than or equal to {{limit}}', max: 'must be less than or equal to {{limit}}', + less: 'must be less than {{limit}}', + greater: 'must be greater than {{limit}}', float: 'must be a float or double', integer: 'must be an integer', negative: 'must be a negative number', - positive: 'must be a positive number' + positive: 'must be a positive number', + precision: 'must have no more than {{limit}} decimal places' }, string: { base: 'must be a string', @@ -78,13 +85,17 @@ exports.errors = { length: 'length must be {{limit}} characters long', alphanum: 'must only contain alpha-numeric characters', token: 'must only contain alpha-numeric and underscore characters', - regex: 'fails to match the required pattern', + regex: { + base: 'fails to match the required pattern', + name: 'fails to match the {{name}} pattern' + }, email: 'must be a valid email', isoDate: 'must be a valid ISO 8601 date', guid: 'must be a valid GUID', hostname: 'must be a valid hostname', lowercase: 'must only contain lowercase characters', uppercase: 'must only contain uppercase characters', - trim: 'must not have leading or trailing whitespace' + trim: 'must not have leading or trailing whitespace', + creditCard: 'must be a credit card' } }; diff --git a/js/node/node_modules/joi/lib/number.js b/js/node/node_modules/joi/lib/number.js index 420713ee6a..298da9965d 100755 --- a/js/node/node_modules/joi/lib/number.js +++ b/js/node/node_modules/joi/lib/number.js @@ -68,6 +68,36 @@ internals.Number.prototype.max = function (limit) { }; +internals.Number.prototype.greater = function (limit) { + + Hoek.assert(Hoek.isInteger(limit), 'limit must be an integer'); + + return this._test('greater', limit, function (value, state, options) { + + if (value > limit) { + return null; + } + + return Errors.create('number.greater', { limit: limit }, state, options); + }); +}; + + +internals.Number.prototype.less = function (limit) { + + Hoek.assert(Hoek.isInteger(limit), 'limit must be an integer'); + + return this._test('less', limit, function (value, state, options) { + + if (value < limit) { + return null; + } + + return Errors.create('number.less', { limit: limit }, state, options); + }); +}; + + internals.Number.prototype.integer = function () { return this._test('integer', undefined, function (value, state, options) { @@ -103,4 +133,24 @@ internals.Number.prototype.positive = function () { }; +internals.precisionRx = /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/; + + +internals.Number.prototype.precision = function (limit) { + + Hoek.assert(Hoek.isInteger(limit), 'limit must be an integer'); + + return this._test('precision', limit, function (value, state, options){ + + var places = value.toString().match(internals.precisionRx); + var decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0); + if (decimals <= limit) { + return null; + } + + return Errors.create('number.precision', {limit: limit}, state, options); + }); +}; + + module.exports = new internals.Number(); diff --git a/js/node/node_modules/joi/lib/object.js b/js/node/node_modules/joi/lib/object.js index 45be2ac9fe..2c4a757f1b 100755 --- a/js/node/node_modules/joi/lib/object.js +++ b/js/node/node_modules/joi/lib/object.js @@ -55,11 +55,21 @@ internals.Object.prototype._base = function (value, state, options) { return finish(); } + // Skip if there are no other rules to test + + if (!this._inner.renames.length && + !this._inner.dependencies.length && + !this._inner.children && // null allows any keys + !this._inner.patterns.length) { + + target = value; + return finish(); + } + // Ensure target is a local copy (parsed) or shallow copy if (target === value) { - target = {}; - target.__proto__ = Object.getPrototypeOf(value); + target = Object.create(Object.getPrototypeOf(value)); var valueKeys = Object.keys(value); for (var t = 0, tl = valueKeys.length; t < tl; ++t) { target[valueKeys[t]] = value[valueKeys[t]]; @@ -320,13 +330,15 @@ internals.Object.prototype.max = function (limit) { }; -internals.Object.prototype.pattern = function (regex, schema) { +internals.Object.prototype.pattern = function (pattern, schema) { - Hoek.assert(regex instanceof RegExp, 'Invalid regular expression'); + Hoek.assert(pattern instanceof RegExp, 'Invalid regular expression'); Hoek.assert(schema !== undefined, 'Invalid rule'); + pattern = new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined); // Future version should break this and forbid unsupported regex flags + var obj = this.clone(); - obj._inner.patterns.push({ regex: regex, rule: Cast.schema(schema) }); + obj._inner.patterns.push({ regex: pattern, rule: Cast.schema(schema) }); return obj; }; @@ -364,6 +376,13 @@ internals.Object.prototype.and = function () { }; +internals.Object.prototype.nand = function () { + + var peers = Hoek.flatten(Array.prototype.slice.call(arguments)); + return this._dependency('nand', null, peers); +}; + + internals.renameDefaults = { alias: false, // Keep old value in place multiple: false, // Allow renaming multiple keys into the same target @@ -504,6 +523,25 @@ internals.and = function (value, peers, parent, state, options) { }; +internals.nand = function (value, peers, parent, state, options) { + + var present = []; + for (var i = 0, il = peers.length; i < il; ++i) { + var peer = peers[i]; + if (parent.hasOwnProperty(peer) && + parent[peer] !== undefined) { + + present.push(peer); + } + } + + var values = Hoek.clone(peers); + var main = values.splice(0,1); + var allPresent = (present.length === peers.length); + return allPresent ? Errors.create('object.nand', { main: main, peers: values }, state, options) : null; +}; + + internals.Object.prototype.describe = function (shallow) { var description = Any.prototype.describe.call(this); @@ -522,6 +560,15 @@ internals.Object.prototype.describe = function (shallow) { description.dependencies = Hoek.clone(this._inner.dependencies); } + if (this._inner.patterns.length) { + description.patterns = []; + + for (var p = 0, pl = this._inner.patterns.length; p < pl; ++p) { + var pattern = this._inner.patterns[p]; + description.patterns.push({ regex: pattern.regex.toString(), rule: pattern.rule.describe() }); + } + } + return description; }; @@ -530,6 +577,7 @@ internals.Object.prototype.assert = function (ref, schema, message) { ref = Cast.ref(ref); Hoek.assert(ref.isContext || ref.depth > 1, 'Cannot use assertions for root level references - use direct key rules instead'); + message = message || 'pass the assertion test'; var cast = Cast.schema(schema); @@ -545,4 +593,20 @@ internals.Object.prototype.assert = function (ref, schema, message) { }; +internals.Object.prototype.type = function (constructor, name) { + + Hoek.assert(typeof constructor === 'function', 'type must be a constructor function'); + name = name || constructor.name; + + return this._test('type', name, function (value, state, options) { + + if (value instanceof constructor) { + return null; + } + + return Errors.create('object.type', { type: name }, state, options); + }); +}; + + module.exports = new internals.Object(); diff --git a/js/node/node_modules/joi/lib/string.js b/js/node/node_modules/joi/lib/string.js index 145fd62e70..1b22802fe2 100755 --- a/js/node/node_modules/joi/lib/string.js +++ b/js/node/node_modules/joi/lib/string.js @@ -4,9 +4,9 @@ var Net = require('net'); var Hoek = require('hoek'); var Isemail = require('isemail'); var Any = require('./any'); +var JoiDate = require('./date'); var Errors = require('./errors'); - // Declare internals var internals = {}; @@ -85,6 +85,27 @@ internals.String.prototype.max = function (limit, encoding) { }; +internals.String.prototype.creditCard = function () { + + return this._test('creditCard', undefined, function (value, state, options) { + + var i = value.length; + var sum = 0; + var mul = 1; + var char; + + while (i--) { + char = value.charAt(i) * mul; + sum += char - (char > 9) * 9; + mul ^= 3; + } + + var check = (sum % 10 === 0) && (sum > 0); + return check ? null : Errors.create('string.creditCard', null, state, options); + }); +}; + + internals.String.prototype.length = function (limit, encoding) { Hoek.assert(Hoek.isInteger(limit) && limit >= 0, 'limit must be a positive integer'); @@ -102,17 +123,19 @@ internals.String.prototype.length = function (limit, encoding) { }; -internals.String.prototype.regex = function (pattern) { +internals.String.prototype.regex = function (pattern, name) { Hoek.assert(pattern instanceof RegExp, 'pattern must be a RegExp'); + pattern = new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined); // Future version should break this and forbid unsupported regex flags + return this._test('regex', pattern, function (value, state, options) { if (pattern.test(value)) { return null; } - return Errors.create('string.regex', null, state, options); + return Errors.create((name ? 'string.regex.name' : 'string.regex.base'), { name: name }, state, options); }); }; @@ -158,11 +181,9 @@ internals.String.prototype.email = function () { internals.String.prototype.isoDate = function () { - var regex = /^(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))$/; - return this._test('isoDate', undefined, function (value, state, options) { - if (regex.test(value)) { + if (JoiDate._isIsoDate(value)) { return null; } diff --git a/js/node/node_modules/joi/node_modules/hoek/AUTHORS b/js/node/node_modules/joi/node_modules/hoek/AUTHORS deleted file mode 100644 index 93b7813e9e..0000000000 --- a/js/node/node_modules/joi/node_modules/hoek/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Van Nguyen -Eran Hammer (http://hueniverse.com) -Wyatt Preul (http://jsgeek.com) \ No newline at end of file diff --git a/js/node/node_modules/joi/node_modules/hoek/CONTRIBUTING.md b/js/node/node_modules/joi/node_modules/hoek/CONTRIBUTING.md new file mode 100644 index 0000000000..892836159b --- /dev/null +++ b/js/node/node_modules/joi/node_modules/hoek/CONTRIBUTING.md @@ -0,0 +1 @@ +Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md). diff --git a/js/node/node_modules/joi/node_modules/hoek/LICENSE b/js/node/node_modules/joi/node_modules/hoek/LICENSE index 87c1f4e11f..5530904255 100755 --- a/js/node/node_modules/joi/node_modules/hoek/LICENSE +++ b/js/node/node_modules/joi/node_modules/hoek/LICENSE @@ -1,4 +1,5 @@ -Copyright (c) 2011-2013, Walmart. +Copyright (c) 2011-2014, Walmart and other contributors. +Copyright (c) 2011, Yahoo Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -8,14 +9,14 @@ modification, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Walmart nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * The names of any contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL WALMART BE LIABLE FOR ANY +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND @@ -23,11 +24,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * * * - -Portions of this project were initially based on Postmile, Copyright (c) 2011, Yahoo Inc. -Postmile is published at https://github.com/yahoo/postmile and its licensing terms are -published at https://github.com/yahoo/postmile/blob/master/LICENSE. - +The complete list of contributors can be found at: https://github.com/hapijs/hapi/graphs/contributors +Portions of this project were initially based on the Yahoo! Inc. Postmile project, +published at https://github.com/yahoo/postmile. diff --git a/js/node/node_modules/joi/node_modules/hoek/README.md b/js/node/node_modules/joi/node_modules/hoek/README.md index 7ad38b0f47..bde6dbe515 100755 --- a/js/node/node_modules/joi/node_modules/hoek/README.md +++ b/js/node/node_modules/joi/node_modules/hoek/README.md @@ -1,22 +1,30 @@ - -![hoek Logo](https://raw.github.com/spumko/hoek/master/images/hoek.png) +![hoek Logo](https://raw.github.com/hapijs/hoek/master/images/hoek.png) -General purpose node utilities +Utility methods for the hapi ecosystem. This module is not intended to solve every problem for everyone, but rather as a central place to store hapi-specific methods. If you're looking for a general purpose utility module, check out [lodash](https://github.com/lodash/lodash) or [underscore](https://github.com/jashkenas/underscore). -[![Build Status](https://secure.travis-ci.org/spumko/hoek.png)](http://travis-ci.org/spumko/hoek) +[![Build Status](https://secure.travis-ci.org/hapijs/hoek.png)](http://travis-ci.org/hapijs/hoek) + +Lead Maintainer: [Nathan LaFreniere](https://github.com/nlf) # Table of Contents * [Introduction](#introduction "Introduction") * [Object](#object "Object") * [clone](#cloneobj "clone") + * [cloneWithShallow](#clonewithshallowobj-keys "cloneWithShallow") * [merge](#mergetarget-source-isnulloverride-ismergearrays "merge") * [applyToDefaults](#applytodefaultsdefaults-options "applyToDefaults") + * [applyToDefaultsWithShallow](#applytodefaultswithshallowdefaults-options-keys "applyToDefaultsWithShallow") + * [deepEqual](#deepequala-b "deepEqual") * [unique](#uniquearray-key "unique") * [mapToObject](#maptoobjectarray-key "mapToObject") * [intersect](#intersectarray1-array2 "intersect") + * [contain](#containref-values-options "contain") * [flatten](#flattenarray-target "flatten") * [reach](#reachobj-chain-options "reach") + * [transform](#transformobj-transform-options "transform") + * [shallow](#shallowobj "shallow") + * [stringify](#stringifyobj "stringify") * [Timer](#timer "Timer") * [Bench](#bench "Bench") * [Binary Encoding/Decoding](#binary-encodingdecoding "Binary Encoding/Decoding") @@ -31,9 +39,12 @@ General purpose node utilities * [abort](#abortmessage "abort") * [displayStack](#displaystackslice "displayStack") * [callStack](#callstackslice "callStack") -* [Load files](#load-files "Load Files") - * [loadPackage](#loadpackagedir "loadpackage") - * [loadDirModules](#loaddirmodulespath-excludefiles-target "loaddirmodules") +* [Function](#function "Function") + * [nextTick](#nexttickfn "nextTick") + * [once](#oncefn "once") + * [ignore](#ignore "ignore") +* [Miscellaneous](#miscellaneous "Miscellaneous") + * [uniqueFilename](#uniquefilename "uniqueFilename") @@ -45,14 +56,14 @@ For example, to use Hoek to set configuration with default options: ```javascript var Hoek = require('hoek'); -var default = {url : "www.github.com", port : "8000", debug : true} +var default = {url : "www.github.com", port : "8000", debug : true}; var config = Hoek.applyToDefaults(default, {port : "3000", admin : true}); // In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true } ``` -Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the var Hoek = require('hoek') is omitted for brevity. +Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the `var Hoek = require('hoek');` is omitted for brevity. ## Object @@ -79,33 +90,60 @@ var copy = Hoek.clone(nestedObj); copy.x.b = 100; -console.log(copy.y) // results in 'y' -console.log(nestedObj.x.b) // results in 123456 -console.log(copy.x.b) // results in 100 +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 123456 +console.log(copy.x.b); // results in 100 +``` + +### cloneWithShallow(obj, keys) +keys is an array of key names to shallow copy + +This method is also used to clone an object or array, however any keys listed in the `keys` array are shallow copied while those not listed are deep copied. + +```javascript + +var nestedObj = { + w: /^something$/ig, + x: { + a: [1, 2, 3], + b: 123456, + c: new Date() + }, + y: 'y', + z: new Date() + }; + +var copy = Hoek.cloneWithShallow(nestedObj, ['x']); + +copy.x.b = 100; + +console.log(copy.y); // results in 'y' +console.log(nestedObj.x.b); // results in 100 +console.log(copy.x.b); // results in 100 ``` ### merge(target, source, isNullOverride, isMergeArrays) isNullOverride, isMergeArrays default to true -Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied. +Merge all the properties of source into target, source wins in conflict, and by default null and undefined from source are applied. Merge is destructive where the target is modified. For non destructive merge, use `applyToDefaults`. ```javascript -var target = {a: 1, b : 2} -var source = {a: 0, c: 5} -var source2 = {a: null, c: 5} +var target = {a: 1, b : 2}; +var source = {a: 0, c: 5}; +var source2 = {a: null, c: 5}; + +Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5} +Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5} +Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5} var targetArray = [1, 2, 3]; var sourceArray = [4, 5]; -Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5} -Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5} -Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5} - -Hoek.merge(targetArray, sourceArray) // results in [1, 2, 3, 4, 5] -Hoek.merge(targetArray, sourceArray, true, false) // results in [4, 5] +Hoek.merge(targetArray, sourceArray); // results in [1, 2, 3, 4, 5] +Hoek.merge(targetArray, sourceArray, true, false); // results in [4, 5] ``` ### applyToDefaults(defaults, options) @@ -114,10 +152,38 @@ Apply options to a copy of the defaults ```javascript -var defaults = {host: "localhost", port: 8000}; -var options = {port: 8080}; +var defaults = { host: "localhost", port: 8000 }; +var options = { port: 8080 }; -var config = Hoek.applyToDefaults(defaults, options); // results in {host: "localhost", port: 8080}; +var config = Hoek.applyToDefaults(defaults, options); // results in { host: "localhost", port: 8080 } +``` + +### applyToDefaultsWithShallow(defaults, options, keys) +keys is an array of key names to shallow copy + +Apply options to a copy of the defaults. Keys specified in the last parameter are shallow copied from options instead of merged. + +```javascript + +var defaults = { + server: { + host: "localhost", + port: 8000 + }, + name: 'example' + }; + +var options = { server: { port: 8080 } }; + +var config = Hoek.applyToDefaults(defaults, options); // results in { server: { port: 8080 }, name: 'example' } +``` + +### deepEqual(b, a) + +Performs a deep comparison of the two values including support for circular dependencies, prototype, and properties. + +```javascript +Hoek.deepEqual({ a: [1, 2], b: 'string', c: { d: true } }, { a: [1, 2], b: 'string', c: { d: true } }); ``` ### unique(array, key) @@ -128,11 +194,11 @@ Remove duplicate items from Array var array = [1, 2, 2, 3, 3, 4, 5, 6]; -var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6]; +var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6] array = [{id: 1}, {id: 1}, {id: 2}]; -newArray = Hoek.unique(array, "id") // results in [{id: 1}, {id: 2}] +newArray = Hoek.unique(array, "id"); // results in [{id: 1}, {id: 2}] ``` ### mapToObject(array, key) @@ -142,10 +208,10 @@ Convert an Array into an Object ```javascript var array = [1,2,3]; -var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}] +var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}] array = [{id: 1}, {id: 2}]; -newObject = Hoek.mapToObject(array, "id") // results in [{"id": 1}, {"id": 2}] +newObject = Hoek.mapToObject(array, "id"); // results in [{"id": 1}, {"id": 2}] ``` ### intersect(array1, array2) @@ -157,31 +223,117 @@ Find the common unique items in two arrays var array1 = [1, 2, 3]; var array2 = [1, 4, 5]; -var newArray = Hoek.intersect(array1, array2) // results in [1] +var newArray = Hoek.intersect(array1, array2); // results in [1] ``` -### flatten(array, target) +### contain(ref, values, [options]) + +Tests if the reference value contains the provided values where: +- `ref` - the reference string, array, or object. +- `values` - a single or array of values to find within the `ref` value. If `ref` is an object, `values` can be a key name, + an array of key names, or an object with key-value pairs to compare. +- `options` - an optional object with the following optional settings: + - `deep` - if `true`, performed a deep comparison of the values. + - `once` - if `true`, allows only one occurrence of each value. + - `only` - if `true`, does not allow values not explicitly listed. + - `part` - if `true`, allows partial match of the values (at least one must always match). + +Note: comparing a string to overlapping values will result in failed comparison (e.g. `contain('abc', ['ab', 'bc'])`). +Also, if an object key's value does not match the provided value, `false` is returned even when `part` is specified. + +```javascript +Hoek.contain('aaa', 'a', { only: true }); // true +Hoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true }); // true +Hoek.contain([1, 2, 2], [1, 2], { once: true }); // false +Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true +``` + +### flatten(array, [target]) Flatten an array ```javascript -var array = [1, 2, 3]; -var target = [4, 5]; +var array = [1, [2, 3]]; -var flattenedArray = Hoek.flatten(array, target) // results in [4, 5, 1, 2, 3]; +var flattenedArray = Hoek.flatten(array); // results in [1, 2, 3] + +array = [1, [2, 3]]; +target = [4, [5]]; + +flattenedArray = Hoek.flatten(array, target); // results in [4, [5], 1, 2, 3] ``` ### reach(obj, chain, [options]) Converts an object key chain string to reference +- `options` - optional settings + - `separator` - string to split chain path on, defaults to '.' + - `default` - value to return if the path or value is not present, default is `undefined` + - `strict` - if `true`, will throw an error on missing member, default is `false` + - `functions` - if `true` allow traversing functions for properties. `false` will throw an error if a function is part of the chain. + ```javascript var chain = 'a.b.c'; var obj = {a : {b : { c : 1}}}; -Hoek.reach(obj, chain) // returns 1 +Hoek.reach(obj, chain); // returns 1 +``` + +### transform(obj, transform, [options]) + +Transforms an existing object into a new one based on the supplied `obj` and `transform` map. `options` are the same as the `reach` options. + +```javascript +var source = { + address: { + one: '123 main street', + two: 'PO Box 1234' + }, + title: 'Warehouse', + state: 'CA' +}; + +var result = Hoek.transform(source, { + 'person.address.lineOne': 'address.one', + 'person.address.lineTwo': 'address.two', + 'title': 'title', + 'person.address.region': 'state' +}); +// Results in +// { +// person: { +// address: { +// lineOne: '123 main street', +// lineTwo: 'PO Box 1234', +// region: 'CA' +// } +// }, +// title: 'Warehouse' +// } +``` + +### shallow(obj) + +Performs a shallow copy by copying the references of all the top level children where: +- `obj` - the object to be copied. + +```javascript +var shallow = Hoek.shallow({ a: { b: 1 } }); +``` + +### stringify(obj) + +Converts an object to string using the built-in `JSON.stringify()` method with the difference that any errors are caught +and reported back in the form of the returned string. Used as a shortcut for displaying information to the console (e.g. in +error message) without the need to worry about invalid conversion. + +```javascript +var a = {}; +a.b = a; +Hoek.stringify(a); // Returns '[Cannot display object: Converting circular structure to JSON]' ``` # Timer @@ -191,8 +343,8 @@ A Timer object. Initializing a new timer object sets the ts to the number of mil ```javascript var timerObj = new Hoek.Timer(); -console.log("Time is now: " + timerObj.ts) -console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds') +console.log("Time is now: " + timerObj.ts); +console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds'); ``` @@ -266,7 +418,7 @@ Hoek.assert(a === b, 'a should equal b'); // ABORT: a should equal b ### abort(message) -First checks if process.env.NODE_ENV === 'test', and if so, throws error message. Otherwise, +First checks if `process.env.NODE_ENV === 'test'`, and if so, throws error message. Otherwise, displays most recent stack and then exits process. @@ -278,7 +430,7 @@ Displays the trace stack ```javascript var stack = Hoek.displayStack(); -console.log(stack) // returns something like: +console.log(stack); // returns something like: [ 'null (/Users/user/Desktop/hoek/test.js:4:18)', 'Module._compile (module.js:449:26)', @@ -296,7 +448,7 @@ Returns a trace stack array. ```javascript var stack = Hoek.callStack(); -console.log(stack) // returns something like: +console.log(stack); // returns something like: [ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ], [ 'module.js', 449, 26, 'Module._compile', false ], @@ -311,18 +463,55 @@ console.log(stack) // returns something like: false ] ] ``` -# Load Files +## Function -### loadPackage(dir) +### nextTick(fn) -Load and parse package.json process root or given directory +Returns a new function that wraps `fn` in `process.nextTick`. ```javascript -var pack = Hoek.loadPackage(); // pack.name === 'hoek' +var myFn = function () { + console.log('Do this later'); +}; + +var nextFn = Hoek.nextTick(myFn); + +nextFn(); +console.log('Do this first'); + +// Results in: +// +// Do this first +// Do this later ``` -### loadDirModules(path, excludeFiles, target) +### once(fn) -Loads modules from a given path; option to exclude files (array). +Returns a new function that can be run multiple times, but makes sure `fn` is only run once. +```javascript + +var myFn = function () { + console.log('Ran myFn'); +}; + +var onceFn = Hoek.once(myFn); +onceFn(); // results in "Ran myFn" +onceFn(); // results in undefined +``` + +### ignore + +A simple no-op function. It does nothing at all. + +## Miscellaneous + +### uniqueFilename(path, extension) +`path` to prepend with the randomly generated file name. `extension` is the optional file extension, defaults to `''`. + +Returns a randomly generated file name at the specified `path`. The result is a fully resolved path to a file. + +```javascript +var result = Hoek.uniqueFilename('./test/modules', 'txt'); // results in "full/path/test/modules/{random}.txt" +``` diff --git a/js/node/node_modules/joi/node_modules/hoek/lib/index.js b/js/node/node_modules/joi/node_modules/hoek/lib/index.js index 9b4d28baba..2f1d79e8a3 100755 --- a/js/node/node_modules/joi/node_modules/hoek/lib/index.js +++ b/js/node/node_modules/joi/node_modules/hoek/lib/index.js @@ -1,5 +1,6 @@ // Load modules +var Crypto = require('crypto'); var Path = require('path'); var Util = require('util'); var Escape = require('./escape'); @@ -42,12 +43,11 @@ exports.clone = function (obj, seen) { } else { var proto = Object.getPrototypeOf(obj); - if (proto.isImmutable) { + if (!proto || proto.isImmutable) { newObj = obj; } else { - newObj = {}; - newObj.__proto__ = proto; + newObj = Object.create(proto); cloneDeep = true; } } @@ -63,7 +63,15 @@ exports.clone = function (obj, seen) { if (cloneDeep) { for (var i in obj) { if (obj.hasOwnProperty(i)) { - newObj[i] = exports.clone(obj[i], seen); + var descriptor = Object.getOwnPropertyDescriptor(obj, i); + if (descriptor.get || + descriptor.set) { + + Object.defineProperty(newObj, i, descriptor); + } + else { + newObj[i] = exports.clone(obj[i], seen); + } } } } @@ -163,7 +171,7 @@ exports.cloneWithShallow = function (source, keys) { return source; } - return internals.shallow(source, keys, function () { + return internals.withShallow(source, keys, function () { return exports.clone(source); }); @@ -174,14 +182,14 @@ exports.cloneWithShallow = function (source, keys) { exports.applyToDefaultsWithShallow = function (defaults, options, keys) { - return internals.shallow(options, keys, function () { + return internals.withShallow(options, keys, function () { return exports.applyToDefaults(defaults, options); }); }; -internals.shallow = function (source, keys, clone) { +internals.withShallow = function (source, keys, clone) { // Move shallow copy items to storage @@ -212,6 +220,99 @@ internals.shallow = function (source, keys, clone) { }; +// Deep object or array comparison + +exports.deepEqual = function (obj, ref, seen) { + + var type = typeof obj; + if (type !== typeof ref) { + return false; + } + + if (type !== 'object' || + obj === null || + ref === null) { + + if (obj === ref) { // Copied from Deep-eql, copyright(c) 2013 Jake Luer, jake@alogicalparadox.com, MIT Licensed, https://github.com/chaijs/deep-eql + return obj !== 0 || 1 / obj === 1 / ref; // -0 / +0 + } + + return obj !== obj && ref !== ref; // NaN + } + + seen = seen || []; + if (seen.indexOf(obj) !== -1) { + return true; // If previous comparison failed, it would have stopped execution + } + + seen.push(obj); + + if (Array.isArray(obj)) { + if (!Array.isArray(ref)) { + return false; + } + + if (obj.length !== ref.length) { + return false; + } + + for (var i = 0, il = obj.length; i < il; ++i) { + if (!exports.deepEqual(obj[i], ref[i])) { + return false; + } + } + + return true; + } + + if (Buffer.isBuffer(obj)) { + if (!Buffer.isBuffer(ref)) { + return false; + } + + if (obj.length !== ref.length) { + return false; + } + + for (var i = 0, il = obj.length; i < il; ++i) { + if (obj[i] !== ref[i]) { + return false; + } + } + + return true; + } + + if (obj instanceof Date) { + return (ref instanceof Date && obj.getTime() === ref.getTime()); + } + + if (obj instanceof RegExp) { + return (ref instanceof RegExp && obj.toString() === ref.toString()); + } + + if (Object.getPrototypeOf(obj) !== Object.getPrototypeOf(ref)) { + return false; + } + + var keys = Object.keys(obj); + for (var i = 0, l = keys.length; i < l; ++i) { + var key = keys[i]; + var descriptor = Object.getOwnPropertyDescriptor(obj, key); + if (descriptor.get) { + if (!exports.deepEqual(descriptor, Object.getOwnPropertyDescriptor(ref, key), seen)) { + return false; + } + } + else if (!exports.deepEqual(obj[key], ref[key], seen)) { + return false; + } + } + + return true; +}; + + // Remove duplicate items from array exports.unique = function (array, key) { @@ -282,6 +383,116 @@ exports.intersect = function (array1, array2, justFirst) { }; +// Test if the reference contains the values + +exports.contain = function (ref, values, options) { + + /* + string -> string(s) + array -> item(s) + object -> key(s) + object -> object (key:value) + */ + + var valuePairs = null; + if (typeof ref === 'object' && + typeof values === 'object' && + !Array.isArray(ref) && + !Array.isArray(values)) { + + valuePairs = values; + values = Object.keys(values); + } + else { + values = [].concat(values); + } + + options = options || {}; // deep, once, only, part + + exports.assert(arguments.length >= 2, 'Insufficient arguments'); + exports.assert(typeof ref === 'string' || typeof ref === 'object', 'Reference must be string or an object'); + exports.assert(values.length, 'Values array cannot be empty'); + + var compare = options.deep ? exports.deepEqual : function (a, b) { return a === b; }; + + var misses = false; + var matches = new Array(values.length); + for (var i = 0, il = matches.length; i < il; ++i) { + matches[i] = 0; + } + + if (typeof ref === 'string') { + var pattern = '('; + for (i = 0, il = values.length; i < il; ++i) { + var value = values[i]; + exports.assert(typeof value === 'string', 'Cannot compare string reference to non-string value'); + pattern += (i ? '|' : '') + exports.escapeRegex(value); + } + + var regex = new RegExp(pattern + ')', 'g'); + var leftovers = ref.replace(regex, function ($0, $1) { + + var index = values.indexOf($1); + ++matches[index]; + return ''; // Remove from string + }); + + misses = !!leftovers; + } + else if (Array.isArray(ref)) { + for (i = 0, il = ref.length; i < il; ++i) { + for (var j = 0, jl = values.length, found = false; j < jl && found === false; ++j) { + found = compare(ref[i], values[j]) && j; + } + + if (found !== false) { + ++matches[found] + } + else { + misses = true; + } + } + } + else { + var keys = Object.keys(ref); + for (i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + var found = values.indexOf(key); + if (found !== -1) { + if (valuePairs && + !compare(ref[key], valuePairs[key])) { + + return false; + } + + ++matches[found] + } + else { + misses = true; + } + } + } + + var result = false; + for (var i = 0, il = matches.length; i < il; ++i) { + result = result || !!matches[i]; + if ((options.once && matches[i] > 1) || + (!options.part && !matches[i])) { + + return false; + } + } + + if (options.only && + misses) { + + return false; + } + + return result; +}; + + // Flatten array exports.flatten = function (array, target) { @@ -319,7 +530,7 @@ exports.reach = function (obj, chain, options) { exports.assert(!options.strict || i + 1 === il, 'Missing segment', path[i], 'in reach path ', chain); exports.assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', path[i], 'in reach path ', chain); - ref = undefined; + ref = options.default; break; } @@ -413,10 +624,16 @@ exports.assert = function (condition /*, msg1, msg2, msg3 */) { return; } - var msgs = Array.prototype.slice.call(arguments, 1); + var msgs = []; + for (var i = 1, il = arguments.length; i < il; ++i) { + if (arguments[i] !== '') { + msgs.push(arguments[i]); // Avoids Array.slice arguments leak, allowing for V8 optimizations + } + } + msgs = msgs.map(function (msg) { - return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : JSON.stringify(msg); + return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : exports.stringify(msg); }); throw new Error(msgs.join(' ') || 'Unknown error'); }; @@ -496,7 +713,7 @@ exports.base64urlDecode = function (value, encoding) { } try { - var buf = new Buffer(value.replace(/-/g, '+').replace(/:/g, '/'), 'base64'); + var buf = new Buffer(value, 'base64'); return (encoding === 'buffer' ? buf : buf.toString(encoding || 'binary')); } catch (err) { @@ -599,3 +816,77 @@ exports.ignore = function () { }; exports.inherits = Util.inherits; + + +exports.format = Util.format; + + +exports.transform = function (source, transform, options) { + + exports.assert(source == null || typeof source === 'object', 'Invalid source object: must be null, undefined, or an object'); + + var result = {}; + var keys = Object.keys(transform); + + for (var k = 0, kl = keys.length; k < kl; ++k) { + var key = keys[k]; + var path = key.split('.'); + var sourcePath = transform[key]; + + exports.assert(typeof sourcePath === 'string', 'All mappings must be "." delineated strings'); + + var segment; + var res = result; + + while (path.length > 1) { + segment = path.shift(); + if (!res[segment]) { + res[segment] = {}; + } + res = res[segment]; + } + segment = path.shift(); + res[segment] = exports.reach(source, sourcePath, options); + } + + return result; +}; + + +exports.uniqueFilename = function (path, extension) { + + if (extension) { + extension = extension[0] !== '.' ? '.' + extension : extension; + } + else { + extension = ''; + } + + path = Path.resolve(path); + var name = [Date.now(), process.pid, Crypto.randomBytes(8).toString('hex')].join('-') + extension; + return Path.join(path, name); +}; + + +exports.stringify = function () { + + try { + return JSON.stringify.apply(null, arguments); + } + catch (err) { + return '[Cannot display object: ' + err.message + ']'; + } +}; + + +exports.shallow = function (source) { + + var target = {}; + var keys = Object.keys(source); + for (var i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + target[key] = source[key]; + } + + return target; +}; diff --git a/js/node/node_modules/joi/node_modules/hoek/package.json b/js/node/node_modules/joi/node_modules/hoek/package.json old mode 100755 new mode 100644 index 9912b5c153..b1dff21a29 --- a/js/node/node_modules/joi/node_modules/hoek/package.json +++ b/js/node/node_modules/joi/node_modules/hoek/package.json @@ -1,10 +1,10 @@ { "name": "hoek", "description": "General purpose node utilities", - "version": "2.3.0", + "version": "2.9.0", "repository": { "type": "git", - "url": "git://github.com/spumko/hoek" + "url": "git://github.com/hapijs/hoek" }, "main": "index", "keywords": [ @@ -15,7 +15,7 @@ }, "dependencies": {}, "devDependencies": { - "lab": "3.x.x" + "lab": "4.x.x" }, "scripts": { "test": "make test-cov" @@ -23,56 +23,42 @@ "licenses": [ { "type": "BSD", - "url": "http://github.com/spumko/hoek/raw/master/LICENSE" - } - ], - "contributors": [ - { - "name": "Van Nguyen", - "email": "the.gol.effect@gmail.com" - }, - { - "name": "Eran Hammer", - "email": "eran@hueniverse.com", - "url": "http://hueniverse.com" - }, - { - "name": "Wyatt Preul", - "email": "wpreul@gmail.com", - "url": "http://jsgeek.com" + "url": "http://github.com/hapijs/hoek/raw/master/LICENSE" } ], + "gitHead": "e0475764d819a7b9630a6ab47425b0ad64299a38", "bugs": { - "url": "https://github.com/spumko/hoek/issues" + "url": "https://github.com/hapijs/hoek/issues" }, - "homepage": "https://github.com/spumko/hoek", - "_id": "hoek@2.3.0", - "_shasum": "d5f76359d20f008cf04c1b9f6c48a10bba76b10c", - "_from": "hoek@^2.2.x", - "_npmVersion": "1.4.9", + "homepage": "https://github.com/hapijs/hoek", + "_id": "hoek@2.9.0", + "_shasum": "dc3d5011c68084d29869d4499183bf8e9afb9ddd", + "_from": "hoek@>=2.2.0 <3.0.0", + "_npmVersion": "2.1.6", + "_nodeVersion": "0.10.32", "_npmUser": { - "name": "hueniverse", - "email": "eran@hueniverse.com" + "name": "nlf", + "email": "quitlahok@gmail.com" }, "maintainers": [ { "name": "hueniverse", "email": "eran@hueniverse.com" }, - { - "name": "thegoleffect", - "email": "thegoleffect@gmail.com" - }, { "name": "wyatt", "email": "wpreul@gmail.com" + }, + { + "name": "nlf", + "email": "quitlahok@gmail.com" } ], "dist": { - "shasum": "d5f76359d20f008cf04c1b9f6c48a10bba76b10c", - "tarball": "http://registry.npmjs.org/hoek/-/hoek-2.3.0.tgz" + "shasum": "dc3d5011c68084d29869d4499183bf8e9afb9ddd", + "tarball": "http://registry.npmjs.org/hoek/-/hoek-2.9.0.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/hoek/-/hoek-2.3.0.tgz", + "_resolved": "https://registry.npmjs.org/hoek/-/hoek-2.9.0.tgz", "readme": "ERROR: No README data found!" } diff --git a/js/node/node_modules/joi/node_modules/hoek/test/escaper.js b/js/node/node_modules/joi/node_modules/hoek/test/escaper.js index f92a2494c2..972c20c2ac 100755 --- a/js/node/node_modules/joi/node_modules/hoek/test/escaper.js +++ b/js/node/node_modules/joi/node_modules/hoek/test/escaper.js @@ -11,83 +11,80 @@ var internals = {}; // Test shortcuts +var lab = exports.lab = Lab.script(); var expect = Lab.expect; -var before = Lab.before; -var after = Lab.after; -var describe = Lab.experiment; -var it = Lab.test; +var describe = lab.experiment; +var it = lab.test; -describe('Hoek', function () { +describe('escapeJavaScript()', function () { - describe('#escapeJavaScript', function () { + it('encodes / characters', function (done) { - it('encodes / characters', function (done) { - - var encoded = Hoek.escapeJavaScript(''); - expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); - done(); - }); - - it('encodes \' characters', function (done) { - - var encoded = Hoek.escapeJavaScript('something(\'param\')'); - expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); - done(); - }); - - it('encodes large unicode characters with the correct padding', function (done) { - - var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); - expect(encoded).to.equal('\\u0500\\u1000'); - done(); - }); - - it('doesn\'t throw an exception when passed null', function (done) { - - var encoded = Hoek.escapeJavaScript(null); - expect(encoded).to.equal(''); - done(); - }); + var encoded = Hoek.escapeJavaScript(''); + expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); + done(); }); - describe('#escapeHtml', function () { + it('encodes \' characters', function (done) { - it('encodes / characters', function (done) { + var encoded = Hoek.escapeJavaScript('something(\'param\')'); + expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); + done(); + }); - var encoded = Hoek.escapeHtml(''); - expect(encoded).to.equal('<script>alert(1)</script>'); - done(); - }); + it('encodes large unicode characters with the correct padding', function (done) { - it('encodes < and > as named characters', function (done) { + var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); + expect(encoded).to.equal('\\u0500\\u1000'); + done(); + }); - var encoded = Hoek.escapeHtml(''); + expect(encoded).to.equal('<script>alert(1)</script>'); + done(); + }); - it('encodes {} characters', function (done) { + it('encodes < and > as named characters', function (done) { - var encoded = Hoek.escapeHtml('{}'); - expect(encoded).to.equal('{}'); - done(); - }); + var encoded = Hoek.escapeHtml('