eventium-postgresql: Postgres implementations for eventium

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Eventium-postgresql provides a PostgreSQL-based event store implementation for the Eventium event sourcing framework. It uses the Persistent library for type-safe database access and provides efficient event storage and retrieval with support for aggregate streams, event versioning, and optimistic concurrency control. This is a production-ready backend for event-sourced applications.


[Skip to Readme]

Properties

Versions 0.1.0, 0.1.0
Change log CHANGELOG.md
Dependencies aeson (>=1.5 && <2.3), base (>=4.9 && <5), bytestring (>=0.10 && <0.13), eventium-core (>=0.1.0 && <0.2.0), eventium-sql-common (>=0.1.0 && <0.2.0), mtl (>=2.2 && <2.4), persistent (>=2.13 && <2.15), text (>=1.2 && <2.2) [details]
License MIT
Author
Maintainer Alexander Sidorenko
Category Database, Eventsourcing, PostgreSQL
Home page https://github.com/aleks-sidorenko/eventium#readme
Bug tracker https://github.com/aleks-sidorenko/eventium/issues
Source repo head: git clone https://github.com/aleks-sidorenko/eventium
Uploaded by aleks_sidorenko at 2025-12-12T21:56:26Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for eventium-postgresql-0.1.0

[back to package description]

Eventium PostgreSQL

PostgreSQL-based event store implementation for production event sourcing systems.

Overview

eventium-postgresql provides a robust, production-ready event store implementation backed by PostgreSQL. It leverages PostgreSQL's ACID guarantees, indexing capabilities, and reliability for persistent event storage with high performance and data integrity.

Features

Database Schema

The implementation creates two main tables:

Indexes ensure fast lookups by:

Installation

Add to your package.yaml:

dependencies:
  - eventium-core
  - eventium-sql-common
  - eventium-postgresql
  - persistent-postgresql  # PostgreSQL driver

Usage

import Eventium.Store.Postgresql
import Database.Persist.Postgresql

main :: IO ()
main = do
  let connStr = "host=localhost dbname=eventstore user=postgres"
  
  withPostgresqlPool connStr 10 $ \pool -> do
    -- Initialize schema
    flip runSqlPool pool $ do
      runMigration migrateAll
      
      -- Create event store
      let store = makePostgresqlEventStore pool
      
      -- Use with command handlers
      result <- applyCommandHandler 
        (eventStoreWriter store)
        (eventStoreReader store)
        commandHandler
        aggregateId
        command

Configuration

Connection String

-- Basic connection
"host=localhost port=5432 dbname=mydb user=myuser password=mypass"

-- With connection pool
withPostgresqlPool connectionString poolSize $ \pool -> ...

Connection Pooling

Recommended settings for production:

-- Pool size based on concurrent requests
poolSize = numCores * 2 + effectiveSpindleCount

-- Example: 10 connections for typical web app
withPostgresqlPool connStr 10 $ \pool -> ...

Setup

Start PostgreSQL with Docker

# Using docker-compose (provided in project root)
docker-compose up -d postgres

# Or manually
docker run -d \
  --name eventium-postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=eventstore \
  -p 5432:5432 \
  postgres:15

Run Migrations

runSqlPool (runMigration migrateAll) pool

Performance

PostgreSQL provides excellent performance characteristics:

See postgres-event-store-bench/ for benchmarking scripts.

Best Practices

  1. Use Connection Pooling - Essential for web applications
  2. Index Strategy - Default indexes cover common queries
  3. Backup Strategy - Regular PostgreSQL backups
  4. Monitoring - Watch connection pool usage and query performance
  5. Read Replicas - Scale read models with PostgreSQL replication

Production Considerations

Example: Complete Setup

import Eventium.Store.Postgresql
import Control.Monad.Logger (runStdoutLoggingT)

setupEventStore :: IO ()
setupEventStore = runStdoutLoggingT $ do
  let connStr = "host=localhost dbname=eventstore"
  
  withPostgresqlPool connStr 10 $ \pool -> do
    -- Run migrations
    flip runSqlPool pool $ runMigration migrateAll
    
    -- Event store is ready to use
    liftIO $ putStrLn "Event store initialized"

Documentation

License

MIT - see LICENSE.md