Search code examples
databasehaskellyesod

Join multiple tables in yesod


Say I have the following models:

User
    ident Text
    password Text Maybe
    UniqueUser ident
    deriving Typeable
Payment
    timestamp UTCTime
    from UserId
    to UserId
    receiptId ReceiptId
ReceiptUser                     
    userId UserId
    receiptId ReceiptId
Receipt
    owner UserId
    money Int

I want to perform a query like this:

SELECT ReceiptUser.UserId, Receipt.ReceiptOwner, Receipt.Id, Receipt.Price
FROM ReceiptUser, Receipt, Payment
WHERE ReceiptUser.ReceiptId == Receipt.Id
      AND NOT (Payment.ReceiptId == Receipt.Id AND Payment.From == ReceiptUser.UserId AND Payment.To == Receipt.Owner)

Which is supposed to find all users who have not yet payed another user, plus the corresponding receipt information.

How could I express this in yesod persistent? It seems to me persistent only provides an interface for simple queries on one table.


Solution

  • Persistent's interface is very simple and often insufficient to implement even slightly complex SQL. Esqueleto is a library building atop Persistent's database machinery which gives you a much more SQL-like Haskell DSL that may allow you to express what you're looking for.