diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/matrix_app_service/application.ex | 23 | ||||
-rw-r--r-- | lib/matrix_app_service/bridge.ex | 3 | ||||
-rw-r--r-- | lib/matrix_app_service/bridge/room.ex | 21 | ||||
-rw-r--r-- | lib/matrix_app_service/bridge/user.ex | 21 | ||||
-rw-r--r-- | lib/matrix_app_service/bridge_config.ex | 227 | ||||
-rw-r--r-- | lib/matrix_app_service/migrations.ex | 27 | ||||
-rw-r--r-- | lib/matrix_app_service/repo.ex | 5 |
7 files changed, 320 insertions, 7 deletions
diff --git a/lib/matrix_app_service/application.ex b/lib/matrix_app_service/application.ex index 383c0f9..408d5ab 100644 --- a/lib/matrix_app_service/application.ex +++ b/lib/matrix_app_service/application.ex @@ -18,15 +18,20 @@ defmodule MatrixAppService.Application do ] children = - if start_endpoint?() do - [ - # MatrixAppServiceWeb.Endpoint + if start_endpoint?(), + do: [ {MatrixAppServiceWeb.Endpoint, endpoint_config()} | children - ] - else - children - end + ], + else: children + + children = + if start_repo?(), + do: [ + MatrixAppService.Repo + | children + ], + else: children # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options @@ -48,6 +53,10 @@ defmodule MatrixAppService.Application do Application.get_env(:matrix_app_service, :internal_supervisor, false) end + def start_repo?() do + Application.get_env(:matrix_app_service, :internal_repo, false) + end + def endpoint_config() do [ transaction_adapter: Application.fetch_env!(:matrix_app_service, :transaction_adapter), diff --git a/lib/matrix_app_service/bridge.ex b/lib/matrix_app_service/bridge.ex new file mode 100644 index 0000000..e0e0fee --- /dev/null +++ b/lib/matrix_app_service/bridge.ex @@ -0,0 +1,3 @@ +defmodule MatrixAppService.Bridge do + use MatrixAppService.BridgeConfig, repo: MatrixAppService.Repo +end diff --git a/lib/matrix_app_service/bridge/room.ex b/lib/matrix_app_service/bridge/room.ex new file mode 100644 index 0000000..73ef1ea --- /dev/null +++ b/lib/matrix_app_service/bridge/room.ex @@ -0,0 +1,21 @@ +defmodule MatrixAppService.Bridge.Room do + use Ecto.Schema + import Ecto.Changeset + + schema "rooms" do + field(:data, :map) + field(:local_id, :string) + field(:remote_id, :string) + + timestamps() + end + + @doc false + def changeset(room, attrs) do + room + |> cast(attrs, [:local_id, :remote_id, :data]) + # |> validate_required([:local_id, :remote_id, :data]) + |> unique_constraint(:local_id) + |> unique_constraint(:remote_id) + end +end diff --git a/lib/matrix_app_service/bridge/user.ex b/lib/matrix_app_service/bridge/user.ex new file mode 100644 index 0000000..7bf604a --- /dev/null +++ b/lib/matrix_app_service/bridge/user.ex @@ -0,0 +1,21 @@ +defmodule MatrixAppService.Bridge.User do + use Ecto.Schema + import Ecto.Changeset + + schema "users" do + field(:data, :map) + field(:local_id, :string) + field(:remote_id, :string) + + timestamps() + end + + @doc false + def changeset(user, attrs) do + user + |> cast(attrs, [:local_id, :remote_id, :data]) + # |> validate_required([:local_id, :remote_id, :data]) + |> unique_constraint(:local_id) + |> unique_constraint(:remote_id) + end +end diff --git a/lib/matrix_app_service/bridge_config.ex b/lib/matrix_app_service/bridge_config.ex new file mode 100644 index 0000000..68723c6 --- /dev/null +++ b/lib/matrix_app_service/bridge_config.ex @@ -0,0 +1,227 @@ +defmodule MatrixAppService.BridgeConfig do + @moduledoc """ + The Bridge config. + """ + + defmacro __using__(repo: repo) do + quote bind_quoted: [repo: repo] do + @repo repo + + import Ecto.Query, warn: false + # alias MatrixAppService.Repo + + alias MatrixAppService.Bridge.User + + @doc """ + Returns the list of users. + + ## Examples + + iex> list_users() + [%User{}, ...] + + """ + def list_users do + @repo.all(User) + end + + @doc """ + Gets a single user. + + Raises `Ecto.NoResultsError` if the User does not exist. + + ## Examples + + iex> get_user!(123) + %User{} + + iex> get_user!(456) + ** (Ecto.NoResultsError) + + """ + def get_user!(id), do: @repo.get!(User, id) + + def get_user_by_local_id(local_id), + do: @repo.get_by(User, local_id: local_id) || %User{local_id: local_id} + + def get_user_by_remote_id(remote_id), + do: @repo.get_by(User, remote_id: remote_id) || %User{remote_id: remote_id} + + @doc """ + Creates a user. + + ## Examples + + iex> create_user(%{field: value}) + {:ok, %User{}} + + iex> create_user(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_user(attrs \\ %{}) do + %User{} + |> User.changeset(attrs) + |> @repo.insert() + end + + def upsert_user(attrs, selectors) do + with %User{} = user <- @repo.get_by(User, selectors) do + update_user(user, attrs) + else + _ -> + create_user(Enum.into(selectors, attrs, fn {k, v} -> {to_string(k), v} end)) + end + end + + @doc """ + Updates a user. + + ## Examples + + iex> update_user(user, %{field: new_value}) + {:ok, %User{}} + + iex> update_user(user, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_user(%User{} = user, attrs) do + user + |> User.changeset(attrs) + |> @repo.update() + end + + @doc """ + Deletes a user. + + ## Examples + + iex> delete_user(user) + {:ok, %User{}} + + iex> delete_user(user) + {:error, %Ecto.Changeset{}} + + """ + def delete_user(%User{} = user) do + @repo.delete(user) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking user changes. + + ## Examples + + iex> change_user(user) + %Ecto.Changeset{data: %User{}} + + """ + def change_user(%User{} = user, attrs \\ %{}) do + User.changeset(user, attrs) + end + + alias MatrixAppService.Bridge.Room + + @doc """ + Returns the list of rooms. + + ## Examples + + iex> list_rooms() + [%Room{}, ...] + + """ + def list_rooms do + @repo.all(Room) + end + + @doc """ + Gets a single room. + + Raises `Ecto.NoResultsError` if the Room does not exist. + + ## Examples + + iex> get_room!(123) + %Room{} + + iex> get_room!(456) + ** (Ecto.NoResultsError) + + """ + def get_room!(id), do: @repo.get!(Room, id) + + def get_room_by_local_id(local_id), + do: @repo.get_by(Room, local_id: local_id) || %Room{local_id: local_id} + + def get_room_by_remote_id(remote_id), + do: @repo.get_by(Room, remote_id: remote_id) || %Room{remote_id: remote_id} + + @doc """ + Creates a room. + + ## Examples + + iex> create_room(%{field: value}) + {:ok, %Room{}} + + iex> create_room(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_room(attrs \\ %{}) do + %Room{} + |> Room.changeset(attrs) + |> @repo.insert() + end + + @doc """ + Updates a room. + + ## Examples + + iex> update_room(room, %{field: new_value}) + {:ok, %Room{}} + + iex> update_room(room, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_room(%Room{} = room, attrs) do + room + |> Room.changeset(attrs) + |> @repo.update() + end + + @doc """ + Deletes a room. + + ## Examples + + iex> delete_room(room) + {:ok, %Room{}} + + iex> delete_room(room) + {:error, %Ecto.Changeset{}} + + """ + def delete_room(%Room{} = room) do + @repo.delete(room) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking room changes. + + ## Examples + + iex> change_room(room) + %Ecto.Changeset{data: %Room{}} + + """ + def change_room(%Room{} = room, attrs \\ %{}) do + Room.changeset(room, attrs) + end + end + end +end diff --git a/lib/matrix_app_service/migrations.ex b/lib/matrix_app_service/migrations.ex new file mode 100644 index 0000000..6ae5344 --- /dev/null +++ b/lib/matrix_app_service/migrations.ex @@ -0,0 +1,27 @@ +defmodule MatrixAppService.Migrations do + use Ecto.Migration + + def change do + create table(:users) do + add(:local_id, :string) + add(:remote_id, :string) + add(:data, :map) + + timestamps() + end + + create(unique_index(:users, [:local_id])) + create(unique_index(:users, [:remote_id])) + + create table(:rooms) do + add(:local_id, :string) + add(:remote_id, :string) + add(:data, :map) + + timestamps() + end + + create(unique_index(:rooms, [:local_id])) + create(unique_index(:rooms, [:remote_id])) + end +end diff --git a/lib/matrix_app_service/repo.ex b/lib/matrix_app_service/repo.ex new file mode 100644 index 0000000..c52348a --- /dev/null +++ b/lib/matrix_app_service/repo.ex @@ -0,0 +1,5 @@ +defmodule MatrixAppService.Repo do + use Ecto.Repo, + otp_app: :matrix_app_service, + adapter: Ecto.Adapters.Postgres +end |