1
0
Fork 0

split self-contained transactions into read & write transactions

This commit is contained in:
Jan Steemann 2012-11-13 17:56:13 +01:00
parent 39b407a038
commit 57f0677d7b
9 changed files with 310 additions and 722 deletions

View File

@ -282,7 +282,7 @@ bool RestDocumentHandler::createDocument () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), create);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
// .............................................................................
// inside write transaction
@ -406,7 +406,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), false);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_READ);
SelfContainedReadTransaction trx(&c);
// .............................................................................
// inside read transaction
@ -496,7 +496,7 @@ bool RestDocumentHandler::readAllDocuments () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), false);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_READ);
SelfContainedReadTransaction trx(&c);
vector<string> ids;
@ -772,7 +772,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), false);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
TRI_voc_rid_t rid = 0;
TRI_doc_mptr_t document;
@ -926,7 +926,7 @@ bool RestDocumentHandler::deleteDocument () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), false);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
TRI_voc_rid_t rid = 0;
// .............................................................................

View File

@ -158,7 +158,7 @@ bool RestEdgeHandler::createDocument () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, getCollectionType(), create);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
// .............................................................................
// inside write transaction

View File

@ -200,7 +200,7 @@ bool RestImportHandler::createByArray () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
// .............................................................................
// inside write transaction
@ -373,7 +373,7 @@ bool RestImportHandler::createByList () {
// find and load collection given by name or identifier
Collection c(_vocbase, collection, TRI_COL_TYPE_DOCUMENT, create);
SelfContainedTransaction trx(&c, TRI_TRANSACTION_WRITE);
SelfContainedWriteTransaction trx(&c);
// .............................................................................
// inside write transaction

View File

@ -33,9 +33,10 @@
#include "Logger/Logger.h"
#include "Rest/HttpResponse.h"
#include "Utils/Collection.h"
#include "Utils/SelfContainedTransaction.h"
#include "Utils/SelfContainedReadTransaction.h"
#include "Utils/SelfContainedWriteTransaction.h"
#include "VocBase/primary-collection.h"
////#include "VocBase/primary-collection.h"
#include "BasicsC/json.h"
#include "BasicsC/json-utilities.h"

View File

@ -1,472 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief "safe" collection accessor
///
/// @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_COLLECTION_LOCK_H
#define TRIAGENS_UTILS_COLLECTION_LOCK_H 1
#include "Logger/Logger.h"
#include "Basics/StringUtils.h"
#include "ShapedJson/json-shaper.h"
#include "VocBase/primary-collection.h"
#include "VocBase/vocbase.h"
using namespace std;
using namespace triagens::basics;
namespace triagens {
namespace arango {
// -----------------------------------------------------------------------------
// --SECTION-- class CollectionAccessor
// -----------------------------------------------------------------------------
class CollectionAccessor {
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief CollectionAccessor
////////////////////////////////////////////////////////////////////////////////
private:
CollectionAccessor (const CollectionAccessor&);
CollectionAccessor& operator= (const CollectionAccessor&);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private enums
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
enum LockTypes {
TYPE_NONE = 0,
TYPE_READ,
TYPE_WRITE
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the accessor
////////////////////////////////////////////////////////////////////////////////
CollectionAccessor (TRI_vocbase_t* const vocbase,
const string& name,
const TRI_col_type_e type,
const bool create) :
_vocbase(vocbase),
_name(name),
_type(type),
_create(create),
_lockType(TYPE_NONE),
_collection(0),
_primaryCollection(0) {
assert(_vocbase);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the accessor
////////////////////////////////////////////////////////////////////////////////
~CollectionAccessor () {
release();
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief use the collection and initialise the accessor
////////////////////////////////////////////////////////////////////////////////
int use () {
if (_collection != 0) {
// we already called use() before
return TRI_ERROR_NO_ERROR;
}
if (_name.empty()) {
// name is empty. cannot open the collection
return TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
}
// open or create the collection
if (isdigit(_name[0])) {
TRI_voc_cid_t id = StringUtils::uint64(_name);
_collection = TRI_LookupCollectionByIdVocBase(_vocbase, id);
}
else {
if (_type == TRI_COL_TYPE_DOCUMENT) {
_collection = TRI_FindDocumentCollectionByNameVocBase(_vocbase, _name.c_str(), _create);
}
else if (_type == TRI_COL_TYPE_EDGE) {
_collection = TRI_FindEdgeCollectionByNameVocBase(_vocbase, _name.c_str(), _create);
}
}
if (_collection == 0) {
// collection not found
return TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
}
int result = TRI_UseCollectionVocBase(_vocbase, const_cast<TRI_vocbase_col_s*>(_collection));
if (TRI_ERROR_NO_ERROR != result) {
_collection = 0;
return TRI_set_errno(result);
}
LOGGER_TRACE << "using collection " << _name;
assert(_collection->_collection != 0);
_primaryCollection = _collection->_collection;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free all resources. accessor cannot be used after calling this
////////////////////////////////////////////////////////////////////////////////
bool unuse () {
return release();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief read-lock the collection
////////////////////////////////////////////////////////////////////////////////
bool beginRead () {
return lock(TYPE_READ);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief write-lock the collection
////////////////////////////////////////////////////////////////////////////////
bool beginWrite () {
return lock(TYPE_WRITE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief read-unlock the collection
////////////////////////////////////////////////////////////////////////////////
bool endRead () {
return unlock(TYPE_READ);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief write-unlock the collection
////////////////////////////////////////////////////////////////////////////////
bool endWrite () {
return unlock(TYPE_WRITE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check whether a collection is initialised
////////////////////////////////////////////////////////////////////////////////
inline bool isValid () const {
return (_collection != 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check whether a lock is already held
////////////////////////////////////////////////////////////////////////////////
inline bool isLocked () const {
return (_lockType != TYPE_NONE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the underlying collection
////////////////////////////////////////////////////////////////////////////////
inline const bool waitForSync () const {
assert(_primaryCollection != 0);
return _primaryCollection->base._waitForSync;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the underlying primary collection
////////////////////////////////////////////////////////////////////////////////
inline TRI_primary_collection_t* primary () {
assert(_primaryCollection != 0);
return _primaryCollection;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the underlying collection's id
////////////////////////////////////////////////////////////////////////////////
const inline TRI_voc_cid_t cid () const {
assert(_collection != 0);
return _collection->_cid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the collection's shaper
////////////////////////////////////////////////////////////////////////////////
inline TRI_shaper_t* shaper () const {
assert(_primaryCollection != 0);
return _primaryCollection->_shaper;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief release all locks
////////////////////////////////////////////////////////////////////////////////
bool release () {
if (_collection == 0) {
return false;
}
if (isLocked()) {
unlock(_lockType);
}
LOGGER_TRACE << "releasing collection";
TRI_ReleaseCollectionVocBase(_vocbase, _collection);
_collection = 0;
_primaryCollection = 0;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief stores the lock type
////////////////////////////////////////////////////////////////////////////////
inline void setLock (const LockTypes type) {
_lockType = type;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief lock a collection in read or write mode
////////////////////////////////////////////////////////////////////////////////
bool lock (const LockTypes type) {
if (! isValid()) {
LOGGER_ERROR << "logic error - attempt to lock uninitialised collection " << _name;
return false;
}
if (isLocked()) {
LOGGER_ERROR << "logic error - attempt to lock already locked collection " << _name;
}
assert(_primaryCollection != 0);
int result = TRI_ERROR_INTERNAL;
if (TYPE_READ == type) {
LOGGER_TRACE << "read-locking collection " << _name;
result = _primaryCollection->beginRead(_primaryCollection);
}
else if (TYPE_WRITE == type) {
LOGGER_TRACE << "write-locking collection " << _name;
result = _primaryCollection->beginWrite(_primaryCollection);
}
else {
assert(false);
}
if (TRI_ERROR_NO_ERROR == result) {
setLock(type);
return true;
}
LOGGER_WARNING << "could not lock collection";
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief unlock a collection
////////////////////////////////////////////////////////////////////////////////
bool unlock (const LockTypes type) {
if (! isValid()) {
LOGGER_ERROR << "logic error - attempt to unlock uninitialised collection " << _name;
return false;
}
if (! isLocked()) {
LOGGER_ERROR << "logic error - attempt to unlock non-locked collection " << _name;
}
assert(_primaryCollection != 0);
int result = TRI_ERROR_INTERNAL;
if (TYPE_READ == type) {
LOGGER_TRACE << "read-unlocking collection " << _name;
result = _primaryCollection->endRead(_primaryCollection);
}
else if (TYPE_WRITE == type) {
LOGGER_TRACE << "write-unlocking collection " << _name;
result = _primaryCollection->endWrite(_primaryCollection);
}
else {
assert(false);
}
if (TRI_ERROR_NO_ERROR == result) {
setLock(TYPE_NONE);
return true;
}
LOGGER_WARNING << "could not unlock collection " << _name;
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief the vocbase
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_t* const _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief collection name / id
////////////////////////////////////////////////////////////////////////////////
const string _name;
////////////////////////////////////////////////////////////////////////////////
/// @brief type of collection
////////////////////////////////////////////////////////////////////////////////
const TRI_col_type_e _type;
////////////////////////////////////////////////////////////////////////////////
/// @brief create flag for collection
////////////////////////////////////////////////////////////////////////////////
const bool _create;
////////////////////////////////////////////////////////////////////////////////
/// @brief the type of lock currently held
////////////////////////////////////////////////////////////////////////////////
LockTypes _lockType;
////////////////////////////////////////////////////////////////////////////////
/// @brief the underlying vocbase collection
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_col_t* _collection;
////////////////////////////////////////////////////////////////////////////////
/// @brief corresponding loaded primary collection
////////////////////////////////////////////////////////////////////////////////
TRI_primary_collection_t* _primaryCollection;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
};
}
}
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -1,104 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief "safe" read transaction
///
/// @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_READ_TRANSACTION_H
#define TRIAGENS_UTILS_READ_TRANSACTION_H 1
#include "Logger/Logger.h"
#include "Utils/CollectionAccessor.h"
#include "Utils/Transaction.h"
#include "VocBase/primary-collection.h"
namespace triagens {
namespace arango {
// -----------------------------------------------------------------------------
// --SECTION-- class ReadTransaction
// -----------------------------------------------------------------------------
class ReadTransaction : public Transaction {
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief ReadTransaction
////////////////////////////////////////////////////////////////////////////////
private:
ReadTransaction (const ReadTransaction&);
ReadTransaction& operator= (const ReadTransaction&);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction
////////////////////////////////////////////////////////////////////////////////
ReadTransaction (CollectionAccessor* collection) :
Transaction(collection) {
_collection->beginRead();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief end the transaction
////////////////////////////////////////////////////////////////////////////////
~ReadTransaction () {
end();
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
};
}
}
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
// End:

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief "safe" write transaction
/// @brief wrapper for self-contained, single collection read transactions
///
/// @file
///
@ -25,42 +25,25 @@
/// @author Copyright 2011-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_UTILS_WRITE_TRANSACTION_H
#define TRIAGENS_UTILS_WRITE_TRANSACTION_H 1
#ifndef TRIAGENS_UTILS_SELF_CONTAINED_READ_TRANSACTION_H
#define TRIAGENS_UTILS_SELF_CONTAINED_READ_TRANSACTION_H 1
#include "Logger/Logger.h"
#include "Utils/CollectionAccessor.h"
#include "Utils/Transaction.h"
#include "VocBase/primary-collection.h"
using namespace triagens::basics;
#include "Utils/SelfContainedTransaction.h"
namespace triagens {
namespace arango {
// -----------------------------------------------------------------------------
// --SECTION-- class WriteTransaction
// --SECTION-- class SelfContainedReadTransaction
// -----------------------------------------------------------------------------
class WriteTransaction : public Transaction {
class SelfContainedReadTransaction : public SelfContainedTransaction {
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief WriteTransaction
////////////////////////////////////////////////////////////////////////////////
private:
WriteTransaction (const WriteTransaction&);
WriteTransaction& operator= (const WriteTransaction&);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
@ -73,20 +56,41 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction
/// @brief create the transaction, using a collection object
////////////////////////////////////////////////////////////////////////////////
WriteTransaction (CollectionAccessor* collection) :
Transaction(collection) {
_collection->beginWrite();
SelfContainedReadTransaction (Collection* collection) :
SelfContainedTransaction(collection) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief end the transaction
////////////////////////////////////////////////////////////////////////////////
~WriteTransaction () {
end();
~SelfContainedReadTransaction () {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief get the transaction type
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_type_e type () const {
return TRI_TRANSACTION_READ;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -35,7 +35,6 @@
#include "Utils/Collection.h"
#include "Utils/CollectionReadLock.h"
#include "Utils/CollectionWriteLock.h"
#include "Utils/Transaction.h"
namespace triagens {
@ -67,8 +66,9 @@ namespace triagens {
/// @brief create the transaction, using a collection object
////////////////////////////////////////////////////////////////////////////////
SelfContainedTransaction (Collection* collection, const TRI_transaction_type_e accessType) :
Transaction(collection->vocbase()), _collection(collection), _accessType(accessType), _synchronous(false) {
SelfContainedTransaction (Collection* collection) :
Transaction(collection->vocbase()),
_collection(collection) {
}
////////////////////////////////////////////////////////////////////////////////
@ -83,6 +83,7 @@ namespace triagens {
}
}
// unuse underlying collection
_collection->release();
}
@ -101,14 +102,6 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the last write in a transaction was synchronous
////////////////////////////////////////////////////////////////////////////////
inline bool synchronous () const {
return _synchronous;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief start a transaction
////////////////////////////////////////////////////////////////////////////////
@ -119,6 +112,7 @@ namespace triagens {
return TRI_ERROR_TRANSACTION_INVALID_STATE;
}
// register usage of the underlying collection
int res = _collection->use();
if (res != TRI_ERROR_NO_ERROR) {
return res;
@ -129,7 +123,7 @@ namespace triagens {
return TRI_ERROR_OUT_OF_MEMORY;
}
if (! TRI_AddCollectionTransaction(_trx, _collection->name().c_str(), _accessType, _collection->collection())) {
if (! TRI_AddCollectionTransaction(_trx, _collection->name().c_str(), type(), _collection->collection())) {
return TRI_ERROR_INTERNAL;
}
@ -152,7 +146,7 @@ namespace triagens {
int res;
if (_trx->_type == TRI_TRANSACTION_READ) {
if (type() == TRI_TRANSACTION_READ) {
res = TRI_FinishTransaction(_trx);
}
else {
@ -181,86 +175,6 @@ namespace triagens {
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t createDocument (TRI_json_t const* json,
bool forceSync) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_ERROR, forceSync);
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->createJson(&context, TRI_DOC_MARKER_KEY_DOCUMENT, json, 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a single edge within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t createEdge (TRI_json_t const* json,
bool forceSync,
void const* data) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_ERROR, forceSync);
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->createJson(&context, TRI_DOC_MARKER_KEY_EDGE, json, data);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief update a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t updateJson (const string& key,
TRI_json_t* const json,
const TRI_doc_update_policy_e policy,
bool forceSync,
const TRI_voc_rid_t expectedRevision,
TRI_voc_rid_t* actualRevision) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
context._expectedRid = expectedRevision;
context._previousRid = actualRevision;
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->updateJson(&context, json, (TRI_voc_key_t) key.c_str());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief delete a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
int destroy (const string& key,
const TRI_doc_update_policy_e policy,
bool forceSync,
const TRI_voc_rid_t expectedRevision,
TRI_voc_rid_t* actualRevision) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
context._expectedRid = expectedRevision;
context._previousRid = actualRevision;
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->destroy(&context, (TRI_voc_key_t) key.c_str());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief read a document within a transaction
////////////////////////////////////////////////////////////////////////////////
@ -310,16 +224,37 @@ namespace triagens {
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief get the transaction type
////////////////////////////////////////////////////////////////////////////////
virtual TRI_transaction_type_e type () const = 0;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// --SECTION-- protected variables
// -----------------------------------------------------------------------------
private:
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief the collection that is worked on
@ -327,18 +262,6 @@ namespace triagens {
Collection* _collection;
////////////////////////////////////////////////////////////////////////////////
/// @brief the access type for the collection (read | write)
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_type_e _accessType;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether of not the last write action was executed synchronously
////////////////////////////////////////////////////////////////////////////////
bool _synchronous;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,236 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief wrapper for self-contained, single collection write transactions
///
/// @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_SELF_CONTAINED_WRITE_TRANSACTION_H
#define TRIAGENS_UTILS_SELF_CONTAINED_WRITE_TRANSACTION_H 1
#include "Utils/CollectionWriteLock.h"
#include "Utils/SelfContainedTransaction.h"
namespace triagens {
namespace arango {
// -----------------------------------------------------------------------------
// --SECTION-- class SelfContainedWriteTransaction
// -----------------------------------------------------------------------------
class SelfContainedWriteTransaction : public SelfContainedTransaction {
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction, using a collection object
////////////////////////////////////////////////////////////////////////////////
SelfContainedWriteTransaction (Collection* collection) :
SelfContainedTransaction(collection),
_synchronous(false) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief end the transaction
////////////////////////////////////////////////////////////////////////////////
~SelfContainedWriteTransaction () {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the last write in a transaction was synchronous
////////////////////////////////////////////////////////////////////////////////
inline bool synchronous () const {
return _synchronous;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t createDocument (TRI_json_t const* json,
bool forceSync) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_ERROR, forceSync);
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->createJson(&context, TRI_DOC_MARKER_KEY_DOCUMENT, json, 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a single edge within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t createEdge (TRI_json_t const* json,
bool forceSync,
void const* data) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_ERROR, forceSync);
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->createJson(&context, TRI_DOC_MARKER_KEY_EDGE, json, data);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief update a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
TRI_doc_mptr_t updateJson (const string& key,
TRI_json_t* const json,
const TRI_doc_update_policy_e policy,
bool forceSync,
const TRI_voc_rid_t expectedRevision,
TRI_voc_rid_t* actualRevision) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
context._expectedRid = expectedRevision;
context._previousRid = actualRevision;
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->updateJson(&context, json, (TRI_voc_key_t) key.c_str());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief delete a single document within a transaction
////////////////////////////////////////////////////////////////////////////////
int destroy (const string& key,
const TRI_doc_update_policy_e policy,
bool forceSync,
const TRI_voc_rid_t expectedRevision,
TRI_voc_rid_t* actualRevision) {
TRI_primary_collection_t* primary = _collection->primary();
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
context._expectedRid = expectedRevision;
context._previousRid = actualRevision;
_synchronous = context._sync;
CollectionWriteLock lock(_collection);
return primary->destroy(&context, (TRI_voc_key_t) key.c_str());
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- virtual protected functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief get the transaction type
////////////////////////////////////////////////////////////////////////////////
TRI_transaction_type_e type () const {
return TRI_TRANSACTION_WRITE;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether of not the last write action was executed synchronously
////////////////////////////////////////////////////////////////////////////////
bool _synchronous;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
};
}
}
#endif
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\)"
// End: