haskell-beam / haskell-beam/beam
The whole database is a Monoid.
- Dominant language
- Haskell
- Stars
- 635
- Forks
- 193
- PR merge metrics
- No merged PRs in 30d
Description
I had a bit of fun turning the whole database into a Monoid:
```haskell
data Db f = Db
{ datumRows :: f (TableEntity DatumRowT)
, scriptRows :: f (TableEntity ScriptRowT)
, txRows :: f (TableEntity TxRowT)
, addressRows :: f (TableEntity AddressRowT)
}
deriving (Generic, Database be)
type AllTables (c :: * -> Constraint) f = (c (f (TableEntity DatumRowT)), c (f (TableEntity ScriptRowT)), c (f (TableEntity TxRowT)), c (f (TableEntity AddressRowT)))
deriving via (GenericSemigroupMonoid (Db f)) instance AllTables Semigroup f => Semigroup (Db f)
deriving via (GenericSemigroupMonoid (Db f)) instance AllTables Monoid f => Monoid (Db f)
```
It’s useful for generating batch inserts. You can `mconcat` together inserts into various tables, and using `zipTables` to generate batch inserts per table:
```haskell
data InsertRows te where
InsertRows :: BeamableSqlite t => [t Identity] -> InsertRows (TableEntity t)
instance Semigroup (InsertRows te) where
InsertRows l <> InsertRows r = InsertRows (l <> r)
instance BeamableSqlite t => Monoid (InsertRows (TableEntity t)) where
mempty = InsertRows []
insertRows :: Db InsertRows -> SqliteM ()
insertRows = getAp . getConst . zipTables (Proxy :: Proxy Sqlite) (\tbl (InsertRows rows) -> Const . Ap . runInsert . insert tbl $ insertValues rows) db
```
I posted this on Twitter and someone replied that this should go in the documentation somewhere. I think that's a good idea, but I'm not sure what would be the right place, and if some of the code should be part of a beam package. If we can decide on the right place for this I'm more than willing to create a PR.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.