cat-bookmarker/deps/ecto_sql/integration_test/sql/sql.exs

174 lines
5.6 KiB
Elixir
Raw Normal View History

2024-03-10 18:52:04 +00:00
defmodule Ecto.Integration.SQLTest do
use Ecto.Integration.Case, async: Application.compile_env(:ecto, :async_integration_tests, true)
alias Ecto.Integration.PoolRepo
alias Ecto.Integration.TestRepo
alias Ecto.Integration.Barebone
alias Ecto.Integration.Post
alias Ecto.Integration.CorruptedPk
alias Ecto.Integration.Tag
import Ecto.Query, only: [from: 2]
test "fragmented types" do
datetime = ~N[2014-01-16 20:26:51]
TestRepo.insert!(%Post{inserted_at: datetime})
query = from p in Post, where: fragment("? >= ?", p.inserted_at, ^datetime), select: p.inserted_at
assert [^datetime] = TestRepo.all(query)
end
test "fragmented schemaless types" do
TestRepo.insert!(%Post{visits: 123})
assert [123] = TestRepo.all(from p in "posts", select: type(fragment("visits"), :integer))
end
@tag :array_type
test "fragment array types" do
text1 = "foo"
text2 = "bar"
result = TestRepo.query!("SELECT $1::text[]", [[text1, text2]])
assert result.rows == [[[text1, text2]]]
end
@tag :array_type
test "Converts empty array correctly" do
result = TestRepo.query!("SELECT array[1,2,3] = $1", [[]])
assert result.rows == [[false]]
result = TestRepo.query!("SELECT array[]::integer[] = $1", [[]])
assert result.rows == [[true]]
%{id: tag_id} = TestRepo.insert!(%Tag{uuids: []})
query = from t in Tag, where: t.uuids == []
assert [%{id: ^tag_id}] = TestRepo.all(query)
end
test "query!/4 with dynamic repo" do
TestRepo.put_dynamic_repo(:unknown)
assert_raise RuntimeError, ~r/:unknown/, fn -> TestRepo.query!("SELECT 1") end
end
test "query!/4" do
result = TestRepo.query!("SELECT 1")
assert result.rows == [[1]]
end
test "query!/4 with iodata" do
result = TestRepo.query!(["SELECT", ?\s, ?1])
assert result.rows == [[1]]
end
test "disconnect_all/2" do
assert :ok = PoolRepo.disconnect_all(0)
end
test "to_sql/3" do
{sql, []} = TestRepo.to_sql(:all, Barebone)
assert sql =~ "SELECT"
assert sql =~ "barebones"
{sql, [0]} = TestRepo.to_sql(:update_all, from(b in Barebone, update: [set: [num: ^0]]))
assert sql =~ "UPDATE"
assert sql =~ "barebones"
assert sql =~ "SET"
{sql, []} = TestRepo.to_sql(:delete_all, Barebone)
assert sql =~ "DELETE"
assert sql =~ "barebones"
end
test "raises when primary key is not unique on struct operation" do
schema = %CorruptedPk{a: "abc"}
TestRepo.insert!(schema)
TestRepo.insert!(schema)
TestRepo.insert!(schema)
assert_raise Ecto.MultiplePrimaryKeyError,
~r|expected delete on corrupted_pk to return at most one entry but got 3 entries|,
fn -> TestRepo.delete!(schema) end
end
test "Repo.insert! escape" do
TestRepo.insert!(%Post{title: "'"})
query = from(p in Post, select: p.title)
assert ["'"] == TestRepo.all(query)
end
test "Repo.update! escape" do
p = TestRepo.insert!(%Post{title: "hello"})
TestRepo.update!(Ecto.Changeset.change(p, title: "'"))
query = from(p in Post, select: p.title)
assert ["'"] == TestRepo.all(query)
end
@tag :insert_cell_wise_defaults
test "Repo.insert_all escape" do
TestRepo.insert_all(Post, [%{title: "'"}])
query = from(p in Post, select: p.title)
assert ["'"] == TestRepo.all(query)
end
test "Repo.update_all escape" do
TestRepo.insert!(%Post{title: "hello"})
TestRepo.update_all(Post, set: [title: "'"])
reader = from(p in Post, select: p.title)
assert ["'"] == TestRepo.all(reader)
query = from(Post, where: "'" != "")
TestRepo.update_all(query, set: [title: "''"])
assert ["''"] == TestRepo.all(reader)
end
test "Repo.delete_all escape" do
TestRepo.insert!(%Post{title: "hello"})
assert [_] = TestRepo.all(Post)
TestRepo.delete_all(from(Post, where: "'" == "'"))
assert [] == TestRepo.all(Post)
end
test "load" do
inserted_at = ~N[2016-01-01 09:00:00]
TestRepo.insert!(%Post{title: "title1", inserted_at: inserted_at, public: false})
result = Ecto.Adapters.SQL.query!(TestRepo, "SELECT * FROM posts", [])
posts = Enum.map(result.rows, &TestRepo.load(Post, {result.columns, &1}))
assert [%Post{title: "title1", inserted_at: ^inserted_at, public: false}] = posts
end
test "returns true when table exists" do
assert Ecto.Adapters.SQL.table_exists?(TestRepo, "posts")
end
test "returns false table doesn't exists" do
refute Ecto.Adapters.SQL.table_exists?(TestRepo, "unknown")
end
test "returns result as a formatted table" do
TestRepo.insert_all(Post, [%{title: "my post title", counter: 1, public: nil}])
# resolve correct query for each adapter
query = from(p in Post, select: [p.title, p.counter, p.public])
{query, _} = Ecto.Adapters.SQL.to_sql(:all, TestRepo, query)
table =
query
|> TestRepo.query!()
|> Ecto.Adapters.SQL.format_table()
assert table == "+---------------+---------+--------+\n| title | counter | public |\n+---------------+---------+--------+\n| my post title | 1 | NULL |\n+---------------+---------+--------+"
end
test "format_table edge cases" do
assert Ecto.Adapters.SQL.format_table(nil) == ""
assert Ecto.Adapters.SQL.format_table(%{columns: nil, rows: nil}) == ""
assert Ecto.Adapters.SQL.format_table(%{columns: [], rows: []}) == ""
assert Ecto.Adapters.SQL.format_table(%{columns: [], rows: [["test"]]}) == ""
assert Ecto.Adapters.SQL.format_table(%{columns: ["test"], rows: []}) == "+------+\n| test |\n+------+\n+------+"
assert Ecto.Adapters.SQL.format_table(%{columns: ["test"], rows: nil}) == "+------+\n| test |\n+------+\n+------+"
end
end