-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Type-safe, relational, multi-backend persistence. -- -- This library provides just the general interface and helper functions. -- You must use a specific backend in order to make this useful. @package groundhog @version 0.0.1 -- | This module defines the functions and datatypes used throughout the -- framework. Most of them are for internal use module Database.Groundhog.Core -- | Only instances of this class can be persisted in a database class PersistField v => PersistEntity v where { data family Fields v :: * -> * -> *; } entityDef :: PersistEntity v => v -> EntityDef toPersistValues :: (PersistEntity v, PersistBackend m) => v -> m [PersistValue] fromPersistValues :: (PersistEntity v, PersistBackend m) => [PersistValue] -> m v getConstraints :: PersistEntity v => v -> (Int, [(String, [(String, PersistValue)])]) showField :: PersistEntity v => Fields v c a -> String eqField :: PersistEntity v => Fields v c a -> Fields v c a -> Bool -- | A raw value which can be stored in any backend and can be marshalled -- to and from a PersistField. data PersistValue PersistString :: String -> PersistValue PersistByteString :: ByteString -> PersistValue PersistInt64 :: Int64 -> PersistValue PersistDouble :: Double -> PersistValue PersistBool :: Bool -> PersistValue PersistDay :: Day -> PersistValue PersistTimeOfDay :: TimeOfDay -> PersistValue PersistUTCTime :: UTCTime -> PersistValue PersistNull :: PersistValue class PersistField a persistName :: PersistField a => a -> String toPersistValue :: (PersistField a, PersistBackend m) => a -> m PersistValue fromPersistValue :: (PersistField a, PersistBackend m) => PersistValue -> m a dbType :: PersistField a => a -> DbType -- | A unique identifier of a value stored in a database data PersistEntity v => Key v Key :: Int64 -> Key v -- | Represents condition for a query. data Cond v c And :: (Cond v c) -> (Cond v c) -> Cond v c Or :: (Cond v c) -> (Cond v c) -> Cond v c Not :: (Cond v c) -> Cond v c Lesser :: (Expr v c a) -> (Expr v c a) -> Cond v c Greater :: (Expr v c a) -> (Expr v c a) -> Cond v c Equals :: (Expr v c a) -> (Expr v c a) -> Cond v c NotEquals :: (Expr v c a) -> (Expr v c a) -> Cond v c -- | Lookup will be performed only in table for the specified constructor -- c. To fetch value by key without constructor limitation use get KeyIs :: (Key v) -> Cond v c data Update v c Update :: (Fields v c a) -> (Expr v c a) -> Update v c -- | Update field (=.) :: (Expression a, TypesCastV v (FuncV a) v, TypesCastC c (FuncC a) c) => Fields v c (FuncA a) -> a -> Update v c -- | Boolean "and" operator. (&&.) :: (TypesCastV v1 v2 v3, TypesCastC c1 c2 c3) => Cond v1 c1 -> Cond v2 c2 -> Cond v3 c3 -- | Boolean "or" operator. (||.) :: (TypesCastV v1 v2 v3, TypesCastC c1 c2 c3) => Cond v1 c1 -> Cond v2 c2 -> Cond v3 c3 (==.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a)) => a -> b -> Cond v c (/=.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a)) => a -> b -> Cond v c (<.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a), HasOrder (FuncA a)) => a -> b -> Cond v c (<=.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a), HasOrder (FuncA a)) => a -> b -> Cond v c (>.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a), HasOrder (FuncA a)) => a -> b -> Cond v c (>=.) :: (TypeCast a b v c, (FuncA a) ~ (FuncA b), PersistField (FuncA a), HasOrder (FuncA a)) => a -> b -> Cond v c -- | By default during converting values of certain types to Expr, -- the types can be changed. For example, Key a is -- transformed into a. It is convenient because the fields -- usually contain reference to a certain datatype, not its Key. -- But sometimes when automatic transformation gets in the way function -- wrapPrim will help. Use it when a field in a datatype has type -- (Key a) or Maybe (Key a). Example: -- --
-- data Example = Example {entity1 :: Maybe Smth, entity2 :: Key Smth}
-- Entity1Field ==. Just k &&. Entity2Field ==. wrapPrim k
--
wrapPrim :: Primitive a => a -> Expr Any Any a
-- | Convert field to an arithmetic value
toArith :: Fields v c a -> Arith v c a
-- | Instances of this type can be converted to Expr
class Expression a where { type family FuncV a; type family FuncC a; type family FuncA a; }
wrap :: Expression a => a -> Expr (FuncV a) (FuncC a) (FuncA a)
-- | Datatypes which can be converted directly to PersistValue
class Primitive a
toPrim :: Primitive a => a -> PersistValue
fromPrim :: Primitive a => PersistValue -> a
-- | The same goals as for Numeric. Certain types like String which
-- have order in Haskell may not have it in DB
class HasOrder a
-- | Constraint for use in arithmetic expressions. Num is not used
-- to explicitly include only types supported by the library . TODO:
-- consider replacement with Num
class Numeric a
-- | Types which when converted to PersistValue are never NULL.
-- Consider the type Maybe (Maybe a). Now Nothing is stored as
-- NULL, so we cannot distinguish between Just Nothing and Nothing which
-- is a problem. The purpose of this class is to ban the inner Maybe's.
-- Maybe this class can be removed when support for inner Maybe's
-- appears.
class NeverNull a
-- | Arithmetic expressions which can include fields and literals
data Arith v c a
Plus :: (Arith v c a) -> (Arith v c a) -> Arith v c a
Minus :: (Arith v c a) -> (Arith v c a) -> Arith v c a
Mult :: (Arith v c a) -> (Arith v c a) -> Arith v c a
Abs :: (Arith v c a) -> Arith v c a
ArithField :: (Fields v c a) -> Arith v c a
Lit :: Int64 -> Arith v c a
-- | Used to uniformly represent fields, literals and arithmetic
-- expressions. A value should be convertec to Expr for usage in
-- expressions
data Expr v c a
ExprPrim :: a -> Expr v c a
ExprField :: Fields v c a -> Expr v c a
ExprArith :: Arith v c a -> Expr v c a
ExprPlain :: a -> Expr v c (FuncA a)
-- | Defines sort order of a result-set
data Order v c
Asc :: (Fields v c a) -> Order v c
Desc :: (Fields v c a) -> Order v c
-- | A DB data type. Naming attempts to reflect the underlying Haskell
-- datatypes, eg DbString instead of DbVarchar. Different databases may
-- have different translations for these types.
data DbType
DbString :: DbType
DbInt32 :: DbType
DbInt64 :: DbType
DbReal :: DbType
DbBool :: DbType
DbDay :: DbType
DbTime :: DbType
DbDayTime :: DbType
DbBlob :: DbType
DbMaybe :: NamedType -> DbType
DbList :: NamedType -> DbType
DbTuple :: Int -> [NamedType] -> DbType
DbEntity :: EntityDef -> DbType
-- | It is used to store type DbType and persist name of a value
data NamedType
namedType :: PersistField v => v -> NamedType
getName :: NamedType -> String
getType :: NamedType -> DbType
-- | Describes an ADT.
data EntityDef
EntityDef :: String -> [NamedType] -> [ConstructorDef] -> EntityDef
-- | Emtity name
entityName :: EntityDef -> String
-- | Named types of the instantiated polymorphic type parameters
typeParams :: EntityDef -> [NamedType]
-- | List of entity constructors definitions
constructors :: EntityDef -> [ConstructorDef]
-- | Describes an entity constructor
data ConstructorDef
ConstructorDef :: Int -> String -> [(String, NamedType)] -> [Constraint] -> ConstructorDef
-- | Number of the constructor in the ADT
constrNum :: ConstructorDef -> Int
-- | Constructor name
constrName :: ConstructorDef -> String
-- | Parameter names with their named type
constrParams :: ConstructorDef -> [(String, NamedType)]
-- | Uniqueness constraints on the constructor fiels
constrConstrs :: ConstructorDef -> [Constraint]
-- | Phantom constructors are made instances of this class. This class
-- should be used only by Template Haskell codegen
class Constructor a
phantomConstrName :: Constructor a => a -> String
phantomConstrNum :: Constructor a => a -> Int
-- | Constraint name and list of the field names that form a unique
-- combination. Only fields of Primitive types can be used in a
-- constraint
type Constraint = (String, [String])
-- | Either error messages or migration queries with safety flags
type SingleMigration = Either [String] [(Bool, String)]
-- | Datatype names and corresponding migrations
type NamedMigrations = Map String SingleMigration
type Migration m = StateT NamedMigrations m ()
class Monad m => PersistBackend m
insert :: (PersistBackend m, PersistEntity v) => v -> m (Key v)
insertBy :: (PersistBackend m, PersistEntity v) => v -> m (Either (Key v) (Key v))
replace :: (PersistBackend m, PersistEntity v) => Key v -> v -> m ()
selectEnum :: (PersistBackend m, PersistEntity v, Constructor c) => Cond v c -> [Order v c] -> Int -> Int -> Enumerator (Key v, v) m a
selectAllEnum :: (PersistBackend m, PersistEntity v) => Enumerator (Key v, v) m a
select :: (PersistBackend m, PersistEntity v, Constructor c) => Cond v c -> [Order v c] -> Int -> Int -> m [(Key v, v)]
selectAll :: (PersistBackend m, PersistEntity v) => m [(Key v, v)]
get :: (PersistBackend m, PersistEntity v) => Key v -> m (Maybe v)
update :: (PersistBackend m, PersistEntity v, Constructor c) => [Update v c] -> Cond v c -> m ()
delete :: (PersistBackend m, PersistEntity v, Constructor c) => Cond v c -> m ()
deleteByKey :: (PersistBackend m, PersistEntity v) => Key v -> m ()
count :: (PersistBackend m, PersistEntity v, Constructor c) => Cond v c -> m Int
countAll :: (PersistBackend m, PersistEntity v) => v -> m Int
migrate :: (PersistBackend m, PersistEntity v) => v -> Migration m
executeRaw :: PersistBackend m => Bool -> String -> [PersistValue] -> m ()
queryRaw :: PersistBackend m => Bool -> String -> [PersistValue] -> (RowPopper m -> m a) -> m a
insertTuple :: PersistBackend m => NamedType -> [PersistValue] -> m Int64
getTuple :: PersistBackend m => NamedType -> Int64 -> m [PersistValue]
insertList :: (PersistBackend m, PersistField a) => [a] -> m Int64
getList :: (PersistBackend m, PersistField a) => Int64 -> m [a]
type RowPopper m = m (Maybe [PersistValue])
newtype Monad m => DbPersist conn m a
DbPersist :: ReaderT conn m a -> DbPersist conn m a
unDbPersist :: DbPersist conn m a -> ReaderT conn m a
runDbPersist :: Monad m => DbPersist conn m a -> conn -> m a
instance [overlap ok] Show (Fields v c a) => Show (Arith v c a)
instance [overlap ok] Eq (Fields v c a) => Eq (Arith v c a)
instance [overlap ok] Monad m => Monad (DbPersist conn m)
instance [overlap ok] MonadIO m => MonadIO (DbPersist conn m)
instance [overlap ok] Functor m => Functor (DbPersist conn m)
instance [overlap ok] Applicative m => Applicative (DbPersist conn m)
instance [overlap ok] MonadControlIO m => MonadControlIO (DbPersist conn m)
instance [overlap ok] MonadTrans (DbPersist conn)
instance [overlap ok] Show PersistValue
instance [overlap ok] Eq PersistValue
instance [overlap ok] Show DbType
instance [overlap ok] Show EntityDef
instance [overlap ok] Eq EntityDef
instance [overlap ok] Show ConstructorDef
instance [overlap ok] Eq ConstructorDef
instance [overlap ok] PersistEntity v => Show (Key v)
instance [overlap ok] (PersistField a, PersistField b, PersistField c, PersistField d, PersistField e) => PersistField (a, b, c, d, e)
instance [overlap ok] (PersistField a, PersistField b, PersistField c, PersistField d) => PersistField (a, b, c, d)
instance [overlap ok] (PersistField a, PersistField b, PersistField c) => PersistField (a, b, c)
instance [overlap ok] (PersistField a, PersistField b) => PersistField (a, b)
instance [overlap ok] PersistField a => PersistField [a]
instance [overlap ok] PersistEntity a => PersistField (Key a)
instance [overlap ok] (PersistField a, NeverNull a) => PersistField (Maybe a)
instance [overlap ok] PersistField UTCTime
instance [overlap ok] PersistField TimeOfDay
instance [overlap ok] PersistField Day
instance [overlap ok] PersistField Bool
instance [overlap ok] PersistField Double
instance [overlap ok] PersistField Word64
instance [overlap ok] PersistField Word32
instance [overlap ok] PersistField Word16
instance [overlap ok] PersistField Word8
instance [overlap ok] PersistField Int64
instance [overlap ok] PersistField Int32
instance [overlap ok] PersistField Int16
instance [overlap ok] PersistField Int8
instance [overlap ok] PersistField Int
instance [overlap ok] PersistField Text
instance [overlap ok] PersistField String
instance [overlap ok] PersistField ByteString
instance [overlap ok] Expression Bool
instance [overlap ok] Expression Text
instance [overlap ok] Expression ByteString
instance [overlap ok] Expression String
instance [overlap ok] Expression Word64
instance [overlap ok] Expression Word32
instance [overlap ok] Expression Word16
instance [overlap ok] Expression Word8
instance [overlap ok] Expression Int64
instance [overlap ok] Expression Int32
instance [overlap ok] Expression Int16
instance [overlap ok] Expression Int8
instance [overlap ok] Expression Int
instance [overlap ok] Expression (Key a)
instance [overlap ok] (Expression a, Primitive a, NeverNull a) => Expression (Maybe a)
instance [overlap ok] PersistEntity v => Expression (Arith v c a)
instance [overlap ok] PersistEntity v => Expression (Fields v c a)
instance [overlap ok] Expression (Expr v c a)
instance [overlap ok] PersistEntity a => NeverNull a
instance [overlap ok] NeverNull (a, b, c, d, e)
instance [overlap ok] NeverNull (a, b, c, d)
instance [overlap ok] NeverNull (a, b, c)
instance [overlap ok] NeverNull (a, b)
instance [overlap ok] NeverNull [a]
instance [overlap ok] NeverNull (Key a)
instance [overlap ok] NeverNull UTCTime
instance [overlap ok] NeverNull TimeOfDay
instance [overlap ok] NeverNull Day
instance [overlap ok] NeverNull Bool
instance [overlap ok] NeverNull Double
instance [overlap ok] NeverNull Int64
instance [overlap ok] NeverNull Int
instance [overlap ok] NeverNull ByteString
instance [overlap ok] NeverNull Text
instance [overlap ok] NeverNull String
instance [overlap ok] (Primitive a, NeverNull a) => Primitive (Maybe a)
instance [overlap ok] Primitive (Key a)
instance [overlap ok] Primitive UTCTime
instance [overlap ok] Primitive TimeOfDay
instance [overlap ok] Primitive Day
instance [overlap ok] Primitive Bool
instance [overlap ok] Primitive Double
instance [overlap ok] Primitive Word64
instance [overlap ok] Primitive Word32
instance [overlap ok] Primitive Word16
instance [overlap ok] Primitive Word8
instance [overlap ok] Primitive Int64
instance [overlap ok] Primitive Int32
instance [overlap ok] Primitive Int16
instance [overlap ok] Primitive Int8
instance [overlap ok] Primitive Int
instance [overlap ok] Primitive ByteString
instance [overlap ok] Primitive Text
instance [overlap ok] Primitive String
instance [overlap ok] HasOrder UTCTime
instance [overlap ok] HasOrder TimeOfDay
instance [overlap ok] HasOrder Day
instance [overlap ok] HasOrder Bool
instance [overlap ok] HasOrder Double
instance [overlap ok] HasOrder Word64
instance [overlap ok] HasOrder Word32
instance [overlap ok] HasOrder Word16
instance [overlap ok] HasOrder Word8
instance [overlap ok] HasOrder Int64
instance [overlap ok] HasOrder Int32
instance [overlap ok] HasOrder Int16
instance [overlap ok] HasOrder Int8
instance [overlap ok] HasOrder Int
instance [overlap ok] Numeric Double
instance [overlap ok] Numeric Word64
instance [overlap ok] Numeric Word32
instance [overlap ok] Numeric Word16
instance [overlap ok] Numeric Word8
instance [overlap ok] Numeric Int64
instance [overlap ok] Numeric Int32
instance [overlap ok] Numeric Int16
instance [overlap ok] Numeric Int8
instance [overlap ok] Numeric Int
instance [overlap ok] (Eq (Fields v c a), Show (Fields v c a), Numeric a) => Num (Arith v c a)
instance [overlap ok] Eq NamedType
instance [overlap ok] Show NamedType
instance [overlap ok] (Expression a, Expression b, TypesCastV (FuncV a) (FuncV b) v, TypesCastC (FuncC a) (FuncC b) c) => TypeCast a b v c
instance [overlap ok] (MoreSpecific x y ~ z, TypesEqualC x y) => TypesCastC x y z
instance [overlap ok] TypesEqualC Any Any
instance [overlap ok] TypesEqualC x Any
instance [overlap ok] TypesEqualC Any x
instance [overlap ok] TypesEqualC x x
instance [overlap ok] TypesCastV Any Any Any
instance [overlap ok] TypesCastV x Any x
instance [overlap ok] TypesCastV Any x x
instance [overlap ok] (x ~ y, MoreSpecific x y ~ z) => TypesCastV x y z
instance [overlap ok] PersistEntity v => Eq (Fields v c a)
instance [overlap ok] PersistEntity v => Show (Fields v c a)
-- | This helper module is intended for use by the backend creators
module Database.Groundhog.Generic
-- | Create migration for a given entity and all entities it depends on.
-- The stateful Map is used to avoid duplicate migrations when an entity
-- type occurs several times in a datatype
migrateRecursively :: (Monad m, PersistEntity e) => (EntityDef -> m SingleMigration) -> (Int -> [NamedType] -> m SingleMigration) -> (NamedType -> m SingleMigration) -> e -> StateT NamedMigrations m ()
-- | Produce the migrations but not execute them. Fails when an unsafe
-- migration occurs.
createMigration :: PersistBackend m => Migration m -> m NamedMigrations
-- | Execute the migrations and log them.
executeMigration :: (PersistBackend m, MonadIO m) => (String -> IO ()) -> NamedMigrations -> m ()
-- | Execute migrations and log them. Executes the unsafe migrations
-- without warnings
executeMigrationUnsafe :: (PersistBackend m, MonadIO m) => (String -> IO ()) -> NamedMigrations -> m ()
-- | Run migrations and log them. Fails when an unsafe migration occurs.
runMigration :: (PersistBackend m, MonadIO m) => (String -> IO ()) -> Migration m -> m ()
-- | Run migrations and log them. Executes the unsafe migrations without
-- warnings
runMigrationUnsafe :: (PersistBackend m, MonadIO m) => (String -> IO ()) -> Migration m -> m ()
-- | Pretty print the migrations
printMigration :: MonadIO m => NamedMigrations -> m ()
-- | Get full entity name with the names of its parameters.
--
-- -- getEntityName (entityDef v) == persistName v --getEntityName :: EntityDef -> String -- | Joins the migrations. The result is either all error messages or all -- queries mergeMigrations :: [SingleMigration] -> SingleMigration -- | No-op silentMigrationLogger :: String -> IO () -- | Prints the queries to stdout defaultMigrationLogger :: String -> IO () -- | Call selectEnum but return the result as a list defaultSelect :: (PersistBackend m, PersistEntity v, Constructor c) => Cond v c -> [Order v c] -> Int -> Int -> m [(Key v, v)] -- | Call selectAllEnum but return the result as a list defaultSelectAll :: (PersistBackend m, PersistEntity v) => m [(Key v, v)] -- | This module provides functions to generate the auxiliary structures -- for the user data type module Database.Groundhog.TH -- | Creates the auxiliary structures for a user datatype, which are -- required by Groundhog to manipulate it. -- -- It creates GADT Fields data instance for referring to the -- fields in expressions and phantom types for data constructors. For -- record constructors the Field name is the regular field name with -- first letter capitalized and postpended "Field". If the field is an -- ordinary constructor, its name is constructor name and postponed field -- name. The constructor phantom datatypes have the same name as -- constructors with "Constructor" postpended. -- -- The generation can be adjusted using the optional modifier function. -- Example: -- --
-- data SomeData a = Normal Int | Record { bar :: Maybe String, asc :: a}
-- deriveEntity ''SomeData $ Just $ do
-- setDbEntityName "SomeTableName"
-- setConstructor 'Normal $ do
-- setPhantomName "NormalConstructor" -- the same as default
--
--
-- It will generate these new datatypes and required instances.
--
-- -- data NormalConstructor -- data RecordConstructor -- instance PersistEntity where -- data Fields (SomeData a) where -- Normal0Field :: Fields NormalConstructor Int -- BarField :: Fields RecordConstructor (Maybe String) -- AscField :: Fields RecordConstructor a -- ... --deriveEntity :: Name -> Maybe (State THEntityDef ()) -> Q [Dec] -- | Set name of the table in the datatype setDbEntityName :: String -> State THEntityDef () -- | Modify constructor setConstructor :: Name -> State THConstructorDef () -> State THEntityDef () -- | Set name used to parametrise fields setPhantomName :: String -> State THConstructorDef () -- | Set name of the constructor specific table setDbConstrName :: String -> State THConstructorDef () -- | Set constraints of the constructor. The names should be database names -- of the fields setConstraints :: [Constraint] -> State THConstructorDef () -- | Modify field. Field name is a regular field name in record -- constructor. Otherwise, it is lower-case constructor name with field -- number. setField :: String -> State FieldDef () -> State THConstructorDef () -- | Set name of the field column in a database setDbFieldName :: String -> State FieldDef () -- | Set name of field constructor used in expressions setExprFieldName :: String -> State FieldDef () instance Show FieldDef instance Show THConstructorDef instance Show THEntityDef -- | This module defines the functions which are used only for backends -- creation. module Database.Groundhog.Generic.Sql renderCond :: PersistEntity v => (String -> String) -> String -> (forall a. PersistField a => (String -> String) -> Expr v c a -> Expr v c a -> RenderS) -> (forall a. PersistField a => (String -> String) -> Expr v c a -> Expr v c a -> RenderS) -> Cond v c -> RenderS defaultShowPrim :: PersistValue -> String renderArith :: PersistEntity v => (String -> String) -> Arith v c a -> RenderS renderOrders :: PersistEntity v => (String -> String) -> [Order v c] -> ShowS renderUpdates :: PersistEntity v => (String -> String) -> [Update v c] -> RenderS defId :: String defDelim :: Char defRenderEquals :: PersistField a => (String -> String) -> Expr v c a -> Expr v c a -> RenderS defRenderNotEquals :: PersistField a => (String -> String) -> Expr v c a -> Expr v c a -> RenderS renderExpr :: (String -> String) -> Expr v c a -> RenderS type RenderS = (ShowS, [PersistValue] -> [PersistValue]) (<>) :: RenderS -> RenderS -> RenderS -- | This module exports the most commonly used functions and datatypes. -- -- An example which shows the main features: -- --
-- {-# LANGUAGE GADTs, TypeFamilies, TemplateHaskell #-}
-- import Control.Monad.IO.Class(liftIO)
-- import Database.Groundhog.Sqlite
-- import Database.Groundhog.TH
--
-- data Customer a = Customer {customerName :: String, details :: a} deriving Show
-- data Item = ProductItem {productName :: String, quantity :: Int, customer :: Customer String}
-- | ServiceItem {serviceName :: String, deliveryAddress :: String, servicePrice :: Int}
-- deriving Show
--
-- deriveEntity ''Customer $ Just $ do
-- setConstructor 'Customer $ do
-- setConstraints [("NameConstraint", ["customerName"])]
-- deriveEntity ''Item Nothing
--
-- main = withSqliteConn ":memory:" $ runSqliteConn $ do
-- -- Customer is also migrated because Item contains it
-- runMigration silentMigrationLogger $ migrate (undefined :: Item)
-- let john = Customer "John Doe" "Phone: 01234567"
-- johnKey <- insert john
-- -- John is inserted only once because of the name constraint
-- insert $ ProductItem "Apples" 5 john
-- insert $ ProductItem "Melon" 2 john
-- insert $ ServiceItem "Taxi" "Elm Street" 50
-- insert $ ProductItem "Melon" 6 (Customer "Jack Smith" "Don't let him pay by check")
-- -- bonus melon for all large melon orders
-- update [QuantityField =. toArith QuantityField + 1] (ProductNameField ==. "Melon" &&. QuantityField >. (5 :: Int))
-- productsForJohn <- select (CustomerField ==. johnKey) [] 0 0
-- liftIO $ putStrLn $ "Products for John: " ++ show productsForJohn
-- -- let's check bonus
-- melon <- select (ProductNameField ==. "Melon") [Desc QuantityField] 0 0
-- liftIO $ putStrLn $ "Melon orders: " ++ show melon
--
module Database.Groundhog