Эликсир / Феникс - как добавить значение переменной во фрагмент - PullRequest
1 голос
/ 06 апреля 2020

У меня есть запрос к базе данных:

Repo.all(from d in ScannerData,
          where: d.unixdate >= ^dates.start_date,
          order_by: [desc: fragment("?", ^order_by)],
          group_by: d.host,
          limit: 10,
          select: %{
            recipient: d.host,
            email_count: fragment("COUNT(crc)"),
            duration_sum: fragment("SUM(duration)"),
            ham_duration_sum: fragment("SUM(CASE WHEN scanner = 'Clear' THEN duration ELSE 0 END)"),
            spam_duration_sum: fragment("SUM(CASE WHEN scanner != 'Clear' THEN duration ELSE 0 END)")
          }
      )

Запрос содержит строку, отвечающую за сортировку:

order_by: [des c: фрагмент ("? ", ^ order_by)]

В зависимости от ситуации сортировка может выполняться разными способами, поэтому я использую переменную order_by .

order_by = case params["sort"] do
  "email_count" -> "COUNT(crc)"
  "size_sum" -> "SUM(size)"
  "duration_sum" -> "SUM(duration)"
  "ham_duration_sum" -> "SUM(CASE WHEN scanner = 'Clear' THEN duration ELSE 0 END)"
  "spam_duration_sum" -> "SUM(CASE WHEN scanner != 'Clear' THEN duration ELSE 0 END)"
  _ -> "COUNT(crc)"
end

Но сортировка не работает. Если я использую:

order_by: [desc: fragment(^order_by)]

У меня ошибка:

для предотвращения SQL атак с использованием инъекций, фрагмент (...) не позволяет интерполировать строки как первый аргумент через оператор ^, получил: "SUM(size)"

Буду благодарен за помощь.

1 Ответ

1 голос
/ 06 апреля 2020

Чтобы упорядочить по динамическим c значениям, нужно явно объявить Ecto.Query.dynamic/2. Тем не менее, следующее будет работать:

order_by: ^[desc: dynamic([d], fragment("?", order_by))]
...