1
0
Fork 0

some transaction rework

This commit is contained in:
Jan Steemann 2013-01-08 17:26:16 +01:00
parent 992c49d4a1
commit 187d8ecc69
22 changed files with 638 additions and 436 deletions

View File

@ -58,7 +58,7 @@ describe ArangoDB do
# create collection with one document
@cid = ArangoDB.create_collection(cn)
cmd = "/_api/document?collection=#{@cid}"
cmd = "/_api/document?collection=#{cn}"
body = "{ \"Hello\" : \"World\" }"
doc = ArangoDB.log_post("#{prefix}", cmd, :body => body)

View File

@ -280,7 +280,7 @@ bool RestDocumentHandler::createDocument () {
}
// find and load collection given by name or identifier
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), create);
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, create, getCollectionType());
// .............................................................................
// inside write transaction
@ -402,7 +402,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
string key = suffix[1];
// find and load collection given by name or identifier
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, getCollectionType());
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection);
// .............................................................................
// inside read transaction
@ -486,7 +486,7 @@ bool RestDocumentHandler::readAllDocuments () {
string collection = _request->value("collection", found);
// find and load collection given by name or identifier
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, getCollectionType());
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection);
vector<string> ids;
@ -757,7 +757,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
TRI_doc_update_policy_e policy = extractUpdatePolicy();
// find and load collection given by name or identifier
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), false);
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection);
TRI_doc_mptr_t* document = 0;
TRI_voc_rid_t rid = 0;
@ -918,7 +918,7 @@ bool RestDocumentHandler::deleteDocument () {
}
// find and load collection given by name or identifier
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), false);
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection);
TRI_voc_rid_t rid = 0;
// .............................................................................

View File

@ -163,7 +163,7 @@ bool RestEdgeHandler::createDocument () {
}
// find and load collection given by name or identifier
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, getCollectionType(), create);
SelfContainedWriteTransaction<RestTransactionContext> trx(_vocbase, collection, create, getCollectionType());
// .............................................................................
// inside write transaction

View File

@ -205,7 +205,7 @@ bool RestImportHandler::createByDocumentsLines () {
bool create = found ? StringUtils::boolean(valueStr) : false;
// find and load collection given by name or identifier
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
// .............................................................................
// inside write transaction
@ -350,7 +350,7 @@ bool RestImportHandler::createByDocumentsList () {
bool create = found ? StringUtils::boolean(valueStr) : false;
// find and load collection given by name or identifier
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
// .............................................................................
// inside write transaction
@ -498,7 +498,7 @@ bool RestImportHandler::createByKeyValueList () {
}
// find and load collection given by name or identifier
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
ImportTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, collection, create, TRI_COL_TYPE_DOCUMENT);
// .............................................................................
// inside write transaction

View File

@ -953,7 +953,7 @@ mrb_value MR_ArangoDatabase_Collection (mrb_state* mrb, mrb_value self) {
// looking at "mruby.h" I assume that is the way to unwrap the pointer
rdata = (struct RData*) mrb_object(self);
vocbase = (TRI_vocbase_t*) rdata->data;
collection = TRI_FindCollectionByNameVocBase(vocbase, name, false);
collection = TRI_LookupCollectionByNameVocBase(vocbase, name);
if (collection == NULL) {
printf("unknown collection (TODO raise error)\n");

View File

@ -64,7 +64,7 @@ namespace triagens {
if (_trx != 0) {
if (_trx->_status == TRI_TRANSACTION_RUNNING) {
// auto abort
abort();
this->abort();
}
TRI_FreeTransaction(_trx);

View File

@ -62,10 +62,10 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
ImportTransaction (TRI_vocbase_t* const vocbase,
const string& collectionName,
const TRI_col_type_e collectionType,
const bool createCollection) :
SingleCollectionWriteTransaction<T, UINT64_MAX>(vocbase, collectionName, collectionType, createCollection, "ImportTransaction") {
const string& name,
const bool create,
const TRI_col_type_e createType) :
SingleCollectionWriteTransaction<T, UINT64_MAX>(vocbase, name, create, createType) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -64,10 +64,35 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
const string& collectionName,
const TRI_col_type_e collectionType,
const bool createCollection) :
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, collectionName, collectionType, createCollection, "SelfContainedWriteTransaction") {
const string& name) :
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction, using a collection object
///
/// A self contained write transaction operates on a single collection and may
/// execute at most one write operation
////////////////////////////////////////////////////////////////////////////////
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const TRI_col_type_e createType) :
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name, createType) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction, using a collection object
///
/// A self contained write transaction operates on a single collection and may
/// execute at most one write operation
////////////////////////////////////////////////////////////////////////////////
SelfContainedWriteTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const bool create,
const TRI_col_type_e createType) :
SingleCollectionWriteTransaction<StandaloneTransaction<C>, 1>(vocbase, name, create, createType) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -62,9 +62,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
SingleCollectionReadOnlyTransaction (TRI_vocbase_t* const vocbase,
const string& collectionName,
const TRI_col_type_e collectionType) :
SingleCollectionTransaction<T>(vocbase, collectionName, collectionType, false, "SingleCollectionReadOnlyTransaction", TRI_TRANSACTION_READ) {
const string& name) :
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_READ) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -71,16 +71,29 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
const string& collectionName,
const TRI_col_type_e collectionType,
const bool createCollection,
const string& trxName,
const TRI_transaction_type_e type) :
Transaction<T>(vocbase, trxName),
_collectionName(collectionName),
_collectionType(collectionType),
_createCollection(createCollection),
_type(type),
const string& name,
const TRI_transaction_type_e accessType) :
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType)),
_name(name),
_collection(0) {
}
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const TRI_transaction_type_e accessType,
const TRI_col_type_e createType) :
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType, createType)),
_name(name),
_collection(0) {
}
SingleCollectionTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const TRI_transaction_type_e accessType,
const bool create,
const TRI_col_type_e createType) :
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, name, accessType, create, createType)),
_name(name),
_collection(0) {
}
@ -89,103 +102,6 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
virtual ~SingleCollectionTransaction () {
if (! this->isEmbedded()) {
if (this->_trx != 0) {
if (this->status() == TRI_TRANSACTION_RUNNING) {
// auto abort
this->abort();
}
}
releaseCollection();
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief use the underlying collection
////////////////////////////////////////////////////////////////////////////////
int useCollections () {
if (_collection != 0) {
// we already used this collectino, nothing to do
return TRI_ERROR_NO_ERROR;
}
if (_collectionName.empty()) {
// name is empty. cannot open the collection
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
// open or create the collection
if (isdigit(_collectionName[0])) {
TRI_voc_cid_t id = triagens::basics::StringUtils::uint64(_collectionName);
_collection = TRI_LookupCollectionByIdVocBase(this->_vocbase, id);
}
else {
if (_collectionType == TRI_COL_TYPE_DOCUMENT) {
_collection = TRI_FindDocumentCollectionByNameVocBase(this->_vocbase, _collectionName.c_str(), _createCollection);
}
else if (_collectionType == TRI_COL_TYPE_EDGE) {
_collection = TRI_FindEdgeCollectionByNameVocBase(this->_vocbase, _collectionName.c_str(), _createCollection);
}
}
if (_collection == 0) {
// collection not found
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
int res = TRI_UseCollectionVocBase(this->_vocbase, const_cast<TRI_vocbase_col_s*>(_collection));
if (res != TRI_ERROR_NO_ERROR) {
_collection = 0;
return res;
}
LOGGER_TRACE << "using collection " << _collectionName;
assert(_collection->_collection != 0);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add all collections to the transaction (only one)
////////////////////////////////////////////////////////////////////////////////
int addCollections () {
if (this->isEmbedded()) {
assert(_collection == 0);
_collection = TRI_CheckCollectionTransaction(this->_trx, _collectionName.c_str(), type());
if (_collection == 0) {
return TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
}
return TRI_ERROR_NO_ERROR;
}
else {
assert(_collection != 0);
int res = TRI_AddCollectionTransaction(this->_trx, _collectionName.c_str(), type(), _collection);
return res;
}
}
////////////////////////////////////////////////////////////////////////////////
@ -207,8 +123,8 @@ namespace triagens {
/// @brief return the name of the underlying collection
////////////////////////////////////////////////////////////////////////////////
inline string collectionName () {
return _collectionName;
const string collectionName () const {
return _name;
}
////////////////////////////////////////////////////////////////////////////////
@ -216,6 +132,12 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
inline TRI_primary_collection_t* primaryCollection () {
if (_collection == 0) {
const vector<TransactionCollection*> collections = this->_collections->getCollections();
_collection = TRI_GetCollectionTransaction(this->_trx, collections[0]->getName().c_str());
}
assert(_collection != 0);
assert(_collection->_collection != 0);
return _collection->_collection;
}
@ -240,7 +162,11 @@ namespace triagens {
/// @brief get the underlying collection's id
////////////////////////////////////////////////////////////////////////////////
inline TRI_voc_cid_t cid () const {
inline TRI_voc_cid_t cid () {
if (_collection == 0) {
_collection = TRI_GetCollectionTransaction(this->_trx, this->collectionName().c_str());
}
assert(_collection != 0);
return _collection->_cid;
}
@ -283,43 +209,6 @@ namespace triagens {
/// @}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief release the underlying collection
////////////////////////////////////////////////////////////////////////////////
int releaseCollection () {
// unuse underlying collection
if (_collection != 0) {
TRI_ReleaseCollectionVocBase(this->_vocbase, _collection);
_collection = 0;
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the transaction type
////////////////////////////////////////////////////////////////////////////////
inline TRI_transaction_type_e type () const {
return _type;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
@ -332,28 +221,10 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief name of the collection that is worked on
/// @brief name of the collection used
////////////////////////////////////////////////////////////////////////////////
const string _collectionName;
////////////////////////////////////////////////////////////////////////////////
/// @brief the type of the collection
////////////////////////////////////////////////////////////////////////////////
const TRI_col_type_e _collectionType;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not to create the collection
////////////////////////////////////////////////////////////////////////////////
const bool _createCollection;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction type (READ | WRITE)
////////////////////////////////////////////////////////////////////////////////
const TRI_transaction_type_e _type;
string _name;
////////////////////////////////////////////////////////////////////////////////
/// @brief data structure for the single collection used

View File

@ -70,11 +70,33 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
const string& collectionName,
const TRI_col_type_e collectionType,
const bool createCollection,
const string& trxName) :
SingleCollectionTransaction<T>(vocbase, collectionName, collectionType, createCollection, trxName, TRI_TRANSACTION_WRITE),
const string& name) :
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE),
_numWrites(0),
_synchronous(false) {
if (N == 1) {
this->addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION);
}
}
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const TRI_col_type_e createType) :
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE, createType),
_numWrites(0),
_synchronous(false) {
if (N == 1) {
this->addHint(TRI_TRANSACTION_HINT_SINGLE_OPERATION);
}
}
SingleCollectionWriteTransaction (TRI_vocbase_t* const vocbase,
const string& name,
const bool create,
const TRI_col_type_e createType) :
SingleCollectionTransaction<T>(vocbase, name, TRI_TRANSACTION_WRITE, create, createType),
_numWrites(0),
_synchronous(false) {

View File

@ -35,13 +35,24 @@
#include "Logger/Logger.h"
#include "Utils/CollectionReadLock.h"
#include "Utils/CollectionWriteLock.h"
#include "Utils/TransactionCollectionsList.h"
#include "Utils/TransactionCollection.h"
#if TRI_ENABLE_TRX
//#define TRX_LOG LOGGER_INFO << __FUNCTION__ << ":" << __LINE__ << " "
#define TRX_LOG if (false) std::cout
#else
#define TRX_LOG if (false) std::cout
#endif
namespace triagens {
namespace arango {
// -----------------------------------------------------------------------------
// --SECTION-- class Transaction
// -----------------------------------------------------------------------------
template<typename T>
class Transaction : public T {
@ -79,22 +90,27 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
Transaction (TRI_vocbase_t* const vocbase,
const string& trxName) :
TransactionCollectionsList* collections) :
T(),
_vocbase(vocbase),
_trxName(trxName),
_collections(collections),
_hints(0),
_setupError(TRI_ERROR_NO_ERROR) {
assert(_vocbase != 0);
int res = createTransaction();
if (res != TRI_ERROR_NO_ERROR) {
this->_setupError = res;
assert(_vocbase != 0);
TRX_LOG << "creating transaction";
int res = _collections->getError();
if (res == TRI_ERROR_NO_ERROR) {
res = createTransaction();
}
#ifdef TRI_ENABLE_TRX
// LOGGER_INFO << "created transaction " << this->_trxName;
#endif
if (res != TRI_ERROR_NO_ERROR) {
// setting up the transaction failed
TRX_LOG << "creating transaction failed";
this->_setupError = res;
}
}
////////////////////////////////////////////////////////////////////////////////
@ -102,11 +118,17 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
virtual ~Transaction () {
freeTransaction();
#ifdef TRI_ENABLE_TRX
// LOGGER_INFO << "destroyed transaction " << this->_trxName;
#endif
TRX_LOG << "destroying transaction";
if (this->_trx != 0 && ! this->isEmbedded()) {
if (this->status() == TRI_TRANSACTION_RUNNING) {
// auto abort
this->abort();
}
freeTransaction();
}
delete _collections;
}
////////////////////////////////////////////////////////////////////////////////
@ -129,6 +151,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int begin () {
TRX_LOG << "beginning transaction";
if (this->_setupError != TRI_ERROR_NO_ERROR) {
return this->_setupError;
}
@ -140,25 +163,23 @@ namespace triagens {
int res;
if (this->isEmbedded()) {
res = addCollections();
res = this->checkCollections();
return res;
}
// ! this->isEmbedded()
if (status() != TRI_TRANSACTION_CREATED) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
// register usage of the underlying collections
res = useCollections();
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
res = addCollections();
res = this->addCollections();
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
TRX_LOG << "calling transaction start";
return TRI_StartTransaction(this->_trx, _hints);
}
@ -167,21 +188,28 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int commit () {
if (this->_trx == 0 || status() != TRI_TRANSACTION_RUNNING) {
// not created or not running
TRX_LOG << "committing transaction";
if (this->_trx == 0 || this->status() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (this->isEmbedded()) {
// return instantly if the transaction is embedded
return TRI_ERROR_NO_ERROR;
}
int res;
if (this->_trx->_type == TRI_TRANSACTION_READ) {
// a read transaction just finishes
TRX_LOG << "commit - finishing read transaction";
res = TRI_FinishTransaction(this->_trx);
}
else {
// a write transaction commits
TRX_LOG << "commit - committing write transaction";
res = TRI_CommitTransaction(this->_trx);
}
@ -193,12 +221,13 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int abort () {
TRX_LOG << "aborting transaction";
if (this->_trx == 0) {
// transaction not created
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (status() != TRI_TRANSACTION_RUNNING) {
if (this->status() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
@ -217,14 +246,14 @@ namespace triagens {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
if (status() != TRI_TRANSACTION_RUNNING) {
if (this->status() != TRI_TRANSACTION_RUNNING) {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
int res;
if (errorNumber == TRI_ERROR_NO_ERROR) {
// there was no previous error, so we'll commit
res = commit();
res = this->commit();
}
else {
// there was a previous error, so we'll abort
@ -236,14 +265,6 @@ namespace triagens {
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the name of the transaction
////////////////////////////////////////////////////////////////////////////////
inline string name () const {
return this->_trxName;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the "vocbase"
////////////////////////////////////////////////////////////////////////////////
@ -574,33 +595,6 @@ namespace triagens {
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief use all collection
////////////////////////////////////////////////////////////////////////////////
virtual int useCollections () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief add all collections to the transaction
////////////////////////////////////////////////////////////////////////////////
virtual int addCollections () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -612,6 +606,64 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief check all collections to the transaction
///
/// this method is called in case the transaction is embedded. its purpose is
/// to validate if all collections have been previously registered in the
/// current transaction
////////////////////////////////////////////////////////////////////////////////
int checkCollections () {
assert(this->isEmbedded());
TRX_LOG << "checking collections";
const vector<TransactionCollection*>& collections = _collections->getCollections();
for (size_t i = 0; i < collections.size(); ++i) {
TransactionCollection* c = collections[i];
TRI_vocbase_col_t* collection = TRI_CheckCollectionTransaction(this->_trx, c->getName().c_str(), c->getAccessType());
if (collection == 0) {
return TRI_ERROR_TRANSACTION_UNREGISTERED_COLLECTION;
}
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add all collections to the transaction
///
/// this method is called in case the transaction is not embedded. its purpose is
/// to validate if all collections have been previously registered in the
/// current transaction
////////////////////////////////////////////////////////////////////////////////
int addCollections () {
assert(! this->isEmbedded());
TRX_LOG << "adding collections";
const vector<TransactionCollection*>& collections = _collections->getCollections();
for (size_t i = 0; i < collections.size(); ++i) {
TransactionCollection* c = collections[i];
TRX_LOG << "adding collection " << c->getName();
int res = TRI_AddCollectionTransaction(this->_trx, c->getName().c_str(), c->getAccessType());
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
}
TRX_LOG << "all collections added";
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create transaction
////////////////////////////////////////////////////////////////////////////////
@ -622,12 +674,20 @@ namespace triagens {
return TRI_ERROR_TRANSACTION_NESTED;
}
TRX_LOG << "creating embedded transaction";
this->_trx = this->getParent();
if (this->_trx == 0) {
TRX_LOG << "creating embedded transaction failed";
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
return TRI_ERROR_NO_ERROR;
}
TRX_LOG << "creating standalone transaction";
this->_trx = TRI_CreateTransaction(_vocbase->_transactionContext, TRI_TRANSACTION_READ_REPEATABLE);
if (this->_trx == 0) {
return TRI_ERROR_OUT_OF_MEMORY;
}
@ -642,9 +702,9 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int freeTransaction () {
if (this->isEmbedded()) {
return TRI_ERROR_NO_ERROR;
}
assert(! this->isEmbedded());
TRX_LOG << "freeing standalone transaction";
if (this->_trx != 0) {
this->unregisterTransaction();
@ -677,6 +737,12 @@ namespace triagens {
TRI_vocbase_t* const _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief the collections participating in the transaction
////////////////////////////////////////////////////////////////////////////////
TransactionCollectionsList* _collections;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -692,12 +758,6 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction name
////////////////////////////////////////////////////////////////////////////////
string _trxName;
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction hints
////////////////////////////////////////////////////////////////////////////////
@ -709,7 +769,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int _setupError;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,101 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction collection wrapper
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2012 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_UTILS_TRANSACTION_COLLECTION_H
#define TRIAGENS_UTILS_TRANSACTION_COLLECTION_H 1
#include "Basics/Common.h"
#include "VocBase/collection.h"
#include "VocBase/transaction.h"
namespace triagens {
namespace arango {
class TransactionCollection {
private:
TransactionCollection (const TransactionCollection&);
TransactionCollection& operator= (const TransactionCollection&);
public:
TransactionCollection (const string& name, TRI_transaction_type_e accessType) :
_name(name),
_accessType(accessType),
_createType(TRI_COL_TYPE_DOCUMENT),
_create(false) {
}
TransactionCollection (const string& name, TRI_col_type_e createType) :
_name(name),
_accessType(TRI_TRANSACTION_WRITE),
_createType(TRI_COL_TYPE_DOCUMENT),
_create(true) {
}
~TransactionCollection () {
}
inline const string getName () const {
return _name;
}
inline TRI_transaction_type_e getAccessType () const {
return _accessType;
}
inline void setAccessType (TRI_transaction_type_e accessType) {
_accessType = accessType;
}
inline bool getCreateFlag () const {
return _create;
}
inline TRI_col_type_e getCreateType () const {
return _createType;
}
private:
string _name;
TRI_transaction_type_e _accessType;
TRI_col_type_e _createType;
bool _create;
};
}
}
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -0,0 +1,195 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief transaction collections list
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2012 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_UTILS_TRANSACTION_COLLECTION_LIST_H
#define TRIAGENS_UTILS_TRANSACTION_COLLECTION_LIST_H 1
#include "Basics/Common.h"
#include "VocBase/collection.h"
#include "VocBase/transaction.h"
#include "VocBase/vocbase.h"
#include "Utils/TransactionCollection.h"
namespace triagens {
namespace arango {
class TransactionCollectionsList {
typedef map<string, TransactionCollection*> ListType;
private:
TransactionCollectionsList& operator= (const TransactionCollectionsList&);
TransactionCollectionsList (const TransactionCollectionsList&);
public:
TransactionCollectionsList () :
_collections() {
}
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
const string& name,
TRI_transaction_type_e accessType) :
_vocbase(vocbase),
_collections(),
_error(TRI_ERROR_NO_ERROR) {
addCollection(name, accessType, false);
}
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
const string& name,
TRI_transaction_type_e accessType,
const TRI_col_type_e createType) :
_vocbase(vocbase),
_collections(),
_error(TRI_ERROR_NO_ERROR) {
addCollection(name, accessType, true, createType);
}
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
const string& name,
TRI_transaction_type_e accessType,
const bool create,
const TRI_col_type_e createType) :
_vocbase(vocbase),
_collections(),
_error(TRI_ERROR_NO_ERROR) {
addCollection(name, accessType, create, createType);
}
TransactionCollectionsList (TRI_vocbase_t* const vocbase,
const vector<string>& readCollections,
const vector<string>& writeCollections) :
_vocbase(vocbase),
_collections() {
for (size_t i = 0; i < readCollections.size(); ++i) {
addCollection(readCollections[i], TRI_TRANSACTION_READ, false);
}
for (size_t i = 0; i < writeCollections.size(); ++i) {
addCollection(writeCollections[i], TRI_TRANSACTION_WRITE, false);
}
}
~TransactionCollectionsList () {
ListType::iterator it;
for (it = _collections.begin(); it != _collections.end(); ++it) {
delete (*it).second;
}
_collections.clear();
}
inline int getError () const {
return _error;
}
const vector<TransactionCollection*> getCollections () {
ListType::iterator it;
vector<TransactionCollection*> collections;
for (it = _collections.begin(); it != _collections.end(); ++it) {
collections.push_back((*it).second);
}
return collections;
}
void addCollection (const string& name,
TRI_transaction_type_e type,
bool create,
TRI_col_type_e createType = TRI_COL_TYPE_DOCUMENT) {
ListType::iterator it;
string realName;
if (name.empty()) {
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
return;
}
if (isdigit(name[0])) {
// name is passed as a string with the collection id
// look up the collection name for the id
TRI_voc_cid_t id = triagens::basics::StringUtils::uint64(name);
char* n = TRI_GetCollectionNameByIdVocBase(_vocbase, id);
if (n == 0) {
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
return;
}
realName = string(n);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, n);
}
else {
// name is passed as a "real" name
realName = name;
}
it = _collections.find(realName);
if (it != _collections.end()) {
TransactionCollection* c = (*it).second;
if (type == TRI_TRANSACTION_WRITE && type != c->getAccessType()) {
// upgrade the type
c->setAccessType(type);
}
}
else {
// check whether the collection exists. if not, create it
if (( create && TRI_FindCollectionByNameOrBearVocBase(_vocbase, realName.c_str(), createType) == NULL) ||
(! create && TRI_LookupCollectionByNameVocBase(_vocbase, realName.c_str()) == NULL)) {
_error = TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
return;
}
_collections[realName] = new TransactionCollection(realName, type);
}
}
private:
TRI_vocbase_t* _vocbase;
ListType _collections;
int _error;
};
}
}
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -61,9 +61,7 @@ namespace triagens {
UserTransaction (TRI_vocbase_t* const vocbase,
const vector<string>& readCollections,
const vector<string>& writeCollections) :
Transaction<T>(vocbase, "UserTransaction"),
_readCollections(readCollections),
_writeCollections(writeCollections) {
Transaction<T>(vocbase, new TransactionCollectionsList(vocbase, readCollections, writeCollections)) {
}
////////////////////////////////////////////////////////////////////////////////
@ -71,99 +69,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
~UserTransaction () {
if (this->_trx != 0) {
if (this->status() == TRI_TRANSACTION_RUNNING) {
// auto abort
this->abort();
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief use all collections
/// this is a no op, as using is done when trx is started
////////////////////////////////////////////////////////////////////////////////
int useCollections () {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief release all collections in use
/// this is a no op, as releasing is done when trx is finished
////////////////////////////////////////////////////////////////////////////////
int releaseCollections () {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add all collections to the transaction
////////////////////////////////////////////////////////////////////////////////
int addCollections () {
int res;
size_t i;
for (i = 0; i < _readCollections.size(); ++i) {
res = TRI_AddCollectionTransaction(this->_trx, _readCollections[i].c_str(), TRI_TRANSACTION_READ, 0);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
}
for (i = 0; i < _writeCollections.size(); ++i) {
res = TRI_AddCollectionTransaction(this->_trx, _writeCollections[i].c_str(), TRI_TRANSACTION_WRITE, 0);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
}
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief collections that are opened in read mode
////////////////////////////////////////////////////////////////////////////////
vector<string> _readCollections;
////////////////////////////////////////////////////////////////////////////////
/// @brief collections that are opened in write mode
////////////////////////////////////////////////////////////////////////////////
vector<string> _writeCollections;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -416,7 +416,7 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
collection = TRI_LookupCollectionByIdVocBase(vocbase, TRI_UInt64String(v.c_str()));
}
else {
collection = TRI_FindCollectionByNameVocBase(vocbase, v.c_str(), false);
collection = TRI_LookupCollectionByNameVocBase(vocbase, v.c_str());
}
if (collection != 0) {
@ -428,7 +428,7 @@ static HttpResponse* ExecuteActionVocbase (TRI_vocbase_t* vocbase,
}
case TRI_ACT_COLLECTION_NAME: {
TRI_vocbase_col_t const* collection = TRI_FindCollectionByNameVocBase(vocbase, v.c_str(), false);
TRI_vocbase_col_t const* collection = TRI_LookupCollectionByNameVocBase(vocbase, v.c_str());
if (collection != 0) {
valuesObject->Set(v8::String::New(k.c_str()), TRI_WrapCollection(collection));

View File

@ -1741,7 +1741,7 @@ static v8::Handle<v8::Value> JS_AllQuery (v8::Arguments const& argv) {
uint32_t total = 0;
vector<TRI_doc_mptr_t*> docs;
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type);
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {

View File

@ -764,7 +764,7 @@ static v8::Handle<v8::Value> DocumentVocbaseCol (const bool useCollection,
assert(key);
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type);
SingleCollectionReadOnlyTransaction<EmbeddableTransaction<V8TransactionContext> > trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot fetch document", true)));
@ -849,7 +849,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (const bool useCollection,
assert(key);
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "ReplaceVocbase");
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot replace document", true)));
@ -1155,7 +1155,7 @@ static v8::Handle<v8::Value> UpdateVocbaseCol (const bool useCollection,
}
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "UpdateVocbase");
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot update document", true)));
@ -1256,7 +1256,7 @@ static v8::Handle<v8::Value> RemoveVocbaseCol (const bool useCollection,
assert(key);
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "DeleteVocbase");
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot delete document", true)));
@ -4854,7 +4854,7 @@ static v8::Handle<v8::Value> JS_SaveVocbaseCol (v8::Arguments const& argv) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL)));
}
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "SaveVocbase");
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, 1> trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
@ -4960,7 +4960,7 @@ static v8::Handle<v8::Value> JS_TruncateVocbaseCol (v8::Arguments const& argv) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_INTERNAL)));
}
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, UINT64_MAX> trx(col->_vocbase, col->_name, (TRI_col_type_e) col->_type, false, "TruncateVocbase");
SingleCollectionWriteTransaction<EmbeddableTransaction<V8TransactionContext>, UINT64_MAX> trx(col->_vocbase, col->_name);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "cannot truncate collection", true)));
@ -5160,12 +5160,7 @@ static v8::Handle<v8::Value> MapGetVocBase (v8::Local<v8::String> name,
// look up the value if it exists
TRI_vocbase_col_t const* collection;
if (collectionType == TRI_COL_TYPE_EDGE) {
collection = TRI_FindEdgeCollectionByNameVocBase(vocbase, key.c_str(), true);
}
else {
collection = TRI_FindDocumentCollectionByNameVocBase(vocbase, key.c_str(), true);
}
collection = TRI_FindCollectionByNameOrBearVocBase(vocbase, key.c_str(), (TRI_col_type_t) collectionType);
// if the key is not present return an empty handle as signal
if (collection == 0) {
@ -5247,7 +5242,7 @@ static v8::Handle<v8::Value> JS_CollectionVocbase (v8::Arguments const& argv) {
else {
string name = TRI_ObjectToString(val);
collection = TRI_FindCollectionByNameVocBase(vocbase, name.c_str(), false);
collection = TRI_LookupCollectionByNameVocBase(vocbase, name.c_str());
}
if (collection == 0) {

View File

@ -505,8 +505,7 @@ void TRI_DumpTransactionContext (TRI_transaction_context_t* const context) {
////////////////////////////////////////////////////////////////////////////////
static TRI_transaction_collection_t* CreateCollection (const char* const name,
const TRI_transaction_type_e type,
TRI_vocbase_col_t* initialiser) {
const TRI_transaction_type_e type) {
TRI_transaction_collection_t* collection;
collection = (TRI_transaction_collection_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_transaction_collection_t), false);
@ -525,10 +524,9 @@ static TRI_transaction_collection_t* CreateCollection (const char* const name,
// initialise collection properties
collection->_type = type;
collection->_collection = initialiser;
collection->_collection = NULL;
collection->_globalInstance = NULL;
collection->_locked = false;
collection->_externalLock = (initialiser != NULL);
// initialise private copy of write transactions list
InitTransactionList(&collection->_writeTransactions);
@ -595,10 +593,8 @@ static int AcquireCollectionLocks (TRI_transaction_t* const trx) {
for (i = 0; i < n; ++i) {
TRI_transaction_collection_t* collection;
collection = TRI_AtVectorPointer(&trx->_collections, i);
if (! collection->_externalLock) {
collection->_collection = TRI_UseCollectionByNameVocBase(trx->_context->_vocbase, collection->_name);
}
collection = (TRI_transaction_collection_t*) TRI_AtVectorPointer(&trx->_collections, i);
collection->_collection = TRI_UseCollectionByNameVocBase(trx->_context->_vocbase, collection->_name);
if (collection->_collection == NULL) {
return TRI_errno();
@ -655,9 +651,7 @@ static int ReleaseCollectionLocks (TRI_transaction_t* const trx) {
}
// unuse collection
if (! collection->_externalLock) {
TRI_ReleaseCollectionVocBase(trx->_context->_vocbase, collection->_collection);
}
TRI_ReleaseCollectionVocBase(trx->_context->_vocbase, collection->_collection);
collection->_collection = NULL;
}
@ -1091,8 +1085,7 @@ TRI_vocbase_col_t* TRI_CheckCollectionTransaction (TRI_transaction_t* const trx,
int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
const char* const name,
const TRI_transaction_type_e type,
TRI_vocbase_col_t* initialiser) {
const TRI_transaction_type_e type) {
TRI_transaction_collection_t* collection;
size_t i, n;
@ -1116,7 +1109,7 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
if (res < 0) {
// collection is not contained in vector
collection = CreateCollection(name, type, initialiser);
collection = CreateCollection(name, type);
if (collection == NULL) {
// out of memory
return TRI_ERROR_OUT_OF_MEMORY;
@ -1139,7 +1132,7 @@ int TRI_AddCollectionTransaction (TRI_transaction_t* const trx,
}
// collection was not contained. now insert it
collection = CreateCollection(name, type, initialiser);
collection = CreateCollection(name, type);
if (collection == NULL) {
// out of memory
return TRI_ERROR_OUT_OF_MEMORY;
@ -1240,6 +1233,30 @@ int TRI_FinishTransaction (TRI_transaction_t* const trx) {
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the pointer to a collection after it has been initialised
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_GetCollectionTransaction (const TRI_transaction_t* const trx,
const char* const name) {
size_t i, n;
assert(trx->_status == TRI_TRANSACTION_RUNNING);
n = trx->_collections._length;
// process collections in forward order
for (i = 0; i < n; ++i) {
TRI_transaction_collection_t* collection;
collection = (TRI_transaction_collection_t*) TRI_AtVectorPointer(&trx->_collections, i);
if (TRI_EqualString(name, collection->_name)) {
return collection->_collection;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -283,7 +283,6 @@ typedef struct TRI_transaction_collection_s {
struct TRI_vocbase_col_s* _collection; // vocbase collection pointer
TRI_transaction_collection_global_t* _globalInstance; // pointer to the global instance of the collection in the trx system
bool _locked; // lock flag (used for write-transactions)
bool _externalLock; // flag whether collection was locked externally
}
TRI_transaction_collection_t;
@ -395,8 +394,7 @@ struct TRI_vocbase_col_s* TRI_CheckCollectionTransaction (TRI_transaction_t* con
int TRI_AddCollectionTransaction (TRI_transaction_t* const,
const char* const,
const TRI_transaction_type_e,
struct TRI_vocbase_col_s*);
const TRI_transaction_type_e);
////////////////////////////////////////////////////////////////////////////////
/// @brief start a transaction
@ -422,6 +420,13 @@ int TRI_AbortTransaction (TRI_transaction_t* const);
int TRI_FinishTransaction (TRI_transaction_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief get the pointer to a collection after it has been initialised
////////////////////////////////////////////////////////////////////////////////
struct TRI_vocbase_col_s* TRI_GetCollectionTransaction (const TRI_transaction_t* const,
const char* const);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -815,7 +815,6 @@ static int ManifestCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t*
static TRI_vocbase_col_t* FindCollectionByNameVocBase (TRI_vocbase_t* vocbase,
char const* name,
bool bear,
TRI_col_type_e type) {
union { void const* v; TRI_vocbase_col_t* c; } found;
@ -827,15 +826,9 @@ static TRI_vocbase_col_t* FindCollectionByNameVocBase (TRI_vocbase_t* vocbase,
return found.c;
}
if (! bear) {
TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
return NULL;
}
return BearCollectionVocBase(vocbase, name, type);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief loads an existing (document) collection
///
@ -1372,6 +1365,32 @@ TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t* vocbase) {
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get a collection name by a collection id
///
/// the name is fetched under a lock to make this thread-safe. returns NULL if
/// the collection does not exist
/// it is the caller's responsibility to free the name returned
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t* vocbase,
const TRI_voc_cid_t id) {
union { void const* v; TRI_vocbase_col_t* c; } found;
char* name;
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
found.v = TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id);
if (found.v == NULL) {
name = NULL;
}
else {
name = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, found.c->_name);
}
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return name;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up a (document) collection by name
////////////////////////////////////////////////////////////////////////////////
@ -1401,27 +1420,13 @@ TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds a collection by name
/// @brief finds a collection by name, optionally creates it
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
return TRI_FindDocumentCollectionByNameVocBase(vocbase, name, bear);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds a primary collection by name
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindDocumentCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
return FindCollectionByNameVocBase(vocbase, name, bear, TRI_COL_TYPE_DOCUMENT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds an edge collection by name
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindEdgeCollectionByNameVocBase (TRI_vocbase_t* vocbase, char const* name, bool bear) {
return FindCollectionByNameVocBase(vocbase, name, bear, TRI_COL_TYPE_EDGE);
TRI_vocbase_col_t* TRI_FindCollectionByNameOrBearVocBase (TRI_vocbase_t* vocbase,
char const* name,
const TRI_col_type_t type) {
return FindCollectionByNameVocBase(vocbase, name, (TRI_col_type_e) type);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -505,6 +505,16 @@ void TRI_DestroyVocBase (TRI_vocbase_t*);
TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief get a collection name by a collection id
///
/// the name is fetched under a lock to make this thread-safe. returns NULL if
/// the collection does not exist
/// it is the caller's responsibility to free the name returned
////////////////////////////////////////////////////////////////////////////////
char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t*, const TRI_voc_cid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up a (document) collection by name
////////////////////////////////////////////////////////////////////////////////
@ -518,22 +528,12 @@ TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t*, char const
TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t*, TRI_voc_cid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief finds a collection by name
/// @brief finds a collection by name or creates it
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
////////////////////////////////////////////////////////////////////////////////
/// @brief finds a primary collection by name
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindDocumentCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
////////////////////////////////////////////////////////////////////////////////
/// @brief finds an edge collection by name
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* TRI_FindEdgeCollectionByNameVocBase (TRI_vocbase_t*, char const*, bool bear);
TRI_vocbase_col_t* TRI_FindCollectionByNameOrBearVocBase (TRI_vocbase_t*,
char const*,
const TRI_col_type_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new (document) collection from parameter set