Skip to content

Commit

Permalink
WIP2
Browse files Browse the repository at this point in the history
  • Loading branch information
rbino committed Oct 2, 2024
1 parent c8536bd commit a611765
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 16 deletions.
1 change: 1 addition & 0 deletions backend/.formatter.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:ash_json_api,
:ash_postgres,
:ecto,
:ecto_sql,
:phoenix,
:absinthe,
:skogsra,
Expand Down
12 changes: 5 additions & 7 deletions backend/lib/edgehog/base_images/base_image/base_image.ex
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,15 @@ defmodule Edgehog.BaseImages.BaseImage do
end

identities do
# These have to be named this way to match the existing unique indexes
# we already have. Ash uses identities to add a `unique_constraint` to the
# Ecto changeset, so names have to match. There's no need to explicitly add
# :tenant_id in the fields because identity in a multitenant resource are
# automatically scoped to a specific :tenant_id
# TODO: change index names when we generate migrations at the end of the porting
identity :version_base_image_collection_id_tenant_id, [:version, :base_image_collection_id]
identity :version, [:version, :base_image_collection_id]
end

postgres do
table "base_images"
repo Edgehog.Repo

custom_indexes do
index [:base_image_collection_id], unique: false
end
end
end
12 changes: 3 additions & 9 deletions backend/lib/edgehog/base_images/base_image_collection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,9 @@ defmodule Edgehog.BaseImages.BaseImageCollection do
end

identities do
# These have to be named this way to match the existing unique indexes
# we already have. Ash uses identities to add a `unique_constraint` to the
# Ecto changeset, so names have to match. There's no need to explicitly add
# :tenant_id in the fields because identity in a multitenant resource are
# automatically scoped to a specific :tenant_id
# TODO: change index names when we generate migrations at the end of the porting
identity :handle_tenant_id, [:handle]
identity :name_tenant_id, [:name]
identity :system_model_id_tenant_id, [:system_model_id]
identity :handle, [:handle]
identity :name, [:name]
identity :system_model_id, [:system_model_id]
end

postgres do
Expand Down
9 changes: 9 additions & 0 deletions backend/lib/edgehog/multitenant_resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ defmodule Edgehog.MultitenantResource do
references do
reference :tenant, on_delete: :delete
end

if not unquote(Keyword.get(opts, :tenant_id_in_primary_key?, false)) do
custom_indexes do
# Assumptions:
# - There is a primary key and it's called :id
index [:id], unique: true
index [:tenant_id], all_tenants?: false
end
end
end
end
end
Expand Down
48 changes: 48 additions & 0 deletions backend/priv/repo/migrations/20240919153634_reconcile_with_ash.exs
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,53 @@ defmodule Edgehog.Repo.Migrations.ReconcileWithAsh do
null: false,
default: fragment("(now() AT TIME ZONE 'utc')")
end

# Ash puts :tenant_id first in indexes, while we had it as last merely to have a better Ecto
# error message. We need to swap all things around.
# When we drop the index we don't pass and explicit name because it was generated with the
# Ecto default name. When we create it we pass it explicitly to match what Ash migrations
# expect.

drop_if_exists unique_index(:base_image_collections, [:handle, :tenant_id])

create unique_index(:base_image_collections, [:tenant_id, :handle],
name: "base_image_collections_handle_index"
)

drop_if_exists unique_index(:base_image_collections, [:name, :tenant_id])

create unique_index(:base_image_collections, [:tenant_id, :name],
name: "base_image_collections_name_index"
)

drop_if_exists unique_index(:base_image_collections, [:system_model_id, :tenant_id])

create unique_index(:base_image_collections, [:tenant_id, :system_model_id],
name: "base_image_collections_system_model_id_index"
)

drop_if_exists index(:base_images, [:base_image_collection_id, :tenant_id])
create index(:base_images, [:tenant_id, :base_image_collection_id])

drop_if_exists unique_index(:base_images, [:handle, :tenant_id])
create unique_index(:base_images, [:tenant_id, :handle], name: "base_images_handle_index")

drop_if_exists unique_index(:base_images, [:handle, :tenant_id])
create unique_index(:base_images, [:tenant_id, :handle], name: "base_images_handle_index")

# Our MultitenantResource now creates a unique index on `[:tenant_id, :id]` for _all_ resources
# This allows using composite foreign keys to enforce associated resources are on in the same
# tenant at the database level.
# We add just _some_ of those indexes, so we manually create the missing ones
create unique_index(:device_groups, [:tenant_id, :id])
create unique_index(:hardware_type_part_numbers, [:tenant_id, :id])
create unique_index(:hardware_types, [:tenant_id, :id])
create unique_index(:realms, [:tenant_id, :id])
create unique_index(:system_model_part_numbers, [:tenant_id, :id])
create unique_index(:system_models, [:tenant_id, :id])
create unique_index(:tags, [:tenant_id, :id])
create unique_index(:update_campaign_targets, [:tenant_id, :id])

# For
end
end

0 comments on commit a611765

Please sign in to comment.