-- 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