mirror of
https://github.com/sloanelybutsurely/typeid-elixir.git
synced 2024-11-28 01:42:54 -05:00
feat: infer belongs_to type via ecto introspection
This commit is contained in:
parent
5f45fe9306
commit
ff769454e2
13 changed files with 119 additions and 2 deletions
|
@ -1,4 +1,6 @@
|
|||
# Used by "mix format"
|
||||
[
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||
import_deps: [:ecto, :ecto_sql],
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
|
||||
subdirectories: ["priv/*/migrations"]
|
||||
]
|
||||
|
|
3
config/config.exs
Normal file
3
config/config.exs
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Config
|
||||
|
||||
import_config "#{config_env()}.exs"
|
0
config/dev.exs
Normal file
0
config/dev.exs
Normal file
0
config/prod.exs
Normal file
0
config/prod.exs
Normal file
8
config/test.exs
Normal file
8
config/test.exs
Normal file
|
@ -0,0 +1,8 @@
|
|||
import Config
|
||||
|
||||
config :typeid_elixir, ecto_repos: [TypeID.Repo]
|
||||
|
||||
config :typeid_elixir, TypeID.Repo,
|
||||
database: "type_id_test",
|
||||
hostname: "localhost",
|
||||
pool: Ecto.Adapters.SQL.Sandbox
|
15
mix.exs
15
mix.exs
|
@ -8,9 +8,11 @@ defmodule TypeID.MixProject do
|
|||
app: :typeid_elixir,
|
||||
version: @version,
|
||||
elixir: "~> 1.11",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
start_permanent: Mix.env() == :prod,
|
||||
description: description(),
|
||||
package: package(),
|
||||
aliases: aliases(),
|
||||
deps: deps(),
|
||||
name: "TypeID Elixir",
|
||||
source_url: "https://github.com/sloanelybutsurely/typeid-elixir",
|
||||
|
@ -23,6 +25,9 @@ defmodule TypeID.MixProject do
|
|||
[extra_applications: [:logger]]
|
||||
end
|
||||
|
||||
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||
defp elixirc_paths(_), do: ["lib"]
|
||||
|
||||
defp description do
|
||||
"A type-safe, K-sortable, globally unique identifier inspired by Stripe IDs"
|
||||
end
|
||||
|
@ -48,7 +53,15 @@ defmodule TypeID.MixProject do
|
|||
{:phoenix, "~> 1.7", optional: true},
|
||||
{:jason, "~> 1.4", optional: true},
|
||||
{:ex_doc, "~> 0.27", only: :dev, runtime: false},
|
||||
{:yaml_elixir, "~> 2.9", only: [:dev, :test], runtime: false}
|
||||
{:yaml_elixir, "~> 2.9", only: [:dev, :test], runtime: false},
|
||||
{:ecto_sql, "~> 3.10", only: [:dev, :test]},
|
||||
{:postgrex, "~> 0.17", only: [:dev, :test]}
|
||||
]
|
||||
end
|
||||
|
||||
defp aliases do
|
||||
[
|
||||
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
3
mix.lock
3
mix.lock
|
@ -1,8 +1,10 @@
|
|||
%{
|
||||
"castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"},
|
||||
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"},
|
||||
"ecto": {:hex, :ecto, "3.10.2", "6b887160281a61aa16843e47735b8a266caa437f80588c3ab80a8a960e6abe37", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6a895778f0d7648a4b34b486af59a1c8009041fbdf2b17f1ac215eb829c60235"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.10.2", "6b98b46534b5c2f8b8b5f03f126e75e2a73c64f3c071149d32987a5378b0fdbd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "68c018debca57cb9235e3889affdaec7a10616a4e3a80c99fa1d01fdafaa9007"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
|
||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
|
||||
|
@ -16,6 +18,7 @@
|
|||
"phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"},
|
||||
"plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
|
||||
"postgrex": {:hex, :postgrex, "0.17.5", "0483d054938a8dc069b21bdd636bf56c487404c241ce6c319c1f43588246b281", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "50b8b11afbb2c4095a3ba675b4f055c416d0f3d7de6633a595fc131a828a67eb"},
|
||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||
"websock": {:hex, :websock, "0.5.2", "b3c08511d8d79ed2c2f589ff430bd1fe799bb389686dafce86d28801783d8351", [:mix], [], "hexpm", "925f5de22fca6813dfa980fb62fd542ec43a2d1a1f83d2caec907483fe66ff05"},
|
||||
"websock_adapter": {:hex, :websock_adapter, "0.5.3", "4908718e42e4a548fc20e00e70848620a92f11f7a6add8cf0886c4232267498d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "cbe5b814c1f86b6ea002b52dd99f345aeecf1a1a6964e209d208fb404d930d3d"},
|
||||
|
|
4
priv/repo/migrations/.formatter.exs
Normal file
4
priv/repo/migrations/.formatter.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
import_deps: [:ecto_sql],
|
||||
inputs: ["*.exs"]
|
||||
]
|
18
priv/repo/migrations/20241113140930_create_test_tables.exs
Normal file
18
priv/repo/migrations/20241113140930_create_test_tables.exs
Normal file
|
@ -0,0 +1,18 @@
|
|||
defmodule TypeID.Repo.Migrations.CreateTestTables do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:posts, primary_key: false) do
|
||||
add :id, :uuid, primary_key: true
|
||||
add :content, :text
|
||||
end
|
||||
|
||||
create table(:comments, primary_key: false) do
|
||||
add :id, :uuid, primary_key: true
|
||||
add :post_id, references(:posts, type: :uuid, on_delete: :delete_all)
|
||||
add :content, :text
|
||||
end
|
||||
|
||||
create index(:comments, [:post_id], name: :comments_post_id_index)
|
||||
end
|
||||
end
|
21
test/support/data_case.ex
Normal file
21
test/support/data_case.ex
Normal file
|
@ -0,0 +1,21 @@
|
|||
defmodule TypeID.DataCase do
|
||||
use ExUnit.CaseTemplate
|
||||
|
||||
alias Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
using do
|
||||
quote do
|
||||
import TypeID.DataCase
|
||||
end
|
||||
end
|
||||
|
||||
setup tags do
|
||||
TypeID.DataCase.setup_sandbox(tags)
|
||||
:ok
|
||||
end
|
||||
|
||||
def setup_sandbox(tags) do
|
||||
pid = Sandbox.start_owner!(TypeID.Repo, shared: not tags[:async])
|
||||
on_exit(fn -> Sandbox.stop_owner(pid) end)
|
||||
end
|
||||
end
|
5
test/support/repo.ex
Normal file
5
test/support/repo.ex
Normal file
|
@ -0,0 +1,5 @@
|
|||
defmodule TypeID.Repo do
|
||||
use Ecto.Repo,
|
||||
otp_app: :typeid_elixir,
|
||||
adapter: Ecto.Adapters.Postgres
|
||||
end
|
|
@ -1 +1,2 @@
|
|||
TypeID.Repo.start_link()
|
||||
ExUnit.start()
|
||||
|
|
39
test/type_id/ecto_test.exs
Normal file
39
test/type_id/ecto_test.exs
Normal file
|
@ -0,0 +1,39 @@
|
|||
defmodule TypeID.EctoTest do
|
||||
use TypeID.DataCase, async: true
|
||||
|
||||
describe "belongs_to relationships" do
|
||||
defmodule Post do
|
||||
use Ecto.Schema
|
||||
|
||||
@primary_key {:id, TypeID, autogenerate: true, prefix: "post", type: :uuid}
|
||||
@foreign_key_type TypeID
|
||||
schema "posts" do
|
||||
field :content
|
||||
has_many :comments, TypeID.EctoTest.Comment
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Comment do
|
||||
use Ecto.Schema
|
||||
|
||||
@primary_key {:id, TypeID, autogenerate: true, prefix: "post", type: :uuid}
|
||||
@foreign_key_type TypeID
|
||||
schema "comments" do
|
||||
field :content
|
||||
belongs_to :post, TypeID.EctoTest.Post
|
||||
end
|
||||
end
|
||||
|
||||
test "infers the database type for a belongs_to relationship" do
|
||||
post_changeset = Ecto.Changeset.change(%Post{}, %{content: "Hello, World!"})
|
||||
assert {:ok, post} = TypeID.Repo.insert(post_changeset)
|
||||
|
||||
comment_changeset =
|
||||
post
|
||||
|> Ecto.build_assoc(:comments)
|
||||
|> Ecto.Changeset.change(%{content: "Great post!"})
|
||||
|
||||
assert {:ok, comment} = TypeID.Repo.insert(comment_changeset)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue