From 02761428c1d7aaf18a288d0b003b8dfaf423d51e Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sat, 11 Apr 2026 23:57:40 +0100 Subject: [PATCH] Format map and list query params as JSON --- lib/music_library/query_reporter.ex | 4 +++ test/music_library/query_reporter_test.exs | 38 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/music_library/query_reporter.ex b/lib/music_library/query_reporter.ex index 5bfb5281..f96b3119 100644 --- a/lib/music_library/query_reporter.ex +++ b/lib/music_library/query_reporter.ex @@ -135,6 +135,10 @@ defmodule MusicLibrary.QueryReporter do end end + defp format_param(value) when is_list(value) or (is_map(value) and not is_struct(value)) do + "'" <> String.replace(JSON.encode!(value), "'", "''") <> "'" + end + defp format_param(value), do: "'" <> String.replace(to_string(value), "'", "''") <> "'" defp extract_source_location(nil), do: nil diff --git a/test/music_library/query_reporter_test.exs b/test/music_library/query_reporter_test.exs index e8caaab0..144fe041 100644 --- a/test/music_library/query_reporter_test.exs +++ b/test/music_library/query_reporter_test.exs @@ -198,6 +198,44 @@ defmodule MusicLibrary.QueryReporterTest do assert File.read!(path) =~ "SELECT count(*) FROM records;" end + test "interpolates map params as JSON", %{path: path} do + QueryReporter.start(path) + + emit_query( + path, + "UPDATE artist_infos SET musicbrainz_data = ? WHERE id = ?", + [%{"name" => "Test Artist"}, "abc"] + ) + + assert File.read!(path) =~ ~s|SET musicbrainz_data = '{"name":"Test Artist"}'| + end + + test "interpolates list params as JSON", %{path: path} do + QueryReporter.start(path) + emit_query(path, "UPDATE records SET genres = ?", [["rock", "pop"]]) + + assert File.read!(path) =~ ~s|SET genres = '["rock","pop"]'| + end + + test "interpolates list of embedded maps as JSON", %{path: path} do + QueryReporter.start(path) + + emit_query( + path, + "UPDATE records SET artists = ?", + [[%{"name" => "A"}, %{"name" => "B"}]] + ) + + assert File.read!(path) =~ ~s|SET artists = '[{"name":"A"},{"name":"B"}]'| + end + + test "escapes single quotes in map JSON params", %{path: path} do + QueryReporter.start(path) + emit_query(path, "UPDATE records SET data = ?", [%{"title" => "Rock'n'Roll"}]) + + assert File.read!(path) =~ ~s|SET data = '{"title":"Rock''n''Roll"}'| + end + test "uses cast_params over params when both present", %{path: path} do QueryReporter.start(path)