Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save monotykamary/da97a3ee9172555fc8629fb793921f23 to your computer and use it in GitHub Desktop.
Save monotykamary/da97a3ee9172555fc8629fb793921f23 to your computer and use it in GitHub Desktop.
Commanded Ref
defmodule App.Repo.Migrations.CreateExtensionTimescale do
use Ecto.Migration
def up do
# enable extension
execute("CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE")
# remove primary key constraint
execute("ALTER TABLE events DROP CONSTRAINT events_pkey CASCADE")
# create hypertable
execute("SELECT create_hypertable('events', 'created_at')")
# alter events table to enable compression
execute("ALTER TABLE events SET (
timescaledb.compress,
timescaledb.compress_segmentby = 'event_id',
timescaledb.compress_orderby = 'created_at'
)")
# enable compression policy
execute("SELECT add_compression_policy('events', INTERVAL '7 days')")
end
def down do
# clone table to pg_events
execute("CREATE TABLE pg_events (LIKE events INCLUDING ALL)")
execute("INSERT INTO pg_events (SELECT * FROM events)")
# add back primary key constraint
execute("ALTER TABLE pg_events ADD CONSTRAINT events_pkey PRIMARY KEY (id)")
# drop events table and rename pg_events to events
execute("DROP TABLE events")
execute("ALTER TABLE pg_events RENAME TO events")
# disable extension
execute("DROP EXTENSION IF EXISTS timescaledb CASCADE")
end
end
defmodule Healthcare.Accounts.Aggregates.User do
defstruct [
:uuid,
:name,
:username,
:email,
:hashed_password
]
alias Healthcare.Accounts.Aggregates.User
alias Healthcare.Accounts.Commands.{
RegisterUser,
UpdateUser
}
alias Healthcare.Accounts.Events.{
UserEmailChanged,
UsernameChanged,
NameChanged,
UserPasswordChanged,
UserRegistered
}
def execute(%User{uuid: nil}, %RegisterUser{} = register) do
%UserRegistered{
user_uuid: register.user_uuid,
name: register.name,
username: register.username,
email: register.email,
hashed_password: register.hashed_password
}
end
def execute(%User{} = user, %UpdateUser{} = update) do
changes = [&username_changed/2, &email_changed/2, &password_changed/2, &name_changed/2]
Enum.reduce(changes, [], fn change, events ->
case change.(user, update) do
nil -> events
event -> [event | events]
end
end)
end
# state mutators
def apply(%User{} = user, %UserRegistered{} = registered) do
%User{
user
| uuid: registered.user_uuid,
username: registered.username,
email: registered.email,
hashed_password: registered.hashed_password
}
end
def apply(%User{} = user, %UsernameChanged{username: username}) do
%User{user | username: username}
end
def apply(%User{} = user, %UserEmailChanged{email: email}) do
%User{user | email: email}
end
def apply(%User{} = user, %UserPasswordChanged{hashed_password: hashed_password}) do
%User{user | hashed_password: hashed_password}
end
# private helpers
defp username_changed(%User{}, %UpdateUser{username: ""}), do: nil
defp username_changed(%User{username: username}, %UpdateUser{username: username}), do: nil
defp username_changed(%User{uuid: user_uuid}, %UpdateUser{username: username}) do
%UsernameChanged{
user_uuid: user_uuid,
username: username
}
end
defp name_changed(%User{}, %UpdateUser{name: ""}), do: nil
defp name_changed(%User{name: name}, %UpdateUser{name: name}), do: nil
defp name_changed(%User{uuid: user_uuid}, %UpdateUser{name: name}) do
%NameChanged{
user_uuid: user_uuid,
name: name
}
end
defp email_changed(%User{}, %UpdateUser{email: ""}), do: nil
defp email_changed(%User{email: email}, %UpdateUser{email: email}), do: nil
defp email_changed(%User{uuid: user_uuid}, %UpdateUser{email: email}) do
%UserEmailChanged{
user_uuid: user_uuid,
email: email
}
end
defp password_changed(%User{}, %UpdateUser{hashed_password: ""}), do: nil
defp password_changed(%User{hashed_password: hashed_password}, %UpdateUser{
hashed_password: hashed_password
}),
do: nil
defp password_changed(%User{uuid: user_uuid}, %UpdateUser{hashed_password: hashed_password}) do
%UserPasswordChanged{
user_uuid: user_uuid,
hashed_password: hashed_password
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment