mirror of https://gitee.com/bigwinds/arangodb
added temporary attribute entries in shaper
This commit is contained in:
parent
ae53a8c7c9
commit
4ae1f0cd4a
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0. */
|
||||
/* A Bison parser, made by GNU Bison 3.0.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
|
@ -110,14 +110,14 @@ extern int Ahuacatldebug;
|
|||
typedef union YYSTYPE YYSTYPE;
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 26 "arangod/Ahuacatl/ahuacatl-grammar.y" /* yacc.c:1909 */
|
||||
#line 26 "arangod/Ahuacatl/ahuacatl-grammar.y" /* yacc.c:1915 */
|
||||
|
||||
TRI_aql_node_t* node;
|
||||
char* strval;
|
||||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 121 "arangod/Ahuacatl/ahuacatl-grammar.h" /* yacc.c:1909 */
|
||||
#line 121 "arangod/Ahuacatl/ahuacatl-grammar.h" /* yacc.c:1915 */
|
||||
};
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
|
|
@ -179,6 +179,8 @@ typedef enum {
|
|||
TRI_WAL_MARKER_CREATE_DATABASE = 4040,
|
||||
TRI_WAL_MARKER_DROP_DATABASE = 4041,
|
||||
|
||||
TRI_TEMP_MARKER_ATTRIBUTE = 9000,
|
||||
|
||||
TRI_MARKER_MAX // again, this is not a real
|
||||
// marker, but we use it for
|
||||
// bounds checking
|
||||
|
|
|
@ -3507,7 +3507,8 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
TRI_vector_t* pids,
|
||||
TRI_vector_pointer_t* names,
|
||||
bool sorted,
|
||||
bool create) {
|
||||
bool create,
|
||||
bool isTemporary) {
|
||||
pid_name_t* pidnames;
|
||||
|
||||
// .............................................................................
|
||||
|
@ -3527,7 +3528,7 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
pidnames[j]._name = static_cast<char*>(attributes->_buffer[j]);
|
||||
|
||||
if (create) {
|
||||
pidnames[j]._pid = shaper->findOrCreateAttributePathByName(shaper, pidnames[j]._name, true);
|
||||
pidnames[j]._pid = shaper->findOrCreateAttributePathByName(shaper, pidnames[j]._name, true, isTemporary);
|
||||
}
|
||||
else {
|
||||
pidnames[j]._pid = shaper->lookupAttributePathByName(shaper, pidnames[j]._name);
|
||||
|
@ -3568,7 +3569,7 @@ static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
|
||||
TRI_shape_pid_t pid;
|
||||
if (create) {
|
||||
pid = shaper->findOrCreateAttributePathByName(shaper, name, true);
|
||||
pid = shaper->findOrCreateAttributePathByName(shaper, name, true, isTemporary);
|
||||
}
|
||||
else {
|
||||
pid = shaper->lookupAttributePathByName(shaper, name);
|
||||
|
@ -3805,7 +3806,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
shaper = document->getShaper(); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||
|
||||
if (location != NULL) {
|
||||
loc = shaper->findOrCreateAttributePathByName(shaper, location, true);
|
||||
loc = shaper->findOrCreateAttributePathByName(shaper, location, true, true);
|
||||
|
||||
if (loc == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -3814,7 +3815,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
}
|
||||
|
||||
if (latitude != NULL) {
|
||||
lat = shaper->findOrCreateAttributePathByName(shaper, latitude, true);
|
||||
lat = shaper->findOrCreateAttributePathByName(shaper, latitude, true, true);
|
||||
|
||||
if (lat == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -3823,7 +3824,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
}
|
||||
|
||||
if (longitude != NULL) {
|
||||
lon = shaper->findOrCreateAttributePathByName(shaper, longitude, true);
|
||||
lon = shaper->findOrCreateAttributePathByName(shaper, longitude, true, true);
|
||||
|
||||
if (lon == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -4251,6 +4252,7 @@ static TRI_index_t* CreateHashIndexDocumentCollection (TRI_document_collection_t
|
|||
&paths,
|
||||
&fields,
|
||||
true,
|
||||
true,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -4359,7 +4361,8 @@ TRI_index_t* TRI_LookupHashIndexDocumentCollection (TRI_document_collection_t* d
|
|||
&paths,
|
||||
&fields,
|
||||
true,
|
||||
false);
|
||||
false,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return nullptr;
|
||||
|
@ -4444,6 +4447,7 @@ static TRI_index_t* CreateSkiplistIndexDocumentCollection (TRI_document_collecti
|
|||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
true,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -4546,7 +4550,8 @@ TRI_index_t* TRI_LookupSkiplistIndexDocumentCollection (TRI_document_collection_
|
|||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
|
@ -4884,6 +4889,7 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti
|
|||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
true,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -5018,7 +5024,8 @@ TRI_index_t* TRI_LookupBitarrayIndexDocumentCollection (TRI_document_collection_
|
|||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
true);
|
||||
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
|
|
|
@ -1826,7 +1826,7 @@ TRI_index_t* TRI_CreateFulltextIndex (TRI_document_collection_t* document,
|
|||
|
||||
// look up the attribute
|
||||
shaper = document->getShaper(); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||
attribute = shaper->findOrCreateAttributePathByName(shaper, attributeName, true);
|
||||
attribute = shaper->findOrCreateAttributePathByName(shaper, attributeName, true, true);
|
||||
|
||||
if (attribute == 0) {
|
||||
return nullptr;
|
||||
|
|
|
@ -79,14 +79,20 @@ voc_shaper_t;
|
|||
/// @brief extracts an attribute id from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline TRI_shape_aid_t GetAttributeId (void const* marker) {
|
||||
static inline TRI_shape_aid_t GetAttributeId (void const* marker, bool* isTemporary) {
|
||||
TRI_df_marker_t const* p = static_cast<TRI_df_marker_t const*>(marker);
|
||||
|
||||
if (p != nullptr) {
|
||||
if (p->_type == TRI_DF_MARKER_ATTRIBUTE) {
|
||||
*isTemporary = false;
|
||||
return reinterpret_cast<TRI_df_attribute_marker_t const*>(p)->_aid;
|
||||
}
|
||||
else if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
|
||||
*isTemporary = false;
|
||||
return reinterpret_cast<triagens::wal::attribute_marker_t const*>(p)->_attributeId;
|
||||
}
|
||||
else if (p->_type == TRI_TEMP_MARKER_ATTRIBUTE) {
|
||||
*isTemporary = true;
|
||||
return reinterpret_cast<triagens::wal::attribute_marker_t const*>(p)->_attributeId;
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +114,9 @@ static inline char const* GetAttributeName (void const* marker) {
|
|||
else if (p->_type == TRI_WAL_MARKER_ATTRIBUTE) {
|
||||
return reinterpret_cast<char const*>(p) + sizeof(triagens::wal::attribute_marker_t);
|
||||
}
|
||||
else if (p->_type == TRI_TEMP_MARKER_ATTRIBUTE) {
|
||||
return reinterpret_cast<char const*>(p) + sizeof(triagens::wal::attribute_marker_t);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -142,7 +151,7 @@ static bool EqualKeyAttributeName (TRI_associative_synced_t* array, void const*
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds an attribute identifier by name
|
||||
/// @brief looks up an attribute identifier by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t LookupAttributeByName (TRI_shaper_t* shaper,
|
||||
|
@ -153,55 +162,96 @@ static TRI_shape_aid_t LookupAttributeByName (TRI_shaper_t* shaper,
|
|||
void const* p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
||||
|
||||
if (p != nullptr) {
|
||||
return GetAttributeId(p);
|
||||
bool isTemporary;
|
||||
return GetAttributeId(p, &isTemporary);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds an attribute identifier by name
|
||||
/// @brief looks up an attribute identifier by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t LookupAttributeByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool* isTemporary) {
|
||||
TRI_ASSERT(name != nullptr);
|
||||
|
||||
voc_shaper_t* s = reinterpret_cast<voc_shaper_t*>(shaper);
|
||||
void const* p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
||||
|
||||
if (p != nullptr) {
|
||||
return GetAttributeId(p, isTemporary);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds or creates an attribute identifier by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
|
||||
char const* name) {
|
||||
// check if the attribute exists
|
||||
TRI_shape_aid_t aid = LookupAttributeByName(shaper, name);
|
||||
char const* name,
|
||||
bool isTemporary) {
|
||||
voc_shaper_t* s = reinterpret_cast<voc_shaper_t*>(shaper);
|
||||
|
||||
if (aid != 0) {
|
||||
// yes
|
||||
// get a lock for the attributes (TODO: replace assoc sync be normal unordered_map, maybe use RW lock?)
|
||||
MUTEX_LOCKER(s->_attributeLock);
|
||||
|
||||
// check if the attribute exists
|
||||
bool temp;
|
||||
TRI_shape_aid_t aid = LookupAttributeByName(shaper, name, &temp);
|
||||
|
||||
// yes, we found found - check the temporary flag
|
||||
if (aid != 0 && ((temp && isTemporary) || ! temp)) {
|
||||
return aid;
|
||||
}
|
||||
|
||||
// we need to create a new attribute marker
|
||||
// we need to remove the old entries
|
||||
if (temp) {
|
||||
void* old;
|
||||
|
||||
// increase attribute id value
|
||||
voc_shaper_t* s = reinterpret_cast<voc_shaper_t*>(shaper);
|
||||
aid = s->_nextAid++;
|
||||
TRI_ASSERT(aid != 0);
|
||||
|
||||
TRI_document_collection_t* document = s->_collection;
|
||||
old = TRI_RemoveKeyAssociativeSynced(&s->_attributeIds, &aid);
|
||||
TRI_ASSERT(old != nullptr);
|
||||
|
||||
old = TRI_RemoveKeyAssociativeSynced(&s->_attributeNames, name);
|
||||
TRI_ASSERT(old != nullptr);
|
||||
|
||||
if (old != nullptr) {
|
||||
delete[] static_cast<char*>(old);
|
||||
}
|
||||
}
|
||||
|
||||
// increase attribute id value, if we do not already know it
|
||||
if (aid == 0) {
|
||||
aid = s->_nextAid++;
|
||||
}
|
||||
|
||||
// try to create an entry, either temporary or permanently
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
TRI_document_collection_t* document = s->_collection;
|
||||
triagens::wal::AttributeMarker marker(document->_vocbase->_id, document->_info._cid, aid, std::string(name));
|
||||
|
||||
// lock the index and check that the element is still missing
|
||||
{
|
||||
MUTEX_LOCKER(s->_attributeLock);
|
||||
TRI_IF_FAILURE("ShaperWriteAttributeMarker") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
void const* p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
||||
void* ptr;
|
||||
|
||||
// if the element appeared, return the aid
|
||||
if (p != nullptr) {
|
||||
return GetAttributeId(p);
|
||||
}
|
||||
// create a temporary entry
|
||||
if (isTemporary) {
|
||||
marker.setType(TRI_TEMP_MARKER_ATTRIBUTE);
|
||||
ptr = marker.steal();
|
||||
}
|
||||
|
||||
TRI_IF_FAILURE("ShaperWriteAttributeMarker") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
// write marker into wal
|
||||
// create a permanent entry, write marker into wal
|
||||
else {
|
||||
triagens::wal::SlotInfoCopy slotInfo = triagens::wal::LogfileManager::instance()->allocateAndWrite(marker, false);
|
||||
|
||||
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -209,14 +259,16 @@ static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
|
|||
THROW_ARANGO_EXCEPTION(slotInfo.errorCode);
|
||||
}
|
||||
|
||||
void* f TRI_UNUSED = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, const_cast<void*>(slotInfo.mem), false);
|
||||
TRI_ASSERT(f == nullptr);
|
||||
|
||||
// enter into the dictionaries
|
||||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, const_cast<void*>(slotInfo.mem), false);
|
||||
TRI_ASSERT(f == nullptr);
|
||||
ptr = const_cast<void*>(slotInfo.mem);
|
||||
}
|
||||
|
||||
void* f TRI_UNUSED = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, ptr, false);
|
||||
TRI_ASSERT(f == nullptr);
|
||||
|
||||
// enter into the dictionaries
|
||||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, ptr, false);
|
||||
TRI_ASSERT(f == nullptr);
|
||||
|
||||
return aid;
|
||||
}
|
||||
catch (triagens::arango::Exception const& ex) {
|
||||
|
@ -246,7 +298,8 @@ static uint64_t HashKeyAttributeId (TRI_associative_synced_t* array, void const*
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static uint64_t HashElementAttributeId (TRI_associative_synced_t* array, void const* element) {
|
||||
TRI_shape_aid_t aid = GetAttributeId(element);
|
||||
bool isTemporary;
|
||||
TRI_shape_aid_t aid = GetAttributeId(element, &isTemporary);
|
||||
|
||||
return TRI_FnvHashPointer(&aid, sizeof(TRI_shape_aid_t));
|
||||
}
|
||||
|
@ -257,7 +310,8 @@ static uint64_t HashElementAttributeId (TRI_associative_synced_t* array, void co
|
|||
|
||||
static bool EqualKeyAttributeId (TRI_associative_synced_t* array, void const* key, void const* element) {
|
||||
TRI_shape_aid_t const* k = static_cast<TRI_shape_aid_t const*>(key);
|
||||
TRI_shape_aid_t aid = GetAttributeId(element);
|
||||
bool isTemporary;
|
||||
TRI_shape_aid_t aid = GetAttributeId(element, &isTemporary);
|
||||
|
||||
return *k == aid;
|
||||
}
|
||||
|
@ -688,6 +742,7 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s,
|
|||
// remove the old marker
|
||||
// and re-insert the marker with the new pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l, true);
|
||||
|
||||
// note: this assertion is wrong if the recovery collects the shape in the WAL and it has not been transferred
|
||||
// into the collection datafile yet
|
||||
// TRI_ASSERT(f != nullptr);
|
||||
|
@ -698,6 +753,7 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s,
|
|||
// same for the shape dictionary
|
||||
// delete and re-insert
|
||||
f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l, true);
|
||||
|
||||
// note: this assertion is wrong if the recovery collects the shape in the WAL and it has not been transferred
|
||||
// into the collection datafile yet
|
||||
// TRI_ASSERT(f != nullptr);
|
||||
|
@ -716,6 +772,7 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s,
|
|||
// are identical in old and new marker)
|
||||
// and re-insert same attribute with adjusted pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m, true);
|
||||
|
||||
// note: this assertion is wrong if the recovery collects the attribute in the WAL and it has not been transferred
|
||||
// into the collection datafile yet
|
||||
// TRI_ASSERT(f != nullptr);
|
||||
|
@ -726,6 +783,7 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s,
|
|||
// same for attribute ids
|
||||
// delete and re-insert same attribute with adjusted pointer
|
||||
f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m, true);
|
||||
|
||||
// note: this assertion is wrong if the recovery collects the attribute in the WAL and it has not been transferred
|
||||
// into the collection datafile yet
|
||||
// TRI_ASSERT(f != nullptr);
|
||||
|
|
|
@ -186,6 +186,20 @@ AttributeMarker::AttributeMarker (TRI_voc_tick_t databaseId,
|
|||
AttributeMarker::~AttributeMarker () {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief change the type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AttributeMarker::setType (TRI_df_marker_type_t type) {
|
||||
TRI_df_marker_t* m = reinterpret_cast<attribute_marker_t*>(begin());
|
||||
|
||||
m->_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dump marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -365,6 +365,8 @@ namespace triagens {
|
|||
return begin() + sizeof(attribute_marker_t);
|
||||
}
|
||||
|
||||
void setType (TRI_df_marker_type_t);
|
||||
|
||||
void dump () const;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@ AC_CONFIG_AUX_DIR([config])
|
|||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
CURRENT_DIR=`pwd`
|
||||
|
||||
CFLAGS="$CFLAGS $RPM_OPT_FLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $RPM_OPT_FLAGS"
|
||||
|
||||
AC_MSG_NOTICE([configure started in '$CURRENT_DIR])
|
||||
AC_MSG_NOTICE([with CPPFLAGS='$CPPFLAGS'])
|
||||
AC_MSG_NOTICE([with CFLAGS='$CFLAGS'])
|
||||
|
|
|
@ -268,17 +268,21 @@ ArangoCollection.prototype.all = function () {
|
|||
/// Use *toArray* to get all documents at once:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionByExample}
|
||||
/// ~ db._create("users");
|
||||
/// db.users.all().toArray();
|
||||
/// db.users.byExample({ "id" : 323 }).toArray();
|
||||
/// db.users.byExample({ "name" : "Peter" }).toArray();
|
||||
/// db.users.byExample({ "name" : "Peter", "id" : 535 }).toArray();
|
||||
/// ~ db._drop("users");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// Use *next* to loop over all documents:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionByExampleNext}
|
||||
/// ~ db._create("users");
|
||||
/// var a = db.users.byExample( {"name" : "Peter" } );
|
||||
/// while (a.hasNext()) print(a.next());
|
||||
/// ~ db._drop("users");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
|
@ -513,7 +517,9 @@ ArangoCollection.prototype.byConditionBitarray = function (index, condition) {
|
|||
/// Use *toArray* to get all documents at once:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionRange}
|
||||
/// l = db.skip.range("age", 10, 13).toArray();
|
||||
/// ~ db._create("example");
|
||||
/// l = db.example.range("age", 10, 13).toArray();
|
||||
/// ~ db._drop("example")
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
|
@ -693,12 +699,17 @@ ArangoCollection.prototype.geo = function(loc, order) {
|
|||
///
|
||||
/// To get the nearst two locations:
|
||||
///
|
||||
/// @TINYEXAMPLE{simple-query-near,nearest two location}
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionNear}
|
||||
/// db.geo.near(0,0).limit(2).toArray();
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// If you need the distance as well, then you can use the *distance*
|
||||
/// operator:
|
||||
///
|
||||
/// @TINYEXAMPLE{simple-query-near2,nearest two location with distance in meter}
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionNearDistance}
|
||||
/// db.geo.near(0,0).distance().limit(2).toArray();
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -734,7 +745,10 @@ ArangoCollection.prototype.near = function (lat, lon) {
|
|||
///
|
||||
/// To find all documents within a radius of 2000 km use:
|
||||
///
|
||||
/// @TINYEXAMPLE{simple-query-within,within a radius}
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionWithin}
|
||||
/// db.geo.within(0, 0, 2000 * 1000).distance().toArray();
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -750,7 +764,7 @@ ArangoCollection.prototype.within = function (lat, lon, radius) {
|
|||
/// This will find the documents from the collection's fulltext index that match the search
|
||||
/// query.
|
||||
///
|
||||
/// In order to use the @FN{fulltext} operator, a fulltext index must be defined for the
|
||||
/// In order to use the *fulltext* operator, a fulltext index must be defined for the
|
||||
/// collection, for the specified attribute. If multiple fulltext indexes are defined
|
||||
/// for the collection and attribute, the most capable one will be selected.
|
||||
///
|
||||
|
@ -758,7 +772,9 @@ ArangoCollection.prototype.within = function (lat, lon, radius) {
|
|||
///
|
||||
/// To find all documents which contain the terms *text* and *word*:
|
||||
///
|
||||
/// @TINYEXAMPLE{simple-query-fulltext,complete match query}
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{collectionFulltext}
|
||||
/// db.emails.fulltext("text", "word").toArray();
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -909,7 +925,8 @@ ArangoCollection.prototype.iterate = function (iterator, options) {
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{documentsCollectionRemoveByExample}
|
||||
/// ~ db._create("example");
|
||||
/// db.content.removeByExample({ "domain": "de.celler" })
|
||||
/// ~ db.example.save({ Hello : "world" });
|
||||
/// db.example.removeByExample( {Hello : "world"} );
|
||||
/// ~ db._drop("example");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
/// @endDocuBlock
|
||||
|
@ -953,7 +970,8 @@ ArangoCollection.prototype.removeByExample = function (example, waitForSync, lim
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{documentsCollectionReplaceByExample}
|
||||
/// ~ db._create("example");
|
||||
/// db.content.replaceByExample({ "domain": "de.celler" }, { "foo": "someValue }, false, 5)
|
||||
/// ~ db.example.save({ Hello : "world" });
|
||||
/// db.example.replaceByExample({ Hello: "world" }, {Hello: "mars"}, false, 5);
|
||||
/// ~ db._drop("example");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
/// @endDocuBlock
|
||||
|
@ -966,7 +984,7 @@ ArangoCollection.prototype.replaceByExample = function (example, newValue, waitF
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief partially updates documents matching an example
|
||||
/// @startDocuBlock documentsCollectionUpdateByExample
|
||||
/// `collection.updateByExample(example, newValue`
|
||||
/// `collection.updateByExample(example, newValue)`
|
||||
///
|
||||
/// Partially updates all documents matching an example with a new document body.
|
||||
/// Specific attributes in the document body of each document matching the
|
||||
|
@ -1004,10 +1022,11 @@ ArangoCollection.prototype.replaceByExample = function (example, newValue, waitF
|
|||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{documentsCollectionUpdateByExample}
|
||||
/// ~ db._create("example");
|
||||
/// arangod> db.content.updateByExample({ "domain": "de.celler" }, { "foo": "someValue, "domain": null }, false)
|
||||
/// ~ db.example.save({ Hello : "world" });
|
||||
/// db.example.updateByExample({ Hello: "world" }, { Hello: "foo", Hello: "bar" }, false);
|
||||
/// ~ db._drop("example");
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
/// endDocuBlock
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArangoCollection.prototype.updateByExample = function (example, newValue, keepNull, waitForSync, limit) {
|
||||
|
|
|
@ -424,12 +424,15 @@ AQLGenerator.prototype._edges = function(edgeExample, options) {
|
|||
/// `graph_query.edges(examples)`
|
||||
/// *Select all edges for the vertices selected before.*
|
||||
///
|
||||
///
|
||||
/// Creates an AQL statement to select all edges for each of the vertices selected
|
||||
/// in the step before.
|
||||
/// This will include *inbound* as well as *outbound* edges.
|
||||
/// The resulting set of edges can be filtered by defining one or more *examples*.
|
||||
///
|
||||
/// The complexity of this method is **O(n\*m^x)** with *n* being the vertices defined by the
|
||||
/// parameter vertexExamplex, *m* the average amount of edges of a vertex and *x* the maximal depths.
|
||||
/// Hence the default call would have a complexity of **O(n\*m)**;
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *examples*: See [Definition of examples](#definition_of_examples)
|
||||
|
@ -1455,6 +1458,11 @@ var _list = function() {
|
|||
};
|
||||
|
||||
|
||||
var _listObjects = function() {
|
||||
return getGraphCollection().toArray();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1706,6 +1714,7 @@ var _create = function (graphName, edgeDefinitions, orphanCollections) {
|
|||
findOrCreateCollectionByName(oC, ArangoCollection.TYPE_DOCUMENT);
|
||||
}
|
||||
);
|
||||
|
||||
edgeDefinitions.forEach(
|
||||
function(eD, index) {
|
||||
var tmp = sortEdgeDefinition(eD);
|
||||
|
@ -1714,7 +1723,7 @@ var _create = function (graphName, edgeDefinitions, orphanCollections) {
|
|||
);
|
||||
orphanCollections = orphanCollections.sort();
|
||||
|
||||
gdb.save({
|
||||
gdb.save({
|
||||
'orphanCollections' : orphanCollections,
|
||||
'edgeDefinitions' : edgeDefinitions,
|
||||
'_key' : graphName
|
||||
|
@ -2682,6 +2691,9 @@ Graph.prototype._getVertexCollectionByName = function(name) {
|
|||
///
|
||||
/// The function accepts an id, an example, a list of examples or even an empty
|
||||
/// example as parameter for vertexExample.
|
||||
/// The complexity of this method is **O(n\*m^x)** with *n* being the vertices defined by the
|
||||
/// parameter vertexExamplex, *m* the average amount of neighbors and *x* the maximal depths.
|
||||
/// Hence the default call would have a complexity of **O(n\*m)**;
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
|
@ -2739,6 +2751,11 @@ Graph.prototype._neighbors = function(vertexExample, options) {
|
|||
/// and *graph_module._neighbors(vertex2Example, optionsVertex2)*.
|
||||
/// For parameter documentation see [_neighbors](#_neighbors).
|
||||
///
|
||||
/// The complexity of this method is **O(n\*m^x)** with *n* being the maximal amount of vertices
|
||||
/// defined by the parameters vertexExamples, *m* the average amount of neighbors and *x* the
|
||||
/// maximal depths.
|
||||
/// Hence the default call would have a complexity of **O(n\*m)**;
|
||||
///
|
||||
/// *Examples*
|
||||
///
|
||||
/// A route planner example, all common neighbors of capitals.
|
||||
|
@ -2868,6 +2885,9 @@ Graph.prototype._countCommonNeighbors = function(vertex1Example, vertex2Example,
|
|||
/// The function accepts an id, an example, a list of examples or even an empty
|
||||
/// example as parameter for vertex1Example and vertex2Example.
|
||||
///
|
||||
/// The complexity of this method is **O(n)** with *n* being the maximal amount of vertices
|
||||
/// defined by the parameters vertexExamples.
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *vertex1Examples*: Filter the set of source vertices, see [Definition of examples](#definition_of_examples)
|
||||
|
@ -2991,6 +3011,9 @@ Graph.prototype._countCommonProperties = function(vertex1Example, vertex2Example
|
|||
///
|
||||
/// This function determines all available paths in a graph.
|
||||
///
|
||||
/// The complexity of this method is **O(n\*n\*m)** with *n* being the amount of vertices in
|
||||
/// the graph and *m* the average amount of connected edges;
|
||||
///
|
||||
/// *Parameters*
|
||||
///
|
||||
/// * *options* (optional) : An object containing options, see below:
|
||||
|
@ -3060,6 +3083,9 @@ Graph.prototype._paths = function(options) {
|
|||
/// an end vertex. The option weight allows the user to define an edge attribute
|
||||
/// representing the length.
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameters*
|
||||
///
|
||||
/// * *startVertexExample* (optional) : An example for the desired start Vertices
|
||||
|
@ -3203,6 +3229,9 @@ Graph.prototype._distanceTo = function(startVertexExample, endVertexExample, opt
|
|||
/// The function accepts an id, an example, a list of examples or even an empty
|
||||
/// example as parameter for vertexExample.
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *vertexExample*: Filter the vertices, see [Definition of examples](#definition_of_examples)
|
||||
|
@ -3285,6 +3314,9 @@ Graph.prototype._absoluteEccentricity = function(vertexExample, options) {
|
|||
///
|
||||
/// Similar to [_absoluteEccentricity](#_absoluteeccentricity) but returns a normalized result.
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// A route planner example, the eccentricity of all locations.
|
||||
|
@ -3332,6 +3364,9 @@ Graph.prototype._eccentricity = function(options) {
|
|||
/// The function accepts an id, an example, a list of examples or even an empty
|
||||
/// example as parameter for *vertexExample*.
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *vertexExample*: Filter the vertices, see [Definition of examples](#definition_of_examples)
|
||||
|
@ -3412,6 +3447,9 @@ Graph.prototype._absoluteCloseness = function(vertexExample, options) {
|
|||
///
|
||||
/// Similar to [_absoluteCloseness](#_absolutecloseness) but returns a normalized value.
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// A route planner example, the normalized closeness of all locations.
|
||||
|
@ -3467,6 +3505,9 @@ Graph.prototype._closeness = function(options) {
|
|||
/// [betweenness](http://en.wikipedia.org/wiki/Betweenness_centrality)
|
||||
/// *of all vertices in the graph.*
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *options* (optional): An object defining further options. Can have the following values:
|
||||
|
@ -3589,6 +3630,9 @@ Graph.prototype._betweenness = function(options) {
|
|||
/// [radius](http://en.wikipedia.org/wiki/Eccentricity_%28graph_theory%29)
|
||||
/// *of a graph.*
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *options* (optional): An object defining further options. Can have the following values:
|
||||
|
@ -3658,6 +3702,9 @@ Graph.prototype._radius = function(options) {
|
|||
/// [diameter](http://en.wikipedia.org/wiki/Eccentricity_%28graph_theory%29)
|
||||
/// *of a graph.*
|
||||
///
|
||||
/// The complexity of the function is described
|
||||
/// [here](../Aql/GraphOperations.html#the_complexity_of_the_shortest_path_algorithms).
|
||||
///
|
||||
/// *Parameter*
|
||||
///
|
||||
/// * *options* (optional): An object defining further options. Can have the following values:
|
||||
|
@ -4206,6 +4253,7 @@ exports._create = _create;
|
|||
exports._drop = _drop;
|
||||
exports._exists = _exists;
|
||||
exports._list = _list;
|
||||
exports._listObjects = _listObjects;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
|
|
|
@ -314,27 +314,31 @@ SimpleQuery.prototype.clone = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a query
|
||||
/// @startDocuBlock queryExecute
|
||||
/// `query.execute(batchSize)`
|
||||
///
|
||||
/// @FUN{@FA{query}.execute(@FA{batchSize})}
|
||||
/// Executes a simple query. If the optional batchSize value is specified,
|
||||
/// the server will return at most batchSize values in one roundtrip.
|
||||
/// The batchSize cannot be adjusted after the query is first executed.
|
||||
///
|
||||
/// Executes a simple query. If the optional @FA{batchSize} value is specified,
|
||||
/// the server will return at most @FN{batchSize} values in one roundtrip.
|
||||
/// The @FA{batchSize} cannot be adjusted after the query is first executed.
|
||||
///
|
||||
/// Note that there is no need to explicitly call the execute method if another
|
||||
/// **Note**: There is no need to explicitly call the execute method if another
|
||||
/// means of fetching the query results is chosen. The following two approaches
|
||||
/// lead to the same result:
|
||||
/// @code
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{executeQuery}
|
||||
/// result = db.users.all().toArray();
|
||||
/// q = db.users.all(); q.execute(); result = [ ]; while (q.hasNext()) { result.push(q.next()); }
|
||||
/// @endcode
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// The following two alternatives both use a @FA{batchSize} and return the same
|
||||
/// The following two alternatives both use a batchSize and return the same
|
||||
/// result:
|
||||
/// @code
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_OUTPUT{executeQueryBatchSize}
|
||||
/// q = db.users.all(); q.setBatchSize(20); q.execute(); while (q.hasNext()) { print(q.next()); }
|
||||
/// q = db.users.all(); q.execute(20); while (q.hasNext()) { print(q.next()); }
|
||||
/// @endcode
|
||||
/// @END_EXAMPLE_ARANGOSH_OUTPUT
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.execute = function () {
|
||||
|
@ -356,19 +360,21 @@ SimpleQuery.prototype.execute = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief limit
|
||||
/// @startDocuBlock queryLimit
|
||||
/// `query.limit(number)`
|
||||
///
|
||||
/// @FUN{@FA{query}.limit(@FA{number})}
|
||||
///
|
||||
/// Limits a result to the first @FA{number} documents. Specifying a limit of
|
||||
/// @LIT{0} returns no documents at all. If you do not need a limit, just do
|
||||
/// Limits a result to the first *number* documents. Specifying a limit of
|
||||
/// *0* returns no documents at all. If you do not need a limit, just do
|
||||
/// not add the limit operator. The limit must be non-negative.
|
||||
///
|
||||
/// In general the input to @FN{limit} should be sorted. Otherwise it will be
|
||||
/// In general the input to *limit* should be sorted. Otherwise it will be
|
||||
/// unclear which documents are used in the result set.
|
||||
///
|
||||
/// *Examples*
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude simple2
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.limit = function (limit) {
|
||||
|
@ -388,20 +394,22 @@ SimpleQuery.prototype.limit = function (limit) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief skip
|
||||
/// @startDocuBlock queySkip
|
||||
/// `query.skip(number)`
|
||||
///
|
||||
/// @FUN{@FA{query}.skip(@FA{number})}
|
||||
///
|
||||
/// Skips the first @FA{number} documents. If @FA{number} is positive, then skip
|
||||
/// the number of documents. If @FA{number} is negative, then the total amount N
|
||||
/// Skips the first *number* documents. If *number* is positive, then skip
|
||||
/// the number of documents. If *number* is negative, then the total amount N
|
||||
/// of documents must be known and the results starts at position (N +
|
||||
/// @FA{number}).
|
||||
/// *number*).
|
||||
///
|
||||
/// In general the input to @FN{limit} should be sorted. Otherwise it will be
|
||||
/// In general the input to *limit* should be sorted. Otherwise it will be
|
||||
/// unclear which documents are used in the result set.
|
||||
///
|
||||
/// *Examples*
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude simple8
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.skip = function (skip) {
|
||||
|
@ -460,11 +468,12 @@ SimpleQuery.prototype.toArray = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the batch size
|
||||
///
|
||||
/// @FUN{@FA{cursor}.getBatchSize()}
|
||||
/// @startDocuBlock cursorGetBatchSize
|
||||
/// `cursor.getBatchSize()`
|
||||
///
|
||||
/// Returns the batch size for queries. If the returned value is undefined, the
|
||||
/// server will determine a sensible batch size for any following requests.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.getBatchSize = function () {
|
||||
|
@ -473,11 +482,12 @@ SimpleQuery.prototype.getBatchSize = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets the batch size for any following requests
|
||||
///
|
||||
/// @FUN{@FA{cursor}.setBatchSize(@FA{number})}
|
||||
/// @startDocuBlock cursorSetBatchSize
|
||||
/// `cursor.setBatchSize(number)`
|
||||
///
|
||||
/// Sets the batch size for queries. The batch size determines how many results
|
||||
/// are at most transferred from the server to the client in one chunk.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.setBatchSize = function (value) {
|
||||
|
@ -488,27 +498,27 @@ SimpleQuery.prototype.setBatchSize = function (value) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief counts the number of documents
|
||||
/// @startDocuBlock cursorCount
|
||||
/// `cursor.count()`
|
||||
///
|
||||
/// @FUN{@FA{cursor}.count()}
|
||||
///
|
||||
/// The @FN{count} operator counts the number of document in the result set and
|
||||
/// returns that number. The @FN{count} operator ignores any limits and returns
|
||||
/// The *count* operator counts the number of document in the result set and
|
||||
/// returns that number. The *count* operator ignores any limits and returns
|
||||
/// the total number of documents found.
|
||||
///
|
||||
/// @note Not all simple queries support counting. In this case @LIT{null} is
|
||||
/// **Note**: Not all simple queries support counting. In this case *null* is
|
||||
/// returned.
|
||||
///
|
||||
/// @FUN{@FA{cursor}.count(@LIT{true})}
|
||||
/// `cursor.count(true)`
|
||||
///
|
||||
/// If the result set was limited by the @FN{limit} operator or documents were
|
||||
/// skiped using the @FN{skip} operator, the @FN{count} operator with argument
|
||||
/// @LIT{true} will use the number of elements in the final result set - after
|
||||
/// applying @FN{limit} and @FN{skip}.
|
||||
/// If the result set was limited by the *limit* operator or documents were
|
||||
/// skiped using the *skip* operator, the *count* operator with argument
|
||||
/// *true* will use the number of elements in the final result set - after
|
||||
/// applying *limit* and *skip*.
|
||||
///
|
||||
/// @note Not all simple queries support counting. In this case @LIT{null} is
|
||||
/// **Note**: Not all simple queries support counting. In this case *null* is
|
||||
/// returned.
|
||||
///
|
||||
/// *Examples*
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// Ignore any limit:
|
||||
///
|
||||
|
@ -517,6 +527,8 @@ SimpleQuery.prototype.setBatchSize = function (value) {
|
|||
/// Counting any limit or skip:
|
||||
///
|
||||
/// @verbinclude simple10
|
||||
///
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.count = function (applyPagination) {
|
||||
|
@ -531,16 +543,17 @@ SimpleQuery.prototype.count = function (applyPagination) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if the cursor is exhausted
|
||||
/// @startDocuBlock cursorHasNext
|
||||
/// `cursor.hasNext()`
|
||||
///
|
||||
/// @FUN{@FA{cursor}.hasNext()}
|
||||
/// The *hasNext* operator returns *true*, then the cursor still has
|
||||
/// documents. In this case the next document can be accessed using the
|
||||
/// *next* operator, which will advance the cursor.
|
||||
///
|
||||
/// The @FN{hasNext} operator returns @LIT{true}, then the cursor still has
|
||||
/// documents. In this case the next document can be accessed using the
|
||||
/// @FN{next} operator, which will advance the cursor.
|
||||
///
|
||||
/// *Examples*
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude simple7
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.hasNext = function () {
|
||||
|
@ -551,18 +564,19 @@ SimpleQuery.prototype.hasNext = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the next result document
|
||||
/// @startDocuBlock cursorNext
|
||||
/// `cursor.next()`
|
||||
///
|
||||
/// @FUN{@FA{cursor}.next()}
|
||||
///
|
||||
/// If the @FN{hasNext} operator returns @LIT{true}, then the underlying
|
||||
/// If the *hasNext* operator returns *true*, then the underlying
|
||||
/// cursor of the simple query still has documents. In this case the
|
||||
/// next document can be accessed using the @FN{next} operator, which
|
||||
/// will advance the underlying cursor. If you use @FN{next} on an
|
||||
/// exhausted cursor, then @LIT{undefined} is returned.
|
||||
/// next document can be accessed using the *next* operator, which
|
||||
/// will advance the underlying cursor. If you use *next* on an
|
||||
/// exhausted cursor, then *undefined* is returned.
|
||||
///
|
||||
/// *Examples*
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @verbinclude simple5
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.next = function () {
|
||||
|
@ -573,12 +587,13 @@ SimpleQuery.prototype.next = function () {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disposes the result
|
||||
///
|
||||
/// @FUN{@FA{cursor}.dispose()}
|
||||
/// @startDocuBlock cursorDispose
|
||||
/// `cursor.dispose()`
|
||||
///
|
||||
/// If you are no longer interested in any further results, you should call
|
||||
/// @FN{dispose} in order to free any resources associated with the cursor.
|
||||
/// After calling @FN{dispose} you can no longer access the cursor.
|
||||
/// *dispose* in order to free any resources associated with the cursor.
|
||||
/// After calling *dispose* you can no longer access the cursor.
|
||||
/// @endDocuBlock
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SimpleQuery.prototype.dispose = function() {
|
||||
|
|
|
@ -223,6 +223,11 @@ namespace triagens {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static TRI_shape_aid_t FailureFunction (TRI_shaper_t*, char const*, bool) {
|
||||
TRI_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static TRI_shape_t const* FailureFunction (TRI_shaper_t*, TRI_shape_t*, bool) {
|
||||
TRI_ASSERT(false);
|
||||
return 0;
|
||||
|
@ -238,7 +243,7 @@ namespace triagens {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static TRI_shape_pid_t FailureFunction2 (TRI_shaper_t*, char const*, bool) {
|
||||
static TRI_shape_pid_t FailureFunction2 (TRI_shaper_t*, char const*, bool, bool) {
|
||||
TRI_ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ static bool EqualPidKeyAttributePath (TRI_associative_synced_t* array, void cons
|
|||
/// @brief looks up an attribute path by identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_path_t const* LookupPidAttributePath (TRI_shaper_t* shaper, TRI_shape_pid_t pid) {
|
||||
static TRI_shape_path_t const* LookupAttributePathByPid (TRI_shaper_t* shaper, TRI_shape_pid_t pid) {
|
||||
return static_cast<TRI_shape_path_t const*>(TRI_LookupByKeyAssociativeSynced(&shaper->_attributePathsByPid, &pid));
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,8 @@ static bool EqualNameKeyAttributePath (TRI_associative_synced_t* array, void con
|
|||
static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
bool isLocked,
|
||||
bool isTemporary) {
|
||||
TRI_shape_aid_t* aids;
|
||||
TRI_shape_path_t* result;
|
||||
size_t count;
|
||||
|
@ -245,7 +246,7 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
|||
|
||||
if (ptr != prev) {
|
||||
if (create) {
|
||||
aids[count++] = shaper->findOrCreateAttributeByName(shaper, prev);
|
||||
aids[count++] = shaper->findOrCreateAttributeByName(shaper, prev, isTemporary);
|
||||
}
|
||||
else {
|
||||
aids[count] = shaper->lookupAttributeByName(shaper, prev);
|
||||
|
@ -304,8 +305,11 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
|||
|
||||
static TRI_shape_pid_t FindOrCreateAttributePathByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool isLocked) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, true, isLocked);
|
||||
bool isLocked,
|
||||
bool isTemporary) {
|
||||
|
||||
// TODO: is isTemporary always true?
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, true, isLocked, isTemporary);
|
||||
|
||||
return path == nullptr ? 0 : path->_pid;
|
||||
}
|
||||
|
@ -316,7 +320,9 @@ static TRI_shape_pid_t FindOrCreateAttributePathByName (TRI_shaper_t* shaper,
|
|||
|
||||
static TRI_shape_pid_t LookupAttributePathByName (TRI_shaper_t* shaper,
|
||||
char const* name) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, false, true);
|
||||
|
||||
// do not create an unknown attribute (therefore isTemporary will be ignored)
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, false, true, false);
|
||||
|
||||
return path == nullptr ? 0 : path->_pid;
|
||||
}
|
||||
|
@ -385,7 +391,7 @@ int TRI_InitShaper (TRI_shaper_t* shaper, TRI_memory_zone_t* zone) {
|
|||
|
||||
shaper->_nextPid = 1;
|
||||
|
||||
shaper->lookupAttributePathByPid = LookupPidAttributePath;
|
||||
shaper->lookupAttributePathByPid = LookupAttributePathByPid;
|
||||
shaper->findOrCreateAttributePathByName = FindOrCreateAttributePathByName;
|
||||
shaper->lookupAttributePathByName = LookupAttributePathByName;
|
||||
|
||||
|
|
|
@ -92,14 +92,14 @@ TRI_basic_shapes_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_shaper_s {
|
||||
TRI_shape_aid_t (*findOrCreateAttributeByName) (struct TRI_shaper_s*, char const*);
|
||||
TRI_shape_aid_t (*findOrCreateAttributeByName) (struct TRI_shaper_s*, char const*, bool);
|
||||
TRI_shape_aid_t (*lookupAttributeByName) (struct TRI_shaper_s*, char const*);
|
||||
char const* (*lookupAttributeId) (struct TRI_shaper_s*, TRI_shape_aid_t);
|
||||
TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*, bool);
|
||||
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_pid_t (*findOrCreateAttributePathByName) (struct TRI_shaper_s*, char const*, bool);
|
||||
TRI_shape_pid_t (*findOrCreateAttributePathByName) (struct TRI_shaper_s*, char const*, bool, bool);
|
||||
TRI_shape_pid_t (*lookupAttributePathByName) (struct TRI_shaper_s*, char const*);
|
||||
|
||||
TRI_associative_synced_t _attributePathsByName;
|
||||
|
|
|
@ -834,7 +834,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
// first find an identifier for the name
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, key->_value._string.data);
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, key->_value._string.data, false);
|
||||
|
||||
// convert value
|
||||
if (p->_aid == 0) {
|
||||
|
|
|
@ -634,7 +634,7 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
if (create) {
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, *keyStr);
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, *keyStr, false);
|
||||
}
|
||||
else {
|
||||
p->_aid = shaper->lookupAttributeByName(shaper, *keyStr);
|
||||
|
|
|
@ -136,6 +136,7 @@ AM_PROG_CC_C_O
|
|||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AX_CXX_COMPILE_STDCXX_11(noext, mandatory)
|
||||
|
||||
AC_ARG_ENABLE(error-on-warning,
|
||||
|
|
Loading…
Reference in New Issue