groundhog-postgresql 0.3.1 → 0.4.0
raw patch · 4 files changed
+118/−192 lines, 4 filesdep +monad-loggerdep ~blaze-builderdep ~groundhogdep ~monad-controlPVP ok
version bump matches the API change (PVP)
Dependencies added: monad-logger
Dependency ranges changed: blaze-builder, groundhog, monad-control, postgresql-libpq, resource-pool, text, transformers
API changes (from Hackage documentation)
- Database.Groundhog.Postgresql: instance (MonadBaseControl IO m, MonadIO m) => PersistBackend (DbPersist Postgresql m)
- Database.Groundhog.Postgresql: instance (MonadBaseControl IO m, MonadIO m) => SchemaAnalyzer (DbPersist Postgresql m)
- Database.Groundhog.Postgresql.Array: instance [overlap ok] (ArrayElem a, PersistField a) => PurePersistField (Array a)
- Database.Groundhog.Postgresql.Array: instance [overlap ok] (ArrayElem a, PersistField a) => SinglePersistField (Array a)
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Box
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Circle
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Line
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Lseg
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Path
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Point
- Database.Groundhog.Postgresql.Geometry: instance PurePersistField Polygon
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Box
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Circle
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Line
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Lseg
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Path
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Point
- Database.Groundhog.Postgresql.Geometry: instance SinglePersistField Polygon
+ Database.Groundhog.Postgresql: instance (MonadBaseControl IO m, MonadIO m, MonadLogger m) => PersistBackend (DbPersist Postgresql m)
+ Database.Groundhog.Postgresql: instance (MonadBaseControl IO m, MonadIO m, MonadLogger m) => SchemaAnalyzer (DbPersist Postgresql m)
- Database.Groundhog.Postgresql: runDbConn :: (MonadBaseControl IO m, MonadIO m, ConnectionManager cm conn) => DbPersist conn m a -> cm -> m a
+ Database.Groundhog.Postgresql: runDbConn :: (MonadBaseControl IO m, MonadIO m, ConnectionManager cm conn) => DbPersist conn (NoLoggingT m) a -> cm -> m a
Files
- Database/Groundhog/Postgresql.hs +79/−93
- Database/Groundhog/Postgresql/Array.hs +5/−10
- Database/Groundhog/Postgresql/Geometry.hs +25/−81
- groundhog-postgresql.cabal +9/−8
Database/Groundhog/Postgresql.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, FlexibleContexts, OverloadedStrings, TypeFamilies, MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, FlexibleContexts, OverloadedStrings, TypeFamilies, MultiParamTypeClasses, TemplateHaskell #-} module Database.Groundhog.Postgresql ( withPostgresqlPool , withPostgresqlConn@@ -18,7 +18,6 @@ import qualified Database.Groundhog.Generic.PersistBackendHelpers as H import qualified Database.PostgreSQL.Simple as PG-import qualified Database.PostgreSQL.Simple.BuiltinTypes as PG import qualified Database.PostgreSQL.Simple.Internal as PG import qualified Database.PostgreSQL.Simple.ToField as PGTF import qualified Database.PostgreSQL.Simple.FromField as PGFF@@ -28,18 +27,18 @@ import Control.Arrow ((***)) import Control.Exception (throw)-import Control.Monad (forM, liftM, liftM2)+import Control.Monad (forM, liftM, liftM2, (>=>)) import Control.Monad.IO.Class (MonadIO(..))+import Control.Monad.Logger (MonadLogger, logDebugS) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Trans.Reader (ask) import Data.ByteString.Char8 (pack, unpack, copy)-import Data.Char (toUpper)-import Data.Either (partitionEithers)+import Data.Char (isAlphaNum, isSpace, toUpper) import Data.Function (on) import Data.Int (Int64) import Data.IORef-import Data.List (groupBy, intercalate)+import Data.List (groupBy, intercalate, stripPrefix) import Data.Maybe (fromJust, fromMaybe) import Data.Monoid import Data.Pool@@ -56,8 +55,7 @@ instance SqlDb Postgresql where append a b = Expr $ operator 50 "||" a b -instance (MonadBaseControl IO m, MonadIO m) => PersistBackend (DbPersist Postgresql m) where- {-# SPECIALIZE instance PersistBackend (DbPersist Postgresql IO) #-}+instance (MonadBaseControl IO m, MonadIO m, MonadLogger m) => PersistBackend (DbPersist Postgresql m) where type PhantomDb (DbPersist Postgresql m) = Postgresql insert v = insert' v insert_ v = insert_' v@@ -82,7 +80,7 @@ insertList l = insertList' l getList k = getList' k -instance (MonadBaseControl IO m, MonadIO m) => SchemaAnalyzer (DbPersist Postgresql m) where+instance (MonadBaseControl IO m, MonadIO m, MonadLogger m) => SchemaAnalyzer (DbPersist Postgresql m) where listTables schema = queryRaw' "SELECT table_name FROM information_schema.tables WHERE table_schema=coalesce(?,current_schema())" [toPrimitivePersistValue proxy schema] (mapAllRows $ return . fst . fromPurePersistValues proxy) listTableTriggers schema name = queryRaw' "SELECT trigger_name FROM information_schema.triggers WHERE event_object_schema=coalesce(?,current_schema()) AND event_object_table=?" [toPrimitivePersistValue proxy schema, toPrimitivePersistValue proxy name] (mapAllRows $ return . fst . fromPurePersistValues proxy) analyzeTable = analyzeTable'@@ -143,8 +141,7 @@ close' :: Postgresql -> IO () close' (Postgresql conn) = PG.close conn -{-# SPECIALIZE insert' :: PersistEntity v => v -> DbPersist Postgresql IO (AutoKey v) #-}-insert' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m) => v -> DbPersist Postgresql m (AutoKey v)+insert' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m, MonadLogger m) => v -> DbPersist Postgresql m (AutoKey v) insert' v = do -- constructor number and the rest of the field values vals <- toEntityPersistValues' v@@ -170,8 +167,7 @@ executeRaw' cQuery (vals' []) pureFromPersistValue [rowid] -{-# SPECIALIZE insert_' :: PersistEntity v => v -> DbPersist Postgresql IO () #-}-insert_' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m) => v -> DbPersist Postgresql m ()+insert_' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m, MonadLogger m) => v -> DbPersist Postgresql m () insert_' v = do -- constructor number and the rest of the field values vals <- toEntityPersistValues' v@@ -201,7 +197,7 @@ fieldNames = renderFields escapeS fields RenderS placeholders vals' = commasJoin $ map renderPersistValue vals -insertList' :: forall m a.(MonadBaseControl IO m, MonadIO m, PersistField a) => [a] -> DbPersist Postgresql m Int64+insertList' :: forall m a.(MonadBaseControl IO m, MonadIO m, MonadLogger m, PersistField a) => [a] -> DbPersist Postgresql m Int64 insertList' (l :: [a]) = do let mainName = "List" <> delim' <> delim' <> fromString (persistName (undefined :: a)) k <- queryRaw' ("INSERT INTO " <> escapeS mainName <> " DEFAULT VALUES RETURNING(id)") [] getKey@@ -217,7 +213,7 @@ go 0 l return $ fromPrimitivePersistValue proxy k -getList' :: forall m a.(MonadBaseControl IO m, MonadIO m, PersistField a) => Int64 -> DbPersist Postgresql m [a]+getList' :: forall m a.(MonadBaseControl IO m, MonadIO m, MonadLogger m, PersistField a) => Int64 -> DbPersist Postgresql m [a] getList' k = do let mainName = "List" <> delim' <> delim' <> fromString (persistName (undefined :: a)) let valuesName = mainName <> delim' <> "values"@@ -232,9 +228,9 @@ ---------- -executeRaw' :: MonadIO m => Utf8 -> [PersistValue] -> DbPersist Postgresql m ()+executeRaw' :: (MonadIO m, MonadLogger m) => Utf8 -> [PersistValue] -> DbPersist Postgresql m () executeRaw' query vals = do- --liftIO $ print $ fromUtf8 query ""+ $logDebugS "SQL" $ fromString $ show (fromUtf8 query) ++ " " ++ show vals Postgresql conn <- DbPersist ask let stmt = getStatement query liftIO $ do@@ -252,34 +248,34 @@ delim' :: Utf8 delim' = fromChar delim -toEntityPersistValues' :: (MonadBaseControl IO m, MonadIO m, PersistEntity v) => v -> DbPersist Postgresql m [PersistValue]+toEntityPersistValues' :: (MonadBaseControl IO m, MonadIO m, PersistEntity v, MonadLogger m) => v -> DbPersist Postgresql m [PersistValue] toEntityPersistValues' = liftM ($ []) . toEntityPersistValues --- MIGRATION -migrate' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m) => v -> Migration (DbPersist Postgresql m)+migrate' :: (PersistEntity v, MonadBaseControl IO m, MonadIO m, MonadLogger m) => v -> Migration (DbPersist Postgresql m) migrate' v = do x <- lift $ queryRaw' "SELECT current_schema()" [] id let schema = fst $ fromPurePersistValues proxy $ fromJust x migrateRecursively (migrateEntity $ migrationPack schema) (migrateList $ migrationPack schema) v -migrationPack :: (MonadBaseControl IO m, MonadIO m) => String -> GM.MigrationPack (DbPersist Postgresql m)+migrationPack :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => String -> GM.MigrationPack (DbPersist Postgresql m) migrationPack currentSchema = GM.MigrationPack compareTypes (compareRefs currentSchema) compareUniqs+ compareDefaults migTriggerOnDelete migTriggerOnUpdate GM.defaultMigConstr escape- DbInt64 "SERIAL PRIMARY KEY UNIQUE"- "INT8" mainTableId defaultPriority (\uniques refs -> ([], map AddUnique uniques ++ map AddReference refs)) showColumn showAlterDb+ NoAction showColumn :: Column -> String showColumn (Column n nu t def) = concat@@ -293,7 +289,7 @@ Just s -> " DEFAULT " ++ s ] -migTriggerOnDelete :: (MonadBaseControl IO m, MonadIO m) => Maybe String -> String -> [(String, String)] -> DbPersist Postgresql m (Bool, [AlterDB])+migTriggerOnDelete :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Maybe String -> String -> [(String, String)] -> DbPersist Postgresql m (Bool, [AlterDB]) migTriggerOnDelete schema name deletes = do let funcName = name let trigName = name@@ -326,7 +322,7 @@ -- | Table name and a list of field names and according delete statements -- assume that this function is called only for ephemeral fields-migTriggerOnUpdate :: (MonadBaseControl IO m, MonadIO m) => Maybe String -> String -> [(String, String)] -> DbPersist Postgresql m [(Bool, [AlterDB])]+migTriggerOnUpdate :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Maybe String -> String -> [(String, String)] -> DbPersist Postgresql m [(Bool, [AlterDB])] migTriggerOnUpdate schema name dels = forM dels $ \(fieldName, del) -> do let funcName = name ++ delim : fieldName let trigName = name ++ delim : fieldName@@ -351,7 +347,7 @@ else [DropTrigger schema trigName schema name, addTrigger]) return (trigExisted, funcMig ++ trigMig) -analyzeTable' :: (MonadBaseControl IO m, MonadIO m) => Maybe String -> String -> DbPersist Postgresql m (Either [String] (Maybe TableInfo))+analyzeTable' :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Maybe String -> String -> DbPersist Postgresql m (Maybe TableInfo) analyzeTable' schema name = do table <- queryRaw' "SELECT * FROM information_schema.tables WHERE table_schema = coalesce(?, current_schema()) AND table_name = ?" [toPrimitivePersistValue proxy schema, toPrimitivePersistValue proxy name] id case table of@@ -368,8 +364,6 @@ \ ORDER BY c.ordinal_position" cols <- queryRaw' colQuery [toPrimitivePersistValue proxy schema, toPrimitivePersistValue proxy name] (mapAllRows $ return . getColumn name . fst . fromPurePersistValues proxy)- let (col_errs, cols') = partitionEithers cols- let constraintQuery = "SELECT u.constraint_name, u.column_name FROM information_schema.table_constraints tc INNER JOIN information_schema.constraint_column_usage u ON tc.constraint_catalog=u.constraint_catalog AND tc.constraint_schema=u.constraint_schema AND tc.constraint_name=u.constraint_name WHERE tc.constraint_type=? AND tc.table_schema=coalesce(?,current_schema()) AND u.table_name=? ORDER BY u.constraint_name, u.column_name" uniqConstraints <- queryRaw' constraintQuery [toPrimitivePersistValue proxy ("UNIQUE" :: String), toPrimitivePersistValue proxy schema, toPrimitivePersistValue proxy name] (mapAllRows $ return . fst . fromPurePersistValues proxy)@@ -378,16 +372,14 @@ let mkUniqs typ = map (\us -> UniqueDef' (fst $ head us) typ (map snd us)) . groupBy ((==) `on` fst) let uniqs = mkUniqs UniqueConstraint uniqConstraints ++ mkUniqs UniqueIndex uniqIndexes ++ mkUniqs UniquePrimary uniqPrimary references <- analyzeTableReferences schema name- return $ case col_errs of- [] -> Right $ Just $ TableInfo cols' uniqs references- errs -> Left errs- Nothing -> return $ Right Nothing+ return $ Just $ TableInfo cols uniqs references+ Nothing -> return Nothing -getColumn :: String -> ((String, String, String, Maybe String), (Maybe Int, Maybe Int, Maybe Int, Maybe Int, Maybe String), (Int, Maybe String)) -> Either String Column-getColumn _ ((column_name, is_nullable, udt_name, d), modifiers, arr_info) = Right $ Column column_name (is_nullable == "YES") t d where+getColumn :: String -> ((String, String, String, Maybe String), (Maybe Int, Maybe Int, Maybe Int, Maybe Int, Maybe String), (Int, Maybe String)) -> Column+getColumn _ ((column_name, is_nullable, udt_name, d), modifiers, arr_info) = Column column_name (is_nullable == "YES") t d where t = readSqlType udt_name modifiers arr_info -analyzeTableReferences :: (MonadBaseControl IO m, MonadIO m) => Maybe String -> String -> DbPersist Postgresql m [(Maybe String, Reference)]+analyzeTableReferences :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Maybe String -> String -> DbPersist Postgresql m [(Maybe String, Reference)] analyzeTableReferences schema tName = do let sql = "SELECT c.conname, sch_parent.nspname, cl_parent.relname, c. confdeltype, c.confupdtype, a_child.attname AS child, a_parent.attname AS parent FROM\ \ (SELECT r.conrelid, r.confrelid, unnest(r.conkey) AS conkey, unnest(r.confkey) AS confkey, r.conname, r.confupdtype, r.confdeltype\@@ -546,7 +538,7 @@ ]) -- | udt_name, character_maximum_length, numeric_precision, numeric_scale, datetime_precision, interval_type-readSqlType :: String -> (Maybe Int, Maybe Int, Maybe Int, Maybe Int, Maybe String) -> (Int, Maybe String) -> DbType+readSqlType :: String -> (Maybe Int, Maybe Int, Maybe Int, Maybe Int, Maybe String) -> (Int, Maybe String) -> DbTypePrimitive readSqlType typ (character_maximum_length, numeric_precision, numeric_scale, datetime_precision, _) (array_ndims, array_elem) = (case typ of "int4" -> DbInt32 "int8" -> DbInt64@@ -570,22 +562,20 @@ defDateTimePrec = 6 datetime_precision' = datetime_precision >>= \p -> if p == defDateTimePrec then Nothing else Just p -showSqlType :: DbType -> String-showSqlType DbString = "VARCHAR"-showSqlType DbInt32 = "INT4"-showSqlType DbInt64 = "INT8"-showSqlType DbReal = "DOUBLE PRECISION"-showSqlType DbBool = "BOOLEAN"-showSqlType DbDay = "DATE"-showSqlType DbTime = "TIME"-showSqlType DbDayTime = "TIMESTAMP"-showSqlType DbDayTimeZoned = "TIMESTAMP WITH TIME ZONE"-showSqlType DbBlob = "BYTEA"-showSqlType (DbOther (OtherTypeDef f)) = f showSqlType-showSqlType (DbMaybe t) = showSqlType t-showSqlType (DbList _ _) = showSqlType DbInt64-showSqlType (DbEntity Nothing _ _ _) = showSqlType DbInt64-showSqlType t = error $ "showSqlType: DbType does not have corresponding database type: " ++ show t+showSqlType :: DbTypePrimitive -> String+showSqlType t = case t of+ DbString -> "VARCHAR"+ DbInt32 -> "INT4"+ DbInt64 -> "INT8"+ DbReal -> "DOUBLE PRECISION"+ DbBool -> "BOOLEAN"+ DbDay -> "DATE"+ DbTime -> "TIME"+ DbDayTime -> "TIMESTAMP"+ DbDayTimeZoned -> "TIMESTAMP WITH TIME ZONE"+ DbBlob -> "BYTEA"+ DbOther (OtherTypeDef f) -> f showSqlType+ DbAutoKey -> showSqlType DbInt64 compareUniqs :: UniqueDef' -> UniqueDef' -> Bool compareUniqs (UniqueDef' _ UniquePrimary cols1) (UniqueDef' _ UniquePrimary cols2) = haveSameElems (==) cols1 cols2@@ -602,10 +592,15 @@ && fromMaybe NoAction onUpd1 == fromMaybe NoAction onUpd2 where unescape name = if head name == '"' && last name == '"' then tail $ init name else name -compareTypes :: DbType -> DbType -> Bool+compareTypes :: DbTypePrimitive -> DbTypePrimitive -> Bool compareTypes type1 type2 = f type1 == f type2 where f = map toUpper . showSqlType +compareDefaults :: String -> String -> Bool+compareDefaults def1 def2 = Just def2 `elem` [Just def1, stripType def1, stripType def1 >>= stripParens] where+ stripType = fmap reverse . stripPrefix "::" . dropWhile (\c -> isAlphaNum c || isSpace c) . reverse+ stripParens = stripPrefix "(" >=> fmap reverse . stripPrefix ")" . reverse+ defaultPriority, referencePriority, functionPriority, triggerPriority :: Int defaultPriority = 0 referencePriority = 1@@ -624,11 +619,12 @@ getStatement :: Utf8 -> PG.Query getStatement sql = PG.Query $ fromUtf8 sql -queryRawTyped' :: (MonadBaseControl IO m, MonadIO m) => Utf8 -> [DbType] -> [PersistValue] -> (RowPopper (DbPersist Postgresql m) -> DbPersist Postgresql m a) -> DbPersist Postgresql m a+queryRawTyped' :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Utf8 -> [DbType] -> [PersistValue] -> (RowPopper (DbPersist Postgresql m) -> DbPersist Postgresql m a) -> DbPersist Postgresql m a queryRawTyped' query _ vals f = queryRaw' query vals f -queryRaw' :: (MonadBaseControl IO m, MonadIO m) => Utf8 -> [PersistValue] -> (RowPopper (DbPersist Postgresql m) -> DbPersist Postgresql m a) -> DbPersist Postgresql m a+queryRaw' :: (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Utf8 -> [PersistValue] -> (RowPopper (DbPersist Postgresql m) -> DbPersist Postgresql m a) -> DbPersist Postgresql m a queryRaw' query vals f = do+ $logDebugS "SQL" $ fromString $ show (fromUtf8 query) ++ " " ++ show vals Postgresql conn <- DbPersist ask rawquery <- liftIO $ PG.formatQuery conn (getStatement query) (map P vals) -- Take raw connection@@ -657,16 +653,7 @@ cols <- LibPQ.nfields ret getters <- forM [0..cols-1] $ \col -> do oid <- LibPQ.ftype ret col- case PG.oid2builtin oid of- -- TODO: this is a temporary hack until postgresql-simple supports arrays and has more builtin types. Restore fail clause then.- Nothing -> return $ getGetter PG.Unknown $- PG.Field ret col oid- {- fail $ "Postgresql.withStmt': could not " ++- "recognize " ++ show oid ++ " of column " ++- show (let LibPQ.Col i = col in i) ++- " (counting from zero)" -}- Just bt -> return $ getGetter bt $- PG.Field ret col oid+ return $ getGetter oid $ PG.Field ret col oid -- Ready to go! rowRef <- newIORef (LibPQ.Row 0) rowCount <- LibPQ.ntuples ret@@ -708,35 +695,34 @@ convertPV :: PGFF.FromField a => (a -> b) -> Getter b convertPV f = (fmap f .) . PGFF.fromField --- FIXME: check if those are correct and complete.-getGetter :: PG.BuiltinType -> Getter PersistValue-getGetter PG.Bool = convertPV PersistBool-getGetter PG.ByteA = convertPV (PersistByteString . unBinary)-getGetter PG.Char = convertPV PersistString-getGetter PG.Name = convertPV PersistString-getGetter PG.Int8 = convertPV PersistInt64-getGetter PG.Int2 = convertPV PersistInt64-getGetter PG.Int4 = convertPV PersistInt64-getGetter PG.Text = convertPV PersistString-getGetter PG.Xml = convertPV PersistString-getGetter PG.Float4 = convertPV PersistDouble-getGetter PG.Float8 = convertPV PersistDouble-getGetter PG.AbsTime = convertPV PersistUTCTime-getGetter PG.RelTime = convertPV PersistUTCTime---getGetter PG.Money = convertPV PersistString-getGetter PG.BpChar = convertPV PersistString-getGetter PG.VarChar = convertPV PersistString-getGetter PG.Date = convertPV PersistDay-getGetter PG.Time = convertPV PersistTimeOfDay-getGetter PG.Timestamp = convertPV (PersistUTCTime . localTimeToUTC utc)-getGetter PG.TimestampTZ = convertPV (PersistZonedTime . ZT)-getGetter PG.Bit = convertPV PersistInt64-getGetter PG.VarBit = convertPV PersistInt64-getGetter PG.Numeric = convertPV (PersistDouble . fromRational)-getGetter PG.Void = \_ _ -> return PersistNull-getGetter _ = \f dat -> fmap (PersistByteString . unBinary) $ case dat of- Nothing -> PGFF.returnError PGFF.UnexpectedNull f ""- Just str -> return $ PG.Binary $ copy $ str+getGetter :: PG.Oid -> Getter PersistValue+getGetter (PG.Oid oid) = case oid of+ 16 -> convertPV PersistBool+ 17 -> convertPV (PersistByteString . unBinary)+ 18 -> convertPV PersistString+ 19 -> convertPV PersistString+ 20 -> convertPV PersistInt64+ 21 -> convertPV PersistInt64+ 23 -> convertPV PersistInt64+ 25 -> convertPV PersistString+ 142 -> convertPV PersistString+ 700 -> convertPV PersistDouble+ 701 -> convertPV PersistDouble+ 702 -> convertPV PersistUTCTime+ 703 -> convertPV PersistUTCTime+ 1042 -> convertPV PersistString+ 1043 -> convertPV PersistString+ 1082 -> convertPV PersistDay+ 1083 -> convertPV PersistTimeOfDay+ 1114 -> convertPV (PersistUTCTime . localTimeToUTC utc)+ 1184 -> convertPV (PersistZonedTime . ZT)+ 1560 -> convertPV PersistInt64+ 1562 -> convertPV PersistInt64+ 1700 -> convertPV (PersistDouble . fromRational)+ 2278 -> \_ _ -> return PersistNull+ _ -> \f dat -> fmap PersistByteString $ case dat of+ Nothing -> PGFF.returnError PGFF.UnexpectedNull f ""+ Just str -> return $ copy $ str unBinary :: PG.Binary a -> a unBinary (PG.Binary x) = x
Database/Groundhog/Postgresql/Array.hs view
@@ -49,8 +49,11 @@ persistName a = "Array" ++ delim : persistName ((undefined :: Array a -> a) a) toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType a = DbOther $ OtherTypeDef $ \f -> f elemType ++ "[]" where - elemType = dbType ((undefined :: Array a -> a) a) + dbType a = DbTypePrimitive typ False Nothing Nothing where + typ = DbOther $ OtherTypeDef $ \f -> f elemType ++ "[]" + elemType = case dbType ((undefined :: Array a -> a) a) of + DbTypePrimitive t _ _ _ -> t + t -> error $ "dbType " ++ persistName a ++ ": expected DbTypePrimitive, got " ++ show t class ArrayElem a where -- this function is added to avoid GHC bug 7126 which appears when PrimitivePersistField is added as class constraint @@ -71,14 +74,6 @@ fromPrimitivePersistValue p a = parseHelper parser a where dimensions = char '[' *> takeWhile1 (/= '=') *> char '=' parser = optional dimensions *> parseArr p - -instance (ArrayElem a, PersistField a) => SinglePersistField (Array a) where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance (ArrayElem a, PersistField a) => PurePersistField (Array a) where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues parseString :: Parser ByteString parseString = (char '"' *> jstring_)
Database/Groundhog/Postgresql/Geometry.hs view
@@ -41,77 +41,45 @@ points :: Parser [Point] points = point `sepBy1` char ',' -instance PersistField Point where - persistName _ = "Point" - toPersistValues = primToPersistValue - fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "point" - instance PrimitivePersistField Point where toPrimitivePersistValue _ (Point x y) = PersistString $ show (x, y) fromPrimitivePersistValue _ = parseHelper point -instance SinglePersistField Point where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Point where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues - -instance PersistField Line where - persistName _ = "Line" +instance PersistField Point where + persistName _ = "Point" toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "line" + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "point") False Nothing Nothing instance PrimitivePersistField Line where toPrimitivePersistValue _ (Line (Point x1 y1) (Point x2 y2)) = PersistString $ show ((x1, y1), (x2, y2)) fromPrimitivePersistValue _ = error "fromPrimitivePersistValue Line is not supported yet" -instance SinglePersistField Line where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Line where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues - -instance PersistField Lseg where - persistName _ = "Lseg" +instance PersistField Line where + persistName _ = "Line" toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "lseg" + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "line") False Nothing Nothing instance PrimitivePersistField Lseg where toPrimitivePersistValue _ (Lseg (Point x1 y1) (Point x2 y2)) = PersistString $ show ((x1, y1), (x2, y2)) fromPrimitivePersistValue _ = parseHelper $ pair Lseg '[' ']' point -instance SinglePersistField Lseg where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Lseg where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues - -instance PersistField Box where - persistName _ = "Box" +instance PersistField Lseg where + persistName _ = "Lseg" toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "box" + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "lseg") False Nothing Nothing instance PrimitivePersistField Box where toPrimitivePersistValue _ (Box (Point x1 y1) (Point x2 y2)) = PersistString $ show ((x1, y1), (x2, y2)) fromPrimitivePersistValue _ = parseHelper $ Box <$> (point <* char ',') <*> point -instance SinglePersistField Box where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Box where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues +instance PersistField Box where + persistName _ = "Box" + toPersistValues = primToPersistValue + fromPersistValues = primFromPersistValue + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "box") False Nothing Nothing showPath :: Char -> Char -> [Point] -> ShowS showPath open close [] s = open : close : s @@ -123,12 +91,6 @@ showPoint :: Point -> ShowS showPoint (Point x y) = shows (x, y) -instance PersistField Path where - persistName _ = "Path" - toPersistValues = primToPersistValue - fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "path" - instance PrimitivePersistField Path where toPrimitivePersistValue _ path = PersistString $ case path of ClosedPath ps -> showPath '(' ')' ps "" @@ -136,46 +98,28 @@ fromPrimitivePersistValue _ = parseHelper $ path' ClosedPath '(' ')' <|> path' OpenPath '[' ']' where path' f open close = f <$> (char open *> points <* char close) -instance SinglePersistField Path where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Path where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues - -instance PersistField Polygon where - persistName _ = "Polygon" +instance PersistField Path where + persistName _ = "Path" toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "polygon" + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "path") False Nothing Nothing instance PrimitivePersistField Polygon where toPrimitivePersistValue _ (Polygon ps) = PersistString $ showPath '(' ')' ps "" fromPrimitivePersistValue _ = parseHelper $ Polygon <$> (char '(' *> points <* char ')') -instance SinglePersistField Polygon where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Polygon where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues - -instance PersistField Circle where - persistName _ = "Circle" +instance PersistField Polygon where + persistName _ = "Polygon" toPersistValues = primToPersistValue fromPersistValues = primFromPersistValue - dbType _ = DbOther $ OtherTypeDef $ const "circle" + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "polygon") False Nothing Nothing instance PrimitivePersistField Circle where toPrimitivePersistValue _ (Circle (Point x1 y1) r) = PersistString $ show ((x1, y1), r) fromPrimitivePersistValue _ = parseHelper $ Circle <$> (char '<' *> point) <* char ',' <*> double <* char '>' -instance SinglePersistField Circle where - toSinglePersistValue = primToSinglePersistValue - fromSinglePersistValue = primFromSinglePersistValue - -instance PurePersistField Circle where - toPurePersistValues = primToPurePersistValues - fromPurePersistValues = primFromPurePersistValues +instance PersistField Circle where + persistName _ = "Circle" + toPersistValues = primToPersistValue + fromPersistValues = primFromPersistValue + dbType _ = DbTypePrimitive (DbOther $ OtherTypeDef $ const "circle") False Nothing Nothing
groundhog-postgresql.cabal view
@@ -1,5 +1,5 @@ name: groundhog-postgresql-version: 0.3.1+version: 0.4.0 license: BSD3 license-file: LICENSE author: Boris Lykah <lykahb@gmail.com>@@ -14,16 +14,17 @@ library build-depends: base >= 4 && < 5 , postgresql-simple >= 0.3 && < 0.4- , postgresql-libpq >= 0.6.1 && < 0.9+ , postgresql-libpq >= 0.6.1 , bytestring >= 0.9- , blaze-builder >= 0.3.0.0 && < 0.4- , transformers >= 0.2.1 && < 0.4- , groundhog >= 0.3.0 && < 0.4.0- , monad-control >= 0.3 && < 0.4+ , blaze-builder >= 0.3.0.0+ , transformers >= 0.2.1+ , groundhog >= 0.4.0 && < 0.5.0+ , monad-control >= 0.3+ , monad-logger >= 0.3 , containers >= 0.2- , text >= 0.8 && < 0.12+ , text >= 0.8 , attoparsec >= 0.8.5.3- , resource-pool >= 0.2.1 && < 0.3+ , resource-pool >= 0.2.1 , time >= 1.1 exposed-modules: Database.Groundhog.Postgresql Database.Groundhog.Postgresql.Array