Skip to content

leifg/so_so_soccer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SoSoSoccer

This is an example project on how to build a CQRS/ES system using commanded. It is a simplified version of Event Sourcing as it does not include aggregates and commands.

It also demonstrates the difference between a CRUD system and an ES system when it comes to data modelling.

This project was subject to an Event Sourcing Talk held in January 2018 in Chiang Mai, Thailand.

Task

The task is simple. Given a list of soccer matches, calculate the end season standings teable for every season and league. As an input, a sqlite database from kaggle is used (account needed): https://www.kaggle.com/mkhvalchik/soccer/data.

There are 3 possible solutions implemented in this project

The CRUD way calculating the table in application logic

Function call

Reads the matches and teams data model and calculates the standings in pure Elixir code

The CRUD way using an SQL view

Function call

Using an elaborate SQL view to create the standings table from the data model

The event sourced way

Function call

From a stream of events, build a projection

Setting it up

Download sqlite from kaggle (Ideally place the file in tmp/database.sqlite)

Start Postgres database via Docker Compose:

docker-compose up

Install dependencies

mix deps.get

Create schema:

bin/setup.sh

Import CRUD data model:

mix seed_crud_from_sqlite ./tmp/database.sqlite

Import Event Source Stream

mix seed_eventstore_from_sqlite ./tmp/database.sqlite

Start server:

mix phx.server

Note: for event sourced view, wait until projection is updated

Go to localhost:4000 to select the season and leage

Change way of calculating standings

Play around with the different representations by changing the function all in the standings controller:

    # CRUD application logic
    render(
      conn,
      "show.html",
      standings: StandingsView.crud_app(String.to_integer(season), String.to_integer(league_id))
    )

    # CRUD view logic
    render(
      conn,
      "show.html",
      standings: StandingsView.crud_view(String.to_integer(season), String.to_integer(league_id))
    )

    # Event Sourced
    render(
      conn,
      "show.html",
      standings: StandingsView.event_sourced(String.to_integer(season), String.to_integer(league_id))
    )

Benchmark

If you're interested in the performance of the individual implementations, run the benchmark:

mix run lib/benchmark.exs

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published