Skip to content

Commit

Permalink
refactor: unify preload_defaults functions
Browse files Browse the repository at this point in the history
Provide a global `Repo.preload_defaults` to load default preloads for a
given module, instead of using a distinct function for each one.

`Repo.preload_defaults`'s logic is to make modules define their own
`default_preloads/0` function, and use its return value as
`Repo.preload/3`'s second parameter.

`Repo.preload_defaults_in_result` is provided for ease of use after
a fetch/update/insert method.

Signed-off-by: Francesco Noacco <francesco.noacco@secomind.com>
  • Loading branch information
noaccOS committed Jul 11, 2023
1 parent 6f50083 commit a58425f
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 156 deletions.
61 changes: 17 additions & 44 deletions backend/lib/edgehog/base_images.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ defmodule Edgehog.BaseImages do
BucketStorage
)

@doc """
Preloads the default associations for a Base Image Collection (or a list of base image collections)
"""
def preload_defaults_for_base_image_collection(collection_or_collections) do
Repo.preload(collection_or_collections,
base_images: [],
system_model: [:hardware_type, :part_numbers]
)
end

@doc """
Returns the list of base_image_collections.
Expand All @@ -59,7 +49,7 @@ defmodule Edgehog.BaseImages do
"""
def list_base_image_collections do
Repo.all(BaseImageCollection)
|> preload_defaults_for_base_image_collection()
|> Repo.preload_defaults()
end

@doc """
Expand All @@ -77,9 +67,8 @@ defmodule Edgehog.BaseImages do
"""
def fetch_base_image_collection(id) do
with {:ok, base_image_collection} <- Repo.fetch(BaseImageCollection, id) do
{:ok, preload_defaults_for_base_image_collection(base_image_collection)}
end
Repo.fetch(BaseImageCollection, id)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -99,9 +88,8 @@ defmodule Edgehog.BaseImages do
%BaseImageCollection{system_model_id: system_model.id}
|> BaseImageCollection.changeset(attrs)

with {:ok, base_image_collection} <- Repo.insert(changeset) do
{:ok, preload_defaults_for_base_image_collection(base_image_collection)}
end
Repo.insert(changeset)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -119,9 +107,8 @@ defmodule Edgehog.BaseImages do
def update_base_image_collection(%BaseImageCollection{} = base_image_collection, attrs) do
changeset = BaseImageCollection.changeset(base_image_collection, attrs)

with {:ok, base_image_collection} <- Repo.update(changeset) do
{:ok, preload_defaults_for_base_image_collection(base_image_collection)}
end
Repo.update(changeset)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -137,9 +124,8 @@ defmodule Edgehog.BaseImages do
"""
def delete_base_image_collection(%BaseImageCollection{} = base_image_collection) do
with {:ok, base_image_collection} <- Repo.delete(base_image_collection) do
{:ok, preload_defaults_for_base_image_collection(base_image_collection)}
end
Repo.delete(base_image_collection)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -155,17 +141,6 @@ defmodule Edgehog.BaseImages do
BaseImageCollection.changeset(base_image_collection, attrs)
end

@doc """
Preloads the default associations for a Base Image (or a list of base images)
"""
def preload_defaults_for_base_image(image_or_images) do
Repo.preload(image_or_images,
base_image_collection: [
system_model: [:hardware_type, :part_numbers]
]
)
end

@doc """
Returns the list of base_images.
Expand All @@ -177,7 +152,7 @@ defmodule Edgehog.BaseImages do
"""
def list_base_images do
Repo.all(BaseImage)
|> preload_defaults_for_base_image()
|> Repo.preload_defaults()
end

@doc """
Expand All @@ -192,7 +167,7 @@ defmodule Edgehog.BaseImages do
def list_base_images_for_collection(%BaseImageCollection{} = base_image_collection) do
Ecto.assoc(base_image_collection, :base_images)
|> Repo.all()
|> preload_defaults_for_base_image()
|> Repo.preload_defaults()
end

@doc """
Expand All @@ -210,9 +185,8 @@ defmodule Edgehog.BaseImages do
"""
def fetch_base_image(id) do
with {:ok, base_image} <- Repo.fetch(BaseImage, id) do
{:ok, preload_defaults_for_base_image(base_image)}
end
Repo.fetch(BaseImage, id)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand Down Expand Up @@ -245,7 +219,7 @@ defmodule Edgehog.BaseImages do
|> Repo.transaction()
|> case do
{:ok, %{base_image: base_image}} ->
{:ok, preload_defaults_for_base_image(base_image)}
{:ok, Repo.preload_defaults(base_image)}

{:error, _failed_operation, failed_value, _changes_so_far} ->
{:error, failed_value}
Expand All @@ -267,9 +241,8 @@ defmodule Edgehog.BaseImages do
def update_base_image(%BaseImage{} = base_image, attrs) do
changeset = BaseImage.update_changeset(base_image, attrs)

