-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Structured MongoDB interface -- -- This module exports a structured type-safe interface to MongoDB. @package structured-mongoDB @version 0.3 -- | This module exports a Structued type class which can be used -- to convert Haskel "record types" to BSON objects and vice -- versa. As a Mongo document has an "_id" field, we impose the -- requirement a record type have a field whose type is SObjId -- (corresponding to "_id"). module Database.MongoDB.Structured.Types -- | Structured class used to convert between a Haskell record type and -- BSON document. class Structured a collection :: Structured a => a -> Collection toBSON :: Structured a => a -> Document fromBSON :: Structured a => Document -> Maybe a -- | Type corresponding to the "_id" field of a document in a structured -- object. newtype SObjId SObjId :: (Maybe ObjectId) -> SObjId -- | The "_id" field is unset. noSObjId :: SObjId -- | Check if the "_id" field is unset. isNoSObjId :: SObjId -> Bool -- | Set the "_id" field. toSObjId :: ObjectId -> SObjId -- | Get the "_id" field (assumes that it is set0. unSObjId :: SObjId -> ObjectId instance Typeable SObjId instance Show SObjId instance Read SObjId instance Eq SObjId instance Ord SObjId instance Val SObjId -- | This module exports several classes and combinators that operated on -- Structured types. Specifically, we provide the structured -- versions of mongoDB''s combinators, including structured -- query creation. module Database.MongoDB.Structured.Query -- | Inserts document to its corresponding collection and return the "_id" -- value. insert :: (MonadIO' m, Structured a) => a -> Action m Value -- | Same as insert but discarding result. insert_ :: (MonadIO' m, Structured a) => a -> Action m () -- | Inserts documents to their corresponding collection and return their -- "_id" values. insertMany :: (MonadIO' m, Structured a) => [a] -> Action m [Value] -- | Same as insertMany but discarding result. insertMany_ :: (MonadIO' m, Structured a) => [a] -> Action m () -- | Inserts documents to their corresponding collection and return their -- "_id" values. Unlike insertMany, this function keeps inserting -- remaining documents even if an error occurs. insertAll :: (MonadIO' m, Structured a) => [a] -> Action m [Value] -- | Same as insertAll but discarding result. insertAll_ :: (MonadIO' m, Structured a) => [a] -> Action m () -- | Save document to collection. If the SObjId field is set then -- the document is updated, otherwise we perform an insert. save :: (MonadIO' m, Structured a) => a -> Action m () -- | Delete all documents that match the selection/query. delete :: MonadIO m => StructuredSelection -> Action m () -- | Delete the first documents that match the selection/query. deleteOne :: MonadIO m => StructuredSelection -> Action m () -- | Sort by field, ascending asc :: Selectable a f t => f -> OrderExp -- | Sort by field, descending desc :: Selectable a f t => f -> OrderExp -- | Wrapper for mongoDB's Query type. data StructuredQuery -- | Maximum number of objects to return (default: 0, no limit). limit :: StructuredQuery -> Word32 -- | Number of matching objects to skip (default: 0). skip :: StructuredQuery -> Word32 -- | Sortresult by this order. sort :: StructuredQuery -> [OrderExp] -- | Find documents satisfying query find :: (Functor m, MonadIO m, MonadBaseControl IO m) => StructuredQuery -> Action m StructuredCursor -- | Find documents satisfying query findOne :: (MonadIO m, Structured a) => StructuredQuery -> Action m (Maybe a) -- | Same as findOne but throws DocNotFound if none match. -- Error is thrown if the document cannot e transformed. fetch :: (MonadIO m, Functor m, Structured a) => StructuredQuery -> Action m a -- | Count number of documents satisfying query. count :: MonadIO' m => StructuredQuery -> Action m Int -- | Wrapper for mongoDB's Selection type. data StructuredSelection -- | Analog to mongoDB's Select class class StructuredSelect aQorS select :: (StructuredSelect aQorS, Structured a) => QueryExp a -> aQorS -- | Class defining a selectable type. Type a corresponds to the -- record type, f corresponds to the field or facet, and -- t corresponds to the field/facet type. class Val t => Selectable a f t | f -> a, f -> t s :: Selectable a f t => f -> t -> Label -- | Combining two field names to create a Nested type. (.!) :: (Selectable r f t, Selectable t f' t') => f -> f' -> Nested f f' -- | A query expression. data QueryExp a -- | Combinator for == (.*) :: Structured a => QueryExp a -- | Combinator for == (.==) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for $ne (./=) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for < (.<) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for <= (.<=) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for > (.>) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for >= (.>=) :: (Val t, Selectable a f t) => f -> t -> QueryExp a -- | Combinator for $and (.&&) :: QueryExp a -> QueryExp a -> QueryExp a -- | Combinator for $or (.||) :: QueryExp a -> QueryExp a -> QueryExp a -- | Combinator for $not not_ :: QueryExp a -> QueryExp a -- | Wrapper for mongoDB's Cursor. data StructuredCursor -- | Close the cursor. closeCursor :: (MonadIO m, MonadBaseControl IO m) => StructuredCursor -> Action m () -- | Check if the cursor is closed. isCursorClosed :: (MonadIO m, MonadBase IO m) => StructuredCursor -> Action m Bool -- | Return next batch of structured documents. nextBatch :: (Structured a, Functor m, MonadIO m, MonadBaseControl IO m) => StructuredCursor -> Action m [Maybe a] -- | Return next structured document. If failed return Left, -- otherwise Right of the deserialized result. next :: (Structured a, MonadIO m, MonadBaseControl IO m) => StructuredCursor -> Action m (Either () (Maybe a)) -- | Return up to next N documents. nextN :: (Structured a, Functor m, MonadIO m, MonadBaseControl IO m) => Int -> StructuredCursor -> Action m [Maybe a] -- | Return the remaining documents in query result. rest :: (Structured a, Functor m, MonadIO m, MonadBaseControl IO m) => StructuredCursor -> Action m [Maybe a] -- | A BSON value is one of the following types of values data Value :: * instance Eq StructuredSelection instance Show StructuredSelection instance Eq (QueryExp a) instance Show (QueryExp a) instance Eq OrderExp instance Show OrderExp instance Eq StructuredQuery instance Show StructuredQuery instance (Selectable r f t, Selectable t f' t') => Selectable r (Nested f f') t' instance StructuredSelect StructuredQuery instance StructuredSelect StructuredSelection -- | This module exports a structued interface to MongoDB. -- Specifically, Haskell record types are used (in place of BSON) to -- represent documents which can be inserted and retrieved from a -- MongoDB. Data types corresponding to fields of a document are used in -- forming well-typed queries, as opposed to strings. This module -- re-exports the Database.MongoDB.Structured.Types module, which -- exports a Structured type class --- this class is used to -- convert Haskell record types to and from BSON documents. The module -- Database.MongoDB.Structured.Query exports an interface similar -- to Database.MongoDB.Query which can be used to insert, query, -- update, delete, etc. record types from a Mongo DB. -- -- Though users may provide their own instances for Structured -- (and Selectable, used in composing well-typed queries), we -- provide a Template Haskell function (deriveStructured) that -- can be used to automatically do this. See -- Database.MongoDB.Structured.Deriving.TH. -- -- The example below shows how to use the structued MongoDB interface: -- --
-- {-# LANGUAGE TemplateHaskell #-}
-- {-# LANGUAGE TypeSynonymInstances #-}
-- {-# LANGUAGE MultiParamTypeClasses #-}
-- {-# LANGUAGE FlexibleInstances #-}
-- {-# LANGUAGE OverloadedStrings #-}
-- {-# LANGUAGE DeriveDataTypeable #-}
-- import Database.MongoDB.Structured
-- import Database.MongoDB.Structured.Deriving.TH
-- import Control.Monad.Trans (liftIO)
-- import Data.Typeable
-- import Control.Monad (mapM_)
-- import Control.Monad.IO.Class
-- import Data.Bson (Value)
-- import Data.Maybe (isJust, fromJust)
--
-- data Address = Address { addrId :: SObjId
-- , city :: String
-- , state :: String
-- } deriving (Show, Eq, Typeable)
-- $(deriveStructured ''Address)
--
-- data Team = Team { teamId :: SObjId
-- , name :: String
-- , home :: Address
-- , league :: String
-- } deriving (Show, Eq, Typeable)
-- $(deriveStructured ''Team)
--
-- main = do
-- pipe <- runIOE $ connect (host "127.0.0.1")
-- e <- access pipe master "baseball" run
-- close pipe
-- print e
--
-- run = do
-- clearTeams
-- insertTeams
-- allTeams >>= printDocs "All Teams"
-- nationalLeagueTeams >>= printDocs "National League Teams"
-- newYorkTeams >>= printDocs "New York Teams"
--
-- -- Delete all teams:
-- clearTeams :: Action IO ()
-- clearTeams = delete (select ( (.*) :: QueryExp Team))
--
-- insertTeams :: Action IO [Value]
-- insertTeams = insertMany [
-- Team { teamId = noSObjId
-- , name = "Yankees"
-- , home = Address { addrId = noSObjId
-- , city = "New York"
-- , state = "NY"
-- }
-- , league = "American"}
-- , Team { teamId = noSObjId
-- , name = "Mets"
-- , home = Address { addrId = noSObjId
-- , city = "New York"
-- , state = "NY"
-- }
-- , league = "National"}
-- , Team { teamId = noSObjId
-- , name = "Phillies"
-- , home = Address { addrId = noSObjId
-- , city = "Philadelphia"
-- , state = "PA"
-- }
-- , league = "National"}
-- , Team { teamId = noSObjId
-- , name = "Red Sox"
-- , home = Address { addrId = noSObjId
-- , city = "Boston"
-- , state = "MA"
-- }
-- , league = "National"}
-- ]
--
-- allTeams :: Action IO [Maybe Team]
-- allTeams = let query = (select ((.*) :: QueryExp Team))
-- { sort = [asc (Home .! City)]}
-- in find query >>= rest
--
-- nationalLeagueTeams :: Action IO [Maybe Team]
-- nationalLeagueTeams = rest =<< find (select (League .== "National"))
--
-- newYorkTeams :: Action IO [Maybe Team]
-- newYorkTeams = rest =<< find (select (Home .! State .== "NY"))
--
-- printDocs :: MonadIO m => String -> [Maybe Team] -> m ()
-- printDocs title teams' = liftIO $ do
-- let teams = (map fromJust) . filter (isJust) $ teams'
-- putStrLn title
-- mapM_ (putStrLn . show) teams
--
module Database.MongoDB.Structured
-- | This module exports a Structued type class which can be used
-- to convert from Haskel "record types" to BSON objects and
-- vice versa. We use Templace Haskell to provide a function
-- deriveStructured which can be used to automatically generate an
-- instance of such types for the Structured and BSON's
-- Val classes.
--
-- For instance:
--
--
-- data User = User { userId :: Int
-- , userFirstName :: String
-- , userLastName :: String
-- }
-- deriving(Show, Read, Eq, Ord, Typeable)
-- $(deriveStructured ''User)
--
--
--
-- deriveStrctured used used to create the following instance of
-- Structured:
--
--
-- instance Structured User where
-- toBSON x = [ (u "_id") := val (userId x)
-- , (u "userFirstName") := val (userFirstName x)
-- , (u "userLastName") := val (userLastName x)
-- ]
--
-- fromBSON doc = lookup (u "_id") doc >>= \val_1 ->
-- lookup (u "userFirstName") doc >>= \val_2 ->
-- lookup (u "userLastName") doc >>= \val_3 ->
-- return User { userId = val_1
-- , userFirstName = val_2
-- , userLastname = val_3
-- }
--
--
-- To allow for structured and well-typed queies, it also generates types
-- corresponding to each field (which are made an instance of
-- Selectable). Specifically, for the above data type, it creates:
--
-- -- data UserId = UserId deriving (Show, Eq) -- instance Selectable User UserId SObjId where s _ _ = "_id" -- -- data FirstName = FirstName deriving (Show, Eq) -- instance Selectable User FirstName String where s _ _ = "firstName" -- -- data LastName = LastName deriving (Show, Eq) -- instance Selectable User LastName String where s _ _ = "lastName" --module Database.MongoDB.Structured.Deriving.TH -- | This function generates Structured and Val instances -- for record types. deriveStructured :: Name -> Q [Dec]