简体   繁体   中英

How do you specify different column types based on the database type for Haskell Groundhog?

Using the Groundhog Library in Haskell, I'm looking to implement a column type that uses "uuid" when the backend is Postgresql, and otherwise just use "varchar" for any other backend. While according to the comments in Groundhog.Core this should be possible, I'm not entirely sure how unwrap the dbType from proxy db , and there are no examples of this in the groundhog-examples, as the column type has been hardcoded in those examples.

Where I'd like some help is on the case match of Postgresql, I'll work out the rest once that's sorted. Here's where I'm at:

instance PrimitivePersistField UUID where
  toPrimitivePersistValue _ uuid = PersistString $ show uuid
  fromPrimitivePersistValue _ (PersistString a) = fromJust $ UUIDmethods.fromString a

instance PersistField UUID where
  persistName _ = "UUID"
  toPersistValues = primToPersistValue
  fromPersistValues = primFromPersistValue
  dbType db _ = case db of
    Postgresql _ -> DbTypePrimitive (DbOther $ OtherTypeDef [Left "uuid"]) False Nothing Nothing
    _ -> DbTypePrimitive (DbOther $ OtherTypeDef [Left "varchar"]) False Nothing Nothing

And on compile this comes up:

   Couldn't match expected type ‘proxy db’
                with actual type ‘Postgresql’
    Relevant bindings include
      db :: proxy db (bound at basicGroundhog.hs:34:10)
      dbType :: proxy db -> UUID -> DbType
        (bound at basicGroundhag.hs:34:3)
    In the pattern: Postgresql _
    In a case alternative:
        Postgresql _
          -> DbTypePrimitive
               (DbOther $ OtherTypeDef [Left "uuid"]) False Nothing Nothing
    In the expression:
      case db of {
        Postgresql _
          -> DbTypePrimitive
               (DbOther $ OtherTypeDef [Left "uuid"]) False Nothing Nothing
        _ -> DbTypePrimitive
               (DbOther $ OtherTypeDef [Left "varchar"]) False Nothing Nothing }

You can inspect database in runtime with backendName . It is better to put DbString for the default case so that groundhog can choose a more appropriate type. Varchar without maximum length declaration is invalid in MySQL.

dbType db _ = case backendName db of
   "postgresql" -> DbTypePrimitive (DbOther $ OtherTypeDef [Left "uuid"]) False Nothing Nothing
    _ -> DbTypePrimitive DbString False Nothing Nothing

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM