diff --git a/lib/ecto/adapters/sqlite3/connection.ex b/lib/ecto/adapters/sqlite3/connection.ex index b5b8503..b8f0490 100644 --- a/lib/ecto/adapters/sqlite3/connection.ex +++ b/lib/ecto/adapters/sqlite3/connection.ex @@ -130,6 +130,13 @@ defmodule Ecto.Adapters.SQLite3.Connection do end @impl true + def to_constraints( + %Exqlite.Error{message: "UNIQUE constraint failed: index " <> constraint}, + _opts + ) do + [unique: String.trim(constraint, ~s('))] + end + def to_constraints( %Exqlite.Error{message: "UNIQUE constraint failed: " <> constraint}, _opts diff --git a/test/ecto/adapters/sqlite3/connection_test.exs b/test/ecto/adapters/sqlite3/connection_test.exs index b44a015..8a1f5ef 100644 --- a/test/ecto/adapters/sqlite3/connection_test.exs +++ b/test/ecto/adapters/sqlite3/connection_test.exs @@ -2414,6 +2414,40 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do assert execute_ddl(integer) == [~s/CREATE TABLE "posts" ("id" INTEGER PRIMARY KEY)/] end + describe "to_constraints/2" do + alias Ecto.Adapters.SQLite3.Connection + + test "unique index" do + # created with: + # CREATE UNIQUE INDEX users_email_name_index ON users (email); + + error = %Exqlite.Error{message: "UNIQUE constraint failed: users.email"} + assert Connection.to_constraints(error, []) == [unique: "users_email_index"] + end + + test "multi-column unique index" do + # created with: + # CREATE UNIQUE INDEX users_email_name_index ON users (email, name); + + error = %Exqlite.Error{ + message: "UNIQUE constraint failed: users.email, users.name" + } + + assert Connection.to_constraints(error, []) == [unique: "users_email_name_index"] + end + + test "complex unique index" do + # created with: + # CREATE UNIQUE INDEX users_email_year_index ON users (email, strftime('%Y', inserted_at)); + + error = %Exqlite.Error{ + message: "UNIQUE constraint failed: index 'users_email_year_index'" + } + + assert Connection.to_constraints(error, []) == [unique: "users_email_year_index"] + end + end + defp remove_newlines(string) do string |> String.trim() |> String.replace("\n", " ") end