Module Database

Library for accessing and storing data in databases. The contents of a database is represented in this library as dynamic predicates that are defined by facts than can change over time and can be persistently stored. All functions in this library distinguishes between queries that access the database and transactions that manipulates data in the database. Transactions have a monadic structure. Both queries and transactions can be executed as I/O actions. However, arbitrary I/O actions cannot be embedded in transactions.

A dynamic predicate p with arguments of type t1,...,tn must be declared by:

p :: t1 -> ... -> tn -> Dynamic
p = dynamic

A dynamic predicate where all facts should be persistently stored in the directory DIR must be declared by:

p :: t1 -> ... -> tn -> Dynamic
p = persistent "file:DIR"

Author: Michael Hanus

Version: August 2011

Summary of exported operations:

queryAll :: (a -> Dynamic) -> Query [a]   
A database query that returns all answers to an abstraction on a dynamic expression.
queryOne :: (a -> Dynamic) -> Query (Maybe a)   
A database query that returns a single answer to an abstraction on a dynamic expression.
queryOneWithDefault :: a -> (a -> Dynamic) -> Query a   
A database query that returns a single answer to an abstraction on a dynamic expression.
queryJustOne :: (a -> Dynamic) -> Query a   
A database query that returns a single answer to an abstraction on a dynamic expression.
dynamicExists :: Dynamic -> Query Bool   
A database query that returns True if there exists the argument facts (without free variables!) and False, otherwise.
transformQ :: (a -> b) -> Query a -> Query b   
Transforms a database query from one result type to another according to a given mapping.
runQ :: Query a -> IO a   
Executes a database query on the current state of dynamic predicates.
showTError :: TError -> String   
Transforms a transaction error into a string.
addDB :: Dynamic -> Transaction ()   
Adds new facts (without free variables!) about dynamic predicates.
deleteDB :: Dynamic -> Transaction ()   
Deletes facts (without free variables!) about dynamic predicates.
getDB :: Query a -> Transaction a   
Returns the result of a database query in a transaction.
returnT :: a -> Transaction a   
The empty transaction that directly returns its argument.
doneT :: Transaction ()   
The empty transaction that returns nothing.
errorT :: TError -> Transaction a   
Abort a transaction with a specific transaction error.
failT :: String -> Transaction a   
Abort a transaction with a general error message.
(|>>=) :: Transaction a -> (a -> Transaction b) -> Transaction b   
Sequential composition of transactions.
(|>>) :: Transaction a -> Transaction b -> Transaction b   
Sequential composition of transactions.
sequenceT :: [Transaction a] -> Transaction [a]   
Executes a sequence of transactions and collects all results in a list.
sequenceT_ :: [Transaction a] -> Transaction ()   
Executes a sequence of transactions and ignores the results.
mapT :: (a -> Transaction b) -> [a] -> Transaction [b]   
Maps a transaction function on a list of elements.
mapT_ :: (a -> Transaction b) -> [a] -> Transaction ()   
Maps a transaction function on a list of elements.
runT :: Transaction a -> IO (Either a TError)   
Executes a possibly composed transaction on the current state of dynamic predicates as a single transaction.
runJustT :: Transaction a -> IO a   
Executes a possibly composed transaction on the current state of dynamic predicates as a single transaction.
runTNA :: Transaction a -> IO (Either a TError)   
Executes a possibly composed transaction as a Non-Atomic(!) sequence of its individual database updates.

Exported datatypes:


Query

Abstract datatype to represent database queries.

Constructors:


TError

The type of errors that might occur during a transaction.

Constructors:


TErrorKind

The various kinds of transaction errors.

Constructors:

  • KeyNotExistsError :: TErrorKind
  • NoRelationshipError :: TErrorKind
  • DuplicateKeyError :: TErrorKind
  • KeyRequiredError :: TErrorKind
  • UniqueError :: TErrorKind
  • MinError :: TErrorKind
  • MaxError :: TErrorKind
  • UserDefinedError :: TErrorKind
  • ExecutionError :: TErrorKind

Transaction

Abstract datatype for representing transactions.

Constructors:


Exported operations:

queryAll :: (a -> Dynamic) -> Query [a]   

A database query that returns all answers to an abstraction on a dynamic expression.

queryOne :: (a -> Dynamic) -> Query (Maybe a)   

A database query that returns a single answer to an abstraction on a dynamic expression. It returns Nothing if no answer exists.

queryOneWithDefault :: a -> (a -> Dynamic) -> Query a   

A database query that returns a single answer to an abstraction on a dynamic expression. It returns the first argument if no answer exists.

queryJustOne :: (a -> Dynamic) -> Query a   

A database query that returns a single answer to an abstraction on a dynamic expression. It fails if no answer exists.

dynamicExists :: Dynamic -> Query Bool   

A database query that returns True if there exists the argument facts (without free variables!) and False, otherwise.

transformQ :: (a -> b) -> Query a -> Query b   

Transforms a database query from one result type to another according to a given mapping.

runQ :: Query a -> IO a   

Executes a database query on the current state of dynamic predicates. If other processes made changes to persistent predicates, these changes are read and made visible to the currently running program.

Further infos:
  • solution complete, i.e., able to compute all solutions

showTError :: TError -> String   

Transforms a transaction error into a string.

addDB :: Dynamic -> Transaction ()   

Adds new facts (without free variables!) about dynamic predicates. Conditional dynamics are added only if the condition holds.

deleteDB :: Dynamic -> Transaction ()   

Deletes facts (without free variables!) about dynamic predicates. Conditional dynamics are deleted only if the condition holds.

getDB :: Query a -> Transaction a   

Returns the result of a database query in a transaction.

returnT :: a -> Transaction a   

The empty transaction that directly returns its argument.

Further infos:
  • solution complete, i.e., able to compute all solutions

doneT :: Transaction ()   

The empty transaction that returns nothing.

Further infos:
  • solution complete, i.e., able to compute all solutions

errorT :: TError -> Transaction a   

Abort a transaction with a specific transaction error.

Further infos:
  • solution complete, i.e., able to compute all solutions

failT :: String -> Transaction a   

Abort a transaction with a general error message.

Further infos:
  • solution complete, i.e., able to compute all solutions

(|>>=) :: Transaction a -> (a -> Transaction b) -> Transaction b   

Sequential composition of transactions.

Example call:
(a |>>= fa)
Parameters:
  • a : a transaction
  • fa : a function from a value into a transaction
Returns:
a transaction that first performs a (yielding result r) and then performs (fa r)
Further infos:
  • defined as left-associative infix operator with precedence 1

(|>>) :: Transaction a -> Transaction b -> Transaction b   

Sequential composition of transactions.

Example call:
(a1 |>> a2)
Parameters:
  • a1 : a transaction
  • a2 : a transaction
Returns:
a transaction that first performs a1 and then a2
Further infos:
  • defined as left-associative infix operator with precedence 1

sequenceT :: [Transaction a] -> Transaction [a]   

Executes a sequence of transactions and collects all results in a list.

sequenceT_ :: [Transaction a] -> Transaction ()   

Executes a sequence of transactions and ignores the results.

mapT :: (a -> Transaction b) -> [a] -> Transaction [b]   

Maps a transaction function on a list of elements. The results of all transactions are collected in a list.

mapT_ :: (a -> Transaction b) -> [a] -> Transaction ()   

Maps a transaction function on a list of elements. The results of all transactions are ignored.

runT :: Transaction a -> IO (Either a TError)   

Executes a possibly composed transaction on the current state of dynamic predicates as a single transaction.

Before the transaction is executed, the access to all persistent predicates is locked (i.e., no other process can perform a transaction in parallel). After the successful transaction, the access is unlocked so that the updates performed in this transaction become persistent and visible to other processes. Otherwise (i.e., in case of a failure or abort of the transaction), the changes of the transaction to persistent predicates are ignored and Nothing is returned.

In general, a transaction should terminate and all failures inside a transaction should be handled (execept for an explicit failT that leads to an abort of the transaction). If a transaction is externally interrupted (e.g., by killing the process), some locks might never be removed. However, they can be explicitly removed by deleting the corresponding lock files reported at startup time.

runJustT :: Transaction a -> IO a   

Executes a possibly composed transaction on the current state of dynamic predicates as a single transaction. Similarly to runT but a run-time error is raised if the execution of the transaction fails.

runTNA :: Transaction a -> IO (Either a TError)   

Executes a possibly composed transaction as a Non-Atomic(!) sequence of its individual database updates. Thus, the argument is not executed as a single transaction in contrast to runT, i.e., no predicates are locked and individual updates are not undone in case of a transaction error. This operation could be applied to execute a composed transaction without the overhead caused by (the current implementation of) transactions if one is sure that locking is not necessary (e.g., if the transaction contains only database reads and transaction error raising).