Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- update Ch to [v0.5.x](https://github.com/plausible/ch/blob/master/CHANGELOG.md#050-2025-07-17) which adds Time, Variant, and JSON support https://github.com/plausible/ecto_ch/pull/233

## 0.7.1 (2025-07-07)

- update [Ch](https://github.com/plausible/ch) (our ClickHouse client) to v0.4.x
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule EctoCh.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:ch, "~> 0.4.0"},
{:ch, "~> 0.5.0"},
{:ecto_sql, "~> 3.13.0"},
{:benchee, "~> 1.1", only: :bench},
{:dialyxir, "~> 1.2", only: [:dev, :test], runtime: false},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%{
"benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"},
"ch": {:hex, :ch, "0.4.1", "716fc326a0d29212a35c15e5350355550ff1290a244e6f37bf3eac4318aeeb76", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: false]}], "hexpm", "e6a4cf90d22030afde77e1a2895ebba2888032ccc5f1bec947b26b90a9152ffc"},
"ch": {:hex, :ch, "0.5.0", "e1047b9a650d34ff5b001a149aa88ebfdf3d31a481e3e255747cf1635e9d54eb", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: false]}], "hexpm", "119100210a128fc4d5ef4e7531a1256f4ee686afc85241392e93bb1da0b56967"},
"db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"},
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
Expand Down
98 changes: 98 additions & 0 deletions test/ecto/integration/json_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
defmodule Ecto.Integration.JsonTest do
use Ecto.Integration.Case
import Ecto.Query, only: [from: 2]

@moduletag :json

alias Ecto.Integration.TestRepo
alias EctoClickHouse.Integration.Setting
Expand All @@ -23,4 +26,99 @@ defmodule Ecto.Integration.JsonTest do
[setting.id]
)
end

defmodule SemiStructured do
use Ecto.Schema

@primary_key false
schema "semi_structured" do
field :json, Ch, type: "JSON"
field :time, :naive_datetime
end
end

test "basic" do
TestRepo.query!("""
CREATE TABLE semi_structured (
json JSON,
time DateTime
) ENGINE MergeTree ORDER BY time
""")

on_exit(fn -> TestRepo.query!("DROP TABLE semi_structured") end)

%SemiStructured{}
|> Ecto.Changeset.cast(
%{
json: %{"from" => "insert"},
time: ~N[2023-10-01 12:00:00]
},
[:json, :time]
)
|> TestRepo.insert!()

TestRepo.insert_all(SemiStructured, [
%{json: %{"from" => "insert_all"}, time: ~N[2023-10-01 13:00:00]},
%{json: %{"from" => "another_insert_all"}, time: ~N[2023-10-01 13:01:00]}
])

assert TestRepo.all(from s in SemiStructured, select: s.json, order_by: s.time) == [
%{"from" => "insert"},
%{"from" => "insert_all"},
%{"from" => "another_insert_all"}
]
end

# https://github.com/plausible/ecto_ch/pull/233#issuecomment-3079317842

defmodule TokenInfoSchema do
@moduledoc false
use Ecto.Schema

@primary_key false
schema "token_infos" do
field :mint, Ch, type: "String"
field :data, Ch, type: "JSON", source: :data
field :created_at, Ch, type: "DateTime"
end
end

test "token_info_schema" do
TestRepo.query!("""
create table token_infos(
mint String,
data JSON,
created_at DateTime
) engine = MergeTree order by created_at
""")

on_exit(fn -> TestRepo.query!("DROP TABLE token_infos") end)

missing_tokens = [
%{
mint: "123",
data: %{"name" => "Test", "nested" => %{"name" => "Test", "arr" => ["abc", "b=deb"]}},
created_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
},
%{
mint: "325",
data: %{"name" => "Test", "nested" => %{"name" => "Test", "arr" => ["abc", "b=deb"]}},
created_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
}
]

assert {2, nil} = TestRepo.insert_all(TokenInfoSchema, missing_tokens)

assert TestRepo.all(
from t in TokenInfoSchema,
order_by: t.created_at,
select: %{
mint: t.mint,
name: fragment("?.nested.name::text", t.data)
}
) == [
%{mint: "123", name: "Test"},
%{mint: "325", name: "Test"}
]
end
end
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ alias Ecto.Integration.TestRepo
Application.put_env(:ecto_ch, TestRepo,
adapter: Ecto.Adapters.ClickHouse,
database: "ecto_ch_test",
settings: [enable_json_type: 1],
show_sensitive_data_on_connection_error: true
)

Expand Down
Loading