From e379896512c723ac4555fcbaacbfe9910676ccfa Mon Sep 17 00:00:00 2001 From: shibao Date: Sat, 5 Apr 2025 02:59:27 +0000 Subject: [PATCH] use dynamic dispatch --- lib/memex.ex | 30 ++++++++++++++++++++++++++++++ lib/memex/accounts.ex | 7 +++---- lib/memex/accounts/invite.ex | 7 +------ lib/memex/accounts/invites.ex | 6 ++---- lib/memex/accounts/user.ex | 9 ++------- lib/memex/accounts/user_token.ex | 7 +------ lib/memex/contexts.ex | 4 ++-- lib/memex/contexts/context.ex | 13 ++++--------- lib/memex/notes.ex | 4 ++-- lib/memex/notes/note.ex | 13 ++++--------- lib/memex/pipelines.ex | 4 ++-- lib/memex/pipelines/pipeline.ex | 14 +++++--------- lib/memex/pipelines/step.ex | 9 +++------ lib/memex/pipelines/steps.ex | 4 +--- 14 files changed, 62 insertions(+), 69 deletions(-) diff --git a/lib/memex.ex b/lib/memex.ex index 3ac7ac1..602d9c8 100644 --- a/lib/memex.ex +++ b/lib/memex.ex @@ -6,4 +6,34 @@ defmodule Memex do Contexts are also responsible for managing your data, regardless if it comes from the database, an external API or others. """ + + def context do + quote do + use Gettext, backend: MemexWeb.Gettext + import Ecto.Query + alias Ecto.{Changeset, Multi, Queryable, UUID} + alias Memex.Accounts.User + alias Memex.Repo + end + end + + def schema do + quote do + use Ecto.Schema + use Gettext, backend: MemexWeb.Gettext + import Ecto.{Changeset, Query} + alias Ecto.{Association, Changeset, Queryable, UUID} + alias Memex.Accounts.User + + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + end + end + + @doc """ + When used, dispatch to the appropriate context/schema/etc. + """ + defmacro __using__(which) when is_atom(which) do + apply(__MODULE__, which, []) + end end diff --git a/lib/memex/accounts.ex b/lib/memex/accounts.ex index e605496..17f8f77 100644 --- a/lib/memex/accounts.ex +++ b/lib/memex/accounts.ex @@ -3,10 +3,9 @@ defmodule Memex.Accounts do The Accounts context. """ - import Ecto.Query, warn: false - alias Memex.{Mailer, Repo} - alias Memex.Accounts.{Invite, Invites, User, UserToken} - alias Ecto.{Changeset, Multi} + use Memex, :context + alias Memex.Mailer + alias Memex.Accounts.{Invite, Invites, UserToken} alias Oban.Job ## Database getters diff --git a/lib/memex/accounts/invite.ex b/lib/memex/accounts/invite.ex index d887cf2..ace1c45 100644 --- a/lib/memex/accounts/invite.ex +++ b/lib/memex/accounts/invite.ex @@ -5,13 +5,8 @@ defmodule Memex.Accounts.Invite do `:uses_left` is defined. """ - use Ecto.Schema - import Ecto.Changeset - alias Ecto.{Association, Changeset, UUID} - alias Memex.Accounts.User + use Memex, :schema - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "invites" do field :name, :string field :token, :string diff --git a/lib/memex/accounts/invites.ex b/lib/memex/accounts/invites.ex index 923022c..35acf26 100644 --- a/lib/memex/accounts/invites.ex +++ b/lib/memex/accounts/invites.ex @@ -3,10 +3,8 @@ defmodule Memex.Accounts.Invites do The Invites context. """ - import Ecto.Query, warn: false - alias Ecto.Multi - alias Memex.Accounts.{Invite, User} - alias Memex.Repo + use Memex, :context + alias Memex.Accounts.Invite @invite_token_length 20 diff --git a/lib/memex/accounts/user.ex b/lib/memex/accounts/user.ex index 8af327a..493fac7 100644 --- a/lib/memex/accounts/user.ex +++ b/lib/memex/accounts/user.ex @@ -3,11 +3,8 @@ defmodule Memex.Accounts.User do A Memex user """ - use Ecto.Schema - use Gettext, backend: MemexWeb.Gettext - import Ecto.Changeset - alias Ecto.{Association, Changeset, UUID} - alias Memex.Accounts.{Invite, User} + use Memex, :schema + alias Memex.Accounts.Invite @derive {Jason.Encoder, only: [ @@ -20,8 +17,6 @@ defmodule Memex.Accounts.User do :updated_at ]} @derive {Inspect, except: [:password]} - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "users" do field :email, :string field :password, :string, virtual: true diff --git a/lib/memex/accounts/user_token.ex b/lib/memex/accounts/user_token.ex index 07aeba6..dc45e1c 100644 --- a/lib/memex/accounts/user_token.ex +++ b/lib/memex/accounts/user_token.ex @@ -3,10 +3,7 @@ defmodule Memex.Accounts.UserToken do Schema for a user's session token """ - use Ecto.Schema - import Ecto.Query - alias Ecto.{Association, UUID} - alias Memex.Accounts.User + use Memex, :schema @hash_algorithm :sha256 @rand_size 32 @@ -18,8 +15,6 @@ defmodule Memex.Accounts.UserToken do @change_email_validity_in_days 7 @session_validity_in_days 60 - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "users_tokens" do field :token, :binary field :context, :string diff --git a/lib/memex/contexts.ex b/lib/memex/contexts.ex index 9d9d566..1883b21 100644 --- a/lib/memex/contexts.ex +++ b/lib/memex/contexts.ex @@ -3,8 +3,8 @@ defmodule Memex.Contexts do The Contexts context. """ - import Ecto.Query, warn: false - alias Memex.{Accounts.User, Contexts.Context, Repo} + use Memex, :context + alias Memex.Contexts.Context @doc """ Returns the list of contexts. diff --git a/lib/memex/contexts/context.ex b/lib/memex/contexts/context.ex index fe992d4..18e9665 100644 --- a/lib/memex/contexts/context.ex +++ b/lib/memex/contexts/context.ex @@ -3,11 +3,8 @@ defmodule Memex.Contexts.Context do Represents a document that synthesizes multiple concepts as defined by notes into a single consideration """ - use Ecto.Schema - use Gettext, backend: MemexWeb.Gettext - import Ecto.Changeset - alias Ecto.{Changeset, UUID} - alias Memex.{Accounts.User, Repo} + + use Memex, :schema @derive {Phoenix.Param, key: :slug} @derive {Jason.Encoder, @@ -19,8 +16,6 @@ defmodule Memex.Contexts.Context do :inserted_at, :updated_at ]} - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "contexts" do field :slug, :string field :content, :string @@ -59,7 +54,7 @@ defmodule Memex.Contexts.Context do ) |> validate_required([:slug, :user_id, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end @spec update_changeset(t(), attrs :: map(), User.t()) :: changeset() @@ -73,7 +68,7 @@ defmodule Memex.Contexts.Context do ) |> validate_required([:slug, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end defp cast_tags_string(changeset, attrs) do diff --git a/lib/memex/notes.ex b/lib/memex/notes.ex index 9aabc2e..f6fb2f4 100644 --- a/lib/memex/notes.ex +++ b/lib/memex/notes.ex @@ -3,8 +3,8 @@ defmodule Memex.Notes do The Notes context. """ - import Ecto.Query, warn: false - alias Memex.{Accounts.User, Notes.Note, Repo} + use Memex, :context + alias Memex.Notes.Note @doc """ Returns the list of notes. diff --git a/lib/memex/notes/note.ex b/lib/memex/notes/note.ex index 5812ed6..e4f8392 100644 --- a/lib/memex/notes/note.ex +++ b/lib/memex/notes/note.ex @@ -2,11 +2,8 @@ defmodule Memex.Notes.Note do @moduledoc """ Schema for a user-written note """ - use Ecto.Schema - use Gettext, backend: MemexWeb.Gettext - import Ecto.Changeset - alias Ecto.{Changeset, UUID} - alias Memex.{Accounts.User, Repo} + + use Memex, :schema @derive {Phoenix.Param, key: :slug} @derive {Jason.Encoder, @@ -18,8 +15,6 @@ defmodule Memex.Notes.Note do :inserted_at, :updated_at ]} - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "notes" do field :slug, :string field :content, :string @@ -58,7 +53,7 @@ defmodule Memex.Notes.Note do ) |> validate_required([:slug, :user_id, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end @spec update_changeset(t(), attrs :: map(), User.t()) :: changeset() @@ -72,7 +67,7 @@ defmodule Memex.Notes.Note do ) |> validate_required([:slug, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end defp cast_tags_string(changeset, attrs) do diff --git a/lib/memex/pipelines.ex b/lib/memex/pipelines.ex index 5c2217b..1300287 100644 --- a/lib/memex/pipelines.ex +++ b/lib/memex/pipelines.ex @@ -3,8 +3,8 @@ defmodule Memex.Pipelines do The Pipelines context. """ - import Ecto.Query, warn: false - alias Memex.{Accounts.User, Pipelines.Pipeline, Repo} + use Memex, :context + alias Memex.Pipelines.Pipeline @doc """ Returns the list of pipelines. diff --git a/lib/memex/pipelines/pipeline.ex b/lib/memex/pipelines/pipeline.ex index 2d55554..c90a7cf 100644 --- a/lib/memex/pipelines/pipeline.ex +++ b/lib/memex/pipelines/pipeline.ex @@ -2,11 +2,9 @@ defmodule Memex.Pipelines.Pipeline do @moduledoc """ Represents a chain of considerations to take to accomplish a task """ - use Ecto.Schema - use Gettext, backend: MemexWeb.Gettext - import Ecto.Changeset - alias Ecto.{Changeset, UUID} - alias Memex.{Accounts.User, Pipelines.Steps.Step, Repo} + + use Memex, :schema + alias Memex.Pipelines.Steps.Step @derive {Phoenix.Param, key: :slug} @derive {Jason.Encoder, @@ -19,8 +17,6 @@ defmodule Memex.Pipelines.Pipeline do :steps, :updated_at ]} - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "pipelines" do field :slug, :string field :description, :string @@ -61,7 +57,7 @@ defmodule Memex.Pipelines.Pipeline do ) |> validate_required([:slug, :user_id, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end @spec update_changeset(t(), attrs :: map(), User.t()) :: changeset() @@ -75,7 +71,7 @@ defmodule Memex.Pipelines.Pipeline do ) |> validate_required([:slug, :visibility]) |> unique_constraint(:slug) - |> unsafe_validate_unique(:slug, Repo) + |> unsafe_validate_unique(:slug, Memex.Repo) end defp cast_tags_string(changeset, attrs) do diff --git a/lib/memex/pipelines/step.ex b/lib/memex/pipelines/step.ex index b416953..c9328f2 100644 --- a/lib/memex/pipelines/step.ex +++ b/lib/memex/pipelines/step.ex @@ -2,10 +2,9 @@ defmodule Memex.Pipelines.Steps.Step do @moduledoc """ Represents a step taken while executing a pipeline """ - use Ecto.Schema - import Ecto.Changeset - alias Ecto.{Changeset, UUID} - alias Memex.{Accounts.User, Pipelines.Pipeline} + + use Memex, :schema + alias Memex.Pipelines.Pipeline @derive {Jason.Encoder, only: [ @@ -15,8 +14,6 @@ defmodule Memex.Pipelines.Steps.Step do :inserted_at, :updated_at ]} - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id schema "steps" do field :title, :string field :content, :string diff --git a/lib/memex/pipelines/steps.ex b/lib/memex/pipelines/steps.ex index 80f47e5..46f2032 100644 --- a/lib/memex/pipelines/steps.ex +++ b/lib/memex/pipelines/steps.ex @@ -3,9 +3,7 @@ defmodule Memex.Pipelines.Steps do The context for steps within a pipeline """ - import Ecto.Query, warn: false - alias Ecto.Multi - alias Memex.{Accounts.User, Repo} + use Memex, :context alias Memex.Pipelines.{Pipeline, Steps.Step} @doc """