1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB

Conflicts:
	html/admin/js/client.js
	html/admin/js/master.js
This commit is contained in:
Frank Celler 2012-05-23 11:44:40 +02:00
commit 0236954f04
37 changed files with 1255 additions and 2274 deletions

28
3rdParty/libev/ev.c vendored
View File

@ -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*/\
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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());

View File

@ -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

View File

@ -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 \

View File

@ -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 \

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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, "{}", "[]");
}

View File

@ -56,6 +56,13 @@ LineEditor::LineEditor (string const& history)
rl_initialize();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
LineEditor::~LineEditor () {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -89,6 +89,12 @@ class LineEditor {
LineEditor (std::string const& history);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
virtual ~LineEditor ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
// .............................................................................

View File

@ -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;
}

View File

@ -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);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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"
;;
*)

View File

@ -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

View File

@ -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=""

View File

@ -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%;
}

View File

@ -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>

View File

@ -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

1
html/admin/js/client.js Symbolic link
View File

@ -0,0 +1 @@
../../../js/client/client.js

View File

@ -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>');
}
}

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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"

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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: