mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB
Conflicts: html/admin/js/client.js html/admin/js/master.js
This commit is contained in:
commit
0236954f04
|
@ -1251,7 +1251,11 @@ typedef struct
|
|||
#include "ev_wrap.h"
|
||||
|
||||
static struct ev_loop default_loop_struct;
|
||||
#ifdef EV_API_STATIC
|
||||
EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
|
||||
#else
|
||||
struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
@ -1378,23 +1382,23 @@ array_realloc (int elem, void *base, int *cur, int cnt)
|
|||
return ev_realloc (base, elem * *cur);
|
||||
}
|
||||
|
||||
#define array_init_zero(base,count) \
|
||||
#define array_init_zero(base,count) \
|
||||
memset ((void *)(base), 0, sizeof (*(base)) * (count))
|
||||
|
||||
#define array_needsize(type,base,cur,cnt,init) \
|
||||
if (expect_false ((cnt) > (cur))) \
|
||||
{ \
|
||||
int ecb_unused ocur_ = (cur); \
|
||||
(base) = (type *)array_realloc \
|
||||
(sizeof (type), (base), &(cur), (cnt)); \
|
||||
init ((base) + (ocur_), (cur) - ocur_); \
|
||||
#define array_needsize(type,base,cur,cnt,init) \
|
||||
if (expect_false ((cnt) > (cur))) \
|
||||
{ \
|
||||
int ecb_unused ocur_ = (cur); \
|
||||
(base) = (type *)array_realloc \
|
||||
(sizeof (type), (base), &(cur), (cnt)); \
|
||||
init ((base) + (ocur_), (cur) - ocur_); \
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define array_slim(type,stem) \
|
||||
if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
|
||||
{ \
|
||||
stem ## max = array_roundsize (stem ## cnt >> 1); \
|
||||
#define array_slim(type,stem) \
|
||||
if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
|
||||
{ \
|
||||
stem ## max = array_roundsize (stem ## cnt >> 1); \
|
||||
base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\
|
||||
fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ mrb_obj_value(void *p)
|
|||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_false_value()
|
||||
mrb_false_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
|
@ -153,7 +153,7 @@ mrb_false_value()
|
|||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_nil_value()
|
||||
mrb_nil_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
|
@ -163,7 +163,7 @@ mrb_nil_value()
|
|||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_true_value()
|
||||
mrb_true_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
|
@ -173,7 +173,7 @@ mrb_true_value()
|
|||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_undef_value()
|
||||
mrb_undef_value(void)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
typedef struct global_variable {
|
||||
int counter;
|
||||
mrb_value *data;
|
||||
mrb_value (*getter)();
|
||||
void (*setter)();
|
||||
mrb_value (*getter)(void);
|
||||
void (*setter)(void);
|
||||
//void (*marker)();
|
||||
//int block_trace;
|
||||
//struct trace_var *trace;
|
||||
|
|
|
@ -342,6 +342,7 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
|
||||
// . = argument of any type (except collection)
|
||||
// c = collection
|
||||
// z = null
|
||||
// b = bool
|
||||
// n = number
|
||||
// s = string
|
||||
|
@ -356,8 +357,8 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("TONULL", "CAST_NULL", true, false, ".");
|
||||
|
||||
// string functions
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, false, "s,s|+");
|
||||
REGISTER_FUNCTION("CONCATSEPARATOR", "STRING_CONCAT_SEPARATOR", true, false, "s,s,s|+");
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, false, "sz,sz|+");
|
||||
REGISTER_FUNCTION("CONCATSEPARATOR", "STRING_CONCAT_SEPARATOR", true, false, "s,sz,sz|+");
|
||||
REGISTER_FUNCTION("CHARLENGTH", "STRING_LENGTH", true, false, "s");
|
||||
REGISTER_FUNCTION("LOWER", "STRING_LOWER", true, false, "s");
|
||||
REGISTER_FUNCTION("UPPER", "STRING_UPPER", true, false, "s");
|
||||
|
@ -381,10 +382,15 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
// geo functions
|
||||
REGISTER_FUNCTION("NEAR", "GEO_NEAR", false, false, "c,n,n,n|s");
|
||||
REGISTER_FUNCTION("WITHIN", "GEO_WITHIN", false, false, "c,n,n,n|s");
|
||||
|
||||
// graph functions
|
||||
REGISTER_FUNCTION("PATHS", "GRAPH_PATHS", false, false, "c,s|n,n,b");
|
||||
|
||||
// misc functions
|
||||
REGISTER_FUNCTION("FAIL", "FAIL", false, false, "|s"); // FAIL is non-deterministic, otherwise query optimisation will fail!
|
||||
REGISTER_FUNCTION("PASSTHRU", "PASSTHRU", false, false, "."); // simple non-deterministic wrapper to avoid optimisations at parse time
|
||||
REGISTER_FUNCTION("COLLECTIONS", "COLLECTIONS", false, false, "");
|
||||
REGISTER_FUNCTION("HAS", "HAS", true, false, "az,s");
|
||||
|
||||
REGISTER_FUNCTION("MERGE", "MERGE", true, false, "a,a|+");
|
||||
|
||||
|
@ -394,6 +400,10 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("MIN", "MIN", true, true, "l");
|
||||
REGISTER_FUNCTION("MAX", "MAX", true, true, "l");
|
||||
REGISTER_FUNCTION("SUM", "SUM", true, true, "l");
|
||||
REGISTER_FUNCTION("UNIQUE", "UNIQUE", true, false, "l");
|
||||
REGISTER_FUNCTION("REVERSE", "REVERSE", true, false, "l");
|
||||
REGISTER_FUNCTION("FIRST", "FIRST", true, false, "l");
|
||||
REGISTER_FUNCTION("LAST", "LAST", true, false, "l");
|
||||
|
||||
if (!result) {
|
||||
TRI_FreeFunctionsAql(functions);
|
||||
|
@ -532,9 +542,7 @@ bool TRI_ValidateArgsFunctionAql (TRI_aql_context_t* const context,
|
|||
const char* pattern;
|
||||
size_t i, n;
|
||||
bool eof = false;
|
||||
bool parse = true;
|
||||
bool repeat = false;
|
||||
bool foundArg = false;
|
||||
|
||||
assert(function);
|
||||
assert(parameters);
|
||||
|
@ -554,6 +562,8 @@ bool TRI_ValidateArgsFunctionAql (TRI_aql_context_t* const context,
|
|||
// validate argument types
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_aql_node_t* parameter = (TRI_aql_node_t*) TRI_AQL_NODE_MEMBER(parameters, i);
|
||||
bool parse = true;
|
||||
bool foundArg = false;
|
||||
|
||||
if (repeat) {
|
||||
// last argument is repeated
|
||||
|
@ -565,11 +575,9 @@ bool TRI_ValidateArgsFunctionAql (TRI_aql_context_t* const context,
|
|||
|
||||
foundArg = false;
|
||||
|
||||
while (parse) {
|
||||
while (parse && !eof) {
|
||||
char c = *pattern++;
|
||||
|
||||
assert(!eof);
|
||||
|
||||
switch (c) {
|
||||
case '\0':
|
||||
parse = false;
|
||||
|
@ -582,19 +590,21 @@ bool TRI_ValidateArgsFunctionAql (TRI_aql_context_t* const context,
|
|||
if (foundArg) {
|
||||
parse = false;
|
||||
ARG_CHECK
|
||||
break;
|
||||
if (*pattern == '+') {
|
||||
repeat = true;
|
||||
eof = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ',': // next argument
|
||||
assert(foundArg);
|
||||
foundArg = false;
|
||||
parse = false;
|
||||
ARG_CHECK
|
||||
break;
|
||||
case '+': // repeat last argument
|
||||
assert(foundArg);
|
||||
repeat = true;
|
||||
parse = false;
|
||||
eof = true;
|
||||
ARG_CHECK
|
||||
break;
|
||||
case '.': // any type except collections
|
||||
|
|
|
@ -811,8 +811,12 @@ static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* con
|
|||
}
|
||||
value = fmod(TRI_GetNumericNodeValueAql(lhs), TRI_GetNumericNodeValueAql(rhs));
|
||||
}
|
||||
else {
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeValueDoubleAql(context, value);
|
||||
|
||||
if (!node) {
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
return NULL;
|
||||
|
|
|
@ -838,7 +838,6 @@ static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
|
|||
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#define YY_NO_INPUT
|
||||
#ifndef YY_NO_INPUT
|
||||
/* %if-c-only Standard (non-C++) definition */
|
||||
/* %not-for-header */
|
||||
|
@ -1683,7 +1682,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|||
|
||||
/* Read in more data. */
|
||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
||||
yyg->yy_n_chars, (size_t) num_to_read );
|
||||
yyg->yy_n_chars, (int) num_to_read );
|
||||
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
||||
}
|
||||
|
|
|
@ -62,11 +62,13 @@ using namespace std;
|
|||
/// @brief word break characters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
static char WordBreakCharacters[] = {
|
||||
' ', '\t', '\n', '"', '\\', '\'', '`', '@',
|
||||
'<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
|
||||
'\0'
|
||||
};
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -199,6 +201,7 @@ static char* CompletionGenerator (char const* text, int state) {
|
|||
/// @brief attempted completion
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
static char** AttemptedCompletion (char const* text, int start, int end) {
|
||||
char** result;
|
||||
|
||||
|
@ -219,6 +222,7 @@ static char** AttemptedCompletion (char const* text, int start, int end) {
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -281,7 +285,7 @@ bool MRLineEditor::open (const bool autoComplete) {
|
|||
|
||||
bool MRLineEditor::isComplete (string const& source, size_t lineno, size_t column) {
|
||||
|
||||
#ifdef TRI_ENABLE_MRUBY
|
||||
#ifdef TRI_ENABLE_MRUBY
|
||||
char const* msg = "syntax error, unexpected $end";
|
||||
char* text = TRI_DuplicateString(source.c_str());
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ MR_state_t;
|
|||
/// @brief opens a new context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MR_state_t* MR_OpenShell ();
|
||||
MR_state_t* MR_OpenShell (void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a ArangoError
|
||||
|
|
|
@ -1057,6 +1057,7 @@ SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-operators.js \
|
|||
@srcdir@/js/server/tests/ahuacatl-relational.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-ternary.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-parse.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-hash.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-skiplist.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-simple.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-variables.js \
|
||||
|
|
|
@ -186,6 +186,7 @@ SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-operators.js \
|
|||
@srcdir@/js/server/tests/ahuacatl-relational.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-ternary.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-parse.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-hash.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-skiplist.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-simple.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-variables.js \
|
||||
|
|
12
README.md
12
README.md
|
@ -48,7 +48,7 @@ The ArangoDB shell will be install as
|
|||
Start the server:
|
||||
|
||||
> mkdir /tmp/vocbase
|
||||
> ./arango /tmp/vocbase
|
||||
> ./arangod /tmp/vocbase
|
||||
2012-03-30T12:54:19Z [11794] INFO ArangoDB (version 0.x.y) is ready for business
|
||||
2012-03-30T12:54:19Z [11794] INFO HTTP client port: 127.0.0.1:8529
|
||||
2012-03-30T12:54:19Z [11794] INFO HTTP admin port: 127.0.0.1:8530
|
||||
|
@ -56,7 +56,7 @@ Start the server:
|
|||
|
||||
Start the shell in another windows:
|
||||
|
||||
> ./avocsh
|
||||
> ./arangosh
|
||||
_
|
||||
__ _ _ __ __ _ _ __ __ _ ___ ___| |__
|
||||
/ _` | '__/ _` | '_ \ / _` |/ _ \/ __| '_ \
|
||||
|
@ -64,19 +64,19 @@ Start the shell in another windows:
|
|||
\__,_|_| \__,_|_| |_|\__, |\___/|___/_| |_|
|
||||
|___/
|
||||
|
||||
Welcome to avocsh 0.3.5. Copyright (c) 2012 triAGENS GmbH.
|
||||
Welcome to arangosh 0.3.5. Copyright (c) 2012 triAGENS GmbH.
|
||||
Using Google V8 3.9.4.0 JavaScript engine.
|
||||
Using READLINE 6.1.
|
||||
|
||||
Connected to Arango DB 127.0.0.1:8529 Version 0.3.5
|
||||
|
||||
avocsh> db._create("examples")
|
||||
arangosh> db._create("examples")
|
||||
[ArangoCollection 106097, "examples]
|
||||
|
||||
avocsh> db.examples.save({ Hallo: "World" });
|
||||
arangosh> db.examples.save({ Hallo: "World" });
|
||||
{"error":false,"_id":"106097/2333739","_rev":2333739}
|
||||
|
||||
avocsh> db.examples.all();
|
||||
arangosh> db.examples.all();
|
||||
[{ _id : "82883/1524675", _rev : 1524675, Hallo : "World" }]
|
||||
|
||||
## Caveat
|
||||
|
|
|
@ -695,6 +695,8 @@ int ArangoServer::startupServer () {
|
|||
RestHandlerCreator<RestActionHandler>::createData< pair< TRI_vocbase_t*, set<string>* >* >,
|
||||
(void*) &handlerDataAdmin);
|
||||
|
||||
adminFactory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_IMPORT_PATH, RestHandlerCreator<RestImportHandler>::createData<TRI_vocbase_t*>, _vocbase);
|
||||
|
||||
_adminHttpServer = _applicationHttpServer->buildServer(new ArangoHttpServer(scheduler, dispatcher), adminFactory, adminPorts);
|
||||
}
|
||||
|
||||
|
|
|
@ -863,7 +863,8 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper, TRI_shape_value_t* dst, T
|
|||
a = (TRI_array_shape_t*) (ptr = TRI_Allocate(shaper->_memoryZone, i, true));
|
||||
|
||||
if (ptr == NULL) {
|
||||
// TODO: FIXME my compiler complains about e being potentially undefined. what to do?
|
||||
e = values + n;
|
||||
|
||||
for (p = values; p < e; ++p) {
|
||||
if (p->_value != NULL) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
|
|
|
@ -92,7 +92,7 @@ static void TRI_DestroySkipListNode (TRI_skiplist_base_t* skiplist, TRI_skiplist
|
|||
/// @brief Grow the node at the height specified.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool GrowNodeHeight(TRI_skiplist_node_t* node, uint32_t newHeight) {
|
||||
static bool GrowNodeHeight (TRI_skiplist_node_t* node, uint32_t newHeight) {
|
||||
|
||||
TRI_skiplist_nb_t* oldColumn = node->_column;
|
||||
uint32_t j;
|
||||
|
|
|
@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE (tst_compare_values_unequal) {
|
|||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[0]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[1]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[null]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[false");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[false]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "[true]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "0", "{}");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[]");
|
||||
|
@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE (tst_compare_values_unequal) {
|
|||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[0]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[1]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[null]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[false");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[false]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "[true]");
|
||||
JSON_CHECK(-1, TRI_CompareValuesJson, "1", "{}");
|
||||
|
||||
|
@ -263,8 +263,8 @@ BOOST_AUTO_TEST_CASE (tst_check_in_list_empty) {
|
|||
JSON_CHECK(false, TRI_CheckInListJson, "0", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "1", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "\"fox\"", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, " ", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "\"\"", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "\" \"", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "[]", "[]");
|
||||
JSON_CHECK(false, TRI_CheckInListJson, "{}", "[]");
|
||||
}
|
||||
|
|
|
@ -56,6 +56,13 @@ LineEditor::LineEditor (string const& history)
|
|||
rl_initialize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LineEditor::~LineEditor () {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -89,6 +89,12 @@ class LineEditor {
|
|||
|
||||
LineEditor (std::string const& history);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructor
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~LineEditor ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -662,7 +662,8 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
a = (TRI_array_shape_t*) (ptr = (char*) TRI_Allocate(shaper->_memoryZone, i, true));
|
||||
|
||||
if (ptr == NULL) {
|
||||
// TODO FIXME: my compiler complains about e being potentially undefined. what to do?
|
||||
e = values + n;
|
||||
|
||||
for (p = values; p < e; ++p) {
|
||||
if (p->_value != NULL) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
|
@ -1340,7 +1341,7 @@ bool TRI_IdentifiersObjectReference (v8::Handle<v8::Value> value, TRI_voc_cid_t&
|
|||
did = 0;
|
||||
|
||||
if (value->IsNumber() || value->IsNumberObject()) {
|
||||
did = TRI_ObjectToDouble(value, error);
|
||||
did = (TRI_voc_did_t) TRI_ObjectToDouble(value, error);
|
||||
return ! error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1352,7 +1352,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
|||
|
||||
/* Read in more data. */
|
||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
||||
yyg->yy_n_chars, (size_t) num_to_read );
|
||||
yyg->yy_n_chars, (int) num_to_read );
|
||||
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
||||
}
|
||||
|
|
|
@ -977,7 +977,7 @@ static v8::Handle<v8::Value> JS_AllQuery (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
// limit
|
||||
for (; ptr < end && (TRI_voc_ssize_t) count < limit; ++ptr) {
|
||||
for (; ptr < end && count < limit; ++ptr) {
|
||||
if (*ptr) {
|
||||
TRI_doc_mptr_t const* d = (TRI_doc_mptr_t const*) *ptr;
|
||||
|
||||
|
@ -1096,6 +1096,8 @@ static v8::Handle<v8::Value> JS_ByExampleQuery (v8::Arguments const& argv) {
|
|||
}
|
||||
}
|
||||
|
||||
TRI_DestroyVector(&filtered);
|
||||
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
// .............................................................................
|
||||
|
|
|
@ -71,7 +71,7 @@ static TRI_doc_mptr_t CreateJson (TRI_doc_collection_t* collection,
|
|||
|
||||
if (shaped == 0) {
|
||||
collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
|
||||
result._did = 0;
|
||||
memset(&result, 0, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ static TRI_doc_mptr_t UpdateJson (TRI_doc_collection_t* collection,
|
|||
|
||||
if (shaped == 0) {
|
||||
collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
|
||||
result._did = 0;
|
||||
memset(&result, 0, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -434,6 +434,9 @@ TRI_index_t* TRI_CreateCapConstraint (struct TRI_doc_collection_s* collection,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_DestroyCapConstraint (TRI_index_t* idx) {
|
||||
TRI_cap_constraint_t* cap = (TRI_cap_constraint_t*) idx;
|
||||
|
||||
TRI_DestroyLinkedArray(&cap->_array);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -331,7 +331,7 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* sim,
|
|||
sim->base.endWrite(&sim->base);
|
||||
}
|
||||
|
||||
mptr._did = 0;
|
||||
memset(&mptr, 0, sizeof(mptr));
|
||||
return mptr;
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ static TRI_doc_mptr_t UpdateDocument (TRI_sim_collection_t* collection,
|
|||
}
|
||||
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_CONFLICT);
|
||||
mptr._did = 0;
|
||||
memset(&mptr, 0, sizeof(mptr));
|
||||
return mptr;
|
||||
}
|
||||
}
|
||||
|
@ -1012,7 +1012,7 @@ static TRI_doc_mptr_t ReadShapedJson (TRI_doc_collection_t* document,
|
|||
header = TRI_LookupByKeyAssociativePointer(&collection->_primaryIndex, &did);
|
||||
|
||||
if (header == NULL || header->_deletion != 0) {
|
||||
result._did = 0;
|
||||
memset(&result, 0, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
|
@ -1048,7 +1048,7 @@ static TRI_doc_mptr_t UpdateShapedJson (TRI_doc_collection_t* document,
|
|||
}
|
||||
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND);
|
||||
mptr._did = 0;
|
||||
memset(&mptr, 0, sizeof(mptr));
|
||||
return mptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -617,6 +617,7 @@ TRI_shaper_t* TRI_CreateVocShaper (TRI_vocbase_t* vocbase,
|
|||
|
||||
void TRI_DestroyVocShaper (TRI_shaper_t* s) {
|
||||
voc_shaper_t* shaper = (voc_shaper_t*) s;
|
||||
size_t i;
|
||||
|
||||
assert(shaper);
|
||||
assert(shaper->_collection);
|
||||
|
@ -627,6 +628,13 @@ void TRI_DestroyVocShaper (TRI_shaper_t* s) {
|
|||
TRI_DestroyAssociativeSynced(&shaper->_attributeIds);
|
||||
TRI_DestroyAssociativeSynced(&shaper->_shapeDictionary);
|
||||
TRI_DestroyAssociativeSynced(&shaper->_shapeIds);
|
||||
|
||||
for (i = 0; i < shaper->_accessors._nrAlloc; ++i) {
|
||||
TRI_shape_access_t* accessor = (TRI_shape_access_t*) shaper->_accessors._table[i];
|
||||
if (accessor != NULL) {
|
||||
TRI_FreeShapeAccessor(accessor);
|
||||
}
|
||||
}
|
||||
TRI_DestroyAssociativePointer(&shaper->_accessors);
|
||||
|
||||
TRI_DestroyMutex(&shaper->_shapeLock);
|
||||
|
|
|
@ -178,7 +178,7 @@ extern size_t PageSize;
|
|||
/// @brief no limit
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_QRY_NO_LIMIT ((TRI_voc_size_t) UINT32_MAX)
|
||||
#define TRI_QRY_NO_LIMIT ((TRI_voc_size_t) (4294967295U))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief no skip
|
||||
|
|
20
build.sh
20
build.sh
|
@ -9,7 +9,7 @@ echo
|
|||
|
||||
OPTIONS="--disable-dependency-tracking --disable-relative"
|
||||
PREFIX="--prefix=/usr --sysconfdir=/etc"
|
||||
RESULTS="arango avocsh avocirb"
|
||||
RESULTS="arangod arangosh arangoimp"
|
||||
|
||||
export CPPFLAGS=""
|
||||
export LDFLAGS=""
|
||||
|
@ -26,20 +26,23 @@ case $TRI_OS_LONG in
|
|||
|
||||
Linux-openSUSE-11.4*)
|
||||
echo "Using configuration for openSuSE 11.4"
|
||||
OPTIONS="$OPTIONS --disable-all-in-one --with-boost-test"
|
||||
OPTIONS="$OPTIONS --disable-all-in-one --with-boost-test --enable-mruby"
|
||||
LDD_INFO="yes"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
Linux-openSUSE-11*)
|
||||
echo "Using configuration for openSuSE 11"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one --enable-mruby"
|
||||
LDD_INFO="yes"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
Linux-Debian-6*)
|
||||
echo "Using configuration for Debian"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one --enable-mruby"
|
||||
LDD_INFO="yes"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
Linux-Debian*)
|
||||
|
@ -56,21 +59,24 @@ case $TRI_OS_LONG in
|
|||
|
||||
Linux-Ubuntu-11.10*)
|
||||
echo "Using configuration for Ubuntu"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one --enable-mruby"
|
||||
LDD_INFO="yes"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
Linux-Ubuntu-*)
|
||||
echo "Using configuration for Ubuntu"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one --enable-mruby"
|
||||
LDD_INFO="yes"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
Darwin*)
|
||||
echo "Using configuration for DARWIN"
|
||||
CPPFLAGS='-isystem /usr/include -isystem /opt/local/include -Wno-deprecated-declarations'
|
||||
LDFLAGS='-L/usr/lib -L/opt/local/lib' # need to use OpenSSL from system
|
||||
OPTIONS="$OPTIONS --enable-all-in-one"
|
||||
OPTIONS="$OPTIONS --enable-all-in-one --enable-mruby"
|
||||
RESULTS="$RESULTS arangoirb"
|
||||
;;
|
||||
|
||||
*)
|
||||
|
|
|
@ -26,7 +26,7 @@ test -f ${OUTPUT} || exit 1
|
|||
#############################################################################
|
||||
|
||||
cat ${OUTPUT} \
|
||||
| sed -e 's:(yy_n_chars), (size_t) num_to_read );:(yy_n_chars), (int) num_to_read );:' \
|
||||
| sed -e 's:yy_n_chars, (size_t) num_to_read );:yy_n_chars, (int) num_to_read );:' \
|
||||
> ${OUTPUT}.tmp
|
||||
|
||||
# give some information
|
||||
|
|
|
@ -8,7 +8,7 @@ echo "########################################################"
|
|||
|
||||
OPTIONS="--disable-dependency-tracking --disable-relative --enable-gcov"
|
||||
PREFIX="--prefix=/usr --sysconfdir=/etc"
|
||||
RESULTS="arango avocsh"
|
||||
RESULTS="arangod arangosh"
|
||||
|
||||
export CPPFLAGS=""
|
||||
export LDFLAGS=""
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#delete {
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ form {
|
|||
|
||||
#queryOutput {
|
||||
height:40%;
|
||||
yoverflow-y: auto;
|
||||
overflow-y: auto;
|
||||
border: 1px solid black;
|
||||
background: white;
|
||||
font-family: "courier";
|
||||
|
@ -352,6 +356,7 @@ form {
|
|||
margin-top: 0px;
|
||||
background-color: white;
|
||||
height: 70%;
|
||||
word-wrap: break-word;
|
||||
overflow-y: auto;
|
||||
width:100%;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<button class="minimal" id="Logs">Logs</button>
|
||||
<button class="minimal" id="Configuration">Configuration</button>
|
||||
<button class="minimal" id="Query">Query</button>
|
||||
<button class="minimal" id="AvocSH">ArangoSH</button>
|
||||
<button class="minimal" id="AvocSH">Shell</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -388,7 +388,7 @@
|
|||
<form>
|
||||
<input type="text" class="editBox" id="avocshContent"></input><button class="minimal" id="submitAvoc">Ok</button>
|
||||
</form>
|
||||
<a href="">ArangoDB Shell - click for more information</a>
|
||||
<a href="http://www.arangodb.org/manuals/UserManual.html">ArangoDB Shell - click for more informaytion</a>
|
||||
</div>
|
||||
|
||||
<div id="queryView" style="display: none">
|
||||
|
@ -397,8 +397,8 @@
|
|||
</div>
|
||||
<form id="queryForm" method="post" onsubmit="return false">
|
||||
<textarea placeholder="Type in your query..." class="editBox" id="queryContent"></textarea><br>
|
||||
<button class="minimal" id="submitQuery">Post</button>
|
||||
<a href=https://github.com/triAGENS/ArangoDB/wiki/Aql>ArangoDB Query Language - click for more information</a>
|
||||
<button class="minimal" id="submitQuery">Execute</button>
|
||||
<a href="http://www.arangodb.org/manuals/Aql.html">ArangoDB Query Language - click for more information</a>
|
||||
<br></br>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
var ModuleCache = { "/internal" : { "exports": { } } };
|
||||
|
||||
var SYS_START_PAGER = function() { };
|
||||
var SYS_STOP_PAGER = function() { };
|
||||
var TRI_SYS_OUTPUT = function() { };
|
||||
|
||||
var print = function (value) {
|
||||
hansmann(value);
|
||||
};
|
||||
|
||||
function ArangoConnection () {
|
||||
|
||||
}
|
||||
|
||||
function TRI_SYS_OUTPUT (a, b, c, d, e, f, g, h) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var arango = new ArangoConnection();
|
||||
|
||||
ArangoConnection.prototype.get = function (url, obj) {
|
||||
ArangoConnection.prototype.get = function (url) {
|
||||
var msg;
|
||||
$.ajax({
|
||||
async: false,
|
||||
|
@ -24,10 +30,9 @@ var msg;
|
|||
}
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ArangoConnection.prototype.delete = function (url, obj) {
|
||||
ArangoConnection.prototype.delete = function (url) {
|
||||
var msg;
|
||||
$.ajax({
|
||||
async: false,
|
||||
|
@ -43,39 +48,40 @@ var msg;
|
|||
}
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ArangoConnection.prototype.post = function (url, body, obj) {
|
||||
var msg;
|
||||
ArangoConnection.prototype.post = function (url, body) {
|
||||
var msg;
|
||||
$.ajax({
|
||||
async: false,
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: obj,
|
||||
data: body,
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function(data) {
|
||||
msg = JSON.stringify(data);
|
||||
msg = data; //JSON.stringify(data);
|
||||
},
|
||||
error: function(data) {
|
||||
msg = JSON.stringify(data);
|
||||
}
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ArangoConnection.prototype.put = function (url, body, obj) {
|
||||
ArangoConnection.prototype.put = function (url, body) {
|
||||
var msg;
|
||||
$.ajax({
|
||||
async: false,
|
||||
type: "PUT",
|
||||
url: url,
|
||||
data: obj,
|
||||
data: body,
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function(data) {
|
||||
return data;
|
||||
msg = JSON.stringify(data);
|
||||
},
|
||||
error: function(data) {
|
||||
|
@ -83,4 +89,9 @@ var msg;
|
|||
}
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
||||
ArangoConnection.prototype.GET = ArangoConnection.prototype.get;
|
||||
ArangoConnection.prototype.POST = ArangoConnection.prototype.post;
|
||||
ArangoConnection.prototype.DELETE = ArangoConnection.prototype.delete;
|
||||
ArangoConnection.prototype.PUT = ArangoConnection.prototype.put;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
../../../js/client/client.js
|
|
@ -765,13 +765,15 @@ var logTable = $('#logTableID').dataTable({
|
|||
else {
|
||||
var collectionID;
|
||||
var boxContent = $('#documentEditSourceBox').val();
|
||||
var jsonContent = JSON.parse(boxContent);
|
||||
collectionID = globalCollectionID;
|
||||
|
||||
boxContent = stateReplace(boxContent);
|
||||
parsedContent = JSON.parse(boxContent);
|
||||
|
||||
$.ajax({
|
||||
type: "PUT",
|
||||
url: "/_api/document/" + collectionID,
|
||||
data: JSON.stringify(jsonContent),
|
||||
data: JSON.stringify(parsedContent),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function(data) {
|
||||
|
@ -1009,9 +1011,9 @@ var logTable = $('#logTableID').dataTable({
|
|||
|
||||
/*animation*/
|
||||
$('#movetologinButton').text("Login");
|
||||
$('#footerSlideContent').animate({ height: '25px' });
|
||||
$('#footerSlideButton').css('backgroundPosition', 'top left');
|
||||
open = false;
|
||||
$('#footerSlideContent').animate({ height: '25px' });
|
||||
$('#footerSlideButton').css('backgroundPosition', 'top left');
|
||||
open = false;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
@ -1164,14 +1166,7 @@ var logTable = $('#logTableID').dataTable({
|
|||
var client = "arangodb:" + data;
|
||||
|
||||
$('#avocshWindow').append('<b class="avocshClient">' + client + '</b>');
|
||||
|
||||
try {
|
||||
var server = "" + eval(data);
|
||||
$('#avocshWindow').append('<p class="avocshSuccess">' + server + '</p>');
|
||||
}
|
||||
catch(e) {
|
||||
$('#avocshWindow').append('<p class="avocshError">Error:' + e + '</p>');
|
||||
}
|
||||
hansmann(data);
|
||||
$("#avocshWindow").animate({scrollTop:$("#avocshWindow")[0].scrollHeight}, 1);
|
||||
$("#avocshContent").val('');
|
||||
return false;
|
||||
|
@ -1190,14 +1185,14 @@ var logTable = $('#logTableID').dataTable({
|
|||
contentType: "application/json",
|
||||
processData: false,
|
||||
success: function(data) {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
$("#queryOutput").empty();
|
||||
$("#queryOutput").append('<font color=green>' + JSON.stringify(temp.errorMessage) + '</font>');
|
||||
$("#queryOutput").append('<font color=green>' + JSON.stringify(data.result) + '</font>');
|
||||
},
|
||||
error: function(data) {
|
||||
console.log(data);
|
||||
var temp = JSON.parse(data.responseText);
|
||||
$("#queryOutput").empty();
|
||||
$("#queryOutput").append('<font color=red>' + JSON.stringify(temp.errorMessage) + '</font>');
|
||||
$("#queryOutput").append('<font color=red>[' + temp.errorNum + '] ' + temp.errorMessage + '</font>');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1516,7 +1511,7 @@ function drawCollectionsTable () {
|
|||
error: function(data) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
items.push(['<button class="enabled" id="delete"><img src="/_admin/html/media/icons/round_minus_icon16.png" width="16" height="16" title="Delete"></button><button class="enabled" id="unload"><img src="/_admin/html/media/icons/not_connected_icon16.png" width="16" height="16" title="Unload"></button><button class="enabled" id="showdocs"><img src="/_admin/html/media/icons/zoom_icon16.png" width="16" height="16" title="Show Documents"></button><button class="enabled" id="edit" title="Edit"><img src="/_admin/html/media/icons/doc_edit_icon16.png" width="16" height="16"></button>',
|
||||
val.id, val.name, tempStatus, bytesToSize(size*1024), alive]);
|
||||
}
|
||||
|
@ -2273,3 +2268,35 @@ function hideLogPagination() {
|
|||
$('#logToolbarInfo').hide();
|
||||
}
|
||||
|
||||
function hansmann (data) {
|
||||
try {
|
||||
var server = eval(data);
|
||||
if (server !== undefined) {
|
||||
var resultung = "";
|
||||
if (server === null) {
|
||||
resultung = "null";
|
||||
}
|
||||
else if (typeof(server) == "string") {
|
||||
resultung = server;
|
||||
}
|
||||
else if (typeof(server) == "number" || typeof(server) == "boolean") {
|
||||
resultung = "" + server;
|
||||
}
|
||||
else if (typeof(server) == "object") {
|
||||
try {
|
||||
resultung = JSON.stringify(server);
|
||||
}
|
||||
catch (err) {
|
||||
resultung = server.toString();
|
||||
}
|
||||
}
|
||||
|
||||
$('#avocshWindow').append('<p class="avocshSuccess">' + resultung + '</p>');
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
$('#avocshWindow').append('<p class="avocshError">Error:' + e + '</p>');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,47 @@ function AHUACATL_INDEX (collection, indexTypes) {
|
|||
return null;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief normalize a value for comparison, sorting etc.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_NORMALIZE (value) {
|
||||
if (value === null || value === undefined) {
|
||||
return null;
|
||||
}
|
||||
if (typeof(value) !== "object") {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
var result = [ ];
|
||||
var length = value.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
result.push(AHUACATL_NORMALIZE(value[i]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
var attributes = [ ];
|
||||
for (var attribute in value) {
|
||||
if (!value.hasOwnProperty(attribute)) {
|
||||
continue;
|
||||
}
|
||||
attributes.push(attribute);
|
||||
}
|
||||
attributes.sort();
|
||||
|
||||
var result = { };
|
||||
var length = attributes.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
result[attributes[i]] = AHUACATL_NORMALIZE(value[attributes[i]]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clone an object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -122,7 +163,7 @@ function AHUACATL_CLONE (obj) {
|
|||
/// @brief validate function call argument
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_ARG_CHECK (actualValue, expectedType, functionName, argument) {
|
||||
function AHUACATL_ARG_CHECK (actualValue, expectedType, functionName) {
|
||||
if (AHUACATL_TYPEWEIGHT(actualValue) !== expectedType) {
|
||||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, functionName);
|
||||
}
|
||||
|
@ -442,10 +483,23 @@ function AHUACATL_GET_DOCUMENTS_SKIPLIST_LIST (collection, idx, attribute, value
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get names of all collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_COLLECTIONS () {
|
||||
var collections = internal.db._collections();
|
||||
var result = [ ];
|
||||
|
||||
for (var i = 0; i < collections.length; ++i) {
|
||||
result.push({ "_id" : collections[i]._id, "name" : collections[i].name() });
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -1149,7 +1203,7 @@ function AHUACATL_STRING_CONCAT () {
|
|||
continue;
|
||||
}
|
||||
|
||||
AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, "CONCAT", i + 1);
|
||||
AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, "CONCAT");
|
||||
|
||||
result += element;
|
||||
}
|
||||
|
@ -1175,7 +1229,7 @@ function AHUACATL_STRING_CONCAT_SEPARATOR () {
|
|||
continue;
|
||||
}
|
||||
|
||||
AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, "CONCAT_SEPARATOR", i + 1);
|
||||
AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, "CONCAT_SEPARATOR");
|
||||
|
||||
if (i == 0) {
|
||||
separator = element;
|
||||
|
@ -1200,7 +1254,7 @@ function AHUACATL_STRING_CONCAT_SEPARATOR () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_STRING_LENGTH (value) {
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "STRING_LENGTH", 1);
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "STRING_LENGTH");
|
||||
|
||||
return value.length;
|
||||
}
|
||||
|
@ -1212,7 +1266,7 @@ function AHUACATL_STRING_LENGTH (value) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_STRING_LOWER (value) {
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "LOWER", 1);
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "LOWER");
|
||||
|
||||
return value.toLowerCase();
|
||||
}
|
||||
|
@ -1224,7 +1278,7 @@ function AHUACATL_STRING_LOWER (value) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_STRING_UPPER (value) {
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "UPPER", 1);
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "UPPER");
|
||||
|
||||
return value.toUpperCase();
|
||||
}
|
||||
|
@ -1236,8 +1290,8 @@ function AHUACATL_STRING_UPPER (value) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_STRING_SUBSTRING (value, offset, count) {
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "SUBSTRING", 1);
|
||||
AHUACATL_ARG_CHECK(offset, AHUACATL_TYPEWEIGHT_NUMBER, "SUBSTRING", 2);
|
||||
AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, "SUBSTRING");
|
||||
AHUACATL_ARG_CHECK(offset, AHUACATL_TYPEWEIGHT_NUMBER, "SUBSTRING");
|
||||
|
||||
return value.substr(offset, count);
|
||||
}
|
||||
|
@ -1587,6 +1641,74 @@ function AHUACATL_LENGTH () {
|
|||
return value.length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the first element of a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_FIRST () {
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
if (value.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value[0];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the last element of a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_LAST () {
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
if (value.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value[value.length - 1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief reverse the elements in a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_REVERSE () {
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
return value.reverse();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a list of unique elements from the list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_UNIQUE () {
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
var length = value.length;
|
||||
var keys = { };
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var normalized = AHUACATL_NORMALIZE(value[i]);
|
||||
keys[JSON.stringify(normalized)] = normalized;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
for (var i in keys) {
|
||||
result.push(keys[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the union (all) of all arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1776,6 +1898,177 @@ function AHUACATL_GEO_WITHIN () {
|
|||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- graph functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find all paths through a graph
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_GRAPH_PATHS () {
|
||||
var collection = arguments[0];
|
||||
var edgeType = arguments[1];
|
||||
var minLength = arguments[2] != undefined ? arguments[2] : 1;
|
||||
var maxLength = arguments[3] != undefined ? arguments[3] : 10;
|
||||
var followCycles = arguments[4] ? arguments[4] : false;
|
||||
var direction;
|
||||
|
||||
// validate arguments
|
||||
if (edgeType == "outbound") {
|
||||
direction = 1;
|
||||
}
|
||||
else if (edgeType == "inbound") {
|
||||
direction = 2;
|
||||
}
|
||||
else if (edgeType == "any") {
|
||||
direction = 3;
|
||||
}
|
||||
else {
|
||||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "PATHS");
|
||||
}
|
||||
|
||||
if (minLength < 0 || maxLength < 0 || minLength > maxLength) {
|
||||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "PATHS");
|
||||
}
|
||||
|
||||
var edgeCollection = internal.edges[collection];
|
||||
var searchAttributes = {
|
||||
"edgeCollection" : edgeCollection,
|
||||
"minLength" : minLength,
|
||||
"maxLength" : maxLength,
|
||||
"direction" : direction,
|
||||
"followCycles" : followCycles,
|
||||
};
|
||||
|
||||
var allEdges = edgeCollection.all().toArray();
|
||||
// TODO: restrict allEdges to edges with certain _from values etc.
|
||||
|
||||
var result = [ ];
|
||||
var n = allEdges.length;
|
||||
for (var i = 0; i < n; ++i) {
|
||||
|
||||
var edge = allEdges[i];
|
||||
var _from = edge._from;
|
||||
var _to = edge._to;
|
||||
var sources = [ ];
|
||||
|
||||
if (searchAttributes.direction & 1) {
|
||||
sources.push(_from);
|
||||
}
|
||||
if (searchAttributes.direction & 2) {
|
||||
sources.push(_to);
|
||||
}
|
||||
|
||||
for (var j = 0; j < sources.length; ++j) {
|
||||
var visited = { };
|
||||
var vertices = [ ];
|
||||
var edges = [ ];
|
||||
|
||||
var source = sources[j];
|
||||
var next = internal.db._document(source);
|
||||
vertices.push(next);
|
||||
if (!searchAttributes.followCycles) {
|
||||
visited[source] = true;
|
||||
}
|
||||
|
||||
if (searchAttributes.minLength == 0) {
|
||||
var copy = AHUACATL_CLONE(vertices);
|
||||
result.push({ "vertices" : copy, "edges" : [ ], "source" : copy[0], "destination" : copy[copy.length - 1] });
|
||||
}
|
||||
|
||||
if (searchAttributes.maxLength > 0) {
|
||||
var subResult = AHUACATL_GRAPH_SUBNODES(searchAttributes, AHUACATL_CLONE(visited), edges, vertices, edge, 0);
|
||||
for (var k = 0; k < subResult.length; ++k) {
|
||||
result.push(subResult[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find all paths through a graph, internal part called recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_GRAPH_SUBNODES (searchAttributes, visited, edges, vertices, edge, level) {
|
||||
var result = [ ];
|
||||
|
||||
var _from = edge._from;
|
||||
var _to = edge._to;
|
||||
var targets = [ ];
|
||||
|
||||
if (searchAttributes.direction & 1) {
|
||||
targets.push(_to);
|
||||
}
|
||||
if (searchAttributes.direction & 2) {
|
||||
targets.push(_from);
|
||||
}
|
||||
|
||||
for (var i = 0; i < targets.length; ++i) {
|
||||
var target = targets[i];
|
||||
|
||||
if (!searchAttributes.followCycles && visited[target]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var clonedEdges = AHUACATL_CLONE(edges);
|
||||
var clonedVertices = AHUACATL_CLONE(vertices);
|
||||
|
||||
clonedEdges.push(edge);
|
||||
var vertex = internal.db._document(target);
|
||||
clonedVertices.push(vertex);
|
||||
|
||||
if (level + 1 >= searchAttributes.minLength) {
|
||||
result.push({ "vertices" : clonedVertices, "edges" : clonedEdges, "source" : clonedVertices[0], "destination" : clonedVertices[clonedVertices.length - 1] });
|
||||
}
|
||||
|
||||
if (level + 1 < searchAttributes.maxLength) {
|
||||
// recursion
|
||||
|
||||
if (!searchAttributes.followCycles) {
|
||||
visited[target] = true;
|
||||
}
|
||||
|
||||
var subEdges;
|
||||
if (searchAttributes.direction == 1) {
|
||||
subEdges = searchAttributes.edgeCollection.outEdges(vertex);
|
||||
}
|
||||
else if (searchAttributes.direction == 2) {
|
||||
subEdges = searchAttributes.edgeCollection.inEdges(vertex);
|
||||
}
|
||||
else if (searchAttributes.direction == 3) {
|
||||
subEdges = searchAttributes.edgeCollection.edges(vertex);
|
||||
}
|
||||
|
||||
for (var j = 0; j < subEdges.length; ++j) {
|
||||
var subResult = AHUACATL_GRAPH_SUBNODES(searchAttributes, AHUACATL_CLONE(visited), clonedEdges, clonedVertices, subEdges[j], level + 1);
|
||||
|
||||
for (var k = 0; k < subResult.length; ++k) {
|
||||
result.push(subResult[k]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!searchAttributes.followCycles) {
|
||||
delete visited[target];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- misc functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1785,6 +2078,25 @@ function AHUACATL_GEO_WITHIN () {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief check whether a document has an attribute
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_HAS () {
|
||||
var element = arguments[0];
|
||||
var name = arguments[1];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_DOCUMENT) {
|
||||
AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "HAS");
|
||||
}
|
||||
|
||||
return element.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge all arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -87,6 +87,47 @@ static string JS_server_ahuacatl =
|
|||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief normalize a value for comparison, sorting etc.\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_NORMALIZE (value) {\n"
|
||||
" if (value === null || value === undefined) {\n"
|
||||
" return null;\n"
|
||||
" }\n"
|
||||
" if (typeof(value) !== \"object\") {\n"
|
||||
" return value;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (Array.isArray(value)) {\n"
|
||||
" var result = [ ];\n"
|
||||
" var length = value.length;\n"
|
||||
" for (var i = 0; i < length; ++i) {\n"
|
||||
" result.push(AHUACATL_NORMALIZE(value[i]));\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" return result;\n"
|
||||
" } \n"
|
||||
" else {\n"
|
||||
" var attributes = [ ];\n"
|
||||
" for (var attribute in value) {\n"
|
||||
" if (!value.hasOwnProperty(attribute)) {\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
" attributes.push(attribute);\n"
|
||||
" }\n"
|
||||
" attributes.sort();\n"
|
||||
"\n"
|
||||
" var result = { };\n"
|
||||
" var length = attributes.length;\n"
|
||||
" for (var i = 0; i < length; ++i) {\n"
|
||||
" result[attributes[i]] = AHUACATL_NORMALIZE(value[attributes[i]]);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief clone an object\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -123,7 +164,7 @@ static string JS_server_ahuacatl =
|
|||
"/// @brief validate function call argument\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_ARG_CHECK (actualValue, expectedType, functionName, argument) {\n"
|
||||
"function AHUACATL_ARG_CHECK (actualValue, expectedType, functionName) {\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(actualValue) !== expectedType) {\n"
|
||||
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, functionName);\n"
|
||||
" }\n"
|
||||
|
@ -443,10 +484,23 @@ static string JS_server_ahuacatl =
|
|||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief get names of all collections\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_COLLECTIONS () {\n"
|
||||
" var collections = internal.db._collections();\n"
|
||||
" var result = [ ];\n"
|
||||
"\n"
|
||||
" for (var i = 0; i < collections.length; ++i) {\n"
|
||||
" result.push({ \"_id\" : collections[i]._id, \"name\" : collections[i].name() });\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @}\n"
|
||||
|
@ -1150,7 +1204,7 @@ static string JS_server_ahuacatl =
|
|||
" continue;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT\", i + 1);\n"
|
||||
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT\");\n"
|
||||
"\n"
|
||||
" result += element;\n"
|
||||
" }\n"
|
||||
|
@ -1176,7 +1230,7 @@ static string JS_server_ahuacatl =
|
|||
" continue;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT_SEPARATOR\", i + 1);\n"
|
||||
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT_SEPARATOR\");\n"
|
||||
"\n"
|
||||
" if (i == 0) {\n"
|
||||
" separator = element;\n"
|
||||
|
@ -1201,7 +1255,7 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_STRING_LENGTH (value) {\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"STRING_LENGTH\", 1);\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"STRING_LENGTH\");\n"
|
||||
"\n"
|
||||
" return value.length;\n"
|
||||
"}\n"
|
||||
|
@ -1213,7 +1267,7 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_STRING_LOWER (value) {\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"LOWER\", 1);\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"LOWER\");\n"
|
||||
"\n"
|
||||
" return value.toLowerCase();\n"
|
||||
"}\n"
|
||||
|
@ -1225,7 +1279,7 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_STRING_UPPER (value) {\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"UPPER\", 1);\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"UPPER\");\n"
|
||||
"\n"
|
||||
" return value.toUpperCase();\n"
|
||||
"}\n"
|
||||
|
@ -1237,8 +1291,8 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_STRING_SUBSTRING (value, offset, count) {\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"SUBSTRING\", 1);\n"
|
||||
" AHUACATL_ARG_CHECK(offset, AHUACATL_TYPEWEIGHT_NUMBER, \"SUBSTRING\", 2);\n"
|
||||
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"SUBSTRING\");\n"
|
||||
" AHUACATL_ARG_CHECK(offset, AHUACATL_TYPEWEIGHT_NUMBER, \"SUBSTRING\");\n"
|
||||
"\n"
|
||||
" return value.substr(offset, count);\n"
|
||||
"}\n"
|
||||
|
@ -1589,6 +1643,74 @@ static string JS_server_ahuacatl =
|
|||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief get the first element of a list\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_FIRST () {\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" if (value.length == 0) {\n"
|
||||
" return null;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return value[0];\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief get the last element of a list\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_LAST () {\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" if (value.length == 0) {\n"
|
||||
" return null;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return value[value.length - 1];\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief reverse the elements in a list\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_REVERSE () {\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" return value.reverse();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief return a list of unique elements from the list\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_UNIQUE () {\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
" var length = value.length;\n"
|
||||
" var keys = { };\n"
|
||||
" for (var i = 0; i < length; ++i) {\n"
|
||||
" var normalized = AHUACATL_NORMALIZE(value[i]);\n"
|
||||
" keys[JSON.stringify(normalized)] = normalized;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var result = [];\n"
|
||||
" for (var i in keys) {\n"
|
||||
" result.push(keys[i]);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief create the union (all) of all arguments\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
@ -1778,6 +1900,177 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"// --SECTION-- graph functions\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @addtogroup Ahuacatl\n"
|
||||
"/// @{\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief find all paths through a graph\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_GRAPH_PATHS () {\n"
|
||||
" var collection = arguments[0];\n"
|
||||
" var edgeType = arguments[1];\n"
|
||||
" var minLength = arguments[2] != undefined ? arguments[2] : 1;\n"
|
||||
" var maxLength = arguments[3] != undefined ? arguments[3] : 10;\n"
|
||||
" var followCycles = arguments[4] ? arguments[4] : false;\n"
|
||||
" var direction;\n"
|
||||
"\n"
|
||||
" // validate arguments\n"
|
||||
" if (edgeType == \"outbound\") {\n"
|
||||
" direction = 1;\n"
|
||||
" }\n"
|
||||
" else if (edgeType == \"inbound\") {\n"
|
||||
" direction = 2;\n"
|
||||
" }\n"
|
||||
" else if (edgeType == \"any\") {\n"
|
||||
" direction = 3;\n"
|
||||
" }\n"
|
||||
" else {\n"
|
||||
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"PATHS\");\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (minLength < 0 || maxLength < 0 || minLength > maxLength) {\n"
|
||||
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"PATHS\");\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var edgeCollection = internal.edges[collection];\n"
|
||||
" var searchAttributes = { \n"
|
||||
" \"edgeCollection\" : edgeCollection, \n"
|
||||
" \"minLength\" : minLength, \n"
|
||||
" \"maxLength\" : maxLength, \n"
|
||||
" \"direction\" : direction,\n"
|
||||
" \"followCycles\" : followCycles,\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" var allEdges = edgeCollection.all().toArray();\n"
|
||||
" // TODO: restrict allEdges to edges with certain _from values etc.\n"
|
||||
"\n"
|
||||
" var result = [ ];\n"
|
||||
" var n = allEdges.length;\n"
|
||||
" for (var i = 0; i < n; ++i) {\n"
|
||||
"\n"
|
||||
" var edge = allEdges[i];\n"
|
||||
" var _from = edge._from; \n"
|
||||
" var _to = edge._to; \n"
|
||||
" var sources = [ ];\n"
|
||||
"\n"
|
||||
" if (searchAttributes.direction & 1) {\n"
|
||||
" sources.push(_from);\n"
|
||||
" }\n"
|
||||
" if (searchAttributes.direction & 2) {\n"
|
||||
" sources.push(_to);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" for (var j = 0; j < sources.length; ++j) {\n"
|
||||
" var visited = { };\n"
|
||||
" var vertices = [ ];\n"
|
||||
" var edges = [ ];\n"
|
||||
"\n"
|
||||
" var source = sources[j];\n"
|
||||
" var next = internal.db._document(source);\n"
|
||||
" vertices.push(next);\n"
|
||||
" if (!searchAttributes.followCycles) {\n"
|
||||
" visited[source] = true;\n"
|
||||
" }\n"
|
||||
" \n"
|
||||
" if (searchAttributes.minLength == 0) {\n"
|
||||
" var copy = AHUACATL_CLONE(vertices);\n"
|
||||
" result.push({ \"vertices\" : copy, \"edges\" : [ ], \"source\" : copy[0], \"destination\" : copy[copy.length - 1] });\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (searchAttributes.maxLength > 0) {\n"
|
||||
" var subResult = AHUACATL_GRAPH_SUBNODES(searchAttributes, AHUACATL_CLONE(visited), edges, vertices, edge, 0);\n"
|
||||
" for (var k = 0; k < subResult.length; ++k) {\n"
|
||||
" result.push(subResult[k]);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief find all paths through a graph, internal part called recursively\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_GRAPH_SUBNODES (searchAttributes, visited, edges, vertices, edge, level) {\n"
|
||||
" var result = [ ];\n"
|
||||
"\n"
|
||||
" var _from = edge._from; \n"
|
||||
" var _to = edge._to;\n"
|
||||
" var targets = [ ];\n"
|
||||
"\n"
|
||||
" if (searchAttributes.direction & 1) {\n"
|
||||
" targets.push(_to);\n"
|
||||
" }\n"
|
||||
" if (searchAttributes.direction & 2) {\n"
|
||||
" targets.push(_from);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" for (var i = 0; i < targets.length; ++i) {\n"
|
||||
" var target = targets[i];\n"
|
||||
"\n"
|
||||
" if (!searchAttributes.followCycles && visited[target]) {\n"
|
||||
" continue;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var clonedEdges = AHUACATL_CLONE(edges);\n"
|
||||
" var clonedVertices = AHUACATL_CLONE(vertices);\n"
|
||||
"\n"
|
||||
" clonedEdges.push(edge);\n"
|
||||
" var vertex = internal.db._document(target);\n"
|
||||
" clonedVertices.push(vertex);\n"
|
||||
" \n"
|
||||
" if (level + 1 >= searchAttributes.minLength) {\n"
|
||||
" result.push({ \"vertices\" : clonedVertices, \"edges\" : clonedEdges, \"source\" : clonedVertices[0], \"destination\" : clonedVertices[clonedVertices.length - 1] });\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (level + 1 < searchAttributes.maxLength) {\n"
|
||||
" // recursion\n"
|
||||
"\n"
|
||||
" if (!searchAttributes.followCycles) {\n"
|
||||
" visited[target] = true;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" var subEdges;\n"
|
||||
" if (searchAttributes.direction == 1) {\n"
|
||||
" subEdges = searchAttributes.edgeCollection.outEdges(vertex);\n"
|
||||
" }\n"
|
||||
" else if (searchAttributes.direction == 2) {\n"
|
||||
" subEdges = searchAttributes.edgeCollection.inEdges(vertex);\n"
|
||||
" }\n"
|
||||
" else if (searchAttributes.direction == 3) {\n"
|
||||
" subEdges = searchAttributes.edgeCollection.edges(vertex);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" for (var j = 0; j < subEdges.length; ++j) {\n"
|
||||
" var subResult = AHUACATL_GRAPH_SUBNODES(searchAttributes, AHUACATL_CLONE(visited), clonedEdges, clonedVertices, subEdges[j], level + 1);\n"
|
||||
"\n"
|
||||
" for (var k = 0; k < subResult.length; ++k) {\n"
|
||||
" result.push(subResult[k]);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (!searchAttributes.followCycles) {\n"
|
||||
" delete visited[target];\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @}\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"// --SECTION-- misc functions\n"
|
||||
"// -----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
|
@ -1787,6 +2080,25 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief check whether a document has an attribute\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_HAS () {\n"
|
||||
" var element = arguments[0];\n"
|
||||
" var name = arguments[1];\n"
|
||||
" \n"
|
||||
" if (AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
|
||||
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"HAS\");\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return element.hasOwnProperty(name);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"/// @brief merge all arguments\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
|
|
@ -117,6 +117,223 @@ function ahuacatlFunctionsTestSuite () {
|
|||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test first function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFirst1 : function () {
|
||||
var expected = [ { "the fox" : "jumped" } ];
|
||||
var actual = getQueryResults("RETURN FIRST([ { \"the fox\" : \"jumped\" }, \"over\", [ \"the dog\" ] ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test first function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFirst2 : function () {
|
||||
var expected = [ "over" ];
|
||||
var actual = getQueryResults("RETURN FIRST([ \"over\", [ \"the dog\" ] ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test first function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFirst3 : function () {
|
||||
var expected = [ [ "the dog" ] ];
|
||||
var actual = getQueryResults("RETURN FIRST([ [ \"the dog\" ] ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test first function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFirst4 : function () {
|
||||
var expected = [ null ];
|
||||
var actual = getQueryResults("RETURN FIRST([ ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test first function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFirstInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST([ ], [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST(null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST(true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST(4)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST(\"yes\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN FIRST({ })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test last function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testlast1 : function () {
|
||||
var expected = [ [ "the dog" ] ];
|
||||
var actual = getQueryResults("RETURN LAST([ { \"the fox\" : \"jumped\" }, \"over\", [ \"the dog\" ] ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test last function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testlast2 : function () {
|
||||
var expected = [ "over" ];
|
||||
var actual = getQueryResults("RETURN LAST([ { \"the fox\" : \"jumped\" }, \"over\" ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test last function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testlast3 : function () {
|
||||
var expected = [ { "the fox" : "jumped" } ];
|
||||
var actual = getQueryResults("RETURN LAST([ { \"the fox\" : \"jumped\" } ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test last function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testlast4 : function () {
|
||||
var expected = [ null ];
|
||||
var actual = getQueryResults("RETURN LAST([ ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test last function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testlastInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST([ ], [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST(null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST(true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST(4)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST(\"yes\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LAST({ })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reverse function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReverse1 : function () {
|
||||
var expected = [ [ ] ];
|
||||
var actual = getQueryResults("RETURN REVERSE([ ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reverse function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReverse2 : function () {
|
||||
var expected = [ [ "fox" ] ];
|
||||
var actual = getQueryResults("RETURN REVERSE([ \"fox\" ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reverse function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReverse3 : function () {
|
||||
var expected = [ [ false, [ "fox", "jumped" ], { "quick" : "brown" }, "the" ] ];
|
||||
var actual = getQueryResults("RETURN REVERSE([ \"the\", { \"quick\" : \"brown\" }, [ \"fox\", \"jumped\" ], false ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reverse function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReverseInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE([ ], [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE(null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE(true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE(4)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE(\"yes\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN REVERSE({ })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnique1 : function () {
|
||||
var expected = [ [ ] ];
|
||||
var actual = getQueryResults("RETURN UNIQUE([ ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnique2 : function () {
|
||||
var expected = [ [ 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, false, true, null, "fox", "FOX", "Fox", "FoX", [0], [1], { "the fox" : "jumped" } ] ];
|
||||
var actual = getQueryResults("RETURN UNIQUE([ 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, false, true, null, \"fox\", \"FOX\", \"Fox\", \"FoX\", [ 0 ], [ 1 ], { \"the fox\" : \"jumped\" } ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnique3 : function () {
|
||||
var expected = [ [ 1, 2, 3, 4, 5, 7, 9, 42, -1, -33 ] ];
|
||||
var actual = getQueryResults("RETURN UNIQUE([ 1, -1, 1, 2, 3, -1, 2, 3, 4, 5, 1, 3, 9, 2, -1, 9, -33, 42, 7 ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnique4 : function () {
|
||||
var expected = [ [ [1, 2, 3], [3, 2, 1], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2] ] ];
|
||||
var actual = getQueryResults("RETURN UNIQUE([ [ 1, 2, 3 ], [ 3, 2, 1 ], [ 2, 1, 3 ], [ 2, 3, 1 ], [ 1, 2, 3 ], [ 1, 3, 2 ], [ 2, 3, 1 ], [ 3, 1, 2 ], [ 2 , 1, 3 ] ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnique5 : function () {
|
||||
var expected = [ [ { "the fox" : "jumped" }, { "the fox" : "jumped over" }, { "over" : "the dog", "the fox" : "jumped" }]]
|
||||
|
||||
var actual = getQueryResults("RETURN UNIQUE([ { \"the fox\" : \"jumped\" }, { \"the fox\" : \"jumped over\" }, { \"the fox\" : \"jumped\", \"over\" : \"the dog\" }, { \"over\" : \"the dog\", \"the fox\" : \"jumped\" } ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test unique function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUniqueInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE([ ], [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE(null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE(true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE(4)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE(\"yes\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN UNIQUE({ })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test length function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -143,6 +360,7 @@ function ahuacatlFunctionsTestSuite () {
|
|||
|
||||
testLengthInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LENGTH()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LENGTH([ ], [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LENGTH(null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LENGTH(true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN LENGTH(4)"); } ));
|
||||
|
@ -709,7 +927,7 @@ function ahuacatlFunctionsTestSuite () {
|
|||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
/// @brief test max function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMax3 : function () {
|
||||
|
@ -719,7 +937,7 @@ function ahuacatlFunctionsTestSuite () {
|
|||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test min function
|
||||
/// @brief test max function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMaxInvalid : function () {
|
||||
|
@ -732,6 +950,46 @@ function ahuacatlFunctionsTestSuite () {
|
|||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN MAX({ })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test has function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testHas1 : function () {
|
||||
var expected = [ true, true, true, false, true ];
|
||||
var actual = getQueryResults("FOR u IN [ { \"the fox\" : true }, { \"the fox\" : false }, { \"the fox\" : null }, { \"the FOX\" : true }, { \"the FOX\" : true, \"the fox\" : false } ] return HAS(u, \"the fox\")", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test has function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testHas2 : function () {
|
||||
var expected = [ false, false, false ];
|
||||
var actual = getQueryResults("FOR u IN [ { \"the foxx\" : { \"the fox\" : false } }, { \" the fox\" : false }, null ] return HAS(u, \"the fox\")", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test has function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testHasInvalid : function () {
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS()"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ })"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, \"fox\", true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS(false, \"fox\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS(3, \"fox\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS(\"yes\", \"fox\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS([ ], \"fox\")"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, null)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, false)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, true)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, 1)"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, [ ])"); } ));
|
||||
assertEqual(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, getErrorCode(function() { AHUACATL_RUN("RETURN HAS({ }, { })"); } ));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test non-existing functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for Ahuacatl, hash index queries
|
||||
///
|
||||
/// @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 internal = require("internal");
|
||||
var jsunity = require("jsunity");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ahuacatlHashTestSuite () {
|
||||
var errors = internal.errors;
|
||||
var hash;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function executeQuery (query, bindVars) {
|
||||
var cursor = AHUACATL_RUN(query, bindVars);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query and return the results as an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getQueryResults (query, bindVars) {
|
||||
var result = executeQuery(query, bindVars).getRows();
|
||||
var results = [ ];
|
||||
|
||||
for (var i in result) {
|
||||
if (!result.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.push(result[i]);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
hash = internal.db.UnitTestsAhuacatlHash;
|
||||
|
||||
if (hash.count() == 0) {
|
||||
for (var i = 1; i <= 5; ++i) {
|
||||
for (var j = 1; j <= 5; ++j) {
|
||||
hash.save({ "a" : i, "b": j, "c": i });
|
||||
}
|
||||
}
|
||||
|
||||
hash.ensureHashIndex("a", "b");
|
||||
hash.ensureHashIndex("c");
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the single field hash index with equality
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testEqSingle1 : function () {
|
||||
var expected = [ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ] ];
|
||||
var actual = getQueryResults("FOR v IN " + hash.name() + " FILTER v.c == 1 SORT v.b RETURN [ v.b ]");
|
||||
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test the first hash index field with equality
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testEqSingle2 : function () {
|
||||
var expected = [ [ 1, 4 ], [ 2, 4 ], [ 3, 4 ], [ 4, 4 ], [ 5, 4 ] ];
|
||||
var actual = getQueryResults("FOR v IN " + hash.name() + " FILTER v.c == 4 SORT v.b RETURN [ v.b, v.c ]");
|
||||
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test multiple hash fields with multiple operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testEqMultiAll : function () {
|
||||
for (var i = 1; i <= 5; ++i) {
|
||||
for (var j = 1; j <=5; ++j) {
|
||||
var expected = [ [ i, j ] ];
|
||||
var actual = getQueryResults("FOR v IN " + hash.name() + " FILTER v.a == @a && v.b == @b RETURN [ v.a, v.b ]", { "a" : i, "b" : j });
|
||||
|
||||
assertEqual(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(ahuacatlHashTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
Loading…
Reference in New Issue