diff --git a/arangod/VocBase/document-collection.c b/arangod/VocBase/document-collection.c index 0560eae219..bd2f84ef2e 100644 --- a/arangod/VocBase/document-collection.c +++ b/arangod/VocBase/document-collection.c @@ -4079,7 +4079,7 @@ bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document, #ifdef TRI_ENABLE_REPLICATION vocbase = primary->base._vocbase; - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif @@ -4118,7 +4118,7 @@ bool TRI_DropIndexDocumentCollection (TRI_document_collection_t* document, TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(primary); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif // ............................................................................. @@ -4404,7 +4404,7 @@ TRI_index_t* TRI_EnsureCapConstraintDocumentCollection (TRI_document_collection_ // ............................................................................. #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif TRI_WRITE_LOCK_DOCUMENTS_INDEXES_PRIMARY_COLLECTION(primary); @@ -4430,7 +4430,7 @@ TRI_index_t* TRI_EnsureCapConstraintDocumentCollection (TRI_document_collection_ } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -4821,7 +4821,7 @@ TRI_index_t* TRI_EnsureGeoIndex1DocumentCollection (TRI_document_collection_t* d primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -4851,7 +4851,7 @@ TRI_index_t* TRI_EnsureGeoIndex1DocumentCollection (TRI_document_collection_t* d } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -4873,7 +4873,7 @@ TRI_index_t* TRI_EnsureGeoIndex2DocumentCollection (TRI_document_collection_t* d primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -4903,7 +4903,7 @@ TRI_index_t* TRI_EnsureGeoIndex2DocumentCollection (TRI_document_collection_t* d } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -5109,7 +5109,7 @@ TRI_index_t* TRI_EnsureHashIndexDocumentCollection (TRI_document_collection_t* d primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -5140,7 +5140,7 @@ TRI_index_t* TRI_EnsureHashIndexDocumentCollection (TRI_document_collection_t* d } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -5338,7 +5338,7 @@ TRI_index_t* TRI_EnsureSkiplistIndexDocumentCollection (TRI_document_collection_ primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -5368,7 +5368,7 @@ TRI_index_t* TRI_EnsureSkiplistIndexDocumentCollection (TRI_document_collection_ } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -5634,7 +5634,7 @@ TRI_index_t* TRI_EnsureFulltextIndexDocumentCollection (TRI_document_collection_ primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -5664,7 +5664,7 @@ TRI_index_t* TRI_EnsureFulltextIndexDocumentCollection (TRI_document_collection_ } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -5902,7 +5902,7 @@ TRI_index_t* TRI_EnsurePriorityQueueIndexDocumentCollection(TRI_document_collect primary = &document->base; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -5933,7 +5933,7 @@ TRI_index_t* TRI_EnsurePriorityQueueIndexDocumentCollection(TRI_document_collect } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif return idx; @@ -6200,7 +6200,7 @@ TRI_index_t* TRI_EnsureBitarrayIndexDocumentCollection (TRI_document_collection_ *errorStr = NULL; #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. @@ -6242,7 +6242,7 @@ TRI_index_t* TRI_EnsureBitarrayIndexDocumentCollection (TRI_document_collection_ } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&primary->base._vocbase->_inventoryLock); #endif // ............................................................................. diff --git a/arangod/VocBase/vocbase.c b/arangod/VocBase/vocbase.c index e526ca91a0..558d860d59 100644 --- a/arangod/VocBase/vocbase.c +++ b/arangod/VocBase/vocbase.c @@ -1557,7 +1557,7 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path, #ifdef TRI_ENABLE_REPLICATION - TRI_InitReadWriteLock(&vocbase->_objectLock); + TRI_InitReadWriteLock(&vocbase->_inventoryLock); #endif TRI_InitReadWriteLock(&vocbase->_authInfoLock); @@ -1804,7 +1804,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase) { // destroy locks #ifdef TRI_ENABLE_REPLICATION - TRI_DestroyReadWriteLock(&vocbase->_objectLock); + TRI_DestroyReadWriteLock(&vocbase->_inventoryLock); #endif TRI_DestroyReadWriteLock(&vocbase->_authInfoLock); TRI_DestroyReadWriteLock(&vocbase->_lock); @@ -1898,7 +1898,7 @@ TRI_json_t* TRI_InventoryCollectionsVocBase (TRI_vocbase_t* vocbase, TRI_InitVectorPointer(&collections, TRI_CORE_MEM_ZONE); #ifdef TRI_ENABLE_REPLICATION - TRI_WriteLockReadWriteLock(&vocbase->_objectLock); + TRI_WriteLockReadWriteLock(&vocbase->_inventoryLock); #endif // copy collection pointers into vector so we can work with the copy without @@ -1965,7 +1965,7 @@ TRI_json_t* TRI_InventoryCollectionsVocBase (TRI_vocbase_t* vocbase, } #ifdef TRI_ENABLE_REPLICATION - TRI_WriteUnlockReadWriteLock(&vocbase->_objectLock); + TRI_WriteUnlockReadWriteLock(&vocbase->_inventoryLock); #endif TRI_DestroyVectorPointer(&collections); @@ -2116,7 +2116,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase); @@ -2131,7 +2131,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif LOG_DEBUG("collection named '%s' already exists", name); @@ -2150,7 +2150,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return NULL; @@ -2176,7 +2176,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return NULL; @@ -2194,7 +2194,7 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif #ifdef TRI_ENABLE_REPLICATION @@ -2284,7 +2284,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, } #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif // mark collection as deleted @@ -2300,7 +2300,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return TRI_ERROR_NO_ERROR; @@ -2320,7 +2320,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return TRI_set_errno(res); } @@ -2345,7 +2345,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return TRI_set_errno(res); } @@ -2360,7 +2360,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, DropCollectionCallback(0, collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return TRI_ERROR_NO_ERROR; @@ -2379,7 +2379,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif return res; @@ -2391,7 +2391,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif // added callback for dropping @@ -2416,7 +2416,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase, TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif LOG_WARNING("internal error in TRI_DropCollectionVocBase"); @@ -2534,13 +2534,13 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_CopyString(info._name, newName, sizeof(info._name)); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif res = TRI_SaveCollectionInfo(collection->_path, &info, vocbase->_forceSyncProperties); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif TRI_FreeCollectionInfoOptions(&info); @@ -2561,13 +2561,13 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, else if (collection->_status == TRI_VOC_COL_STATUS_LOADED || collection->_status == TRI_VOC_COL_STATUS_UNLOADING) { #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif res = TRI_RenameCollection(&collection->_collection->base, newName); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif if (res != TRI_ERROR_NO_ERROR) { @@ -2598,7 +2598,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, // ............................................................................. #ifdef TRI_ENABLE_REPLICATION - TRI_ReadLockReadWriteLock(&vocbase->_objectLock); + TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock); #endif TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName); @@ -2608,7 +2608,7 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, CONST_CAST(collection), false); #ifdef TRI_ENABLE_REPLICATION - TRI_ReadUnlockReadWriteLock(&vocbase->_objectLock); + TRI_ReadUnlockReadWriteLock(&vocbase->_inventoryLock); #endif TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase); diff --git a/arangod/VocBase/vocbase.h b/arangod/VocBase/vocbase.h index 73490af87a..5d8a123574 100644 --- a/arangod/VocBase/vocbase.h +++ b/arangod/VocBase/vocbase.h @@ -353,7 +353,7 @@ typedef struct TRI_vocbase_s { TRI_associative_pointer_t _collectionsById; // collections by id #ifdef TRI_ENABLE_REPLICATION - TRI_read_write_lock_t _objectLock; // object lock needed when replication is assessing the state of the vocbase + TRI_read_write_lock_t _inventoryLock; // object lock needed when replication is assessing the state of the vocbase #endif TRI_associative_pointer_t _authInfo; diff --git a/html/admin/js/modules/org/arangodb/arango-collection.js b/html/admin/js/modules/org/arangodb/arango-collection.js index 9c9392162b..6f83101f9d 100644 --- a/html/admin/js/modules/org/arangodb/arango-collection.js +++ b/html/admin/js/modules/org/arangodb/arango-collection.js @@ -256,7 +256,10 @@ var helpArangoCollection = arangosh.createHelpHeadline("ArangoCollection help") ' ) ' + "\n" + ' update(, , partially update document ' + "\n" + ' , ) ' + "\n" + - ' delete() delete document ' + "\n" + + ' remove() delete document ' + "\n" + + ' exists() checks whether a document exists ' + "\n" + + ' first() get first inserted/update document' + "\n" + + ' last() get last inserted/update document ' + "\n" + ' ' + "\n" + 'Attributes: ' + "\n" + ' _database database object ' + "\n" + @@ -919,7 +922,7 @@ ArangoCollection.prototype.exists = function (id) { arangosh.checkRequestResult(requestResult); - return requestResult; + return true; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/html/admin/js/modules/org/arangodb/arango-database.js b/html/admin/js/modules/org/arangodb/arango-database.js index fe81dba588..1d95addc3f 100644 --- a/html/admin/js/modules/org/arangodb/arango-database.js +++ b/html/admin/js/modules/org/arangodb/arango-database.js @@ -211,6 +211,7 @@ var helpArangoDatabase = arangosh.createHelpHeadline("ArangoDatabase help") + ' ' + "\n" + 'Administration Functions: ' + "\n" + ' _help(); this help ' + "\n" + + ' _flushCache(); flush and refill collection cache' + "\n" + ' ' + "\n" + 'Collection Functions: ' + "\n" + ' _collections() list all collections ' + "\n" + @@ -225,9 +226,11 @@ var helpArangoDatabase = arangosh.createHelpHeadline("ArangoDatabase help") + ' _update(, , update document ' + "\n" + ' , ) ' + "\n" + ' _remove() delete document ' + "\n" + + ' _exists() checks whether a document exists ' + "\n" + ' _truncate() delete all documents ' + "\n" + ' ' + "\n" + - 'Query Functions: ' + "\n" + + 'Query / Transaction Functions: ' + "\n" + + ' _executeTransaction(); execute transaction ' + "\n" + ' _query(); execute AQL query ' + "\n" + ' _createStatement(); create and return AQL query '; @@ -616,7 +619,7 @@ ArangoDatabase.prototype._exists = function (id) { arangosh.checkRequestResult(requestResult); - return requestResult; + return true; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/js/client/modules/org/arangodb/arango-collection.js b/js/client/modules/org/arangodb/arango-collection.js index 3cda0946f2..37de169476 100644 --- a/js/client/modules/org/arangodb/arango-collection.js +++ b/js/client/modules/org/arangodb/arango-collection.js @@ -255,7 +255,10 @@ var helpArangoCollection = arangosh.createHelpHeadline("ArangoCollection help") ' ) ' + "\n" + ' update(, , partially update document ' + "\n" + ' , ) ' + "\n" + - ' delete() delete document ' + "\n" + + ' remove() delete document ' + "\n" + + ' exists() checks whether a document exists ' + "\n" + + ' first() get first inserted/update document' + "\n" + + ' last() get last inserted/update document ' + "\n" + ' ' + "\n" + 'Attributes: ' + "\n" + ' _database database object ' + "\n" + @@ -918,7 +921,7 @@ ArangoCollection.prototype.exists = function (id) { arangosh.checkRequestResult(requestResult); - return requestResult; + return true; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/js/client/modules/org/arangodb/arango-database.js b/js/client/modules/org/arangodb/arango-database.js index f131a83630..83f12f2f11 100644 --- a/js/client/modules/org/arangodb/arango-database.js +++ b/js/client/modules/org/arangodb/arango-database.js @@ -210,6 +210,7 @@ var helpArangoDatabase = arangosh.createHelpHeadline("ArangoDatabase help") + ' ' + "\n" + 'Administration Functions: ' + "\n" + ' _help(); this help ' + "\n" + + ' _flushCache(); flush and refill collection cache' + "\n" + ' ' + "\n" + 'Collection Functions: ' + "\n" + ' _collections() list all collections ' + "\n" + @@ -224,9 +225,11 @@ var helpArangoDatabase = arangosh.createHelpHeadline("ArangoDatabase help") + ' _update(, , update document ' + "\n" + ' , ) ' + "\n" + ' _remove() delete document ' + "\n" + + ' _exists() checks whether a document exists ' + "\n" + ' _truncate() delete all documents ' + "\n" + ' ' + "\n" + - 'Query Functions: ' + "\n" + + 'Query / Transaction Functions: ' + "\n" + + ' _executeTransaction(); execute transaction ' + "\n" + ' _query(); execute AQL query ' + "\n" + ' _createStatement(); create and return AQL query '; @@ -615,7 +618,7 @@ ArangoDatabase.prototype._exists = function (id) { arangosh.checkRequestResult(requestResult); - return requestResult; + return true; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index 2638b7a7f6..86f901543b 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -642,6 +642,10 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { part = ''; } + // ............................................................................. + // exact match + // ............................................................................. + if (typeof part === "string") { if (! subwhere.hasOwnProperty('exact')) { subwhere.exact = {}; @@ -657,21 +661,22 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { defineRoutePart(route, subpart, parts, pos + 1, constraint, callback); } else { - if (subpart.hasOwnProperty('route')) { - p1 = subpart.route.priority || 0; - p2 = route.priority || 0; + if (! subpart.hasOwnProperty('routes')) { + subpart.routes = []; + } - if (p1 <= p2) { - subpart.route = route; - subpart.callback = callback; - } - } - else { - subpart.route = route; - subpart.callback = callback; - } + subpart.routes.push({ + priority: route.priority || 0, + route: route, + callback: callback + }); } } + + // ............................................................................. + // parameter match + // ............................................................................. + else if (part.hasOwnProperty('parameters')) { if (! subwhere.hasOwnProperty('parameters')) { subwhere.parameters = []; @@ -693,7 +698,7 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { if (ok) { for (i = 0; i < part.parameters.length; ++i) { p = part.parameters[i]; - subsub = { parameter: p, match: {}}; + subsub = { parameter: p, match: {} }; subwhere.parameters.push(subsub); if (constraint.hasOwnProperty(p)) { @@ -706,15 +711,27 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { defineRoutePart(route, subsub.match, parts, pos + 1, constraint, callback); } else { - subsub.match.route = route; - subsub.match.callback = callback; + if (! subsub.match.hasOwnProperty('routes')) { + subsub.match.routes = []; + } + + subsub.match.routes.push({ + priority: route.priority || 0, + route: route, + callback: callback + }); } } } } + + // ............................................................................. + // prefix match + // ............................................................................. + else if (part.hasOwnProperty('prefix')) { if (! subwhere.hasOwnProperty('prefix')) { - subwhere.prefix = {}; + subwhere.prefix = []; } var subprefix = subwhere.prefix; @@ -723,19 +740,11 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { console.error("cannot define prefix match within url, ignoring route"); } else { - if (subprefix.hasOwnProperty('route')) { - p1 = subprefix.route.priority || 0; - p2 = route.priority || 0; - - if (p1 <= p2) { - subprefix.route = route; - subprefix.callback = callback; - } - } - else { - subprefix.route = route; - subprefix.callback = callback; - } + subprefix.push({ + priority: route.priority || 0, + route: route, + callback: callback + }); } } } @@ -776,7 +785,10 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { var match; var result = []; - // start with exact matches + // ............................................................................. + // descend down to the next exact matches + // ............................................................................. + if (routes.hasOwnProperty('exact')) { for (k in routes.exact) { if (routes.exact.hasOwnProperty(k)) { @@ -792,7 +804,10 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { } } - // next are parameter matches + // ............................................................................. + // descend down the parameter matches + // ............................................................................. + if (routes.hasOwnProperty('parameters')) { for (i = 0; i < routes.parameters.length; ++i) { parameter = routes.parameters[i]; @@ -830,32 +845,41 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { } } - // next use the current callback - if (routes.hasOwnProperty('callback')) { - result = result.concat([{ + // ............................................................................. + // we have done the depth first descend, now add the current callback(s) + // ............................................................................. + + if (routes.hasOwnProperty('routes')) { + var sorted = routes.routes.sort(function(a,b) { + return b.priority - a.priority; + }); + + for (i = 0; i < sorted.length; ++i) { + sorted[i] = { path: path, regexp: new RegExp("^" + path + "$"), prefix: prefix, depth: depth, urlParameters: urlParameters, - callback: routes.callback, - route: routes.route - }]); + callback: sorted[i].callback, + route: sorted[i].route + }; + } + + result = result.concat(sorted); } - // finally use a prefix match + // ............................................................................. + // finally append the prefix matches + // ............................................................................. + if (routes.hasOwnProperty('prefix')) { - if (! routes.prefix.hasOwnProperty('callback')) { - console.error("prefix match must specify a callback"); - } - else { - cur = path + "(/[^/]+)*"; - result = result.concat(flattenRouting(routes.prefix, - cur, - urlParameters._shallowCopy, - depth + 1, - true)); - } + cur = path + "(/[^/]+)*"; + result = result.concat(flattenRouting(routes.prefix, + cur, + urlParameters._shallowCopy, + depth + 1, + true)); } return result; diff --git a/js/server/modules/org/arangodb/foxx-manager.js b/js/server/modules/org/arangodb/foxx-manager.js index 3ff9943f05..170104decb 100644 --- a/js/server/modules/org/arangodb/foxx-manager.js +++ b/js/server/modules/org/arangodb/foxx-manager.js @@ -258,7 +258,8 @@ function executeAppScript (app, name, mount, prefix) { appModule: app.createAppModule(), isDevelopment: devel, isProduction: ! devel, - options: app._options + options: app._options, + basePath: fs.join(root, app._path) }; var cp = appContext.collectionPrefix; @@ -472,9 +473,14 @@ function routingAalApp (app, mount, options) { if (apps.hasOwnProperty(i)) { var file = apps[i]; var devel = false; + var root; if (app._id.substr(0,4) === "dev:") { devel = true; + root = module.devAppPath(); + } + else { + root = module.appPath(); } // set up a context for the application start function @@ -487,6 +493,7 @@ function routingAalApp (app, mount, options) { collectionPrefix: prefix, // collection prefix appModule: app.createAppModule(), // app module options: options, + basePath: fs.join(root, app._path), isDevelopment: devel, isProduction: ! devel, diff --git a/js/server/modules/org/arangodb/foxx.js b/js/server/modules/org/arangodb/foxx.js index 4b9558b6be..6132e5d127 100644 --- a/js/server/modules/org/arangodb/foxx.js +++ b/js/server/modules/org/arangodb/foxx.js @@ -125,8 +125,6 @@ Application = function (context, options) { } } - this.isDevelopment = context.isDevelopment; - this.isProduction = context.isProduction; this.helperCollection = {}; this.routingInfo.urlPrefix = urlPrefix; @@ -144,16 +142,14 @@ Application = function (context, options) { action: { callback: myMiddleware.stringRepresentation, options: { + name: context.name, + version: context.version, + appId: context.appId, + mount: context.mount, isDevelopment: context.isDevelopment, isProduction: context.isProduction, - app: { - appId: context.appId, - name: context.name, - version: context.version, - mount: context.mount, - prefix: context.prefix, - options: context.options - } + prefix: context.prefix, + options: context.options } } } @@ -409,7 +405,7 @@ _.extend(Application.prototype, { this.routingInfo.middleware.push({ url: {match: path}, action: { - callback: "function (req, res, opts, next) { " + String(func) + "(req, res); next(); }" + callback: function (req, res, opts, next) { func(req, res, opts); next(); } } }); }, @@ -442,7 +438,7 @@ _.extend(Application.prototype, { this.routingInfo.middleware.push({ url: {match: path}, action: { - callback: "function (req, res, opts, next) { next(); " + String(func) + "(req, res); }" + callback: function (req, res, opts, next) { next(); func(req, res, opts); } } }); }, @@ -855,35 +851,34 @@ BaseMiddleware = function (templateCollection, helperCollection) { }; var trace = options.isDevelopment; - if (!trace && options.hasOwnProperty("app") && options.app.hasOwnProperty("options")) { - trace = options.app.options.trace; + if (!trace && options.hasOwnProperty("options")) { + trace = options.options.trace; } - if (trace) { console.log("%s, incoming request from %s: %s", - options.app.mount, + options.mount, request.client.address, actions.stringifyRequestAddress(request)); } - request = _.extend(request, requestFunctions); - response = _.extend(response, responseFunctions); + _.extend(request, requestFunctions); + _.extend(response, responseFunctions); next(); if (trace) { if (response.hasOwnProperty("body")) { console.log("%s, outgoing response of type %s, body length: %d", - options.app.mount, + options.mount, response.contentType, parseInt(response.body.length, 10)); } else if (response.hasOwnProperty("bodyFromFile")) { console.log("%s, outgoing response of type %s, body file: %s", - options.app.mount, + options.mount, response.contentType, response.bodyFromFile); } else { console.log("%s, outgoing response of type %s, no body", - options.app.mount, + options.mount, response.contentType); } }