defmodule Archeometer.Analysis.DSM.Data do @moduledoc false import Archeometer.Query alias Archeometer.Repo alias Archeometer.Schema.XRef alias Archeometer.Schema.Module def get_data(app, namespace, db_name, skip_tests) do module_names = get_modules(app, namespace, db_name, skip_tests) xrefs = get_xrefs(module_names, db_name) {module_names, xrefs} end defp get_modules(app, ns, db_name, skip_tests) do is_tests_vals = if skip_tests, do: [false], else: [true, false] modules = do_get_modules(app, ns, db_name, is_tests_vals) modules |> Enum.map(fn [id, name] -> {id, name} end) |> Enum.into(%{}) end defp do_get_modules(:none, "*", db_name, is_tests_vals) do %{rows: modules} = Repo.all( from(m in Module, select: [ id: m.id, name: m.name ], where: m.is_test in ^is_tests_vals ), [], db_name ) modules end defp do_get_modules(:none, ns, db_name, is_tests_vals) do %{rows: modules} = Repo.all( from(m in Module, select: [ id: m.id, name: m.name ], where: (m.name == ^ns or like(m.name, ^(ns <> ".%"))) and m.is_test in ^is_tests_vals ), [], db_name ) modules end defp do_get_modules(app, "*", db_name, is_tests_vals) do %{rows: modules} = Repo.all( from(m in Module, select: [ id: m.id, name: m.name ], where: m.application.name == ^app and m.is_test in ^is_tests_vals ), [], db_name ) modules end defp do_get_modules(app, ns, db_name, is_tests_vals) do %{rows: modules} = Repo.all( from(m in Module, select: [ id: m.id, name: m.name ], where: m.application.name == ^app and (m.name == ^ns or like(m.name, ^(ns <> ".%"))) and m.is_test in ^is_tests_vals ), [], db_name ) modules end defp get_xrefs(modules, db_name) do modules |> Map.keys() |> Enum.map(&callees(&1, modules, db_name)) |> Enum.into(%{}) end defp callees(id, modules_map, db_name) do others = Map.keys(modules_map) -- [id] %{rows: xrefs_ids} = Repo.all( from(x in XRef, select: [ callee_id: x.callee.id ], where: x.caller.id == ^id ), [], db_name ) callees = xrefs_ids |> List.flatten() |> Enum.uniq() |> Enum.filter(fn callee_id -> Enum.member?(others, callee_id) end) {id, callees} end end