1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/AvocadoDB into devel

Conflicts:
	configure
This commit is contained in:
Jan Steemann 2012-05-08 12:38:41 +02:00
commit bf21b866aa
43 changed files with 894 additions and 301 deletions

View File

@ -240,6 +240,58 @@ void* TRI_AtVector (TRI_vector_t const* vector, size_t pos) {
return (void*) (vector->_buffer + pos * vector->_elementSize); return (void*) (vector->_buffer + pos * vector->_elementSize);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief inserts an element at a given position
////////////////////////////////////////////////////////////////////////////////
void TRI_InsertVector (TRI_vector_t* vector, void const* element, size_t position) {
char* newBuffer;
size_t newSize;
// ...........................................................................
// Check and see if we need to extend the vector
// ...........................................................................
if (vector->_length >= vector->_capacity || position >= vector->_length) {
newSize = (size_t) (1 + GROW_FACTOR * vector->_capacity);
if (position >= newSize) {
newSize = position + 1;
}
newBuffer = (char*) TRI_Allocate(vector->_memoryZone, newSize * vector->_elementSize, false);
if (newBuffer == NULL) {
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
return;
}
vector->_capacity = newSize;
if (vector->_buffer != NULL) {
memcpy(newBuffer, vector->_buffer, vector->_length * vector->_elementSize);
TRI_Free(vector->_memoryZone, vector->_buffer);
}
vector->_buffer = newBuffer;
}
if (position < vector->_length) {
memmove(vector->_buffer + (vector->_elementSize * (position + 1)),
vector->_buffer + (vector->_elementSize * position),
vector->_elementSize * (vector->_length - position)
);
vector->_length += 1;
}
else {
vector->_length = position + 1;
}
memcpy(vector->_buffer + (vector->_elementSize * position), element, vector->_elementSize);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief sets an element at a given position /// @brief sets an element at a given position
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -458,6 +510,11 @@ int TRI_PushBackVectorPointer (TRI_vector_pointer_t* vector, void* element) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int TRI_InsertVectorPointer (TRI_vector_pointer_t* vector, void* element, size_t n) { int TRI_InsertVectorPointer (TRI_vector_pointer_t* vector, void* element, size_t n) {
// ...........................................................................
// Check and see if we need to extend the vector
// ...........................................................................
if (vector->_length >= vector->_capacity || n >= vector->_length) { if (vector->_length >= vector->_capacity || n >= vector->_length) {
void* newBuffer; void* newBuffer;
size_t newSize = (size_t) (1 + GROW_FACTOR * vector->_capacity); size_t newSize = (size_t) (1 + GROW_FACTOR * vector->_capacity);
@ -728,6 +785,11 @@ int TRI_PushBackVectorString (TRI_vector_string_t* vector, char* element) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int TRI_InsertVectorString (TRI_vector_string_t* vector, char* element, size_t n) { int TRI_InsertVectorString (TRI_vector_string_t* vector, char* element, size_t n) {
// ...........................................................................
// Check and see if we need to extend the vector
// ...........................................................................
if (n >= vector->_capacity || n >= vector->_length) { if (n >= vector->_capacity || n >= vector->_length) {
char** newBuffer; char** newBuffer;
size_t newSize = (size_t) (1 + GROW_FACTOR * vector->_capacity); size_t newSize = (size_t) (1 + GROW_FACTOR * vector->_capacity);

View File

@ -146,6 +146,13 @@ void TRI_RemoveVector (TRI_vector_t*, size_t n);
void* TRI_AtVector (TRI_vector_t const*, size_t); void* TRI_AtVector (TRI_vector_t const*, size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief inserts an element at a given position
////////////////////////////////////////////////////////////////////////////////
void TRI_InsertVector (TRI_vector_t* vector, void const* element, size_t position);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief sets an element at a given position /// @brief sets an element at a given position
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,18 @@
> curl --data @- -X PUT --dump - http://localhost:8529/_api/simple/by-example
{ "collection" : "3179705695", "example" : [ { "i" : 1 } ] }
HTTP/1.1 201 Created
content-type: application/json
{
"result": [
{ "a": { "k": 2, "j": 2 }, "i": 1, "_rev": 3181802847, "_id": "3179705695/3181802847" },
{ "a": { "j": 1 }, "i": 1, "_rev": 3181475167, "_id": "3179705695/3181475167" },
{ "a": { "k": 1, "j": 1 }, "i": 1, "_rev": 3181737311, "_id": "3179705695/3181737311" },
{ "i": 1, "_rev": 3181147487, "_id": "3179705695/3181147487" }
],
"count": 4,
"error": false,
"hasMore": false,
"code": 201
}

View File

@ -0,0 +1,15 @@
> curl --data @- -X PUT --dump - http://localhost:8529/_api/simple/by-example
{ "collection" : "3179705695", "example" : [ { "a" : { "j" : 1 } } ] }
HTTP/1.1 201 Created
content-type: application/json
{
"result": [
{ "a": { "j": 1 }, "i": 1, "_rev": 3181475167, "_id": "3179705695/3181475167" }
],
"count": 1,
"error": false,
"hasMore": false,
"code": 201
}

View File

@ -0,0 +1,16 @@
> curl --data @- -X PUT --dump - http://localhost:8529/_api/simple/by-example
{ "collection" : "3179705695", "example" : [ "a.j", 1 ] }
HTTP/1.1 201 Created
content-type: application/json
{
"result": [
{ "a": { "j": 1 }, "i": 1, "_rev": 3181475167, "_id": "3179705695/3181475167" },
{ "a": { "k": 1, "j": 1 }, "i": 1, "_rev": 3181737311, "_id": "3179705695/3181737311" }
],
"count": 2,
"error": false,
"hasMore": false,
"code": 201
}

View File

@ -0,0 +1,11 @@
> curl --data @- -X PUT --dump - http://localhost:8529/_api/simple/first-example
{ "collection" : "666351134", "example" : [ "a.j", 1, "a.k", 1 ] }
HTTP/1.1 200 OK
content-type: application/json
{
"error": false,
"code": 200,
"document": { "_rev": 668382750, "_id": "666351134/668382750", "a": { "k": 1, "j": 1, "l" : 10 }, "i": 1 }
}

View File

@ -0,0 +1,12 @@
> curl --data @- -X PUT --dump - http://localhost:8529/_api/simple/first-example
{ "collection" : "666351134", "example" : [ "a.j", 1, "a.k", 2 ] }
HTTP/1.1 404 Not Found
content-type: application/json
{
"errorMessage": "no match",
"error": true,
"code": 404,
"errorNum": 404
}

View File

@ -1,7 +1,10 @@
function aqlTestSuite () { function aqlTestSuite () {
function testSizeOfTestCollection () { return {
assertEqual(5, 5); testSizeOfTestCollection : function () {
} assertEqual(5, 5);
};
} }
jsUnity.run(aqlTestSuite); jsUnity.run(aqlTestSuite);
return jsunity.done();

View File

@ -0,0 +1,2 @@
avocado> db.users.count();
10001

View File

@ -0,0 +1,2 @@
avocado> db.users.firstExample("name", 1237);
{ "_id" : "100225/83049373", "_rev" : 83049373, "name" : 1237 }

View File

@ -11,6 +11,6 @@ fi
HEADER='<html><head><title>AvocadoDB Manual</title> <style media="screen" type="text/css" style="display:none">body{background-color:white;font:13px Helvetica,arial,freesans,clean,sans-serif;line-height:1.4;color:#333;}#access{font-size:16px;margin-left:12px;display:block;margin-left:10px;margin-right:10px;background-color:#F3F1EE!important;}#access a{border-right:1px solid #DBDEDF;color:#A49F96;display:block;line-height:38px;padding:0 10px;text-decoration:none;}#navigation ul{text-transform:uppercase;list-style:none;margin:0;}#navigation li{float:left;position:relative;}#container{width:920px;margin:0 auto;}a{color:#4183C4;text-decoration:none;}.contents h2{font-size:24px;border-bottom:1px solid #CCC;color:black;}.contents h1{font-size:33px;border-bottom:1px solid #CCC;color:black;}.clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;visibility:hidden;}/**/ *:first-child+html .clearfix{min-height:0;}/**/ * html .clearfix{height:1%;}</style></head><body><div id="container"><img src="images/logo_avocadodb.jpg" width="397" height="67" alt="AvocadoDB"><div id="access" role="navigation"><div id="navigation"><ul id="menu-ahome" class="menu"><li><a href="Home.html">Table of contents</a></li> <li><a href="http://www.avocadodb.org">AvocadoDB homepage</a></li></ul></div><div class="clearfix"></div></div><div>' HEADER='<html><head><title>AvocadoDB Manual</title> <style media="screen" type="text/css" style="display:none">body{background-color:white;font:13px Helvetica,arial,freesans,clean,sans-serif;line-height:1.4;color:#333;}#access{font-size:16px;margin-left:12px;display:block;margin-left:10px;margin-right:10px;background-color:#F3F1EE!important;}#access a{border-right:1px solid #DBDEDF;color:#A49F96;display:block;line-height:38px;padding:0 10px;text-decoration:none;}#navigation ul{text-transform:uppercase;list-style:none;margin:0;}#navigation li{float:left;position:relative;}#container{width:920px;margin:0 auto;}a{color:#4183C4;text-decoration:none;}.contents h2{font-size:24px;border-bottom:1px solid #CCC;color:black;}.contents h1{font-size:33px;border-bottom:1px solid #CCC;color:black;}.clearfix:after{content:".";display:block;clear:both;font-size:0;height:0;visibility:hidden;}/**/ *:first-child+html .clearfix{min-height:0;}/**/ * html .clearfix{height:1%;}</style></head><body><div id="container"><img src="images/logo_avocadodb.jpg" width="397" height="67" alt="AvocadoDB"><div id="access" role="navigation"><div id="navigation"><ul id="menu-ahome" class="menu"><li><a href="Home.html">Table of contents</a></li> <li><a href="http://www.avocadodb.org">AvocadoDB homepage</a></li></ul></div><div class="clearfix"></div></div><div>'
FOOTER='</div></body></html>' FOOTER='</div></body></html>'
sed -e "s~<\\?php include \"include/header.php\" \\?> ~${HEADER}~" $INPUT \ sed -e "s~<?php include \"include/header.php\" ?> ~${HEADER}~" $INPUT \
| sed -e "s~<\\?php include \"include/footer.php\" \\?> ~${FOOTER}~" \ | sed -e "s~<?php include \"include/footer.php\" ?> ~${FOOTER}~" \
| sed -e "s~<div class=\"title\">\\([^<]*\\)</div>~<h1>\\1</h1>~" > $OUTPUT | sed -e "s~<div class=\"title\">\\([^<]*\\)</div>~<h1>\\1</h1>~" > $OUTPUT

View File

@ -410,6 +410,8 @@ WIKI = \
ShellIndex \ ShellIndex \
SimpleQueries \ SimpleQueries \
UserManualServer \ UserManualServer \
UserManualServerBasics \
UserManualServerStartStop \
UserManualShell \ UserManualShell \
UserManualShellStartStop \ UserManualShellStartStop \
jsUnity jsUnity

View File

@ -1011,6 +1011,8 @@ WIKI = \
ShellIndex \ ShellIndex \
SimpleQueries \ SimpleQueries \
UserManualServer \ UserManualServer \
UserManualServerBasics \
UserManualServerStartStop \
UserManualShell \ UserManualShell \
UserManualShellStartStop \ UserManualShellStartStop \
jsUnity jsUnity

View File

@ -11,6 +11,6 @@ MANUAL_DST="fceller@www.avocadodb.org:/srv/www/www.avocadodb.org/avoc/manuals"
publish: publish:
(cd Doxygen/wiki && git checkout --force && git pull) (cd Doxygen/wiki && git checkout --force && git pull)
$(MAKE) wiki $(MAKE) wiki
(cd Doxygen/wiki && git commit -m "`date`" -a; git push) (cd Doxygen/wiki && git add *.md; git commit -m "`date`" -a; git push)
@for w in $(WIKI); do scp Doxygen/html/$$w.html $(MANUAL_DST); done @for w in $(WIKI); do scp Doxygen/html/$$w.html $(MANUAL_DST); done

View File

@ -52,7 +52,7 @@
/// @page HttpIndex HTTP Interface for Indexes /// @page HttpIndex HTTP Interface for Indexes
/// ///
/// This is an introduction to AvocadoDB's Http interface for indexes in /// This is an introduction to AvocadoDB's Http interface for indexes in
/// general. There are special section for /// general. There are special sections for
/// ///
/// @copydoc IndexesTOC /// @copydoc IndexesTOC
/// ///

View File

@ -41,6 +41,8 @@
/// ///
/// <ol> /// <ol>
/// <li>@ref HttpSimpleAll "POST /_api/simple/all"</li> /// <li>@ref HttpSimpleAll "POST /_api/simple/all"</li>
/// <li>@ref HttpSimpleByExample "POST /_api/simple/by-example"</li>
/// <li>@ref HttpSimpleFirstExample "POST /_api/simple/first-example"</li>
/// <li>@ref HttpSimpleNear "POST /_api/simple/near"</li> /// <li>@ref HttpSimpleNear "POST /_api/simple/near"</li>
/// <li>@ref HttpSimpleWithin "POST /_api/simple/within"</li> /// <li>@ref HttpSimpleWithin "POST /_api/simple/within"</li>
/// </ol> /// </ol>
@ -71,13 +73,20 @@
/// @copydetails JSA_PUT_api_simple_all /// @copydetails JSA_PUT_api_simple_all
/// <hr> /// <hr>
/// ///
/// @anchor HttpSimpleByExample
/// @copydetails JSA_PUT_api_simple_by_example
/// <hr>
///
/// @anchor HttpSimpleFirstExample
/// @copydetails JSA_PUT_api_simple_first_example
/// <hr>
///
/// @anchor HttpSimpleNear /// @anchor HttpSimpleNear
/// @copydetails JSA_PUT_api_simple_near /// @copydetails JSA_PUT_api_simple_near
/// <hr> /// <hr>
/// ///
/// @anchor HttpSimpleWithin /// @anchor HttpSimpleWithin
/// @copydetails JSA_PUT_api_simple_within /// @copydetails JSA_PUT_api_simple_within
/// <hr>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:

View File

@ -74,9 +74,6 @@
/// ///
/// @subsection HomePython Python /// @subsection HomePython Python
/// ///
/// Help wanted:
/// http://www.avocadodb.org/2012/03/24/contributors-for-python-api-wanted-for-nosql-project
///
/// @subsection HomeREST REST /// @subsection HomeREST REST
/// ///
/// @subsection HomeRuby Ruby /// @subsection HomeRuby Ruby

View File

@ -29,10 +29,8 @@
/// @page InstallManual AvocadoDB Installation Manual /// @page InstallManual AvocadoDB Installation Manual
/// ///
/// <ol> /// <ol>
/// <li>@ref Installing /// <li>@ref Installing</li>
/// <li> /// <li>@ref Compiling</li>
/// <li>@ref Compiling
/// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -56,7 +54,7 @@
/// @page Installing Installing the AvocadoDB /// @page Installing Installing the AvocadoDB
/// ///
/// <hr> /// <hr>
/// @copydoc CompilingTOC /// @copydoc InstallingTOC
/// <hr> /// <hr>
/// ///
/// @section MacOSX /// @section MacOSX

View File

@ -0,0 +1,64 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief module "internal"
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 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 Dr. Frank Celler
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @page jsUnity Using jsUnity and node-jscoverage
///
/// The AvocadoDB contains a wrapper for
/// <a href="http://jsunity.com/">jsUnity</a>, a lightyweight universal
/// JavAScript unit testing framework.
///
/// @section jsUnityRunningTest Running jsUnity Tests
/////////////////////////////////////////////////////
///
/// Assume that you have a test file containing
///
/// @verbinclude jsunity1
///
/// Then you can run the test suite using @FN{jsunity.runTest}
///
/// @verbinclude jsunity2
///
/// @section jsUnityRunningCoverage Running jsUnity Tests with Coverage
///////////////////////////////////////////////////////////////////////
///
/// You can use the coverage tool
/// <a href="https://github.com/visionmedia/node-jscoverage">@LIT{node-jscoverage}</a>.
///
/// Assume that your file live in a directory called @LIT{lib}. Use
///
/// @CODE{node-jscoverage lib lib-cov}
///
/// to create a copy of the JavaScript files with coverage information. Start
/// the AvocadoDB with these files and use @FN{jsunity.runCoverage} instead of
/// @FN{jsunity.runTest}.
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:

View File

@ -60,22 +60,18 @@
/// <li>@ref HttpSystem /// <li>@ref HttpSystem
/// @copydetails HttpSystemTOC /// @copydetails HttpSystemTOC
/// </li> /// </li>
/// <li>@ref OTWPSimpleQueries
/// <ol>
/// <li>@ref OTWPSimpleQueriesByExample "PUT /_api/simple/by-example"</li>
/// </ol>
/// </li>
/// <li>@ref Key-Value
/// <ol>
/// <li>@ref Key-ValuePost "POST /_api/key/@FA{collection-name}/@FA{key}"</li>
/// <li>@ref Key-ValuePut "PUT /_api/key/@FA{collection-name}/@FA{key}"</li>
/// <li>@ref Key-ValueGet "GET /_api/key/@FA{collection-name}/@FA{key}"</li>
/// <li>@ref Key-ValueDelete "DELETE /_api/key/@FA{collection-name}/@FA{key}"</li>
/// <li>@ref Key-ValueSearch "GET /_api/keys/@FA{collection-name}/@FA{prefix}"</li>
/// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref Key-Value (Under Construction)
/// <ol>
/// <li>@ref Key-ValuePost "POST /_api/key/collection-name/key"</li>
/// <li>@ref Key-ValuePut "PUT /_api/key/collection-name/key"</li>
/// <li>@ref Key-ValueGet "GET /_api/key/collection-name/key"</li>
/// <li>@ref Key-ValueDelete "DELETE /_api/key/collection-name/key"</li>
/// <li>@ref Key-ValueSearch "GET /_api/keys/collection-name/prefix"</li>
/// </ol>
/// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -85,14 +81,6 @@
/// <hr> /// <hr>
/// @copydoc OTWPTOC /// @copydoc OTWPTOC
/// <hr> /// <hr>
///
/// @section OTWPSimpleQueries Simple Queries
/////////////////////////////////////////////
///
/// @anchor OTWPSimpleQueriesByExample
/// @copydetails JSA_PUT_api_simple_by_example
/// <hr>
///
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:

View File

@ -31,36 +31,39 @@
/// <ol> /// <ol>
/// <li>@ref SimpleQueriesQueries /// <li>@ref SimpleQueriesQueries
/// <ol> /// <ol>
/// <li>@ref SimpleQueryDocument "db.@FA{collection}.document(@FA{document-reference})"</li> /// <li>@ref SimpleQueryDocument "collection.document(document-reference)"</li>
/// <li>@ref SimpleQueryAll "db.@FA{collection}.all()"</li> /// <li>@ref SimpleQueryAll "collection.all()"</li>
/// <li>@ref SimpleQueryByExample "db.@FA{collection}.byExample()"</li> /// <li>@ref SimpleQueryByExample "collection.byExample(example)"</li>
/// <li>@ref SimpleQueryCount "@FA{query}.count()"</li> /// <li>@ref SimpleQueryFirstExample "collection.firstExample(example)"</li>
/// <li>@ref SimpleQueryCollectionCount "collection.count()"</li>
/// <li>@ref SimpleQueryToArray "collection.toArray()"</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref SimpleQueriesGeoQueries /// <li>@ref SimpleQueriesGeoQueries
/// <ol> /// <ol>
/// <li>@ref SimpleQueryNear "db.@FA{collection}.near()"</li> /// <li>@ref SimpleQueryNear "collection.near(latitude, longitude)"</li>
/// <li>@ref SimpleQueryWithin "db.@FA{collection}.within()"</li> /// <li>@ref SimpleQueryWithin "collection.within(latitude, longitude)"</li>
/// <li>@ref SimpleQueryGeo "db.@FA{collection}.geo()"</li> /// <li>@ref SimpleQueryGeo "collection.geo(location)"</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref SimpleQueriesEdgesQueries /// <li>@ref SimpleQueriesEdgesQueries
/// <ol> /// <ol>
/// <li>@ref SimpleQueryEdges "edges.@FA{collection}.edges()"</li> /// <li>@ref SimpleQueryEdges "edges-collection.edges(vertex)"</li>
/// <li>@ref SimpleQueryInEdges "edges.@FA{collection}.inEdges()"</li> /// <li>@ref SimpleQueryInEdges "edges-collection.inEdges(vertex)"</li>
/// <li>@ref SimpleQueryOutEdges "edges.@FA{collection}.outEdges()"</li> /// <li>@ref SimpleQueryOutEdges "edges-collection.outEdges(vertex)"</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref SimpleQueriesPagination /// <li>@ref SimpleQueriesPagination
/// <ol> /// <ol>
/// <li>@ref SimpleQueryLimit "@FA{query}.limit(@FA{limit})"</li> /// <li>@ref SimpleQueryLimit "query.limit(limit)"</li>
/// <li>@ref SimpleQuerySkip "@FA{query}.skip(@FA{skip})"</li> /// <li>@ref SimpleQuerySkip "query.skip(skip)"</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref SimpleQueriesSequentialAccess /// <li>@ref SimpleQueriesSequentialAccess
/// <ol> /// <ol>
/// <li>@ref SimpleQueryHasNext "@FA{query}.hasNext()"</li> /// <li>@ref SimpleQueryHasNext "query.hasNext()"</li>
/// <li>@ref SimpleQueryNext "@FA{query}.next()"</li> /// <li>@ref SimpleQueryNext "query.next()"</li>
/// <li>@ref SimpleQueryCount "query.count()"</li>
/// </ol> /// </ol>
/// </li> /// </li>
/// </ol> /// </ol>
@ -72,17 +75,20 @@
/// Simple queries can be used if the query condition is straight forward /// Simple queries can be used if the query condition is straight forward
/// simple, i. e., a document reference, all documents, a query-by-example, or a /// simple, i. e., a document reference, all documents, a query-by-example, or a
/// simple geo query. In a simple query you can specify exactly one collection /// simple geo query. In a simple query you can specify exactly one collection
/// and one condition. The result can then be sorted and result can be split /// and one condition.
/// into pages.
/// ///
/// <hr> /// <hr>
/// @copydoc SimpleQueriesTOC /// @copydoc SimpleQueriesTOC
/// <hr> /// <hr>
/// ///
/// If a query returns a cursor, then you can use @FN{hasNext} and @FN{next} to
/// iterate over the result set or @FN{toArray} to convert it to an array.
///
/// @section SimpleQueriesQueries Queries /// @section SimpleQueriesQueries Queries
///////////////////////////////////////// /////////////////////////////////////////
/// ///
/// @anchor SimpleQueryDocument /// @anchor SimpleQueryDocument
/// @copydetails JS_DocumentVocbaseCol
/// <hr> /// <hr>
/// ///
/// @anchor SimpleQueryAll /// @anchor SimpleQueryAll
@ -93,8 +99,16 @@
/// @copydetails JSF_AvocadoCollection_prototype_byExample /// @copydetails JSF_AvocadoCollection_prototype_byExample
/// <hr> /// <hr>
/// ///
/// @anchor SimpleQueryCount /// @anchor SimpleQueryFirstExample
/// @copydetails JSF_SimpleQuery_prototype_count /// @copydetails JSF_AvocadoCollection_prototype_firstExample
/// <hr>
///
/// @anchor SimpleQueryCollectionCount
/// @copydetails JS_CountVocbaseCol
/// <hr>
///
/// @anchor SimpleQueryToArray
/// @copydetails JSF_AvocadoCollection_prototype_toArray
/// ///
/// @section SimpleQueriesGeoQueries Geo Queries /// @section SimpleQueriesGeoQueries Geo Queries
//////////////////////////////////////////////// ////////////////////////////////////////////////
@ -148,7 +162,7 @@
/// If, for example, you display the result of a user search, then you are in /// If, for example, you display the result of a user search, then you are in
/// general not interested in the completed result set, but only the first 10 or /// general not interested in the completed result set, but only the first 10 or
/// so documents. Or maybe the next 10 documents for the second page. In this /// so documents. Or maybe the next 10 documents for the second page. In this
/// case, you can the @FN{skip} and @FN{limit} operators. These operators works /// case, you can the @FN{skip} and @FN{limit} operators. These operators work
/// like LIMIT in MySQL. /// like LIMIT in MySQL.
/// ///
/// @FN{skip} used together with @FN{limit} can be used to implement pagination. /// @FN{skip} used together with @FN{limit} can be used to implement pagination.
@ -174,6 +188,10 @@
/// ///
/// @anchor SimpleQueryNext /// @anchor SimpleQueryNext
/// @copydetails JSF_SimpleQuery_prototype_next /// @copydetails JSF_SimpleQuery_prototype_next
/// <hr>
///
/// @anchor SimpleQueryCount
/// @copydetails JSF_SimpleQuery_prototype_count
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:

View File

@ -33,12 +33,6 @@
/// <ol> /// <ol>
/// <li>@ref UserManualServerStartStop /// <li>@ref UserManualServerStartStop
/// </li> /// </li>
/// <li>AvocadoScript
/// <ol>
/// <li>@ref SimpleQueries
/// </li>
/// </ol>
/// </li>
/// <li>Avocado Query Language /// <li>Avocado Query Language
/// <ol> /// <ol>
/// <li>@ref AQLBasics /// <li>@ref AQLBasics
@ -49,47 +43,18 @@
/// </li> /// </li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref AvocadoScript
/// <ol>
/// <li>GeoCoordinates
/// </li>
/// </ol>
/// </li>
/// <li>Vertices, Edges, and Graphs
/// <ol>
/// <li>@ref Graphs
/// </li>
/// <li>@ref JSModuleGraph
/// </li>
/// </ol>
/// </li>
/// <li>@ref AvocadoErrors /// <li>@ref AvocadoErrors
/// </li> /// </li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>Client Communication
/// <ol>
/// <li>@ref HttpInterface
/// <ol>
/// <li>@ref RestDocument
/// </li>
/// </ol>
/// </li>
/// </ol>
/// </li>
/// <li>@ref DBAdmin
/// <ol>
/// <li>@ref DBAdminDurability
/// </li>
/// <li>@ref DBAdminIndex
/// <ol>
/// <li>@ref DBAdminIndexGeo
/// </ol>
/// </li>
/// </ol>
/// </li>
/// <li>Advanced Topics /// <li>Advanced Topics
/// <ol> /// <ol>
/// <li>@ref DBAdmin
/// <ol>
/// <li>@ref DBAdminDurability
/// </li>
/// </ol>
/// </li>
/// <li>Actions /// <li>Actions
/// <ol> /// <ol>
/// <li>@ref Actions /// <li>@ref Actions
@ -98,12 +63,6 @@
/// </li> /// </li>
/// </ol> /// </ol>
/// </li> /// </li>
/// <li>@ref HttpInterface
/// <ol>
/// <li>@ref RestSystem
/// </li>
/// </ol>
/// </li>
/// <li>@ref jsUnity /// <li>@ref jsUnity
/// </li> /// </li>
/// </ol> /// </ol>
@ -128,20 +87,21 @@
/// @page UserManualServerStartStopTOC /// @page UserManualServerStartStopTOC
/// ///
/// <ol> /// <ol>
/// <li>@ref UserManualServerStartStopHttp "Starting the HTTP Server"</li> /// <li>@ref UserManualServerStartStopHttp</li>
/// <li>@ref UserManualServerStartStopDebug "Starting the Debug Shell"</li> /// <li>@ref UserManualServerStartStopDebug</li>
/// <li>@ref UserManualServerStartStopOptions "Frequently Used Options"</li> /// <li>@ref UserManualServerStartStopOptions</li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @page UserManualServerStartStop Starting the AvocadoDB /// @page UserManualServerStartStop Starting the AvocadoDB
/// ///
/// The AvocadoDB has two mode of operation: as server, where it will answer to /// The AvocadoDB has two modes of operation: as server, where it will answer to
/// HTTP requests, see @ref HttpInterface, and a debug shell, where you can /// client requests and an emergency console, where you can access the database
/// access the database directly. Using the debug shell allows you to issue all /// directly. The latter should - as the name suggests - only be used in case of
/// commands normally available in actions and transactions, see @ref /// an emergency, for example, a corrupted collection. Using the emergency
/// AvocadoScript. /// console allows you to issue all commands normally available in actions and
/// transactions.
/// ///
/// You should never start more than one server for the same database, /// You should never start more than one server for the same database,
/// independent from the mode of operation. /// independent from the mode of operation.
@ -151,6 +111,7 @@
/// <hr> /// <hr>
/// ///
/// @section UserManualServerStartStopHttp Starting the HTTP Server /// @section UserManualServerStartStopHttp Starting the HTTP Server
///////////////////////////////////////////////////////////////////
/// ///
/// The following command starts the AvocadoDB in server mode. You will be able /// The following command starts the AvocadoDB in server mode. You will be able
/// to access the server using HTTP request on port 8529. See below for a list /// to access the server using HTTP request on port 8529. See below for a list
@ -158,14 +119,16 @@
/// ///
/// @verbinclude option-database-directory /// @verbinclude option-database-directory
/// ///
/// @section UserManualServerStartStopDebug Starting the Debug Shell /// @section UserManualServerStartStopDebug Starting the Emergency Console
//////////////////////////////////////////////////////////////////////////
/// ///
/// The following command starts a debug shell. See below for a list of /// The following command starts a emergency console. See below for a list of
/// frequently used options, see @ref CommandLine "here" for a complete list. /// frequently used options, see @ref CommandLine "here" for a complete list.
/// ///
/// @verbinclude start1 /// @verbinclude start1
/// ///
/// @section UserManualServerStartStopOptions Frequently Used Options /// @section UserManualServerStartStopOptions Frequently Used Options
/////////////////////////////////////////////////////////////////////
/// ///
/// The following command-line options are frequently used. For a full /// The following command-line options are frequently used. For a full
/// list of options see @ref CommandLine "here". /// list of options see @ref CommandLine "here".
@ -198,11 +161,6 @@
/// <ol> /// <ol>
/// <li>@ref DBAdminDurability /// <li>@ref DBAdminDurability
/// </li> /// </li>
/// <li>@ref DBAdminIndex
/// <ol>
/// <li>@ref DBAdminIndexGeo
/// </ol>
/// </li>
/// </ol> /// </ol>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -214,8 +172,10 @@
/// <hr> /// <hr>
/// ///
/// @section DBAdminDurability Durability /// @section DBAdminDurability Durability
/////////////////////////////////////////
/// ///
/// @subsection DBAdminDurability1 Mostly Memory/Durability /// @subsection DBAdminDurability1 Mostly Memory/Durability
///////////////////////////////////////////////////////////
/// ///
/// Database documents are stored in the memory-memory-mapped files are used to /// Database documents are stored in the memory-memory-mapped files are used to
/// store them. The operating system has the advantageous option to decide /// store them. The operating system has the advantageous option to decide
@ -224,6 +184,7 @@
/// documents securely at once (durability). /// documents securely at once (durability).
/// ///
/// @subsection DBAdminDurability2 AppendOnly/MVCC /// @subsection DBAdminDurability2 AppendOnly/MVCC
//////////////////////////////////////////////////
/// ///
/// Instead of overwriting existing documents, a completely new version of the /// Instead of overwriting existing documents, a completely new version of the
/// document is generated. The two benefits are: /// document is generated. The two benefits are:
@ -237,18 +198,9 @@
/// processes. /// processes.
/// ///
/// @subsection DBAdminDurability3 Configuration /// @subsection DBAdminDurability3 Configuration
////////////////////////////////////////////////
/// ///
/// @copydetails JS_PropertiesVocbaseCol /// @copydetails JS_PropertiesVocbaseCol
///
/// @section DBAdminIndex Index Management
///
/// @subsection DBAdminIndexHash Hash Indexes
///
/// copydetails JS_EnsureHashIndexVocbaseCol
///
/// @subsection DBAdminIndexGeo Geo Indexes
///
/// copydetails JS_EnsureGeoIndexVocbaseCol
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:

View File

@ -74,6 +74,8 @@ typedef struct array_shaper_s {
TRI_associative_pointer_t _shapeDictionary; TRI_associative_pointer_t _shapeDictionary;
TRI_vector_pointer_t _shapes; TRI_vector_pointer_t _shapes;
// todo: add attribute weight structure
} }
array_shaper_t; array_shaper_t;
@ -402,6 +404,12 @@ static char const* LookupAttributeIdArrayShaper (TRI_shaper_t* shaper, TRI_shape
return NULL; return NULL;
} }
static int64_t LookupAttributeWeight (TRI_shaper_t* shaper, TRI_shape_aid_t aid) {
// todo: add support for an attribute weight
assert(0);
return -1;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -559,6 +567,7 @@ TRI_shaper_t* TRI_CreateArrayShaper (TRI_memory_zone_t* zone) {
shaper->base.lookupAttributeId = LookupAttributeIdArrayShaper; shaper->base.lookupAttributeId = LookupAttributeIdArrayShaper;
shaper->base.findShape = FindShapeShape; shaper->base.findShape = FindShapeShape;
shaper->base.lookupShapeId = LookupShapeId; shaper->base.lookupShapeId = LookupShapeId;
shaper->base.lookupAttributeWeight = LookupAttributeWeight;
// handle basics // handle basics
ok = TRI_InsertBasicTypesShaper(&shaper->base); ok = TRI_InsertBasicTypesShaper(&shaper->base);

View File

@ -60,7 +60,7 @@ typedef struct TRI_shaper_s {
char const* (*lookupAttributeId) (struct TRI_shaper_s*, TRI_shape_aid_t); char const* (*lookupAttributeId) (struct TRI_shaper_s*, TRI_shape_aid_t);
TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*); TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*);
TRI_shape_t const* (*lookupShapeId) (struct TRI_shaper_s*, TRI_shape_sid_t); TRI_shape_t const* (*lookupShapeId) (struct TRI_shaper_s*, TRI_shape_sid_t);
int64_t (*lookupAttributeWeight) (struct TRI_shaper_s*, TRI_shape_aid_t);
TRI_shape_path_t const* (*lookupAttributePathByPid) (struct TRI_shaper_s*, TRI_shape_pid_t); TRI_shape_path_t const* (*lookupAttributePathByPid) (struct TRI_shaper_s*, TRI_shape_pid_t);
TRI_shape_pid_t (*findAttributePathByName) (struct TRI_shaper_s*, char const*); TRI_shape_pid_t (*findAttributePathByName) (struct TRI_shaper_s*, char const*);

View File

@ -470,6 +470,21 @@ static int CompareShapedJsonShapedJson (const TRI_shaped_json_t* left, const TRI
result = CompareShapeTypes (left, right, leftShaper, rightShaper); result = CompareShapeTypes (left, right, leftShaper, rightShaper);
// ............................................................................
// In the above function CompareShaeTypes we use strcmp which may return
// an integer greater than 1 or less than -1. From this function we only
// need to know whether we have equality (0), less than (-1) or greater than (1)
// ............................................................................
if (result < 0) {
result = -1;
}
else if (result > 0) {
result = 1;
}
return result; return result;
} // end of function CompareShapedJsonShapedJson } // end of function CompareShapedJsonShapedJson
@ -718,7 +733,16 @@ static int IndexStaticMultiCompareElementElement (TRI_skiplist_multi_t* multiSki
for (j = 0; j < hLeftElement->numFields; j++) { for (j = 0; j < hLeftElement->numFields; j++) {
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper); compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
if (compareResult != 0) { if (compareResult != 0) {
// ......................................................................
// The function CompareShaedJsonShapedJson can only return 0, -1, or 1
// that is, TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL (0)
// TRI_SKIPLIST_COMPARE_STRICTLY_LESS (-1)
// TRI_SKIPLIST_COMPARE_STRICTLY_GREATER (1)
// ......................................................................
return compareResult; return compareResult;
} }
} }

View File

@ -25,9 +25,10 @@
/// @author Copyright 2006-2012, triAGENS GmbH, Cologne, Germany /// @author Copyright 2006-2012, triAGENS GmbH, Cologne, Germany
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "skiplist.h" #include <BasicsC/logging.h>
#include <BasicsC/random.h> #include <BasicsC/random.h>
#include "skiplist.h"
#include "compare.h" #include "compare.h"
#define SKIPLIST_ABSOLUTE_MAX_HEIGHT 100 #define SKIPLIST_ABSOLUTE_MAX_HEIGHT 100
@ -340,11 +341,11 @@ void TRI_InitSkipList (TRI_skiplist_t* skiplist, size_t elementSize,
} }
// .......................................................................... // ..........................................................................
// Assign the comparision call back functions // Assign the STATIC comparision call back functions
// .......................................................................... // ..........................................................................
skiplist->compareElementElement = compareElementElement; skiplist->compareElementElement = IndexStaticCompareElementElement; // compareElementElement;
skiplist->compareKeyElement = compareKeyElement; skiplist->compareKeyElement = IndexStaticCompareKeyElement; // compareKeyElement;
// .......................................................................... // ..........................................................................
// Assign the maximum height of the skip list. This maximum height must be // Assign the maximum height of the skip list. This maximum height must be
@ -352,7 +353,7 @@ void TRI_InitSkipList (TRI_skiplist_t* skiplist, size_t elementSize,
// .......................................................................... // ..........................................................................
skiplist->_base._maxHeight = maximumHeight; skiplist->_base._maxHeight = maximumHeight;
if (maximumHeight > SKIPLIST_ABSOLUTE_MAX_HEIGHT) { if (maximumHeight > SKIPLIST_ABSOLUTE_MAX_HEIGHT) {
printf("%s:%d:Invalid maximum height for skiplist\n",__FILE__,__LINE__); LOG_ERROR("Invalid maximum height for skiplist", TRI_ERROR_INTERNAL);
assert(false); assert(false);
} }
@ -1290,7 +1291,7 @@ void* TRI_RightLookupByKeySkipList (TRI_skiplist_t* skiplist, void* key) {
// Use the callback to determine if the element is less or greater than // Use the callback to determine if the element is less or greater than
// the next node element. // the next node element.
// ....................................................................... // .......................................................................
compareResult = IndexStaticCompareKeyElement(skiplist,key,&(prevNode->_element), 1); compareResult = IndexStaticCompareKeyElement(skiplist, key, &(prevNode->_element), 1);
// ....................................................................... // .......................................................................
@ -1311,7 +1312,7 @@ void* TRI_RightLookupByKeySkipList (TRI_skiplist_t* skiplist, void* key) {
} }
// ....................................................................... // .......................................................................
// The element is greater than the next node element. Keep going on this // The key is greater than the next node element. Keep going on this
// level. // level.
// ....................................................................... // .......................................................................
if (compareResult < 0) { if (compareResult < 0) {
@ -1399,9 +1400,9 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
// Assign the comparision call back functions // Assign the comparision call back functions
// .......................................................................... // ..........................................................................
skiplist->compareElementElement = compareElementElement; skiplist->compareElementElement = IndexStaticMultiCompareElementElement; //compareElementElement;
skiplist->compareKeyElement = compareKeyElement; skiplist->compareKeyElement = IndexStaticMultiCompareKeyElement; // compareKeyElement;
skiplist->equalElementElement = equalElementElement; skiplist->equalElementElement = IndexStaticMultiEqualElementElement; //equalElementElement;
// .......................................................................... // ..........................................................................
// Assign the maximum height of the skip list. This maximum height must be // Assign the maximum height of the skip list. This maximum height must be
@ -1409,7 +1410,7 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
// .......................................................................... // ..........................................................................
skiplist->_base._maxHeight = maximumHeight; skiplist->_base._maxHeight = maximumHeight;
if (maximumHeight > SKIPLIST_ABSOLUTE_MAX_HEIGHT) { if (maximumHeight > SKIPLIST_ABSOLUTE_MAX_HEIGHT) {
printf("%s:%d:Invalid maximum height for skiplist\n",__FILE__,__LINE__); LOG_ERROR("Invalid maximum height for skiplist", TRI_ERROR_INTERNAL);
assert(false); assert(false);
} }
@ -2114,7 +2115,7 @@ int TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* elemen
} }
// ..................................................................... // .....................................................................
// The element could be located and we are at the lowest level // The element could be located (by matching the key) and we are at the lowest level
// ..................................................................... // .....................................................................
if (compareResult == TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS) { if (compareResult == TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS) {
goto END; goto END;
@ -2163,7 +2164,7 @@ int TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* elemen
// .......................................................................... // ..........................................................................
if (old != NULL) { if (old != NULL) {
memcpy(old, &(currentNode->_element), skiplist->_base._elementSize); IndexStaticCopyElementElement(&(skiplist->_base), old, &(currentNode->_element));
} }

View File

@ -1150,6 +1150,8 @@ static bool multiSkiplistIndex_findHelperIntervalValid(SkiplistIndex* skiplistIn
compareResult = skiplistIndex->skiplist.nonUniqueSkiplist->compareKeyElement( compareResult = skiplistIndex->skiplist.nonUniqueSkiplist->compareKeyElement(
skiplistIndex->skiplist.nonUniqueSkiplist, skiplistIndex->skiplist.nonUniqueSkiplist,
&(lNode->_element), &(rNode->_element), 0); &(lNode->_element), &(rNode->_element), 0);
return (compareResult == -1); return (compareResult == -1);
} }
@ -1292,6 +1294,7 @@ TRI_skiplist_iterator_t* MultiSkiplistIndex_find(SkiplistIndex* skiplistIndex, T
if (results == NULL) { if (results == NULL) {
return NULL; return NULL;
} }
results->_index = skiplistIndex; results->_index = skiplistIndex;
TRI_InitVector(&(results->_intervals), TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_skiplist_iterator_interval_t)); TRI_InitVector(&(results->_intervals), TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_skiplist_iterator_interval_t));
results->_currentInterval = 0; results->_currentInterval = 0;

View File

@ -109,10 +109,6 @@ describe AvocadoDB do
AvocadoDB.drop_collection(@cn) AvocadoDB.drop_collection(@cn)
@cid = AvocadoDB.create_collection(@cn, false) @cid = AvocadoDB.create_collection(@cn, false)
cmd = api + "?collection=#{@cid}"
body = "{ \"type\" : \"geo\", \"fields\" : [ \"a\" ] }"
#doc = AvocadoDB.post(cmd, :body => body)
(0..10).each{|i| (0..10).each{|i|
lat = 10 * (i - 5) lat = 10 * (i - 5)
@ -189,10 +185,6 @@ describe AvocadoDB do
AvocadoDB.drop_collection(@cn) AvocadoDB.drop_collection(@cn)
@cid = AvocadoDB.create_collection(@cn, false) @cid = AvocadoDB.create_collection(@cn, false)
cmd = api + "?collection=#{@cid}"
body = "{ \"type\" : \"geo\", \"fields\" : [ \"a\" ] }"
#doc = AvocadoDB.post(cmd, :body => body)
(0..10).each{|i| (0..10).each{|i|
lat = 10 * (i - 5) lat = 10 * (i - 5)
@ -259,5 +251,116 @@ describe AvocadoDB do
end end
end end
################################################################################
## by-example query
################################################################################
context "by-example query:" do
before do
@cn = "UnitTestsCollectionByExample"
AvocadoDB.drop_collection(@cn)
@cid = AvocadoDB.create_collection(@cn, false)
end
after do
AvocadoDB.drop_collection(@cn)
end
it "finds the examples" do
body = "{ \"i\" : 1 }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d1 = doc.parsed_response['_id']
body = "{ \"i\" : 1, \"a\" : { \"j\" : 1 } }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d2 = doc.parsed_response['_id']
body = "{ \"i\" : 1, \"a\" : { \"j\" : 1, \"k\" : 1 } }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d3 = doc.parsed_response['_id']
body = "{ \"i\" : 1, \"a\" : { \"j\" : 2, \"k\" : 2 } }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d4 = doc.parsed_response['_id']
body = "{ \"i\" : 2 }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d5 = doc.parsed_response['_id']
body = "{ \"i\" : 2, \"a\" : 2 }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d6 = doc.parsed_response['_id']
body = "{ \"i\" : 2, \"a\" : { \"j\" : 2, \"k\" : 2 } }"
doc = AvocadoDB.post("/document?collection=#{@cid}", :body => body)
doc.code.should eq(202)
d7 = doc.parsed_response['_id']
cmd = api + "/by-example"
body = "{ \"collection\" : \"#{@cid}\", \"example\" : [ { \"i\" : 1 } ] }"
doc = AvocadoDB.log_put("#{prefix}-by-example1", cmd, :body => body)
doc.code.should eq(201)
doc.headers['content-type'].should eq("application/json")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['hasMore'].should eq(false)
doc.parsed_response['result'].length.should eq(4)
doc.parsed_response['count'].should eq(4)
doc.parsed_response['result'].map{|i| i['_id']}.should =~ [d1,d2,d3,d4]
cmd = api + "/by-example"
body = "{ \"collection\" : \"#{@cid}\", \"example\" : [ { \"a\" : { \"j\" : 1 } } ] }"
doc = AvocadoDB.log_put("#{prefix}-by-example2", cmd, :body => body)
doc.code.should eq(201)
doc.headers['content-type'].should eq("application/json")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['hasMore'].should eq(false)
doc.parsed_response['result'].length.should eq(1)
doc.parsed_response['count'].should eq(1)
doc.parsed_response['result'].map{|i| i['_id']}.should =~ [d2]
cmd = api + "/by-example"
body = "{ \"collection\" : \"#{@cid}\", \"example\" : [ \"a.j\", 1 ] }"
doc = AvocadoDB.log_put("#{prefix}-by-example3", cmd, :body => body)
doc.code.should eq(201)
doc.headers['content-type'].should eq("application/json")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(201)
doc.parsed_response['hasMore'].should eq(false)
doc.parsed_response['result'].length.should eq(2)
doc.parsed_response['count'].should eq(2)
doc.parsed_response['result'].map{|i| i['_id']}.should =~ [d2,d3]
cmd = api + "/first-example"
body = "{ \"collection\" : \"#{@cid}\", \"example\" : [ \"a.j\", 1, \"a.k\", 1 ] }"
doc = AvocadoDB.log_put("#{prefix}-first-example", cmd, :body => body)
doc.code.should eq(200)
doc.headers['content-type'].should eq("application/json")
doc.parsed_response['error'].should eq(false)
doc.parsed_response['code'].should eq(200)
doc.parsed_response['document']['_id'].should eq(d3)
cmd = api + "/first-example"
body = "{ \"collection\" : \"#{@cid}\", \"example\" : [ \"a.j\", 1, \"a.k\", 2 ] }"
doc = AvocadoDB.log_put("#{prefix}-first-example-not-found", cmd, :body => body)
doc.code.should eq(404)
doc.headers['content-type'].should eq("application/json")
doc.parsed_response['error'].should eq(true)
doc.parsed_response['code'].should eq(404)
end
end
end end
end end

View File

@ -480,6 +480,14 @@ BOOST_AUTO_TEST_CASE (tst_insert) {
void* r = 0; void* r = 0;
// ...........................................................................
// this test needs to be altered slightly e.g.
// TRI_InsertVectorPointer(&v1, &a, 100);
// TRI_InsertVectorPointer(&v1, &a, 20);
// TRI_InsertVectorPointer(&v1, &a, 200);
// ...........................................................................
TRI_InsertVectorPointer(&v1, &a, 0); TRI_InsertVectorPointer(&v1, &a, 0);
BOOST_CHECK_EQUAL((size_t) 1, v1._length); BOOST_CHECK_EQUAL((size_t) 1, v1._length);
BOOST_CHECK_EQUAL(&a, TRI_AtVectorPointer(&v1, 0)); BOOST_CHECK_EQUAL(&a, TRI_AtVectorPointer(&v1, 0));

View File

@ -1851,7 +1851,7 @@ static v8::Handle<v8::Value> JS_ByExampleQuery (v8::Arguments const& argv) {
ReleaseCollection(collection); ReleaseCollection(collection);
return scope.Close(v8::ThrowException( return scope.Close(v8::ThrowException(
CreateErrorObject(TRI_ERROR_BAD_PARAMETER, CreateErrorObject(TRI_ERROR_BAD_PARAMETER,
"usage: document(<path1>, <value1>, ...)"))); "usage: byExample(<path1>, <value1>, ...)")));
} }
size_t n = argv.Length() / 2; size_t n = argv.Length() / 2;
@ -4112,6 +4112,14 @@ static v8::Handle<v8::Value> JS_ExecuteAql (v8::Arguments const& argv) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief counts the number of documents in a result set /// @brief counts the number of documents in a result set
///
/// @FUN{@FA{collection}.count()}
///
/// Returns the number of living documents in the collection.
///
/// @EXAMPLES
///
/// @verbinclude shell-collection-count
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static v8::Handle<v8::Value> JS_CountVocbaseCol (v8::Arguments const& argv) { static v8::Handle<v8::Value> JS_CountVocbaseCol (v8::Arguments const& argv) {

View File

@ -1 +1 @@
0.4.0 0.4.2

20
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for triAGENS AvocadoDB 0.4.0. # Generated by GNU Autoconf 2.68 for triAGENS AvocadoDB 0.4.2.
# #
# Report bugs to <info@triagens.de>. # Report bugs to <info@triagens.de>.
# #
@ -560,8 +560,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='triAGENS AvocadoDB' PACKAGE_NAME='triAGENS AvocadoDB'
PACKAGE_TARNAME='avocado' PACKAGE_TARNAME='avocado'
PACKAGE_VERSION='0.4.0' PACKAGE_VERSION='0.4.2'
PACKAGE_STRING='triAGENS AvocadoDB 0.4.0' PACKAGE_STRING='triAGENS AvocadoDB 0.4.2'
PACKAGE_BUGREPORT='info@triagens.de' PACKAGE_BUGREPORT='info@triagens.de'
PACKAGE_URL='http://www.avocadodb.org' PACKAGE_URL='http://www.avocadodb.org'
@ -1398,7 +1398,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures triAGENS AvocadoDB 0.4.0 to adapt to many kinds of systems. \`configure' configures triAGENS AvocadoDB 0.4.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1469,7 +1469,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of triAGENS AvocadoDB 0.4.0:";; short | recursive ) echo "Configuration of triAGENS AvocadoDB 0.4.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1622,7 +1622,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
triAGENS AvocadoDB configure 0.4.0 triAGENS AvocadoDB configure 0.4.2
generated by GNU Autoconf 2.68 generated by GNU Autoconf 2.68
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2010 Free Software Foundation, Inc.
@ -2087,7 +2087,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by triAGENS AvocadoDB $as_me 0.4.0, which was It was created by triAGENS AvocadoDB $as_me 0.4.2, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@ $ $0 $@
@ -3214,7 +3214,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='avocado' PACKAGE='avocado'
VERSION='0.4.0' VERSION='0.4.2'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -10112,7 +10112,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by triAGENS AvocadoDB $as_me 0.4.0, which was This file was extended by triAGENS AvocadoDB $as_me 0.4.2, which was
generated by GNU Autoconf 2.68. Invocation command line was generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -10179,7 +10179,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
triAGENS AvocadoDB config.status 0.4.0 triAGENS AvocadoDB config.status 0.4.2
configured by $0, generated by GNU Autoconf 2.68, configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -6,7 +6,7 @@ dnl ============================================================================
dnl PREAMBLE triAGENS GmbH Build Environment dnl PREAMBLE triAGENS GmbH Build Environment
dnl ============================================================================ dnl ============================================================================
AC_INIT([triAGENS AvocadoDB], [0.4.0], [info@triagens.de], [avocado], [http://www.avocadodb.org]) AC_INIT([triAGENS AvocadoDB], [0.4.2], [info@triagens.de], [avocado], [http://www.avocadodb.org])
dnl ---------------------------------------------------------------------------- dnl ----------------------------------------------------------------------------
dnl auxillary directory for install-sh and missing dnl auxillary directory for install-sh and missing

View File

@ -209,6 +209,9 @@ pre ul li span{
.ui-tabs-nav { .ui-tabs-nav {
font-size: 0.8em !important; font-size: 0.8em !important;
height: 35px; height: 35px;
-webkit-box-shadow: inset 0 0 1px 1px #f6f6f6 !important;
-moz-box-shadow: inset 0 0 1px 1px #f6f6f6 !important;
box-shadow: inset 0 0 1px 1px #f6f6f6 !important;
//border-bottom: 0px !important; //border-bottom: 0px !important;
} }

View File

@ -136,6 +136,7 @@ else {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
var collectionTable = $('#collectionsTableID').dataTable({ var collectionTable = $('#collectionsTableID').dataTable({
"aaSorting": [[ 2, "desc" ]],
"bPaginate": false, "bPaginate": false,
"bFilter": false, "bFilter": false,
"bLengthChange": false, "bLengthChange": false,
@ -152,7 +153,7 @@ var collectionTable = $('#collectionsTableID').dataTable({
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
var documentEditTable = $('#documentEditTableID').dataTable({ var documentEditTable = $('#documentEditTableID').dataTable({
"aaSorting": [], "aaSorting": [[ 1, "desc" ]],
"bFilter": false, "bFilter": false,
"bPaginate":false, "bPaginate":false,
"bSortable": false, "bSortable": false,
@ -2030,4 +2031,3 @@ function stateReplace (value) {
return output; return output;
} }

View File

@ -351,25 +351,29 @@ actions.defineHttp({
/// ///
/// The call expects a JSON hash array as body with the following attributes: /// The call expects a JSON hash array as body with the following attributes:
/// ///
/// @FA{collection} /// - @LIT{collection}: The identifier or name of the collection to query.
/// ///
/// The identifier or name of the collection to query. /// - @LIT{example}: The example.
/// ///
/// @FA{example} /// - @LIT{skip}: The documents to skip in the query. (optional)
/// ///
/// The example. /// - @LIT{limit}: The maximal amount of documents to return. (optional)
/// ///
/// @FA{skip} (optional) /// Returns a cursor containing the result, see @ref HttpCursor for details.
///
/// The documents to skip in the query.
///
/// @FA{limit} (optional)
///
/// The maximal amount of documents to return.
/// ///
/// @EXAMPLES /// @EXAMPLES
/// ///
/// @verbinclude api_simple7 /// Matching an attribute:
///
/// @verbinclude api-simple-by-example1
///
/// Matching an attribute which is a sub-document:
///
/// @verbinclude api-simple-by-example2
///
/// Matching an attribute within a sub-document:
///
/// @verbinclude api-simple-by-example3
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({ actions.defineHttp({
@ -383,16 +387,18 @@ actions.defineHttp({
return; return;
} }
var limit = body.limit;
var skip = body.skip;
var name = body.collection;
var example = body.example;
if (req.requestType != actions.PUT) { if (req.requestType != actions.PUT) {
actions.unsupported(req, res); actions.unsupported(req, res);
} }
else { else {
collection = internal.db._collection(name); var limit = body.limit;
var skip = body.skip;
var name = body.collection;
var example = body.example;
var name = body.collection;
var id = parseInt(name) || name;
var collection = internal.db._collection(id);
if (collection == null) { if (collection == null) {
actions.collectionNotFound(req, res, name); actions.collectionNotFound(req, res, name);
@ -401,17 +407,95 @@ actions.defineHttp({
actions.badParameter(req, res, "example"); actions.badParameter(req, res, "example");
} }
else { else {
var result = collection.byExample(example); try {
var result = collection.byExample.apply(collection, example);
if (skip != null) { if (skip != null) {
result = result.skip(skip); result = result.skip(skip);
}
if (limit != null) {
result = result.limit(limit);
}
actions.resultCursor(req, res, CREATE_CURSOR(result.toArray(), true));
} }
catch (err) {
if (limit != null) { actions.resultException(req, res, err);
result = result.limit(limit);
} }
}
}
}
});
actions.resultOk(req, res, actions.HTTP_OK, result.toArray()); ////////////////////////////////////////////////////////////////////////////////
/// @fn JSA_PUT_api_simple_first_example
/// @brief returns one document of a collection matching a given example
///
/// @REST{PUT /_api/simple/first-example}
///
/// This will return the first document matching a given example.
///
/// The call expects a JSON hash array as body with the following attributes:
///
/// - @LIT{collection}: The identifier or name of the collection to query.
///
/// - @LIT{example}: The example.
///
/// - @LIT{skip}: The documents to skip in the query. (optional)
///
/// - @LIT{limit}: The maximal amount of documents to return. (optional)
///
/// Returns a result containing the document or @LIT{HTTP 404} if no
/// document matched the example.
///
/// @EXAMPLES
///
/// If a matching document was found:
///
/// @verbinclude api-simple-first-example
///
/// If no document was found:
///
/// @verbinclude api-simple-first-example-not-found
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url : API + "first-example",
context : "api",
callback : function (req, res) {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
if (req.requestType != actions.PUT) {
actions.unsupported(req, res);
}
else {
var example = body.example;
var name = body.collection;
var id = parseInt(name) || name;
var collection = internal.db._collection(id);
if (collection == null) {
actions.collectionNotFound(req, res, name);
}
else if (typeof example !== "object") {
actions.badParameter(req, res, "example");
}
else {
var result = collection.byExample.apply(collection, example).limit(1);
if (result.hasNext()) {
actions.resultOk(req, res, actions.HTTP_OK, { document : result.next() });
}
else {
actions.resultNotFound(req, res, "no match");
}
} }
} }
} }

View File

@ -98,29 +98,28 @@ SQ.SimpleQueryByExample.prototype.execute = function () {
var documents; var documents;
if (this._execution == null) { if (this._execution == null) {
if (this._skip == null || this._skip <= 0) { var data = {
this._skip = 0; collection : this._collection._id,
example : this._example
} }
var parameters = [ ]; if (this._limit != null) {
data.limit = this._limit;
// the actual example is passed in the first argument
for (var i in this._example[0]) {
if (this._example[0].hasOwnProperty(i)) {
// attribute name
parameters.push(i);
// attribute value
parameters.push(this._example[0][i]);
}
} }
var documents = this._collection.BY_EXAMPLE.apply(this._collection, parameters); if (this._skip != null) {
data.skip = this._skip;
}
this._execution = new SQ.GeneralArrayCursor(documents, this._skip, this._limit); var requestResult = this._collection._database._connection.PUT("/_api/simple/by-example", JSON.stringify(data));
this._countQuery = documents.length;
this._countTotal = documents.length; TRI_CheckRequestResult(requestResult);
this._execution = new AvocadoQueryCursor(this._collection._database, requestResult);
if (requestResult.hasOwnProperty("count")) {
this._countQuery = requestResult.count;
}
} }
} }
@ -128,6 +127,52 @@ SQ.SimpleQueryByExample.prototype.execute = function () {
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup SimpleQuery
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a query-by-example for a collection
////////////////////////////////////////////////////////////////////////////////
AvocadoCollection.prototype.firstExample = function () {
// create a REAL array, otherwise JSON.stringify will fail
var example = [];
for (var i = 0; i < arguments.length; ++i) {
example.push(arguments[i]);
}
var data = {
collection : this._id,
example : example
}
var requestResult = this._database._connection.PUT("/_api/simple/first-example", JSON.stringify(data));
if (requestResult != null
&& requestResult.error == true
&& requestResult.errorNum == internal.errors.ERROR_HTTP_NOT_FOUND.code) {
return null;
}
TRI_CheckRequestResult(requestResult);
return requestResult.document;
}
AvocadoEdgesCollection.prototype.firstExample = AvocadoCollection.prototype.firstExample;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY NEAR // --SECTION-- SIMPLE QUERY NEAR
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -36,37 +36,6 @@ var DURATION = 0;
internal.loadFile("jsunity/jsunity"); internal.loadFile("jsunity/jsunity");
jsUnity.log = console; jsUnity.log = console;
////////////////////////////////////////////////////////////////////////////////
/// @page jsUnity Using jsUnity and node-jscoverage
///
/// The AvocadoDB contains a wrapper for
/// <a href="http://jsunity.com/">jsUnity</a>, a lightyweight universal
/// JavAScript unit testing framework.
///
/// @section jsUnityRunningTest Running jsUnity Tests
///
/// Assume that you have a test file containing
///
/// @verbinclude jsunity1
///
/// Then you can run the test suite using @FN{jsunity.runTest}
///
/// @verbinclude jsunity2
///
/// @section jsUnityRunningCoverage Running jsUnity Tests with Coverage
///
/// You can use the coverage tool
/// <a href="https://github.com/visionmedia/node-jscoverage">@LIT{node-jscoverage}</a>.
///
/// Assume that your file live in a directory called @LIT{lib}. Use
///
/// @CODE{node-jscoverage lib lib-cov}
///
/// to create a copy of the JavaScript files with coverage information. Start
/// the AvocadoDB with these files and use @FN{jsunity.runCoverage} instead of
/// @FN{jsunity.runTest}.
////////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private functions // --SECTION-- private functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -47,9 +47,9 @@ var AvocadoEdgesCollection = internal.AvocadoEdgesCollection;
/// ///
/// @FUN{all()} /// @FUN{all()}
/// ///
/// Selects all documents of a collection. You can use @FN{toArray}, @FN{next}, /// Selects all documents of a collection and returns a cursor. You can use
/// or @FN{hasNext} to access the result. The result can be limited using the /// @FN{toArray}, @FN{next}, or @FN{hasNext} to access the result. The result
/// @FN{skip} and @FN{limit} operator. /// can be limited using the @FN{skip} and @FN{limit} operator.
/// ///
/// @EXAMPLES /// @EXAMPLES
/// ///
@ -257,14 +257,20 @@ AvocadoEdgesCollection.prototype.geo = AvocadoCollection.geo;
/// ///
/// @FUN{@FA{collection}.byExample(@FA{path1}, @FA{value1}, ...)} /// @FUN{@FA{collection}.byExample(@FA{path1}, @FA{value1}, ...)}
/// ///
/// Selects all documents of a collection that match the specified /// Selects all documents of a collection that match the specified example and
/// example. The example must be specified as paths and values. Allowed /// returns a cursor. The example must be specified as paths and values. Allowed
/// attribute types for searching are numbers, strings, and boolean values. /// attribute types for searching are numbers, strings, and boolean values.
/// ///
/// You can use @FN{toArray}, @FN{next}, or @FN{hasNext} to access /// You can use @FN{toArray}, @FN{next}, or @FN{hasNext} to access
/// the result. The result can be limited using the @FN{skip} and @FN{limit} /// the result. The result can be limited using the @FN{skip} and @FN{limit}
/// operator. /// operator.
/// ///
/// @FUN{@FA{collection}.byExample(@FA{example})}
///
/// As alternative you can supply an example as single argument. Note that an
/// attribute name of the form @LIT{a.b} is interpreted as attribute path, not
/// as attribute.
///
/// @EXAMPLES /// @EXAMPLES
/// ///
/// Use @FN{toArray} to get all documents at once: /// Use @FN{toArray} to get all documents at once:
@ -277,40 +283,19 @@ AvocadoEdgesCollection.prototype.geo = AvocadoCollection.geo;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AvocadoCollection.prototype.byExample = function () { AvocadoCollection.prototype.byExample = function () {
return new SimpleQueryByExample(this, arguments);
// create a REAL array, otherwise JSON.stringify will fail
var example = [];
for (var i = 0; i < arguments.length; ++i) {
example.push(arguments[i]);
}
return new SimpleQueryByExample(this, example);
} }
AvocadoEdgesCollection.prototype.byExample = AvocadoCollection.prototype.byExample; AvocadoEdgesCollection.prototype.byExample = AvocadoCollection.prototype.byExample;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a query-by-example for a collection
///
/// @FUN{@FA{collection}.firstExample(@FA{path1}, @FA{value1}, ...)}
///
/// Returns the first documents of a collection that match the specified example
/// or @LIT{null}. The example must be specified as paths and
/// values. Allowed attribute types for searching are numbers, strings, and
/// boolean values.
///
/// @EXAMPLES
////////////////////////////////////////////////////////////////////////////////
AvocadoCollection.prototype.firstExample = function () {
var cursor = new SimpleQueryByExample(this, arguments);
var result = null;
if (cursor.hasNext()) {
result = cursor.next();
}
cursor.dispose();
return result;
}
AvocadoEdgesCollection.prototype.firstExample = AvocadoCollection.prototype.firstExample;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -41,7 +41,7 @@ var SQB = require("simple-query-basics");
require("simple-query"); require("simple-query");
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- basic skips and limits // --SECTION-- basic skips and limits for array
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -176,14 +176,14 @@ function SimpleQueryArraySkipLimitSuite () {
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- basic skips and limits // --SECTION-- basic skips and limits for all
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: skip and limit with a collection /// @brief test suite: skip and limit with a collection
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
function SimpleQuerySkipLimitSuite () { function SimpleQueryAllSkipLimitSuite () {
var cn = "UnitTestsCollectionSkipLimit"; var cn = "UnitTestsCollectionSkipLimit";
var collection = null; var collection = null;
var numbers = null; var numbers = null;
@ -195,30 +195,30 @@ function SimpleQuerySkipLimitSuite () {
/// @brief set up /// @brief set up
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
setUp : function () { setUp : function () {
internal.db._drop(cn); internal.db._drop(cn);
collection = internal.db._create(cn, { waitForSync : false }); collection = internal.db._create(cn, { waitForSync : false });
for (var i = 0; i < 10; ++i) { for (var i = 0; i < 10; ++i) {
collection.save({ n : i }); collection.save({ n : i });
} }
numbers = collection.all().toArray().map(num); numbers = collection.all().toArray().map(num);
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief tear down /// @brief tear down
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
tearDown : function () { tearDown : function () {
collection.drop(); collection.drop();
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief test: skip /// @brief test: skip
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testSkip : function () { testAllSkip : function () {
var n = collection.all().skip(0).toArray().map(num); var n = collection.all().skip(0).toArray().map(num);
assertEqual(n, numbers); assertEqual(n, numbers);
@ -256,7 +256,7 @@ function SimpleQuerySkipLimitSuite () {
/// @brief test: limit /// @brief test: limit
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testLimit : function () { testAllLimit : function () {
var n = collection.all().limit(10).toArray().map(num); var n = collection.all().limit(10).toArray().map(num);
assertEqual(n, numbers); assertEqual(n, numbers);
@ -290,7 +290,7 @@ function SimpleQuerySkipLimitSuite () {
/// @brief test: skip and limit /// @brief test: skip and limit
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testSkipLimit : function () { testAllSkipLimit : function () {
var n = collection.all().skip(0).limit(10).toArray().map(num); var n = collection.all().skip(0).limit(10).toArray().map(num);
assertEqual(n, numbers); assertEqual(n, numbers);
@ -318,6 +318,112 @@ function SimpleQuerySkipLimitSuite () {
}; };
} }
// -----------------------------------------------------------------------------
// --SECTION-- basic tests for byExample
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: skip and limit with a collection
////////////////////////////////////////////////////////////////////////////////
function SimpleQueryByExampleSuite () {
var cn = "UnitTestsCollectionByExample";
var collection = null;
var id = function(d) { return d._id; };
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
internal.db._drop(cn);
collection = internal.db._create(cn, { waitForSync : false });
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////
tearDown : function () {
collection.drop();
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: byExample
////////////////////////////////////////////////////////////////////////////////
testByExampleObject : function () {
var d1 = collection.save({ i : 1 });
var d2 = collection.save({ i : 1, a : { j : 1 } });
var d3 = collection.save({ i : 1, a : { j : 1, k : 1 } });
var d4 = collection.save({ i : 1, a : { j : 2, k : 2 } });
var d5 = collection.save({ i : 2 });
var d6 = collection.save({ i : 2, a : 2 });
var d7 = collection.save({ i : 2, a : { j : 2, k : 2 } });
var s;
s = collection.byExample({ i : 1 }).toArray().map(id).sort();
assertEqual([d1._id, d2._id, d3._id, d4._id].sort(), s);
s = collection.byExample({ i : 2 }).toArray().map(id).sort();
assertEqual([d5._id, d6._id, d7._id].sort(), s);
s = collection.byExample({ a : { j : 1 } }).toArray().map(id).sort();
assertEqual([d2._id], s);
s = collection.byExample({ "a.j" : 1 }).toArray().map(id).sort();
assertEqual([d2._id, d3._id].sort(), s);
s = collection.byExample({ i : 2, "a.k" : 2 }).toArray().map(id).sort();
assertEqual([d7._id], s);
s = collection.firstExample({ "i" : 2, "a.k" : 2 });
assertEqual(d7._id, s._id);
s = collection.firstExample({ "i" : 2, "a.k" : 27 });
assertEqual(null, s);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test: byExample
////////////////////////////////////////////////////////////////////////////////
testByExampleList : function () {
var d1 = collection.save({ i : 1 });
var d2 = collection.save({ i : 1, a : { j : 1 } });
var d3 = collection.save({ i : 1, a : { j : 1, k : 1 } });
var d4 = collection.save({ i : 1, a : { j : 2, k : 2 } });
var d5 = collection.save({ i : 2 });
var d6 = collection.save({ i : 2, a : 2 });
var d7 = collection.save({ i : 2, a : { j : 2, k : 2 } });
var s;
s = collection.byExample("i", 1).toArray().map(id).sort();
assertEqual([d1._id, d2._id, d3._id, d4._id].sort(), s);
s = collection.byExample("i", 2).toArray().map(id).sort();
assertEqual([d5._id, d6._id, d7._id].sort(), s);
s = collection.byExample("a", { j : 1 }).toArray().map(id).sort();
assertEqual([d2._id], s);
s = collection.byExample("a.j", 1).toArray().map(id).sort();
assertEqual([d2._id, d3._id].sort(), s);
s = collection.byExample("i", 2, "a.k", 2).toArray().map(id).sort();
assertEqual([d7._id], s);
s = collection.firstExample("i", 2, "a.k", 2);
assertEqual(d7._id, s._id);
s = collection.firstExample("i", 2, "a.k", 27);
assertEqual(null, s);
}
};
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- main // --SECTION-- main
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -327,7 +433,8 @@ function SimpleQuerySkipLimitSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
jsunity.run(SimpleQueryArraySkipLimitSuite); jsunity.run(SimpleQueryArraySkipLimitSuite);
jsunity.run(SimpleQuerySkipLimitSuite); jsunity.run(SimpleQueryAllSkipLimitSuite);
jsunity.run(SimpleQueryByExampleSuite);
return jsunity.done(); return jsunity.done();

View File

@ -419,6 +419,11 @@ static string JS_server_server =
"\n" "\n"
"////////////////////////////////////////////////////////////////////////////////\n" "////////////////////////////////////////////////////////////////////////////////\n"
"/// @brief converts collection into an array\n" "/// @brief converts collection into an array\n"
"///\n"
"/// @FUN{@FA{collection}.toArray()}\n"
"///\n"
"/// Converts the collection into an array of documents. Never use this call\n"
"/// in a production environment.\n"
"////////////////////////////////////////////////////////////////////////////////\n" "////////////////////////////////////////////////////////////////////////////////\n"
"\n" "\n"
"AvocadoCollection.prototype.toArray = function() {\n" "AvocadoCollection.prototype.toArray = function() {\n"

View File

@ -90,20 +90,27 @@ SQ.SimpleQueryByExample.prototype.execute = function () {
this._skip = 0; this._skip = 0;
} }
var parameters = [ ]; var parameters = [];
// the actual example is passed in the first argument // the actual example is passed in the first argument
for (var i in this._example[0]) { if (this._example.length == 1) {
if (this._example[0].hasOwnProperty(i)) { for (var i in this._example[0]) {
if (this._example[0].hasOwnProperty(i)) {
// attribute name // attribute name
parameters.push(i); parameters.push(i);
// attribute value // attribute value
parameters.push(this._example[0][i]); parameters.push(this._example[0][i]);
}
} }
} }
// the arguments are passed
else {
parameters = this._example;
}
var documents = this._collection.BY_EXAMPLE.apply(this._collection, parameters); var documents = this._collection.BY_EXAMPLE.apply(this._collection, parameters);
this._execution = new SQ.GeneralArrayCursor(documents, this._skip, this._limit); this._execution = new SQ.GeneralArrayCursor(documents, this._skip, this._limit);
@ -116,6 +123,55 @@ SQ.SimpleQueryByExample.prototype.execute = function () {
/// @} /// @}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup SimpleQuery
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a query-by-example for a collection
///
/// @FUN{@FA{collection}.firstExample(@FA{path1}, @FA{value1}, ...)}
///
/// Returns the first documents of a collection that match the specified example
/// or @LIT{null}. The example must be specified as paths and
/// values. Allowed attribute types for searching are numbers, strings, and
/// boolean values.
///
/// @FUN{@FA{collection}.firstExample(@FA{example})}
///
/// As alternative you can supply an example as single argument. Note that an
/// attribute name of the form @LIT{a.b} is interpreted as attribute path, not
/// as attribute.
///
/// @EXAMPLES
///
/// @verbinclude shell-simple-query-first-example
////////////////////////////////////////////////////////////////////////////////
AvocadoCollection.prototype.firstExample = function () {
var cursor = new SQ.SimpleQueryByExample(this, arguments);
var result = null;
if (cursor.hasNext()) {
result = cursor.next();
}
cursor.dispose();
return result;
}
AvocadoEdgesCollection.prototype.firstExample = AvocadoCollection.prototype.firstExample;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY NEAR // --SECTION-- SIMPLE QUERY NEAR
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -418,6 +418,11 @@ AvocadoEdgesCollection.STATUS_DELETED = 5;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief converts collection into an array /// @brief converts collection into an array
///
/// @FUN{@FA{collection}.toArray()}
///
/// Converts the collection into an array of documents. Never use this call
/// in a production environment.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AvocadoCollection.prototype.toArray = function() { AvocadoCollection.prototype.toArray = function() {