Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: unify preload_defaults functions #316

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions backend/lib/edgehog/astarte.ex
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,7 @@ defmodule Edgehog.Astarte do

"""
def fetch_realm_by_name(realm_name) do
case Repo.get_by(Realm, name: realm_name) do
%Realm{} = realm -> {:ok, realm}
nil -> {:error, :realm_not_found}
end
Repo.fetch_by(Realm, [name: realm_name], empty_return: :realm_not_found)
end

@doc """
Expand Down Expand Up @@ -399,10 +396,9 @@ defmodule Edgehog.Astarte do

"""
def fetch_realm_device(%Realm{id: realm_id}, device_id) do
case Repo.get_by(Device, realm_id: realm_id, device_id: device_id) do
%Device{} = device -> {:ok, device}
nil -> {:error, :device_not_found}
end
Repo.fetch_by(Device, [realm_id: realm_id, device_id: device_id],
empty_return: :device_not_found
)
end

@doc """
Expand Down
66 changes: 17 additions & 49 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,13 +67,8 @@ defmodule Edgehog.BaseImages do

"""
def fetch_base_image_collection(id) do
case Repo.get(BaseImageCollection, id) do
%BaseImageCollection{} = base_image_collection ->
{:ok, preload_defaults_for_base_image_collection(base_image_collection)}

nil ->
{:error, :not_found}
end
Repo.fetch(BaseImageCollection, id)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand All @@ -103,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 @@ -123,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 @@ -141,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 @@ -159,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 @@ -181,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 @@ -196,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 @@ -214,10 +185,8 @@ defmodule Edgehog.BaseImages do

"""
def fetch_base_image(id) do
case Repo.get(BaseImage, id) do
nil -> {:error, :not_found}
%BaseImage{} = base_image -> {:ok, preload_defaults_for_base_image(base_image)}
end
Repo.fetch(BaseImage, id)
|> Repo.preload_defaults_in_result()
end

@doc """
Expand Down Expand Up @@ -250,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 @@ -272,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 @@ -301,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
33 changes: 7 additions & 26 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 @@ -209,7 +198,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 Expand Up @@ -309,12 +298,8 @@ defmodule Edgehog.Devices do

"""
def fetch_hardware_type(id) do
case Repo.get(HardwareType, id) do
%HardwareType{} = hardware_type ->
{:ok, Repo.preload(hardware_type, :part_numbers)}

nil ->
{:error, :not_found}
with {:ok, hardware_type} <- Repo.fetch(HardwareType, id) do
{:ok, Repo.preload(hardware_type, :part_numbers)}
end
end

Expand Down Expand Up @@ -483,12 +468,8 @@ defmodule Edgehog.Devices do

"""
def fetch_system_model(id) do
case Repo.get(SystemModel, id) do
%SystemModel{} = system ->
{:ok, Repo.preload(system, [:part_numbers, :hardware_type])}

nil ->
{:error, :not_found}
with {:ok, system} <- Repo.fetch(SystemModel, id) do
{:ok, Repo.preload(system, [:part_numbers, :hardware_type])}
end
end

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
10 changes: 3 additions & 7 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 Expand Up @@ -109,10 +108,7 @@ defmodule Edgehog.Groups do

"""
def fetch_device_group(id) do
case Repo.get(DeviceGroup, id) do
%DeviceGroup{} = device_group -> {:ok, device_group}
nil -> {:error, :not_found}
end
Repo.fetch(DeviceGroup, id)
end

@doc """
Expand Down
53 changes: 52 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 @@ -35,6 +35,24 @@ defmodule Edgehog.Repo do
Process.get(@tenant_key)
end

def fetch(queryable, id, opts \\ []) do
empty = Keyword.get(opts, :empty_return, :not_found)

case get(queryable, id, opts) do
nil -> {:error, empty}
item -> {:ok, item}
end
end

def fetch_by(queryable, clauses, opts \\ []) do
empty = Keyword.get(opts, :empty_return, :not_found)

case get_by(queryable, clauses, opts) do
nil -> {:error, empty}
item -> {:ok, item}
end
end

@impl true
def prepare_query(_operation, query, opts) do
cond do
Expand All @@ -53,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