ash_postgres/lib/repo.ex

90 lines
3.3 KiB
Elixir
Raw Normal View History

2020-05-31 17:51:41 +12:00
defmodule AshPostgres.Repo do
2020-06-04 17:27:26 +12:00
@moduledoc """
2022-08-24 11:56:46 +12:00
Resources that use `AshPostgres.DataLayer` use a `Repo` to access the database.
2020-06-04 17:27:26 +12:00
2022-08-24 11:56:46 +12:00
This repo is a thin wrapper around an `Ecto.Repo`.
2020-07-08 12:01:01 +12:00
You can use `Ecto.Repo`'s `init/2` to configure your repo like normal, but
instead of returning `{:ok, config}`, use `super(config)` to pass the
configuration to the `AshPostgres.Repo` implementation.
2020-09-03 20:18:11 +12:00
2020-11-17 18:37:04 +13:00
## Installed Extensions
2020-09-03 20:18:11 +12:00
2020-11-17 18:37:04 +13:00
To configure your list of installed extensions, define `installed_extensions/0`
Extensions that are relevant to ash_postgres:
2022-07-21 06:25:47 +12:00
* "ash-functions" - This isn't really an extension, but it expresses that certain functions
should be added when generating migrations, to support the `||` and `&&` operators in expressions.
2020-11-17 18:37:04 +13:00
* `"uuid-ossp"` - Sets UUID primary keys defaults in the migration generator
* `"pg_trgm"` - Makes the `AshPostgres.Predicates.Trigram` custom predicate available
* "citext" - Allows case insensitive fields to be used
2020-09-03 20:18:11 +12:00
```
def installed_extensions() do
2020-11-17 18:37:04 +13:00
["pg_trgm", "uuid-ossp"]
2020-09-03 20:18:11 +12:00
end
```
2020-06-04 17:27:26 +12:00
"""
2020-07-08 12:01:01 +12:00
@doc "Use this to inform the data layer about what extensions are installed"
2020-05-31 17:51:41 +12:00
@callback installed_extensions() :: [String.t()]
2020-10-29 16:53:28 +13:00
@doc "Return a list of all schema names (only relevant for a multitenant implementation)"
@callback all_tenants() :: [String.t()]
@doc "The path where your tenant migrations are stored (only relevant for a multitenant implementation)"
2020-10-29 16:56:59 +13:00
@callback tenant_migrations_path() :: String.t()
@doc "The path where your migrations are stored"
@callback migrations_path() :: String.t()
@doc "The default prefix(postgres schema) to use when building queries"
@callback default_prefix() :: String.t()
@doc "Allows overriding a given migration type for *all* fields, for example if you wanted to always use :timestamptz for :utc_datetime fields"
@callback override_migration_type(atom) :: atom
2020-05-31 17:51:41 +12:00
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
otp_app = opts[:otp_app] || raise("Must configure OTP app")
use Ecto.Repo,
adapter: Ecto.Adapters.Postgres,
otp_app: otp_app
2020-10-29 16:53:28 +13:00
def installed_extensions, do: []
def tenant_migrations_path, do: nil
def migrations_path, do: nil
def default_prefix, do: "public"
def override_migration_type(type), do: type
def all_tenants do
raise """
`#{inspect(__MODULE__)}.all_tenants/0` was called, but was not defined. In order to migrate tenants, you must define this function.
For example, you might say:
def all_tenants do
for org <- MyApp.Accounts.all_organizations!() do
org.schema
end
end
"""
end
2020-05-31 17:51:41 +12:00
2020-06-28 07:11:28 +12:00
def init(_, config) do
2020-10-29 16:53:28 +13:00
new_config =
config
|> Keyword.put(:installed_extensions, installed_extensions())
|> Keyword.put(:tenant_migrations_path, tenant_migrations_path())
|> Keyword.put(:migrations_path, migrations_path())
|> Keyword.put(:default_prefix, default_prefix())
2020-05-31 17:51:41 +12:00
{:ok, new_config}
end
defoverridable init: 2,
installed_extensions: 0,
all_tenants: 0,
tenant_migrations_path: 0,
default_prefix: 0,
override_migration_type: 1
2020-05-31 17:51:41 +12:00
end
end
end