with {:ok, base_image} <- Repo.update(changeset) do
{:ok, preload_defaults_for_base_image(base_image)}
end
Repo.update(changeset)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -296,7 +269,7 @@ defmodule Edgehog.BaseImages do
|> Repo.transaction()
|> case do
{:ok, %{base_image: base_image}} ->
{:ok, preload_defaults_for_base_image(base_image)}
{:ok, Repo.preload_defaults(base_image)}

{:error, _failed_operation, failed_value, _changes_so_far} ->
{:error, failed_value}
Expand Down
8 changes: 8 additions & 0 deletions backend/lib/edgehog/base_images/base_image.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,12 @@ defmodule Edgehog.BaseImages.BaseImage do
[{field, "is not a valid version requirement"}]
end
end

def default_preloads do
[
base_image_collection: [
system_model: [:hardware_type, :part_numbers]
]
]
end
end
4 changes: 4 additions & 0 deletions backend/lib/edgehog/base_images/base_image_collection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ defmodule Edgehog.BaseImages.BaseImageCollection do
"should start with a lower case ASCII letter and only contain lower case ASCII letters, digits and -"
)
end

def default_preloads do
[base_images: [], system_model: [:hardware_type, :part_numbers]]
end
end
17 changes: 3 additions & 14 deletions backend/lib/edgehog/devices.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defmodule Edgehog.Devices do
"""
def get_device!(id) do
Repo.get!(Device, id)
|> preload_defaults_for_device()
|> Repo.preload_defaults()
end

@doc """
Expand All @@ -67,18 +67,7 @@ defmodule Edgehog.Devices do
filters
|> Enum.reduce(Device, &filter_with/2)
|> Repo.all()
|> preload_defaults_for_device()
end

@doc """
Preloads the default associations for an Edgehog Device (or a list of devices)
"""
def preload_defaults_for_device(device_or_devices) do
Repo.preload(device_or_devices,
tags: [],
custom_attributes: [],
system_model: [:hardware_type, :part_numbers]
)
|> Repo.preload_defaults()
end

defp filter_with({:online, online}, query) do
Expand Down Expand Up @@ -220,7 +209,7 @@ defmodule Edgehog.Devices do
|> Repo.transaction()
|> case do
{:ok, %{update_device: device}} ->
{:ok, preload_defaults_for_device(device)}
{:ok, Repo.preload_defaults(device)}

{:error, _failed_operation, failed_value, _progress_so_far} ->
{:error, failed_value}
Expand Down
4 changes: 4 additions & 0 deletions backend/lib/edgehog/devices/device.ex
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ defmodule Edgehog.Devices.Device do
with: &Labeling.DeviceAttribute.custom_attribute_changeset/2
)
end

def default_preloads do
[tags: [], custom_attributes: [], system_model: [:hardware_type, :part_numbers]]
end
end
5 changes: 2 additions & 3 deletions backend/lib/edgehog/groups.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2022 SECO Mind Srl
# Copyright 2022-2023 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,6 @@ defmodule Edgehog.Groups do
"""

import Ecto.Query, warn: false
alias Edgehog.Devices
alias Edgehog.Groups.DeviceGroup
alias Edgehog.Repo
alias Edgehog.Selector
Expand Down Expand Up @@ -57,7 +56,7 @@ defmodule Edgehog.Groups do
{:ok, device_query} = Selector.to_ecto_query(device_group.selector)

Repo.all(device_query)
|> Devices.preload_defaults_for_device()
|> Repo.preload_defaults()
end

@doc """
Expand Down
35 changes: 34 additions & 1 deletion backend/lib/edgehog/repo.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of Edgehog.
#
# Copyright 2021 SECO Mind Srl
# Copyright 2021-2023 SECO Mind Srl
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -71,4 +71,37 @@ defmodule Edgehog.Repo do
def default_options(_operation) do
[tenant_id: get_tenant_id()]
end

@doc """
Preloads default relationships for the given struct(s), defined by a `default_preloads/0` function
in the struct's module.
"""
def preload_defaults(struct_or_structs_or_nil, opts \\ [])

def preload_defaults(struct_or_structs_or_nil, opts)
when is_struct(struct_or_structs_or_nil) or is_nil(struct_or_structs_or_nil) do
do_preload_defaults(struct_or_structs_or_nil, struct_or_structs_or_nil, opts)
end

def preload_defaults(struct_or_structs_or_nil, opts)
when is_list(struct_or_structs_or_nil) do
non_nil_item = Enum.find(struct_or_structs_or_nil, & &1)
do_preload_defaults(non_nil_item, struct_or_structs_or_nil, opts)
end

defp do_preload_defaults(nil = _reference_item, struct_or_structs_or_nil, _opts) do
struct_or_structs_or_nil
end

defp do_preload_defaults(reference_item, struct_or_structs_or_nil, opts) do
module = reference_item.__struct__
preloads = module.default_preloads()
preload(struct_or_structs_or_nil, preloads, opts)
end

def preload_defaults_in_result(result, opts \\ []) do
with {:ok, item} <- result do
{:ok, preload_defaults(item, opts)}
end
end
end
Loading

0 comments on commit a58425f

Please sign in to comment.