Copyright | (c) 2015 Călin Ardelean |
---|---|
License | MIT |
Maintainer | Călin Ardelean <calinucs@gmail.com> |
Stability | experimental |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Extensions |
|
Muesli markup types and typeclasses.
Normally, with the DeriveAnyClass
and DeriveGeneric
extensions enabled,
types can be marked up as documents with a
deriving (Generic, Serialize)
clause, and a separate empty Document
instance.
For structured field types, the following will suffice:
deriving (Generic, Serialize, Indexable)
Then Reference
, Sortable
and Unique
can be used inside document types
to mark up the fields that should be automatically indexed, becoming queryable
with the primitives in Database.Muesli.Query.
The record syntax must be used, and the accesor name will become the
Property
name used in queries.
- newtype Reference a = Reference {
- unReference :: IxKey
- newtype Sortable a = Sortable {
- unSortable :: a
- newtype Unique a = Unique {
- unUnique :: a
- class Indexable a where
- getIxValues :: a -> [IxKey]
- isReference :: Proxy a -> Bool
- getUnique :: a -> Maybe UniqueKey
- class (Typeable a, Generic a, Serialize a) => Document a where
- getIndexables :: a -> Indexables
- data Indexables = Indexables {
- ixReferences :: [(String, DocumentKey)]
- ixSortables :: [(String, SortableKey)]
- ixUniques :: [(String, UniqueKey)]
- newtype IxKey = IxKey {}
- class ToKey a where
- type DocumentKey = IxKey
- type SortableKey = IxKey
- type UniqueKey = IxKey
- type PropertyKey = IxKey
- newtype Property a = Property {
- unProperty :: (PropertyKey, String)
- newtype DateTime = DateTime {}
- data DatabaseError
- type TransactionId = Word64
- type DocAddress = Word64
- type DocSize = Word64
Indexable value wrappers
Reference
fields are pointers to other Document
s. They are
indexed automatically and can be queried with filter
.
To ensure type safety, use and store only references returned by the
primitive queries, like insert
,
range
or filter
.
Numerical instances like Num
or Integral
are provided to support
generic database programs that take the responsibility of maintaining
invariants upon themselves. In this context, type safety means that it is
impossible in normal operation to try and deserialize a document at a wrong
type or address (note that all primitive query functions are polymorphic),
and risk getting bogus data without errors being reported.
Bounded (Reference a) Source | |
Enum (Reference a) Source | |
Eq (Reference a) Source | |
Integral (Reference a) Source | |
Num (Reference a) Source | |
Ord (Reference a) Source | |
Real (Reference a) Source | |
Show (Reference a) Source | |
Serialize (Reference a) Source | |
Indexable (Maybe (Reference a)) Source | |
Indexable (Reference a) Source |
Marks a field available for sorting and range
queries.
Indexing requires a ToKey
instance. Apart from the provided Bool
, Int
and DateTime
instances, there is an overlappable fallback instance based on
converting the Show
string representation to an IxKey
by taking the first
4 or 8 bytes. This is good enough for primitive string sorting.
Sortable | |
|
Bounded a => Bounded (Sortable a) Source | |
Eq a => Eq (Sortable a) Source | |
Ord a => Ord (Sortable a) Source | |
Show a => Show (Sortable a) Source | |
Serialize a => Serialize (Sortable a) Source | |
(Hashable a, Indexable (Sortable a)) => Indexable (Unique (Sortable a)) Source | |
ToKey (Sortable a) => Indexable (Sortable a) Source | |
Hashable a => ToKey (Unique (Sortable a)) Source | |
ToKey (Sortable Bool) Source | |
ToKey (Sortable Int) Source | |
Show a => ToKey (Sortable a) Source | |
ToKey (Sortable IxKey) Source | |
ToKey (Sortable DateTime) Source |
Unique
fields act as primary keys, and can be queried with
unique
and updateUnique
.
The Hashable
instance is used to generate the key.
For fields that need to be both unique and sortable, use
Unique
(Sortable
a) rather then the other way around.
Eq a => Eq (Unique a) Source | |
Show a => Show (Unique a) Source | |
Serialize a => Serialize (Unique a) Source | |
Hashable a => Indexable (Unique a) Source | |
(Hashable a, Indexable (Sortable a)) => Indexable (Unique (Sortable a)) Source | |
Hashable a => ToKey (Unique a) Source | |
Hashable a => ToKey (Unique (Sortable a)) Source |
Indexable value classes
class Indexable a where Source
This class is used by the generic scrapper to extract indexable keys from
the fields of a Document
. There are instances for Reference
, Sortable
and Unique
, a general Foldable
instance, and a special one for Maybe
that converts Nothing
into 0, such that null values will be indexed too,
and become queryable with filter
.
Users are not expected to need writing instances for this class.
They can rather be generated automatically with the DeriveAnyClass
extension.
Nothing
getIxValues :: a -> [IxKey] Source
isReference :: Proxy a -> Bool Source
Indexable Bool Source | |
Indexable Int Source | |
Indexable String Source | |
(Indexable a, Foldable f) => Indexable (f a) Source | |
Indexable (Maybe (Reference a)) Source | |
Hashable a => Indexable (Unique a) Source | |
(Hashable a, Indexable (Sortable a)) => Indexable (Unique (Sortable a)) Source | |
ToKey (Sortable a) => Indexable (Sortable a) Source | |
Indexable (Reference a) Source |
class (Typeable a, Generic a, Serialize a) => Document a where Source
Class used by the generic key scrapper to extract indexing information from user types. Only an empty instance needs to be added in user code.
Nothing
getIndexables :: a -> Indexables Source
data Indexables Source
Data type used by the key scrapper to collect keys while traversing generically user types.
Indexables | |
|
Index keyes
Used inside indexes and as arguments to query primitives.
type DocumentKey = IxKey Source
Primary key for a document.
Allocated by functions in the Database.Muesli.IdSupply module.
type SortableKey = IxKey Source
Key extracted from non-reference fields for building a
SortIndex
.
Key extracted from unique fields for building a
UniqueIndex
type PropertyKey = IxKey Source
Key generated by Property
for building a
SortIndex
or a FilterIndex
.
Other
With the OverloadedStrings
extension, or directly using the IsString
instance, field names specified in query arguments are converted to
Property
. An IxKey
is computed by hashing the property name together
with the TypeRep
of the phantom argument.
This key is used in indexes.
Property | |
|
data DatabaseError Source
Type for exceptions thrown by the database. During normal operation these should never be thrown.
LogParseError String | Thrown when the log file is corrupted. |
DataParseError DocAddress DocSize String | Thrown after deserialization errors. Holds starting position, size, and a message. |
IdAllocationError String | ID allocation failure. For instance, full address space on a 32 bit machine. |
DataAllocationError DocSize (Maybe DocSize) String | Data allocation failure. Containes the size requested, the biggest available gap, and a message. |
type TransactionId = Word64 Source
Transaction ids are auto-incremented globally.
See mkNewTransactionId
.
type DocAddress = Word64 Source
Address in the abstract data file of a serialized document's data.
These addresses are allocated by functions in the module Database.Muesli.Allocator.