Skip to content

How to use nextval with a newtyped ID? #172

@sullyj3

Description

@sullyj3

I have the following table:

newtype UserId = UserId { toInt32 :: Int32 }
  deriving newtype (DBEq, DBType, Eq, Show)

deriving newtype instance DBType (PasswordHash a)

data User f = User
  { userId :: Column f UserId,
    userName :: Column f Text,
    userPassword :: Column f (PasswordHash Bcrypt)
  }
  deriving stock (Generic)
  deriving anyclass (Rel8able)

And I'm trying to figure out how to insert a user. I have this snippet in a Yesod Handler

    hashed <- liftIO <| hashPassword <| mkPassword password
    let user = User {
          userId = nextval "user_id_seq",
          userName = lit username,
          userPassword = lit hashed
        }
    Yesoder conn <- getYesod
    liftIO $ run (insertUser user) conn
    pure "registered"

But I'm getting

    • Couldn't match type ‘GHC.Int.Int64’ with ‘UserId’
      Expected: Column Expr UserId
        Actual: Expr GHC.Int.Int64
    • In the ‘userId’ field of a record
      In the expression:
        User
          {userId = nextval "user_id_seq", userName = lit username,
           userPassword = lit hashed}
      In an equation for ‘user’:
          user
            = User
                {userId = nextval "user_id_seq", userName = lit username,
                 userPassword = lit hashed}
   |
87 |             userId = nextval "user_id_seq",
   |                      ^^^^^^^^^^^^^^^^^^^^^

I thought I might be able to do something like UserId <$> nextval "user_id_seq" to obtain an Expr UserId, but Expr doesn't have a Functor instance. I only have the fuzziest understanding of how expr works, so I assume there's some good reason for this. On reflection this probably doesn't make sense.

How do I handle this correctly? It seems like a pretty foundational use case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions