36

I'm new to both Haskell and Yesod, and am trying to build a simple web application that can answer queries from an external API. I have built a parser (using Parsec), that gets me the ID of an entity I want to load as a regular Int value.

However, I for the life of me can't figure out how to turn this Int into something that get will accept (i. e. a Key (?)). All the examples in the documentation only get the id from previous inserts, or from url dispatch.

Any help would be greatly appreciated, since I seem to be stuck... :)

  • 4
    Okay, I figured this out thanks to the nice people on #yesod: To create a key from an Int, `i`, (or Int64, in this case) and for a database backend, the syntax is `Key $ PersistInt64 i`. This will create the key, and the compiler will figure out which entity to fetch from the context (i.e. type information associated with the use of the key). – Toke Høiland-Jørgensen Dec 27 '11 at 00:05
  • 4
    Feel free to respond to your own question so that it is closed. – dflemstr Dec 27 '11 at 00:36

3 Answers3

28

Even if the answer can already be found in the comments, I would like to give a complete example.

Assuming we have a Person Model, the following function returns a record for the persion with the given ID (if it exists):

import Database.Persist.Types (PersistValue(PersistInt64))

getByIntId :: Integral i => i -> Handler (Maybe Person)
getByIntId i = runDB $ get $ Key $ PersistInt64 (fromIntegral i)

The import is needed to let us construct the persist-version of an integer. fromIntegral converts any integer to the expected type Int64.

Update: Since Yesod 1.2 PersistValue lives in the module Database.Persist.Types, before 1.2 it was Database.Persist.Store (API Documentation).

Update 2: Since Persistent 2.0.2 there are two build-in functions to convert from/to database keys: toSqlKey and fromSqlKey (API Documentation, see answer by hhefesto for an example).

Sven Koschnicke
  • 6,523
  • 2
  • 34
  • 49
  • 1
    Sven, I just wanted to let you know that you are doing folks like myself a huge favor by updating this post and increasing the "googleability" for Yesod / Haskel. Your answer saved me a ton of time. – Steven L. Nov 27 '18 at 12:55
  • 1
    Thank you! Always nice to hear (and motivating) that I can help people :) – Sven Koschnicke Nov 28 '18 at 10:52
5

PersistInt64 is here: Database.Persist.Types.

Previously PersistInt64 was here: Database.Persist.Store.

panurg
  • 309
  • 4
  • 11
3

Just an example of how to use toSqlKey (Persistent 2.0.2)

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Users
    email String
    password String
    alias String
    deriving Show
|]

connStr = "host=localhost dbname=communis_db user=communis password=develpass port=5432"

inBackend :: ReaderT SqlBackend (NoLoggingT (ResourceT IO)) a-> IO a
inBackend action = runStderrLoggingT $ withPostgresqlPool connStr 10 $ \pool -> liftIO $ do
  flip runSqlPersistMPool pool $ do
    runMigration migrateAll
    action

toUserId :: Int64 -> UsersId
toUserId = toSqlKey

get_user :: Int64 -> IO (Maybe Users)
get_user = inBackend . get . toUserId

delete_user :: Int64 -> IO ()
delete_user = inBackend . delete . toUserId
hhefesto
  • 331
  • 1
  • 11