Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module implements an experimental typed query language for TCache build on pure haskell. It is minimally intrusive (no special data definitions, no special syntax, no template haskell). It uses the same register fields from the data definitions. Both for query conditions and selections. It is executed in haskell, no external database support is needed.
it includes
- A method for triggering the
index
-ation of the record fields that you want to query A typed query language of these record fields, with:
- Relational operators:
.==.
.>.
.>=.
.<=.
.<.
.&&.
.||.
to compare fields with values (returning lists of DBRefs) or fields between them, returning joins (lists of pairs of lists of DBRefs that meet the condition). - a
select
method to extract tuples of field values from the DBRefs - a
recordsWith
clause to extract entire registers
- Relational operators:
An example that register the owner and name fields fo the Car register and the name of the Person register, create the Bruce register, return the Bruce DBRef, create two Car registers with bruce as owner and query for the registers with bruce as owner and its name alpabeticaly higuer than "Bat mobile"
import Data.TCache import Data.TCache.IndexQuery import Data.TCache.DefaultPersistence import Data.Typeable data Person= Person {pname :: String} deriving (Show, Read, Eq, Typeable) data Car= Car{owner :: DBRef Person , cname:: String} deriving (Show, Read, Eq, Typeable) instanceIndexable
Person where key Person{pname= n} = "Person " ++ n instanceIndexable
Car where key Car{cname= n} = "Car " ++ n main = doindex
ownerindex
pnameindex
cname bruce <- atomically $newDBRef
$ Person "bruce" atomically $ mapM_newDBRef
[Car bruce "Bat Mobile", Car bruce "Porsche"] r <- atomically $ cname.==.
"Porsche" print r r <- atomically $select
(cname, owner) $ owner.==.
bruce.&&.
cname.>=.
"Bat Mobile" print r
Will produce:
[DBRef "Car Porsche"] [("Porsche",DBRef "Person bruce")]
NOTES:
- the index is instance of
Indexable
andSerializable
. This can be used to persist in the user-defined storage using DefaultPersistence - The Join feature has not been properly tested
- Record fields are recognized by its type, so if we define two record fields with the same type:
data Person = Person {name , surname :: String}
then a query for name
is indistinguishable from .==.
Brucesurname
.==.
Bruce
Will return indexOf the registers with surname Bruce as well. So if two or more fields in a registers are to be indexed, they must have different types.
Synopsis
- index :: Queriable reg a => (reg -> a) -> IO ()
- (.==.) :: RelationOps field1 field2 res => field1 -> field2 -> STM res
- (.<.) :: RelationOps field1 field2 res => field1 -> field2 -> STM res
- (.<=.) :: RelationOps field1 field2 res => field1 -> field2 -> STM res
- (.>=.) :: RelationOps field1 field2 res => field1 -> field2 -> STM res
- (.>.) :: RelationOps field1 field2 res => field1 -> field2 -> STM res
- indexOf :: Queriable reg a => (reg -> a) -> STM [(a, [DBRef reg])]
- recordsWith :: (IResource a, Typeable a) => STM [DBRef a] -> STM [a]
- (.&&.) :: SetOperations set set' setResult => STM set -> STM set' -> STM setResult
- (.||.) :: SetOperations set set' setResult => STM set -> STM set' -> STM setResult
- select :: Select selector a res => selector -> a -> res
- class (Read a, Show a, IResource reg, Typeable reg, Typeable a, Ord a, PersistIndex reg) => Queriable reg a
Documentation
index :: Queriable reg a => (reg -> a) -> IO () Source #
Register a trigger for indexing the values of the field passed as parameter. the indexed field can be used to perform relational-like searches
indexOf :: Queriable reg a => (reg -> a) -> STM [(a, [DBRef reg])] Source #
return all the (indexed) values which this field has and a DBRef pointer to the register
(.&&.) :: SetOperations set set' setResult => STM set -> STM set' -> STM setResult infixr 4 Source #