Created
December 25, 2024 03:50
-
-
Save monotykamary/da97a3ee9172555fc8629fb793921f23 to your computer and use it in GitHub Desktop.
Commanded Ref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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