4
votes

I am building a web application in Haskell. I am using the persistent library to connect to a postgresql database.

I am using the standard schema definition file system where template Haskell is used to generate types from the schema.

share [mkPersist sqlSettings, mkMigrate "migrateAll"]
  $(persistFileWith lowerCaseSettings "schema")

I have many data types defined in my schema file that look like (fake example):

User json
  email Text

Post json
  owner UserId
  name  Text
  body  Text

The "json" next to "Post" indicates that ToJSON / FromJSON are to be automatically generated by the framework.

I have been using this automatic instance generation for many of my types so that I can serialize them over the network.

My issue: I want to provide a custom instance of ToJSON for the Keys. For example in the above "UserId" would be a "Key User". Every time has such an instance generated for it automatically at the moment "PostId" as "Key Post" etc.

When "Post" is serialized it would convert "owner" from a key to the index number like say "52".

I would like to serialize all of the database keys to a different style. For example instead of producing the number '52' producing the string "fiftytwo" (just an example).

If I did not use code generation I could do something like

instance ToJSON (Key record) where
  toJSON _ = Data.Aeson.String "placeholder"

But this would require not using the automatic code generation because of overlapping instance errors. Perhaps there is a way to tell the code generator not to generate instances of "ToJSON (Key Post)" etc for all the datatypes?

I could also simply write custom instance declarations for every type but this would be very redundant.

I am familiar with using newtypes to have multiple instances of a type class, however this would not fit well into this scenario.

Thanks!

1
I too have run into this problem and unfortunately the persistent-th package is very "all or nothing" about the Aeson instances it generates. On the large production system I worked on, we eventually bit the bullet and forked the package. There is (relatively) not that much code. For your specific problem you could, for example, modify mkKeyTypeDec (where the key types are declared and then instanced) to produce the desired ToJSON instance. hackage.haskell.org/package/persistent-template-2.5.2/docs/src/…hao

1 Answers

0
votes

Based by the advice in the comment from haoformayor this issue is now solved. The answer is to fork the persistent-template library and modify the mkKeyTypeDec portion.