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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions