• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nshkrdotcom / ElixirScope / 8a215eb3f714f8dc47a0edb1d9b77c2e56987123

30 May 2025 03:05AM UTC coverage: 57.384% (-0.07%) from 57.458%
8a215eb3f714f8dc47a0edb1d9b77c2e56987123

push

github

NSHkr
Update phoenix test app

6186 of 10780 relevant lines covered (57.38%)

3118.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

37.23
/lib/elixir_scope/ast_repository/query_builder/executor.ex
1
defmodule ElixirScope.ASTRepository.QueryBuilder.Executor do
2
  @moduledoc """
3
  Executes queries against the repository with filtering, ordering, and selection.
4
  """
5

6
  alias ElixirScope.ASTRepository.QueryBuilder.Types
7

8
  @doc """
9
  Executes a query against the repository.
10
  """
11
  @spec execute_query(pid() | atom(), Types.query_t()) :: {:ok, Types.query_result()} | {:error, term()}
12
  def execute_query(repo, %Types{} = query) do
13
    case query.from do
7✔
14
      :functions -> execute_function_query(repo, query)
7✔
15
      :modules -> execute_module_query(repo, query)
×
16
      :patterns -> execute_pattern_query(repo, query)
×
17
    end
18
  end
19

20
  @doc """
21
  Validates that a repository is accessible.
22
  """
23
  @spec validate_repository(pid() | atom()) :: :ok | {:error, term()}
24
  def validate_repository(repo) when is_pid(repo) do
25
    if Process.alive?(repo) do
×
26
      :ok
27
    else
28
      {:error, :repository_not_available}
29
    end
30
  end
31

32
  def validate_repository(repo) when is_atom(repo) do
33
    case Process.whereis(repo) do
7✔
34
      nil -> {:error, :repository_not_found}
7✔
35
      pid when is_pid(pid) ->
36
        if Process.alive?(pid) do
×
37
          :ok
38
        else
39
          {:error, :repository_not_available}
40
        end
41
    end
42
  end
43

44
  def validate_repository(_repo) do
×
45
    {:error, :invalid_repository}
46
  end
47

48
  @doc """
49
  Applies WHERE conditions to filter data.
50
  """
51
  @spec apply_where_filters(list(map()), list(Types.filter_condition())) :: list(map())
52
  def apply_where_filters(data, []), do: data
×
53
  def apply_where_filters(data, conditions) do
54
    Enum.filter(data, fn item ->
×
55
      evaluate_conditions(item, conditions)
×
56
    end)
57
  end
58

59
  @doc """
60
  Applies ordering to data.
61
  """
62
  @spec apply_ordering(list(map()), term()) :: list(map())
63
  def apply_ordering(data, nil), do: data
×
64
  def apply_ordering(data, {field, :asc}) do
65
    Enum.sort_by(data, &Map.get(&1, field, 0))
2✔
66
  end
67
  def apply_ordering(data, {field, :desc}) do
68
    Enum.sort_by(data, &Map.get(&1, field, 0), :desc)
2✔
69
  end
70
  def apply_ordering(data, {:asc, field}) do
71
    Enum.sort_by(data, &Map.get(&1, field, 0))
×
72
  end
73
  def apply_ordering(data, {:desc, field}) do
74
    Enum.sort_by(data, &Map.get(&1, field, 0), :desc)
×
75
  end
76
  def apply_ordering(data, order_specs) when is_list(order_specs) do
77
    Enum.reduce(order_specs, data, fn order_spec, acc ->
1✔
78
      apply_ordering(acc, order_spec)
2✔
79
    end)
80
  end
81

82
  @doc """
83
  Applies LIMIT and OFFSET to data.
84
  """
85
  @spec apply_limit_offset(list(map()), pos_integer() | nil, non_neg_integer()) :: list(map())
86
  def apply_limit_offset(data, nil, 0), do: data
×
87
  def apply_limit_offset(data, nil, offset), do: Enum.drop(data, offset)
1✔
88
  def apply_limit_offset(data, limit, 0), do: Enum.take(data, limit)
1✔
89
  def apply_limit_offset(data, limit, offset) do
90
    data |> Enum.drop(offset) |> Enum.take(limit)
1✔
91
  end
92

93
  @doc """
94
  Applies SELECT to choose specific fields.
95
  """
96
  @spec apply_select(list(map()), :all | list(atom())) :: list(map())
97
  def apply_select(data, :all), do: data
1✔
98
  def apply_select(data, fields) when is_list(fields) do
99
    Enum.map(data, fn item ->
1✔
100
      Map.take(item, fields)
2✔
101
    end)
102
  end
103

104
  @doc """
105
  Evaluates a single condition against an item.
106
  """
107
  @spec evaluate_condition(map(), Types.filter_condition()) :: boolean()
108
  def evaluate_condition(item, {field, :eq, value}) do
109
    Map.get(item, field) == value
8✔
110
  end
111

112
  def evaluate_condition(item, {field, :ne, value}) do
113
    Map.get(item, field) != value
2✔
114
  end
115

116
  def evaluate_condition(item, {field, :gt, value}) do
117
    case Map.get(item, field) do
6✔
118
      nil -> false
×
119
      item_value -> item_value > value
6✔
120
    end
121
  end
122

123
  def evaluate_condition(item, {field, :lt, value}) do
124
    case Map.get(item, field) do
2✔
125
      nil -> false
×
126
      item_value -> item_value < value
2✔
127
    end
128
  end
129

130
  def evaluate_condition(item, {field, :gte, value}) do
131
    case Map.get(item, field) do
3✔
132
      nil -> false
×
133
      item_value -> item_value >= value
3✔
134
    end
135
  end
136

137
  def evaluate_condition(item, {field, :lte, value}) do
138
    case Map.get(item, field) do
3✔
139
      nil -> false
×
140
      item_value -> item_value <= value
3✔
141
    end
142
  end
143

144
  def evaluate_condition(item, {field, :in, values}) when is_list(values) do
145
    case Map.get(item, field) do
×
146
      list when is_list(list) ->
147
        Enum.any?(list, &(&1 in values))
×
148
      single_value ->
149
        single_value in values
×
150
    end
151
  end
152

153
  def evaluate_condition(item, {field, :not_in, values}) when is_list(values) do
154
    case Map.get(item, field) do
×
155
      list when is_list(list) ->
156
        not Enum.any?(list, &(&1 in values))
×
157
      single_value ->
158
        single_value not in values
×
159
    end
160
  end
161

162
  def evaluate_condition(item, {field, :contains, value}) do
163
    case Map.get(item, field) do
6✔
164
      list when is_list(list) -> value in list
2✔
165
      string when is_binary(string) -> String.contains?(string, to_string(value))
4✔
166
      _ -> false
×
167
    end
168
  end
169

170
  def evaluate_condition(item, {field, :not_contains, value}) do
171
    not evaluate_condition(item, {field, :contains, value})
2✔
172
  end
173

174
  def evaluate_condition(item, {field, :matches, pattern}) do
175
    case Map.get(item, field) do
×
176
      string when is_binary(string) ->
177
        case Regex.compile(pattern) do
×
178
          {:ok, regex} -> Regex.match?(regex, string)
×
179
          _ -> false
×
180
        end
181
      _ -> false
×
182
    end
183
  end
184

185
  def evaluate_condition(item, {field, :similar_to, {module, function, arity}}) do
186
    case Map.get(item, field) do
×
187
      {^module, ^function, ^arity} -> true
×
188
      _ -> false
×
189
    end
190
  end
191

192
  def evaluate_condition(item, {field, :not_nil}) do
193
    Map.get(item, field) != nil
×
194
  end
195

196
  def evaluate_condition(item, {field, :nil}) do
197
    Map.get(item, field) == nil
×
198
  end
199

200
  def evaluate_condition(item, {:similar_to, {module, function, arity}}) do
201
    case Map.get(item, :mfa) || {Map.get(item, :module), Map.get(item, :function), Map.get(item, :arity)} do
×
202
      {^module, ^function, ^arity} -> true
×
203
      _ -> false
×
204
    end
205
  end
206

207
  def evaluate_condition(item, {:similarity_threshold, threshold}) do
208
    case Map.get(item, :similarity_score) do
×
209
      nil -> false
×
210
      score -> score >= threshold
×
211
    end
212
  end
213

214
  def evaluate_condition(item, {:and, conditions}) do
215
    Enum.all?(conditions, &evaluate_condition(item, &1))
2✔
216
  end
217

218
  def evaluate_condition(item, {:or, conditions}) do
219
    Enum.any?(conditions, &evaluate_condition(item, &1))
2✔
220
  end
221

222
  def evaluate_condition(item, {:not, condition}) do
223
    not evaluate_condition(item, condition)
2✔
224
  end
225

226
  def evaluate_condition(_item, _condition), do: false
×
227

228
  # Private helper functions
229

230
  defp execute_function_query(repo, %Types{} = query) do
231
    case get_all_functions(repo) do
7✔
232
      {:ok, functions} ->
233
        filtered_functions = apply_where_filters(functions, query.where || [])
×
234
        ordered_functions = apply_ordering(filtered_functions, query.order_by)
×
235
        limited_functions = apply_limit_offset(ordered_functions, query.limit, query.offset || 0)
×
236
        selected_data = apply_select(limited_functions, query.select)
×
237

238
        result = %{
×
239
          data: selected_data,
240
          total_count: length(filtered_functions)
241
        }
242

243
        {:ok, result}
244

245
      error -> error
7✔
246
    end
247
  end
248

249
  defp execute_module_query(repo, %Types{} = query) do
250
    case get_all_modules(repo) do
×
251
      {:ok, modules} ->
252
        filtered_modules = apply_where_filters(modules, query.where || [])
×
253
        ordered_modules = apply_ordering(filtered_modules, query.order_by)
×
254
        limited_modules = apply_limit_offset(ordered_modules, query.limit, query.offset || 0)
×
255
        selected_data = apply_select(limited_modules, query.select)
×
256

257
        result = %{
×
258
          data: selected_data,
259
          total_count: length(filtered_modules)
260
        }
261

262
        {:ok, result}
263

264
      error -> error
×
265
    end
266
  end
267

268
  defp execute_pattern_query(_repo, %Types{} = _query) do
×
269
    {:error, :pattern_queries_not_implemented}
270
  end
271

272
  defp get_all_functions(repo) do
273
    case validate_repository(repo) do
7✔
274
      :ok -> {:ok, []}  # Placeholder - would integrate with Enhanced Repository
×
275
      error -> error
7✔
276
    end
277
  end
278

279
  defp get_all_modules(repo) do
280
    case validate_repository(repo) do
×
281
      :ok -> {:ok, []}  # Placeholder - would integrate with Enhanced Repository
×
282
      error -> error
×
283
    end
284
  end
285

286
  defp evaluate_conditions(item, conditions) do
287
    Enum.all?(conditions, fn condition ->
×
288
      evaluate_condition(item, condition)
×
289
    end)
290
  end
291
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc