Safe Haskell | Trustworthy |
---|
This module exports the type for a Hails BSON document, HsonDoc
and
related classes for creating such documents. A Hails document is
similar to Data.Bson's documents, but differs in two ways. First,
Hails restricts the number of types to a subset of BSON's (see
BsonVal
). This restriction is primarily due to the fact that many of
the BSON types are redundant and not used (at least within Hails).
Second, Hails allows for documents to contain policy-labeled values.
Policy labeled values (PolicyLabeled
) are permitted only at the
"top-level" of a document. (This is primarily done to keep
policy-specification simple and may change in the future.)
Consequently to allow for nested documents and documents containing an
array of values we separate top-level fields (HsonField
), that may
contain policy labeled values, from potentially-nested fields
(BsonField
). A top-level field HsonField
is thus either a
BsonField
or a PolicyLabled
value.
Example:
module Main (x, y) where import Data.Text (Text) import LIO.DCLabel import LIO.Labeled.TCB (labelTCB) import Hails.Data.Hson -- | Create document, verbose approach x :: HsonDocument x = [ "myInt" =: BsonInt32 42 , "nested" =: BsonDoc [ "flag" =: BsonBool True] , "secret" =: (HsonLabeled $ hasPolicy (labelTCB dcPub (BsonString "hi"))) ] -- | Create same document, clean approach y :: HsonDocument y = [ "myInt" -: (42 :: Int) , "nested" -: ([ "flag" -: True] :: BsonDocument) , "secret" -: labelTCB dcPub (toBsonValue ("hi" :: Text)) ]
Both x
and y
with -XOverloadedStrings
:
[myInt -: 42,nested -: [flag -: True],secret -: HsonLabeled]
- type HsonDocument = [HsonField]
- type Document = HsonDocument
- type BsonDocument = [BsonField]
- class Field v f => DocOps v f | v -> f, f -> v where
- class DocValOps d v where
- include :: IsField f => [FieldName] -> [f] -> [f]
- exclude :: IsField f => [FieldName] -> [f] -> [f]
- merge :: IsField f => [f] -> [f] -> [f]
- bsonDocToHsonDoc :: BsonDocument -> HsonDocument
- bsonFieldToHsonField :: BsonField -> HsonField
- isBsonDoc :: HsonDocument -> Bool
- hsonDocToBsonDoc :: HsonDocument -> BsonDocument
- hsonDocToBsonDocStrict :: Monad m => HsonDocument -> m BsonDocument
- labeledRequestToHson :: MonadLIO DCLabel m => DCLabeled Request -> m (DCLabeled HsonDocument)
- type FieldName = Text
- data HsonField = HsonField !FieldName HsonValue
- data BsonField = BsonField !FieldName BsonValue
- class IsField f where
- class (IsField f, Show v, Show f) => Field v f where
- (=:) :: FieldName -> v -> f
- fieldValue :: Monad m => f -> m v
- class (Show v, Show f) => GenField v f where
- data HsonValue
- class (Typeable a, Show a) => HsonVal a where
- toHsonValue :: a -> HsonValue
- fromHsonValue :: Monad m => HsonValue -> m a
- data BsonValue
- class (Typeable a, Show a) => BsonVal a where
- toBsonValue :: a -> BsonValue
- fromBsonValue :: Monad m => BsonValue -> m a
- data PolicyLabeled
- needPolicy :: BsonValue -> PolicyLabeled
- hasPolicy :: DCLabeled BsonValue -> PolicyLabeled
- getPolicyLabeled :: Monad m => PolicyLabeled -> m (DCLabeled BsonValue)
- newtype Binary = Binary {}
- data ObjectId = Oid Word32 Word64
- genObjectId :: MonadLIO DCLabel m => m ObjectId
Documents
type HsonDocument = [HsonField]Source
A top-level document containing HsonField
s.
type Document = HsonDocumentSource
Synonym for HsonDocument
type BsonDocument = [BsonField]Source
A (possibly top-)level document containing BsonField
s.
Operations on documents
class Field v f => DocOps v f | v -> f, f -> v whereSource
Class used to implement operatoins on documents that return
HsonValue
s or BsonValue
s. The main role of this function is to
impose the functional dependency between values and fields. As a
consequence look
ing up and getting valueAt
in a HsonDocument
(resp. BsonDocument
) will return a HsonValue
(resp. BsonValue
).
This eliminates the need to specify the end type of very query, but
forces the programmer to cast between Hson and Bson values.
class DocValOps d v whereSource
Class used to implement operations on documents that return
Haskell values (as opposed to HsonValue
or BsonValue
).
lookup :: Monad m => FieldName -> d -> m vSource
Same as look
, but returns "unwrapped" value.
at :: FieldName -> d -> vSource
Same as valueAt
, but returns "unwrapped" value.
BsonVal v => DocValOps BsonDocument v | |
HsonVal v => DocValOps HsonDocument v |
merge :: IsField f => [f] -> [f] -> [f]Source
Merge documents with preference given to first one when both have the same field name.
Converting tofrom HsonBson
bsonDocToHsonDoc :: BsonDocument -> HsonDocumentSource
Convert BsonDocument
to HsonDocument
isBsonDoc :: HsonDocument -> BoolSource
Returns true if the document is composed solely of BsonValue
s.
This function is useful when converting from HsonDocument
to
BsonDocument
.
hsonDocToBsonDoc :: HsonDocument -> BsonDocumentSource
This is a relaxed version of hsonDocToBsonDocStrict
that only
converts fields containing BsonValue
s. In other words, the
PolicyLabeled
values are dropped.
hsonDocToBsonDocStrict :: Monad m => HsonDocument -> m BsonDocumentSource
Convert an HsonDocument
to a BsonDocument
. If any of the
fields contain PolicyLabeled
values (i.e., are HsonLabeled
values) this function fail
s, otherwise it returns the converted
document. To check for failure use isBsonDoc
.
Converting labeled requests
labeledRequestToHson :: MonadLIO DCLabel m => DCLabeled Request -> m (DCLabeled HsonDocument)Source
Convert a labeled request to a labeled document. Values of fields that
have a name that ends with []
are converted to arrays and the
suffix []
is stripped from the name.
Fields
A field containing a named HsonValue
A field containing a named BsonValue
Class for retrieving the name of a field.
class (IsField f, Show v, Show f) => Field v f whereSource
Class used to define fields.
Values
An HsonValue
is a top-level value that may either be a
BsonValue
or a policy labeled value. The separation of values
into BsonValue
and HsonValue
is solely due to the restriction
that policy-labeled values may only occur at the top level and
BsonValue
s may be nested (e.g. using BsonArray
and BsonDoc
).
HsonValue BsonValue | Bson value |
HsonLabeled PolicyLabeled | Policy labeled value |
class (Typeable a, Show a) => HsonVal a whereSource
Class used to (de)construct HsonValue
s
toHsonValue :: a -> HsonValueSource
Convert to HsonValue
fromHsonValue :: Monad m => HsonValue -> m aSource
Convert from HsonValue
A BsonValue
is a subset of BSON (Data.Bson) values. Note that a
BsonValue
cannot contain any labeled values; all labeled values
occur in a document as HsonValue
s. Correspondingly, BsonValue
s
may be arbitrarily nested.
BsonFloat Double | Float value |
BsonString Text | String value |
BsonDoc BsonDocument | Inner document |
BsonArray [BsonValue] | List of values |
BsonBlob Binary | Binary blob value |
BsonObjId ObjectId | Object Id value |
BsonBool Bool | Boolean value |
BsonUTC UTCTime | Time stamp value |
BsonNull | The |
BsonInt32 Int32 | 32-bit integer |
BsonInt64 Int64 | 64-bit integer |
class (Typeable a, Show a) => BsonVal a whereSource
Class used to (de)construct BsonValue
s
toBsonValue :: a -> BsonValueSource
Convert to BsonValue
fromBsonValue :: Monad m => BsonValue -> m aSource
Convert from BsonValue
data PolicyLabeled Source
A PolicyLabeled
value can be either an unlabeled value for which
the policy needs to be applied (NeedPolicyTCB
), or an already
labeled value (HasPolicyTCB
). PolicyLabeled
is a partially-opaque
type; code should not be able to inspect the value of an unlabeleda
value, but may inspect an already labeled value.
needPolicy :: BsonValue -> PolicyLabeledSource
Create a policy labeled value given an unlabeled HsonValue
.
hasPolicy :: DCLabeled BsonValue -> PolicyLabeledSource
Create a policy labeled value a labeled HsonValue
.
getPolicyLabeled :: Monad m => PolicyLabeled -> m (DCLabeled BsonValue)Source
Get the policy labeled value, only if the policy has been applied.
Arbitrary binary blob
data ObjectId
A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (seconds since epoch), a 3-byte machine id, a 2-byte process id, and a 3-byte counter. Note that the timestamp and counter fields must be stored big endian unlike the rest of BSON. This is because they are compared byte-by-byte and we want to ensure a mostly increasing order.
genObjectId :: MonadLIO DCLabel m => m ObjectIdSource
Create a fresh ObjectId.