mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
632b9bc430
|
@ -685,7 +685,7 @@ v1.0.beta1 (2012-07-29)
|
|||
- tcp://[host]:port or http@tcp://[host]:port (HTTP over IPv6)
|
||||
- ssl://host:port or http@tcp://host:port (HTTP over SSL-encrypted IPv4)
|
||||
- ssl://[host]:port or http@tcp://[host]:port (HTTP over SSL-encrypted IPv6)
|
||||
- unix://path/to/socket or http@unix:///path/to/socket (HTTP over UNIX socket)
|
||||
- unix:///path/to/socket or http@unix:///path/to/socket (HTTP over UNIX socket)
|
||||
|
||||
If no port is specified, the default port of 8529 will be used.
|
||||
|
||||
|
|
|
@ -8,7 +8,3 @@ arango> db.five.all().toArray();
|
|||
arango> db.five.all().limit(2).toArray();
|
||||
[ { _id : 159896:1798296, _rev : 1798296, doc : 3 },
|
||||
{ _id : 159896:1732760, _rev : 1732760, doc : 2 } ]
|
||||
|
||||
arango> db.five.all().limit(-2);
|
||||
[ { _id : 159896:1667224, _rev : 1667224, doc : 1 },
|
||||
{ _id : 159896:1929368, _rev : 1929368, doc : 5 } ]
|
||||
|
|
|
@ -253,7 +253,7 @@ following specification syntax:
|
|||
- `tcp://[host]:port (HTTP over IPv6)`
|
||||
- `ssl://host:port (HTTP over SSL-encrypted IPv4)`
|
||||
- `ssl://[host]:port (HTTP over SSL-encrypted IPv6)`
|
||||
- `unix://path/to/socket (HTTP over Unix domain socket)`
|
||||
- `unix:///path/to/socket (HTTP over Unix domain socket)`
|
||||
|
||||
### TCP endpoints
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ following endpoint specification sytnax is currently supported:
|
|||
- `tcp://[host]:port` (HTTP over IPv6)
|
||||
- `ssl://host:port` (HTTP over SSL-encrypted IPv4)
|
||||
- `ssl://[host]:port` (HTTP over SSL-encrypted IPv6)
|
||||
- `unix://path/to/socket` (HTTP over UNIX socket)
|
||||
- `unix:///path/to/socket` (HTTP over UNIX socket)
|
||||
|
||||
An example value for the option is `--server.endpoint
|
||||
tcp://127.0.0.1:8529`. This will make the server listen to requests
|
||||
|
|
|
@ -207,6 +207,7 @@ SHELL_COMMON = @top_srcdir@/js/common/tests/shell-document.js \
|
|||
@top_srcdir@/js/common/tests/shell-edge.js \
|
||||
@top_srcdir@/js/common/tests/shell-database.js \
|
||||
@top_srcdir@/js/common/tests/shell-collection.js \
|
||||
@top_srcdir@/js/common/tests/shell-collection-volatile.js \
|
||||
@top_srcdir@/js/common/tests/shell-compactor.js \
|
||||
@top_srcdir@/js/common/tests/shell-graph-traversal.js \
|
||||
@top_srcdir@/js/common/tests/shell-simple-query.js \
|
||||
|
|
|
@ -1031,6 +1031,7 @@ static v8::Handle<v8::Value> SaveEdgeCol (SingleCollectionWriteTransaction<Embed
|
|||
const bool forceSync = ExtractForceSync(argv, 4);
|
||||
|
||||
TRI_document_edge_t edge;
|
||||
// the following values are defaults that will be overridden below
|
||||
edge._fromCid = trx->cid();
|
||||
edge._toCid = trx->cid();
|
||||
edge._fromKey = 0;
|
||||
|
@ -6119,15 +6120,15 @@ v8::Handle<v8::Value> TRI_ParseDocumentOrDocumentHandle (TRI_vocbase_t* vocbase,
|
|||
// use the collection
|
||||
int res = TRI_UseCollectionVocBase(vocbase, col);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR && col->_collection == 0) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(TRI_CreateErrorObject(res, "cannot use/load collection", true));
|
||||
}
|
||||
}
|
||||
|
||||
if (col->_collection == 0) {
|
||||
return scope.Close(TRI_CreateErrorObject(TRI_ERROR_INTERNAL, "cannot use/load collection"));
|
||||
}
|
||||
|
||||
collection = col;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
static void InitCollection (TRI_vocbase_t* vocbase,
|
||||
TRI_collection_t* collection,
|
||||
char* directory,
|
||||
TRI_col_info_t* info) {
|
||||
const TRI_col_info_t* const info) {
|
||||
assert(collection);
|
||||
|
||||
memset(collection, 0, sizeof(TRI_collection_t));
|
||||
|
@ -510,7 +510,7 @@ void TRI_InitCollectionInfo (TRI_vocbase_t* vocbase,
|
|||
/// @brief copy a collection info block
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CopyCollectionInfo (TRI_col_info_t* dst, TRI_col_info_t* src) {
|
||||
void TRI_CopyCollectionInfo (TRI_col_info_t* dst, const TRI_col_info_t* const src) {
|
||||
assert(dst);
|
||||
memset(dst, 0, sizeof(TRI_col_info_t));
|
||||
|
||||
|
@ -545,6 +545,63 @@ void TRI_FreeCollectionInfoOptions (TRI_col_info_t* parameter) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the full directory name for a collection
|
||||
///
|
||||
/// it is the caller's responsibility to check if the returned string is NULL
|
||||
/// and to free it if not.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_GetDirectoryCollection (char const* path,
|
||||
const TRI_col_info_t* const parameter) {
|
||||
char* filename;
|
||||
|
||||
assert(path);
|
||||
assert(parameter);
|
||||
|
||||
// shape collections use just the name, e.g. path/SHAPES
|
||||
if (parameter->_type == TRI_COL_TYPE_SHAPE) {
|
||||
filename = TRI_Concatenate2File(path, parameter->_name);
|
||||
}
|
||||
// other collections use the collection identifier
|
||||
else if (TRI_IS_DOCUMENT_COLLECTION(parameter->_type)) {
|
||||
char* tmp1;
|
||||
char* tmp2;
|
||||
|
||||
tmp1 = TRI_StringUInt64(parameter->_cid);
|
||||
if (tmp1 == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp2 = TRI_Concatenate2String("collection-", tmp1);
|
||||
if (tmp2 == NULL) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
|
||||
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filename = TRI_Concatenate2File(path, tmp2);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp2);
|
||||
}
|
||||
// oops, unknown collection type
|
||||
else {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_UNKNOWN_COLLECTION_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filename == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// might be NULL
|
||||
return filename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -552,9 +609,8 @@ void TRI_FreeCollectionInfoOptions (TRI_col_info_t* parameter) {
|
|||
TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t* vocbase,
|
||||
TRI_collection_t* collection,
|
||||
char const* path,
|
||||
TRI_col_info_t* parameter) {
|
||||
const TRI_col_info_t* const parameter) {
|
||||
char* filename;
|
||||
int res;
|
||||
|
||||
// sanity check
|
||||
if (sizeof(TRI_df_header_marker_t) + sizeof(TRI_df_footer_marker_t) > parameter->_maximalSize) {
|
||||
|
@ -576,58 +632,10 @@ TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t* vocbase,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// shape collection use the name
|
||||
if (parameter->_type == TRI_COL_TYPE_SHAPE) {
|
||||
filename = TRI_Concatenate2File(path, parameter->_name);
|
||||
if (filename == NULL) {
|
||||
|
||||
LOG_ERROR("cannot create collection '%s', out of memory", path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// simple collection use the collection identifier
|
||||
else if (TRI_IS_DOCUMENT_COLLECTION(parameter->_type)) {
|
||||
char* tmp1;
|
||||
char* tmp2;
|
||||
|
||||
tmp1 = TRI_StringUInt64(parameter->_cid);
|
||||
if (tmp1 == NULL) {
|
||||
LOG_ERROR("cannot create collection '%s', out of memory", path);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp2 = TRI_Concatenate2String("collection-", tmp1);
|
||||
if (tmp2 == NULL) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
|
||||
LOG_ERROR("cannot create collection '%s', out of memory", path);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
filename = TRI_Concatenate2File(path, tmp2);
|
||||
if (filename == NULL) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp2);
|
||||
LOG_ERROR("cannot create collection '%s', out of memory", path);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp2);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
|
||||
}
|
||||
|
||||
// uups
|
||||
else {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_UNKNOWN_COLLECTION_TYPE);
|
||||
|
||||
LOG_ERROR("cannot create collection '%s' in '%s': unknown type '%d'",
|
||||
parameter->_name,
|
||||
path,
|
||||
(unsigned int) parameter->_type);
|
||||
|
||||
filename = TRI_GetDirectoryCollection(path, parameter);
|
||||
if (filename == NULL) {
|
||||
LOG_ERROR("cannot create collection '%s'", TRI_last_error());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -635,7 +643,7 @@ TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t* vocbase,
|
|||
if (TRI_ExistsFile(filename)) {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_DIRECTORY_ALREADY_EXISTS);
|
||||
|
||||
LOG_ERROR("cannot create collection '%s' in '%s', filename already exists",
|
||||
LOG_ERROR("cannot create collection '%s' in '%s', directory already exists",
|
||||
parameter->_name, filename);
|
||||
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||
|
@ -656,16 +664,6 @@ TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t* vocbase,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// save the parameter block (within create, no need to lock)
|
||||
res = TRI_SaveCollectionInfo(filename, parameter);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot save collection parameter '%s': '%s'", filename, TRI_last_error());
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create collection structure
|
||||
if (collection == NULL) {
|
||||
collection = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_collection_t), false);
|
||||
|
@ -678,11 +676,12 @@ TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t* vocbase,
|
|||
}
|
||||
}
|
||||
|
||||
// we are passing filename to this struct, so we must not free it if you use the struct later
|
||||
InitCollection(vocbase, collection, filename, parameter);
|
||||
/* PANAIA: 1) the parameter file if it exists must be removed
|
||||
2) if collection
|
||||
*/
|
||||
// return collection
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
@ -839,7 +838,7 @@ int TRI_LoadCollectionInfo (char const* path, TRI_col_info_t* parameter) {
|
|||
/// function.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_SaveCollectionInfo (char const* path, TRI_col_info_t* info) {
|
||||
int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info) {
|
||||
TRI_json_t* json;
|
||||
char* filename;
|
||||
bool ok;
|
||||
|
|
|
@ -283,7 +283,7 @@ void TRI_InitCollectionInfo (TRI_vocbase_t*,
|
|||
/// @brief copy a collection info block
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CopyCollectionInfo (TRI_col_info_t*, TRI_col_info_t*);
|
||||
void TRI_CopyCollectionInfo (TRI_col_info_t*, const TRI_col_info_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief free a collection info block
|
||||
|
@ -291,6 +291,15 @@ void TRI_CopyCollectionInfo (TRI_col_info_t*, TRI_col_info_t*);
|
|||
|
||||
void TRI_FreeCollectionInfoOptions (TRI_col_info_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the full directory name for a collection
|
||||
///
|
||||
/// it is the caller's responsibility to check if the returned string is NULL
|
||||
/// and to free it if not.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* TRI_GetDirectoryCollection (char const*, const TRI_col_info_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -298,7 +307,7 @@ void TRI_FreeCollectionInfoOptions (TRI_col_info_t*);
|
|||
TRI_collection_t* TRI_CreateCollection (TRI_vocbase_t*,
|
||||
TRI_collection_t*,
|
||||
char const*,
|
||||
TRI_col_info_t*);
|
||||
const TRI_col_info_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief frees the memory allocated, but does not free the pointer
|
||||
|
@ -337,7 +346,7 @@ int TRI_LoadCollectionInfo (char const*, TRI_col_info_t*);
|
|||
/// @brief saves a parameter info block to file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_SaveCollectionInfo (char const*, TRI_col_info_t*);
|
||||
int TRI_SaveCollectionInfo (char const*, const TRI_col_info_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates the parameter info block
|
||||
|
|
|
@ -1895,6 +1895,7 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
|||
TRI_collection_t* collection;
|
||||
TRI_shaper_t* shaper;
|
||||
TRI_document_collection_t* document;
|
||||
int res;
|
||||
bool waitForSync;
|
||||
bool isVolatile;
|
||||
|
||||
|
@ -1949,6 +1950,18 @@ TRI_document_collection_t* TRI_CreateDocumentCollection (TRI_vocbase_t* vocbase,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// save the parameter block (within create, no need to lock)
|
||||
res = TRI_SaveCollectionInfo(collection->_directory, parameter);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->_directory, TRI_last_error());
|
||||
|
||||
TRI_CloseCollection(collection);
|
||||
TRI_FreeCollection(collection); // will free document
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
|
|
|
@ -920,6 +920,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
|||
voc_shaper_t* shaper;
|
||||
TRI_shape_collection_t* collection;
|
||||
TRI_col_info_t parameter;
|
||||
int res;
|
||||
bool ok;
|
||||
|
||||
TRI_InitCollectionInfo(vocbase, ¶meter, name, TRI_COL_TYPE_SHAPE, SHAPER_DATAFILE_SIZE, 0);
|
||||
|
@ -951,6 +952,13 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
|||
TRI_FreeVocShaper(&shaper->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = TRI_SaveCollectionInfo(collection->base._directory, ¶meter);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot save collection parameters in directory '%s': '%s'", collection->base._directory, TRI_last_error());
|
||||
TRI_FreeVocShaper(&shaper->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// and return
|
||||
return &shaper->base;
|
||||
|
|
|
@ -1452,7 +1452,6 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase,
|
|||
assert(parameter);
|
||||
name = parameter->_name;
|
||||
|
||||
|
||||
// check that the name does not contain any strange characters
|
||||
if (! TRI_IsAllowedCollectionName(parameter->_isSystem, name)) {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
|
||||
|
@ -1644,7 +1643,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collec
|
|||
}
|
||||
|
||||
// remove dangling .json.tmp file if it exists
|
||||
tmpFile = TRI_Concatenate4String(collection->_path, "/", TRI_COL_PARAMETER_FILE, ".tmp");
|
||||
tmpFile = TRI_Concatenate4String(collection->_path, TRI_DIR_SEPARATOR_STR, TRI_COL_PARAMETER_FILE, ".tmp");
|
||||
if (tmpFile != NULL) {
|
||||
if (TRI_ExistsFile(tmpFile)) {
|
||||
TRI_UnlinkFile(tmpFile);
|
||||
|
|
|
@ -784,14 +784,15 @@ function IncludeMatchingAttributesFilter (config, vertex, path) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CombineFilters (filters, config, vertex, path) {
|
||||
var result = [];
|
||||
var result = [ ];
|
||||
filters.forEach( function (f) {
|
||||
var tmp = f(config, vertex, path);
|
||||
if (!Array.isArray(tmp)) {
|
||||
tmp = [tmp];
|
||||
if (! Array.isArray(tmp)) {
|
||||
tmp = [ tmp ];
|
||||
}
|
||||
result = result.concat(tmp);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the collection interface w/ volatile collections
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
var internal = require("internal");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- collection methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- volatile collections
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: volatile collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CollectionVolatileSuite () {
|
||||
var ERRORS = require("internal").errors;
|
||||
var cn = "UnittestsVolatileCollection";
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a volatile collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreation1 : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a volatile collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreation2 : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create w/ error
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreationError : function () {
|
||||
try {
|
||||
// cannot set isVolatile and waitForSync at the same time
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : true });
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test property change
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPropertyChange : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
|
||||
|
||||
try {
|
||||
// cannot set isVolatile and waitForSync at the same time
|
||||
c.properties({ waitForSync : true });
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief load/unload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLoadUnload : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data storage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testStorage : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
|
||||
c.save({"test": true});
|
||||
assertEqual(1, c.count());
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
assertEqual(0, c.count());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data storage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testStorageMany : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, journalSize: 1024 * 1024 });
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
|
||||
for (var i = 0; i < 10000; ++i) {
|
||||
c.save({"test": true, "foo" : "bar"});
|
||||
}
|
||||
|
||||
assertEqual(10000, c.count());
|
||||
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
assertEqual(0, c.count());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- main
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suites
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(CollectionVolatileSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
||||
|
|
@ -776,143 +776,6 @@ function CollectionSuite () {
|
|||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- volatile collections
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite: volatile collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CollectionVolatileSuite () {
|
||||
var ERRORS = require("internal").errors;
|
||||
var cn = "UnittestsVolatileCollection";
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
internal.db._drop(cn);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a volatile collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreation1 : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a volatile collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreation2 : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create w/ error
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreationError : function () {
|
||||
try {
|
||||
// cannot set isVolatile and waitForSync at the same time
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : true });
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test property change
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPropertyChange : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, waitForSync : false });
|
||||
|
||||
try {
|
||||
// cannot set isVolatile and waitForSync at the same time
|
||||
c.properties({ waitForSync : true });
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(ERRORS.ERROR_BAD_PARAMETER.code, err.errorNum);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief load/unload
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLoadUnload : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(cn, c.name());
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data storage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testStorage : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true });
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
|
||||
c.save({"test": true});
|
||||
assertEqual(1, c.count());
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
assertEqual(0, c.count());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data storage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testStorageMany : function () {
|
||||
var c = internal.db._create(cn, { isVolatile : true, journalSize: 1024 * 1024 });
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
|
||||
for (var i = 0; i < 10000; ++i) {
|
||||
c.save({"test": true, "foo" : "bar"});
|
||||
}
|
||||
|
||||
assertEqual(10000, c.count());
|
||||
|
||||
c.unload();
|
||||
|
||||
internal.wait(4);
|
||||
assertEqual(true, c.properties().isVolatile);
|
||||
assertEqual(0, c.count());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- vocbase methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1134,7 +997,6 @@ function CollectionDbSuite () {
|
|||
|
||||
jsunity.run(CollectionSuiteErrorHandling);
|
||||
jsunity.run(CollectionSuite);
|
||||
jsunity.run(CollectionVolatileSuite);
|
||||
jsunity.run(CollectionDbSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
|
|
@ -160,6 +160,125 @@ function CollectionEdgeSuite () {
|
|||
internal.wait(0.0);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an edge referring to a vertex documents by keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSaveEdgeKeys : function () {
|
||||
var k1 = vertex.save({ _key: "vx1", vx: 1 });
|
||||
var k2 = vertex.save({ _key: "vx2", vx: 2 });
|
||||
var k3 = vertex.save({ _key: "vx3", vx: 3 });
|
||||
|
||||
var d1 = vertex.document(k1._key);
|
||||
assertEqual("vx1", k1._key);
|
||||
assertEqual(vn + "/vx1", k1._id);
|
||||
assertEqual("vx1", d1._key);
|
||||
assertEqual(1, d1.vx);
|
||||
assertEqual(vn + "/vx1", d1._id);
|
||||
|
||||
var d2 = vertex.document(k2._key);
|
||||
assertEqual("vx2", k2._key);
|
||||
assertEqual(vn + "/vx2", k2._id);
|
||||
assertEqual("vx2", d2._key);
|
||||
assertEqual(2, d2.vx);
|
||||
assertEqual(vn + "/vx2", d2._id);
|
||||
|
||||
var d3 = vertex.document(vn + "/vx3");
|
||||
assertEqual("vx3", k3._key);
|
||||
assertEqual(vn + "/vx3", k3._id);
|
||||
assertEqual("vx3", d3._key);
|
||||
assertEqual(3, d3.vx);
|
||||
assertEqual(vn + "/vx3", d3._id);
|
||||
|
||||
var e1 = edge.save(vn + "/vx1", vn + "/vx2", { _key: "ex1", connect: "vx1->vx2" });
|
||||
var e2 = edge.save(vn + "/vx2", vn + "/vx1", { _key: "ex2", connect: "vx2->vx1" });
|
||||
var e3 = edge.save(vn + "/vx3", vn + "/vx1", { _key: "ex3", connect: "vx3->vx1" });
|
||||
|
||||
d1 = edge.document("ex1");
|
||||
assertEqual("ex1", d1._key);
|
||||
assertEqual(en + "/ex1", d1._id);
|
||||
assertEqual(vn + "/vx1", d1._from);
|
||||
assertEqual(vn + "/vx2", d1._to);
|
||||
assertEqual("vx1->vx2", d1.connect);
|
||||
assertEqual("ex1", e1._key);
|
||||
assertEqual(en + "/ex1", e1._id);
|
||||
|
||||
d2 = edge.document("ex2");
|
||||
assertEqual("ex2", d2._key);
|
||||
assertEqual(en + "/ex2", d2._id);
|
||||
assertEqual(vn + "/vx2", d2._from);
|
||||
assertEqual(vn + "/vx1", d2._to);
|
||||
assertEqual("vx2->vx1", d2.connect);
|
||||
assertEqual("ex2", e2._key);
|
||||
assertEqual(en + "/ex2", e2._id);
|
||||
|
||||
d3 = edge.document(en + "/ex3");
|
||||
assertEqual("ex3", d3._key);
|
||||
assertEqual(en + "/ex3", d3._id);
|
||||
assertEqual(vn + "/vx3", d3._from);
|
||||
assertEqual(vn + "/vx1", d3._to);
|
||||
assertEqual("vx3->vx1", d3.connect);
|
||||
assertEqual("ex3", e3._key);
|
||||
assertEqual(en + "/ex3", e3._id);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an edge referring to an unloaded vertex collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSaveEdgeUnloaded : function () {
|
||||
var k1 = vertex.save({ _key: "vx1", vx: 1 });
|
||||
var k2 = vertex.save({ _key: "vx2", vx: 2 });
|
||||
|
||||
assertEqual("vx1", k1._key);
|
||||
assertEqual(vn + "/vx1", k1._id);
|
||||
assertEqual("vx2", k2._key);
|
||||
assertEqual(vn + "/vx2", k2._id);
|
||||
|
||||
vertex.unload();
|
||||
edge.unload();
|
||||
|
||||
console.log("waiting for collections to unload");
|
||||
internal.wait(4);
|
||||
|
||||
var e1 = edge.save(vn + "/vx1", vn + "/vx2", { _key: "ex1", connect: "vx1->vx2" });
|
||||
var e2 = edge.save(vn + "/vx2", vn + "/vx1", { _key: "ex2", connect: "vx2->vx1" });
|
||||
|
||||
vertex.unload();
|
||||
edge.unload();
|
||||
|
||||
console.log("waiting for collections to unload");
|
||||
internal.wait(4);
|
||||
var e3 = edge.save(k1, k2, { _key: "ex3", connect: "vx1->vx2" });
|
||||
|
||||
d1 = edge.document("ex1");
|
||||
assertEqual("ex1", d1._key);
|
||||
assertEqual(en + "/ex1", d1._id);
|
||||
assertEqual(vn + "/vx1", d1._from);
|
||||
assertEqual(vn + "/vx2", d1._to);
|
||||
assertEqual("vx1->vx2", d1.connect);
|
||||
assertEqual("ex1", e1._key);
|
||||
assertEqual(en + "/ex1", e1._id);
|
||||
|
||||
d2 = edge.document("ex2");
|
||||
assertEqual("ex2", d2._key);
|
||||
assertEqual(en + "/ex2", d2._id);
|
||||
assertEqual(vn + "/vx2", d2._from);
|
||||
assertEqual(vn + "/vx1", d2._to);
|
||||
assertEqual("vx2->vx1", d2.connect);
|
||||
assertEqual("ex2", e2._key);
|
||||
assertEqual(en + "/ex2", e2._id);
|
||||
|
||||
d3 = edge.document("ex3");
|
||||
assertEqual("ex3", d3._key);
|
||||
assertEqual(en + "/ex3", d3._id);
|
||||
assertEqual(vn + "/vx1", d3._from);
|
||||
assertEqual(vn + "/vx2", d3._to);
|
||||
assertEqual("vx1->vx2", d3.connect);
|
||||
assertEqual("ex3", e3._key);
|
||||
assertEqual(en + "/ex3", e3._id);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an edge
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2347,6 +2347,23 @@ function AHUACATL_GRAPH_TRAVERSE () {
|
|||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "TRAVERSE");
|
||||
}
|
||||
|
||||
if (params.maxDepth <= 0) {
|
||||
// we need to have at least SOME limit to prevent endless iteration
|
||||
params.maxDepth = 1024;
|
||||
}
|
||||
|
||||
// prepare an array of filters
|
||||
var filter = [ ];
|
||||
if (params.minDepth != undefined) {
|
||||
filter.push(traversal.MinDepthFilter);
|
||||
}
|
||||
if (params.maxDepth != undefined) {
|
||||
filter.push(traversal.MaxDepthFilter);
|
||||
}
|
||||
if (filter.length == 0) {
|
||||
filter.push(traversal.VisitAllFilter);
|
||||
}
|
||||
|
||||
var config = {
|
||||
datasource: traversal.CollectionDatasourceFactory(edgeCollection),
|
||||
strategy: validate(params.strategy, {
|
||||
|
@ -2364,7 +2381,7 @@ function AHUACATL_GRAPH_TRAVERSE () {
|
|||
trackPaths: params.paths || false,
|
||||
visitor: AHUACATL_TRAVERSE_VISITOR,
|
||||
maxDepth: params.maxDepth,
|
||||
filter: params.maxDepth != undefined ? traversal.MaxDepthFilter : traversal.VisitAllFilter,
|
||||
filter: filter,
|
||||
uniqueness: {
|
||||
vertices: validate(params.uniqueness && params.uniqueness.vertices, {
|
||||
'none': traversal.Traverser.UNIQUE_NONE,
|
||||
|
|
|
@ -330,6 +330,27 @@ function ahuacatlQueryTraverseTestSuite () {
|
|||
db._drop(en);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min-depth filtering
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTraversalDepthFirstMin : function () {
|
||||
var config = {
|
||||
strategy: "depthfirst",
|
||||
order: "preorder",
|
||||
itemOrder: "forward",
|
||||
minDepth: 1,
|
||||
uniqueness: {
|
||||
vertices: "global"
|
||||
},
|
||||
_sort: true
|
||||
};
|
||||
|
||||
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
|
||||
|
||||
assertEqual([ "A", "B", "C", "D" ], actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test max-depth filtering
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -366,6 +387,25 @@ function ahuacatlQueryTraverseTestSuite () {
|
|||
assertEqual([ "A", "B", "C", "A", "D", "C", "A" ], actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min-/max-depth filtering
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTraversalDepthFirstMinMax : function () {
|
||||
var config = {
|
||||
strategy: "depthfirst",
|
||||
order: "preorder",
|
||||
itemOrder: "forward",
|
||||
minDepth: 1,
|
||||
maxDepth: 3,
|
||||
_sort: true
|
||||
};
|
||||
|
||||
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
|
||||
|
||||
assertEqual([ "A", "B", "C", "A", "D", "C", "A" ], actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test max-depth filtering
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue