Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module contains the core of the FoundationDB transaction API,
including all the basic functionality to create and run transactions.
Transaction
is a monad, and you will generally want to use it with
do-notation.
{-# LANGUAGE OverloadedStrings #-} import FoundationDB.Transaction import Data.ByteString -- | Sets and gets a key in one transaction. Returns the ByteString -- "world". myTransaction :: Transaction ByteString myTransaction = do let mykey = "hello" set mykey "world" get mykey
Run your transactions with runTransaction
in the IO monad.
The documentation in this library assumes that you already have some understanding of how to work with FoundationDB. If you don't, check out the official tutorial.
Synopsis
- data Transaction a
- runTransaction :: Database -> Transaction a -> IO a
- runTransaction' :: Database -> Transaction a -> IO (Either Error a)
- data TransactionConfig = TransactionConfig {
- idempotent :: Bool
- snapshotReads :: Bool
- getConflictingKeys :: Bool
- maxRetries :: Int
- timeout :: Int
- defaultConfig :: TransactionConfig
- runTransactionWithConfig :: TransactionConfig -> Database -> Transaction a -> IO a
- runTransactionWithConfig' :: TransactionConfig -> Database -> Transaction a -> IO (Either Error a)
- cancel :: Transaction ()
- reset :: Transaction ()
- withSnapshot :: Transaction a -> Transaction a
- setOption :: TransactionOption -> Transaction ()
- getReadVersion :: Transaction (Future Word64)
- setReadVersion :: Word64 -> Transaction ()
- getVersionstamp :: Transaction (FutureIO (Either Error TransactionVersionstamp))
- getApproximateSize :: Transaction (Future Word64)
- get :: ByteString -> Transaction (Future (Maybe ByteString))
- set :: ByteString -> ByteString -> Transaction ()
- clear :: ByteString -> Transaction ()
- clearRange :: ByteString -> ByteString -> Transaction ()
- addConflictRange :: ByteString -> ByteString -> FDBConflictRangeType -> Transaction ()
- data FDBConflictRangeType
- addReadConflictKey :: ByteString -> Transaction ()
- addWriteConflictKey :: ByteString -> Transaction ()
- getKey :: KeySelector -> Transaction (Future ByteString)
- getKeyAddresses :: ByteString -> Transaction (Future [ByteString])
- atomicOp :: ByteString -> MutationType -> Transaction ()
- getRange :: RangeQuery -> Transaction (Future RangeResult)
- getRange' :: RangeQuery -> FDBStreamingMode -> Transaction (Future RangeResult)
- data FDBStreamingMode
- getEntireRange :: RangeQuery -> Transaction (Seq (ByteString, ByteString))
- getEntireRange' :: FDBStreamingMode -> RangeQuery -> Transaction (Seq (ByteString, ByteString))
- isRangeEmpty :: RangeQuery -> Transaction Bool
- data RangeQuery = RangeQuery {}
- rangeKeys :: RangeQuery -> (ByteString, ByteString)
- keyRangeQuery :: ByteString -> ByteString -> RangeQuery
- keyRangeQueryInclusive :: ByteString -> ByteString -> RangeQuery
- prefixRange :: ByteString -> Maybe RangeQuery
- prefixRangeEnd :: ByteString -> Maybe ByteString
- data RangeResult
- = RangeDone (Seq (ByteString, ByteString))
- | RangeMore (Seq (ByteString, ByteString)) (Future RangeResult)
- watch :: ByteString -> Transaction (FutureIO ())
- data MappedKeyValue = MappedKeyValue {}
- data MappedRangeResult
- newtype Mapper = Mapper ByteString
- getMappedRange :: RangeQuery -> Mapper -> Transaction (Future MappedRangeResult)
- getMappedRange' :: RangeQuery -> Mapper -> FDBStreamingMode -> Transaction (Future MappedRangeResult)
- getEntireMappedRange :: RangeQuery -> Mapper -> Transaction (Seq MappedKeyValue)
- getEntireMappedRange' :: FDBStreamingMode -> RangeQuery -> Mapper -> Transaction (Seq MappedKeyValue)
- data Future a
- await :: Future a -> Transaction a
- awaitInterruptible :: Future a -> Transaction a
- cancelFuture :: Future a -> Transaction ()
- futureIsReady :: Future a -> Transaction Bool
- data FutureIO a
- awaitIO :: FutureIO a -> IO (Either Error a)
- awaitInterruptibleIO :: FutureIO a -> IO (Either Error a)
- cancelFutureIO :: FutureIO a -> IO ()
- futureIsReadyIO :: FutureIO a -> IO Bool
- data KeySelector
- keySelectorBytes :: KeySelector -> ByteString
- offset :: Int -> KeySelector -> KeySelector
- data TransactionEnv
- createTransactionEnv :: Database -> TransactionConfig -> ExceptT Error IO TransactionEnv
- onEnv :: TransactionEnv -> Transaction a -> IO (Either Error a)
- commitFuture :: Transaction (Future ())
- onError :: Error -> Transaction ()
- getCommittedVersion :: Transaction Int
Transactions
data Transaction a Source #
A transaction monad. This is currently exported with a MonadIO
instance,
but using it comes with caveats:
runTransaction
will retry your transaction in some cases, which means any IO in your transaction will be repeated. You can disable retries by settingmaxRetries
inTransactionConfig
to 0.- Transactions have strict time limits, so slow IO operations should be avoided.
Instances
runTransaction :: Database -> Transaction a -> IO a Source #
Attempts to commit a transaction against the given database. If an
unretryable error occurs, throws an Error
. Attempts to retry the
transaction for retryable errors.
runTransaction' :: Database -> Transaction a -> IO (Either Error a) Source #
Like runTransaction
, but returns a sum instead of throwing an exception
on errors.
data TransactionConfig Source #
Contains useful options that are not directly exposed by the C API (for
options that are, see setOption
).
TransactionConfig | |
|
Instances
Eq TransactionConfig Source # | |
Defined in FoundationDB.Transaction (==) :: TransactionConfig -> TransactionConfig -> Bool # (/=) :: TransactionConfig -> TransactionConfig -> Bool # | |
Ord TransactionConfig Source # | |
Defined in FoundationDB.Transaction compare :: TransactionConfig -> TransactionConfig -> Ordering # (<) :: TransactionConfig -> TransactionConfig -> Bool # (<=) :: TransactionConfig -> TransactionConfig -> Bool # (>) :: TransactionConfig -> TransactionConfig -> Bool # (>=) :: TransactionConfig -> TransactionConfig -> Bool # max :: TransactionConfig -> TransactionConfig -> TransactionConfig # min :: TransactionConfig -> TransactionConfig -> TransactionConfig # | |
Read TransactionConfig Source # | |
Defined in FoundationDB.Transaction | |
Show TransactionConfig Source # | |
Defined in FoundationDB.Transaction showsPrec :: Int -> TransactionConfig -> ShowS # show :: TransactionConfig -> String # showList :: [TransactionConfig] -> ShowS # |
defaultConfig :: TransactionConfig Source #
A config for a non-idempotent transaction, allowing 5 retries, with a time limit of 500 milliseconds.
runTransactionWithConfig :: TransactionConfig -> Database -> Transaction a -> IO a Source #
Attempt to commit a transaction against the given database. If an
unretryable error occurs, throws an Error
. Attempts to retry the
transaction for retryable errors according to the maxRetries
setting
in the provided TransactionConfig
.
runTransactionWithConfig' :: TransactionConfig -> Database -> Transaction a -> IO (Either Error a) Source #
Attempt to commit a transaction against the given database. If an unretryable
error occurs, returns Left
. Attempts to retry the transaction for retryable
errors.
cancel :: Transaction () Source #
Cancel a transaction. The transaction will not be committed, and
will throw TransactionCanceled
.
reset :: Transaction () Source #
Reset the transaction. All operations prior to this will be discarded.
withSnapshot :: Transaction a -> Transaction a Source #
Runs a transaction using snapshot reads, which means that the transaction will see the results of concurrent transactions, removing the default serializable isolation guarantee.
setOption :: TransactionOption -> Transaction () Source #
Set one of the transaction options from the underlying C API.
getReadVersion :: Transaction (Future Word64) Source #
Gets the read version of the current transaction, representing all transactions that were reported committed before this one.
setReadVersion :: Word64 -> Transaction () Source #
Sets the read version on the current transaction. As the FoundationDB docs state, "this is not needed in simple cases".
getVersionstamp :: Transaction (FutureIO (Either Error TransactionVersionstamp)) Source #
Returns a FutureIO
that will resolve to the versionstamp of the committed
transaction. Most applications won't need this.
getApproximateSize :: Transaction (Future Word64) Source #
Returns a future that will return the size, in bytes, of the transaction so far, as a summation of the estimated size of mutations, read conflict ranges, and write conflict ranges. This can be used to decide how to split a large task into smaller transactions.
get :: ByteString -> Transaction (Future (Maybe ByteString)) Source #
Get the value of a key. If the key does not exist, returns Nothing
.
set :: ByteString -> ByteString -> Transaction () Source #
Set a bytestring key to a bytestring value.
clear :: ByteString -> Transaction () Source #
Delete a key from the DB.
clearRange :: ByteString -> ByteString -> Transaction () Source #
clearRange k l
deletes all keys in the half-open range [k,l).
addConflictRange :: ByteString -> ByteString -> FDBConflictRangeType -> Transaction () Source #
Tells FoundationDB to consider the given range to have been read by this transaction.
data FDBConflictRangeType Source #
Instances
addReadConflictKey :: ByteString -> Transaction () Source #
Tells FoundationDB to consider the given key to have been read by this transaction.
addWriteConflictKey :: ByteString -> Transaction () Source #
Tells FoundationDB to consider the given key to have been written by this transaction.
getKey :: KeySelector -> Transaction (Future ByteString) Source #
Gets the key specified by the given KeySelector
.
getKeyAddresses :: ByteString -> Transaction (Future [ByteString]) Source #
Get the public network addresses of all nodes responsible for storing the given key.
atomicOp :: ByteString -> MutationType -> Transaction () Source #
Perform an atomic operation of MutationType
on the given key. A
transaction that performs only atomic operations is guaranteed not to
conflict. However, it may cause other concurrent transactions to conflict.
getRange :: RangeQuery -> Transaction (Future RangeResult) Source #
Reads all key-value pairs in the specified Range
which are
lexicographically greater than or equal to the rangeBegin
KeySelector
and lexicographically less than the rangeEnd
KeySelector
.
Uses StreamingModeIterator
, which assumes that you don't know ahead of
time exactly how many pairs in the range you actually need. If you need
them all (and they are expected to fit in memory), use getEntireRange
.
For more advanced usage, use getRange'
.
getRange' :: RangeQuery -> FDBStreamingMode -> Transaction (Future RangeResult) Source #
Like getRange
, but allows you to specify the streaming mode as desired.
data FDBStreamingMode Source #
StreamingModeWantAll | |
StreamingModeIterator | |
StreamingModeExact | |
StreamingModeSmall | |
StreamingModeMedium | |
StreamingModeLarge | |
StreamingModeSerial |
Instances
getEntireRange :: RangeQuery -> Transaction (Seq (ByteString, ByteString)) Source #
Wrapper around getRange
that reads the entire range into memory.
getEntireRange' :: FDBStreamingMode -> RangeQuery -> Transaction (Seq (ByteString, ByteString)) Source #
isRangeEmpty :: RangeQuery -> Transaction Bool Source #
Return True iff the given range is empty.
data RangeQuery Source #
Specifies a range of keys to be iterated over by getRange
.
RangeQuery | |
|
Instances
Eq RangeQuery Source # | |
Defined in FoundationDB.Transaction (==) :: RangeQuery -> RangeQuery -> Bool # (/=) :: RangeQuery -> RangeQuery -> Bool # | |
Ord RangeQuery Source # | |
Defined in FoundationDB.Transaction compare :: RangeQuery -> RangeQuery -> Ordering # (<) :: RangeQuery -> RangeQuery -> Bool # (<=) :: RangeQuery -> RangeQuery -> Bool # (>) :: RangeQuery -> RangeQuery -> Bool # (>=) :: RangeQuery -> RangeQuery -> Bool # max :: RangeQuery -> RangeQuery -> RangeQuery # min :: RangeQuery -> RangeQuery -> RangeQuery # | |
Show RangeQuery Source # | |
Defined in FoundationDB.Transaction showsPrec :: Int -> RangeQuery -> ShowS # show :: RangeQuery -> String # showList :: [RangeQuery] -> ShowS # |
rangeKeys :: RangeQuery -> (ByteString, ByteString) Source #
keyRangeQuery :: ByteString -> ByteString -> RangeQuery Source #
keyRangeQuery begin end
is the range of keys [begin, end)
.
keyRangeQueryInclusive :: ByteString -> ByteString -> RangeQuery Source #
keyRangeQuery begin end
is the range of keys [begin, end]
.
prefixRange :: ByteString -> Maybe RangeQuery Source #
prefixRange prefix
is the range of all keys of which prefix
is a
prefix. Returns Nothing
if prefix
is empty or contains only 0xff
.
data RangeResult Source #
Structure for returning the result of getRange
in chunks.
RangeDone (Seq (ByteString, ByteString)) | |
RangeMore (Seq (ByteString, ByteString)) (Future RangeResult) |
Instances
Show RangeResult Source # | |
Defined in FoundationDB.Transaction showsPrec :: Int -> RangeResult -> ShowS # show :: RangeResult -> String # showList :: [RangeResult] -> ShowS # |
watch :: ByteString -> Transaction (FutureIO ()) Source #
Creates a future that will be fulfilled when the value associated with the given key is changed, relative to the value it had as of the current transaction's read version, or the last value to which the key was previously set within the current transaction. This future is safe to return from the transaction and await in IO. If the transaction in which it was created fails to commit, awaiting it will return the same error as running the transaction did.
Mapped ranges
data MappedKeyValue Source #
The result of a mapped key value query, containing the parent key and value (i.e., the key and value in the secondary index), and the range of key-value pairs retrieved based on the range query generated from the mapper's operation on the parent key and value.
WARNING: FDB's docs warn that the returned KeySelector fields have not yet been tested. Use them at your own risk!
Instances
Eq MappedKeyValue Source # | |
Defined in FoundationDB.Internal.Bindings (==) :: MappedKeyValue -> MappedKeyValue -> Bool # (/=) :: MappedKeyValue -> MappedKeyValue -> Bool # | |
Show MappedKeyValue Source # | |
Defined in FoundationDB.Internal.Bindings showsPrec :: Int -> MappedKeyValue -> ShowS # show :: MappedKeyValue -> String # showList :: [MappedKeyValue] -> ShowS # |
data MappedRangeResult Source #
Structure for returning the result of getRange
in chunks.
MappedRangeDone (Seq MappedKeyValue) | |
MappedRangeMore (Seq MappedKeyValue) (Future MappedRangeResult) |
Instances
Show MappedRangeResult Source # | |
Defined in FoundationDB.Transaction showsPrec :: Int -> MappedRangeResult -> ShowS # show :: MappedRangeResult -> String # showList :: [MappedRangeResult] -> ShowS # |
getMappedRange :: RangeQuery -> Mapper -> Transaction (Future MappedRangeResult) Source #
getMappedRange' :: RangeQuery -> Mapper -> FDBStreamingMode -> Transaction (Future MappedRangeResult) Source #
Given a range of keys in a secondary index, fetc the corresponding key/values they refer to by using a mapper. See the docs for more information.
Important: you must have read-your-writes enabled, but you must not read anything you have written in the same transaction. Snapshot isolation is not supported. See the docs linked above.
These functions are only available for FDB >= 7.1
getEntireMappedRange :: RangeQuery -> Mapper -> Transaction (Seq MappedKeyValue) Source #
Wrapper around getRange
that reads the entire range into memory.
getEntireMappedRange' :: FDBStreamingMode -> RangeQuery -> Mapper -> Transaction (Seq MappedKeyValue) Source #
Futures
A future result of a FoundationDB call. You can block on a future with
await
.
WARNING: returning a value of this type from runTransaction
and then
calling await
on the value in another transaction will cause a segfault!
Future versions of this library may use more sophisticated types to prevent
this.
await :: Future a -> Transaction a Source #
Block until a future is ready. Unfortunately, does not seem to be interruptible by SIGPIPE (the interrupt sent by Control.Conccurent.Async to cancel), even when using InterruptibleFFI.
awaitInterruptible :: Future a -> Transaction a Source #
Polls a future for readiness roughly every millisecond in a loop until it
is ready, then returns the value in the future. This is less resource
efficient than await
, but can be interrupted more easily.
cancelFuture :: Future a -> Transaction () Source #
Cancel a future. Attempting to await the future after cancellation will
throw OperationCancelled
.
futureIsReady :: Future a -> Transaction Bool Source #
Returns True if the future is ready. If so, calling await
will not block.
A future that can only be awaited after its transaction has committed.
That is, in contrast to Future
, this must be returned from
runTransaction
before it can safely be awaited. Use awaitIO
to await it.
This future type is not needed frequently.
All FutureIO
functions work similarly to their Future
counterparts.
awaitInterruptibleIO :: FutureIO a -> IO (Either Error a) Source #
IO analogue to awaitInterruptible
.
cancelFutureIO :: FutureIO a -> IO () Source #
Cancel a future. Attempts to await the future after cancellation will throw
OperationCancelled
.
Key selectors
data KeySelector Source #
Specifies a key in the database. See the official
docs
for more information. These can be supplied to getKey
or used to build a
Range
.
LastLessThan ByteString | Selects the lexicographically greatest key less than the specified key. |
LastLessOrEq ByteString | Selects the lexicographically greatest less than or equal to the specified key. |
FirstGreaterThan ByteString | Selects the lexicographically least key greater than the specified key. |
FirstGreaterOrEq ByteString | Selects the lexicographically least key greater than or equal to the specified key. |
Instances
Eq KeySelector Source # | |
Defined in FoundationDB.Internal.Bindings (==) :: KeySelector -> KeySelector -> Bool # (/=) :: KeySelector -> KeySelector -> Bool # | |
Ord KeySelector Source # | |
Defined in FoundationDB.Internal.Bindings compare :: KeySelector -> KeySelector -> Ordering # (<) :: KeySelector -> KeySelector -> Bool # (<=) :: KeySelector -> KeySelector -> Bool # (>) :: KeySelector -> KeySelector -> Bool # (>=) :: KeySelector -> KeySelector -> Bool # max :: KeySelector -> KeySelector -> KeySelector # min :: KeySelector -> KeySelector -> KeySelector # | |
Show KeySelector Source # | |
Defined in FoundationDB.Internal.Bindings showsPrec :: Int -> KeySelector -> ShowS # show :: KeySelector -> String # showList :: [KeySelector] -> ShowS # |
offset :: Int -> KeySelector -> KeySelector Source #
Increase the offset of the given KeySelector
.
Advanced Usage
The functionality in this section is for more advanced use cases where you
need to be able to refer to an in-progress transaction and add operations to
it incrementally. This is similar to how the Python bindings work -- you
pass around a transaction object and call methods on it one by one before
finally calling .commit()
.
This functionality was needed to create the bindings tester, which is required to follow the semantics of the bindings for imperative languages more closely. You probably don't need this. In fact, it's not entirely clear that the bindings tester needs it.
data TransactionEnv Source #
The internal state of a transaction as it is being executed by
runTransaction
.
Instances
Show TransactionEnv Source # | |
Defined in FoundationDB.Transaction showsPrec :: Int -> TransactionEnv -> ShowS # show :: TransactionEnv -> String # showList :: [TransactionEnv] -> ShowS # | |
MonadReader TransactionEnv Transaction Source # | |
Defined in FoundationDB.Transaction ask :: Transaction TransactionEnv # local :: (TransactionEnv -> TransactionEnv) -> Transaction a -> Transaction a # reader :: (TransactionEnv -> a) -> Transaction a # |
onEnv :: TransactionEnv -> Transaction a -> IO (Either Error a) Source #
Execute a transactional action on an existing transaction environment.
commitFuture :: Transaction (Future ()) Source #
onError :: Error -> Transaction () Source #
Calls the C API's fdb_transaction_on_error
function. Re-raises
unretryable errors.
getCommittedVersion :: Transaction Int Source #
Gets the committed version of a transaction. Can only be called after the
transaction has committed, so must be used in conjunction with
TransactionEnv
, since runTransaction
and its variants immediately destroy
the internal TransactionEnv
as soon as they return.