WIP: removing stuff like schemas and prefixes

This commit is contained in:
Zach Daniel 2023-09-22 23:11:45 -04:00
parent 6fb41026f8
commit c8c811c7eb
16 changed files with 137 additions and 768 deletions

View file

@ -27,11 +27,9 @@ spark_locals_without_parens = [
polymorphic_name: 1,
polymorphic_on_delete: 1,
polymorphic_on_update: 1,
prefix: 1,
reference: 1,
reference: 2,
repo: 1,
schema: 1,
skip_unique_indexes: 1,
statement: 1,
statement: 2,

View file

@ -5,7 +5,7 @@ defmodule AshSqlite.Calculation do
def add_calculations(query, [], _, _), do: {:ok, query}
def add_calculations(query, calculations, resource, source_binding) do
def add_calculations(query, calculations, resource, _source_binding) do
query = AshSqlite.DataLayer.default_bindings(query, resource)
query =

View file

@ -7,7 +7,6 @@ defmodule AshSqlite.CustomIndex do
:unique,
:concurrently,
:using,
:prefix,
:where,
:include,
:message
@ -40,10 +39,6 @@ defmodule AshSqlite.CustomIndex do
type: :string,
doc: "configures the index type."
],
prefix: [
type: :string,
doc: "specify an optional prefix for the index."
],
where: [
type: :string,
doc: "specify conditions for a partial index."

View file

@ -393,7 +393,7 @@ defmodule AshSqlite.DataLayer do
AshSqlite.DataLayer.Info.repo(resource) == AshSqlite.DataLayer.Info.repo(other_resource)
end
def can?(resource, {:lateral_join, _}) do
def can?(_resource, {:lateral_join, _}) do
false
end
@ -470,13 +470,6 @@ defmodule AshSqlite.DataLayer do
data_layer_query
end
data_layer_query =
if context[:data_layer][:schema] do
Ecto.Query.put_query_prefix(data_layer_query, to_string(context[:data_layer][:schema]))
else
data_layer_query
end
default_bindings(data_layer_query, resource, context)
end
@ -551,13 +544,9 @@ defmodule AshSqlite.DataLayer do
defp no_table?(%{from: %{source: {"", _}}}), do: true
defp no_table?(_), do: false
defp repo_opts(timeout, nil, resource) do
if schema = AshSqlite.DataLayer.Info.schema(resource) do
[prefix: schema]
else
defp repo_opts(timeout, nil, _resource) do
[]
end
|> add_timeout(timeout)
|> add_timeout(timeout)
end
defp repo_opts(timeout, _resource) do
@ -578,28 +567,6 @@ defmodule AshSqlite.DataLayer do
]
end
defp add_exists_aggs(result, resource, query, exists) do
repo = dynamic_repo(resource, query)
repo_opts = repo_opts(nil, nil, resource)
Enum.reduce(exists, result, fn agg, result ->
{:ok, filtered} =
case agg do
%{query: %{filter: filter}} when not is_nil(filter) ->
filter(query, filter, resource)
_ ->
{:ok, query}
end
Map.put(
result || %{},
agg.name,
repo.exists?(filtered, repo_opts)
)
end)
end
@impl true
def resource_to_query(resource, _) do
from(row in {AshSqlite.DataLayer.Info.table(resource) || "", resource}, [])
@ -796,48 +763,12 @@ defmodule AshSqlite.DataLayer do
{:error, Ash.Error.to_ash_error(error, stacktrace)}
end
defp constraints_to_errors(%{constraints: user_constraints} = changeset, action, constraints) do
Enum.map(constraints, fn {type, constraint} ->
user_constraint =
Enum.find(user_constraints, fn c ->
case {c.type, c.constraint, c.match} do
{^type, ^constraint, :exact} -> true
{^type, cc, :suffix} -> String.ends_with?(constraint, cc)
{^type, cc, :prefix} -> String.starts_with?(constraint, cc)
{^type, %Regex{} = r, _match} -> Regex.match?(r, constraint)
_ -> false
end
end)
case user_constraint do
%{field: field, error_message: error_message, type: type, constraint: constraint} ->
Ash.Error.Changes.InvalidAttribute.exception(
field: field,
message: error_message,
private_vars: [
constraint: constraint,
constraint_type: type
]
)
nil ->
Ecto.ConstraintError.exception(
action: action,
type: type,
constraint: constraint,
changeset: changeset
)
end
end)
end
defp set_table(record, changeset, operation, table_error?) do
if AshSqlite.DataLayer.Info.polymorphic?(record.__struct__) do
table =
changeset.context[:data_layer][:table] ||
AshSqlite.DataLayer.Info.table(record.__struct__)
record =
if table do
Ecto.put_meta(record, source: table)
else
@ -848,16 +779,7 @@ defmodule AshSqlite.DataLayer do
end
end
prefix =
changeset.context[:data_layer][:schema] ||
AshSqlite.DataLayer.Info.schema(record.__struct__)
if prefix do
Ecto.put_meta(record, prefix: table)
else
record
end
else
else
record
end
end
@ -1212,12 +1134,6 @@ defmodule AshSqlite.DataLayer do
atomics_result =
Enum.reduce_while(changeset.atomics, {:ok, query, []}, fn {field, expr},
{:ok, query, set} ->
used_calculations =
Ash.Filter.used_calculations(
expr,
resource
)
with {:ok, query} <-
AshSqlite.Join.join_all_relationships(
query,
@ -1641,12 +1557,6 @@ defmodule AshSqlite.DataLayer do
def filter(query, filter, resource, opts \\ []) do
query = default_bindings(query, resource)
used_calculations =
Ash.Filter.used_calculations(
filter,
resource
)
query
|> AshSqlite.Join.join_all_relationships(filter, opts)
|> case do

View file

@ -13,10 +13,6 @@ defmodule AshSqlite.DataLayer.Info do
Extension.get_opt(resource, [:sqlite], :table, nil, true)
end
@doc "The configured schema for a resource"
def schema(resource) do
Extension.get_opt(resource, [:sqlite], :schema, nil, true)
end
@doc "The configured references for a resource"
def references(resource) do

View file

@ -54,19 +54,6 @@ defmodule AshSqlite.Expr do
Ecto.Query.dynamic(not (^new_expression))
end
defp do_dynamic_expr(
query,
%TrigramSimilarity{arguments: [arg1, arg2], embedded?: pred_embedded?},
bindings,
embedded?,
_type
) do
arg1 = do_dynamic_expr(query, arg1, bindings, pred_embedded? || embedded?, :string)
arg2 = do_dynamic_expr(query, arg2, bindings, pred_embedded? || embedded?, :string)
Ecto.Query.dynamic(fragment("similarity(?, ?)", ^arg1, ^arg2))
end
defp do_dynamic_expr(
query,
%Like{arguments: [arg1, arg2], embedded?: pred_embedded?},
@ -956,13 +943,6 @@ defmodule AshSqlite.Expr do
[first_relationship.name]
)
used_calculations =
Ash.Filter.used_calculations(
filter,
first_relationship.destination,
[]
)
{:ok, filtered} =
source
|> set_parent_path(query)
@ -1253,14 +1233,6 @@ defmodule AshSqlite.Expr do
:ok
end
defp maybe_type(dynamic, nil, _query), do: dynamic
defp maybe_type(dynamic, type, query) do
validate_type!(query, type, type)
Ecto.Query.dynamic(type(^dynamic, ^type))
end
defp maybe_sanitize_list(query, value, bindings, embedded?, type) do
if is_list(value) do
Enum.map(value, &do_dynamic_expr(query, &1, bindings, embedded?, type))

View file

@ -1,6 +1,6 @@
defmodule AshSqlite.Join do
@moduledoc false
import Ecto.Query, only: [from: 2, subquery: 1]
import Ecto.Query, only: [from: 2]
alias Ash.Query.{BooleanExpression, Not, Ref}
@ -175,10 +175,7 @@ defmodule AshSqlite.Join do
%{valid?: true} = query ->
ash_query = query
initial_query = %{
AshSqlite.DataLayer.resource_to_query(resource, nil)
| prefix: Map.get(root_query, :prefix)
}
initial_query = AshSqlite.DataLayer.resource_to_query(resource, nil)
case Ash.Query.data_layer_query(query,
initial_query: initial_query
@ -334,16 +331,6 @@ defmodule AshSqlite.Join do
end
end
def set_join_prefix(join_query, query, resource) do
%{
join_query
| prefix:
AshSqlite.DataLayer.Info.schema(resource) ||
AshSqlite.DataLayer.Info.repo(resource).config()[:default_prefix] ||
"public"
}
end
defp can_inner_join?(path, expr, seen_an_or? \\ false)
defp can_inner_join?(path, %{expression: expr}, seen_an_or?),
@ -463,7 +450,7 @@ defmodule AshSqlite.Join do
path,
kind,
source,
filter
_filter
) do
full_path = path ++ [relationship.name]
initial_ash_bindings = query.__ash_bindings__
@ -472,13 +459,6 @@ defmodule AshSqlite.Join do
query = AshSqlite.DataLayer.add_binding(query, binding_data)
used_calculations =
Ash.Filter.used_calculations(
filter,
relationship.destination,
full_path
)
use_root_query_bindings? = true
root_bindings =
@ -500,7 +480,6 @@ defmodule AshSqlite.Join do
relationship_destination =
relationship_destination
|> Ecto.Queryable.to_query()
|> set_join_prefix(query, relationship.destination)
binding_kinds =
case kind do
@ -548,7 +527,7 @@ defmodule AshSqlite.Join do
path,
kind,
source,
filter
_filter
) do
join_relationship =
Ash.Resource.Info.relationship(relationship.source, relationship.join_relationship)
@ -570,13 +549,6 @@ defmodule AshSqlite.Join do
})
|> AshSqlite.DataLayer.add_binding(binding_data)
used_calculations =
Ash.Filter.used_calculations(
filter,
relationship.destination,
full_path
)
use_root_query_bindings? = true
root_bindings =
@ -603,13 +575,10 @@ defmodule AshSqlite.Join do
relationship_through =
relationship_through
|> Ecto.Queryable.to_query()
|> set_join_prefix(query, relationship.through)
relationship_destination =
relationship_destination
|> Ecto.Queryable.to_query()
|> set_join_prefix(query, relationship.destination)
binding_kinds =
case kind do
:left ->
@ -670,7 +639,7 @@ defmodule AshSqlite.Join do
path,
kind,
source,
filter
_filter
) do
full_path = path ++ [relationship.name]
initial_ash_bindings = query.__ash_bindings__
@ -679,13 +648,6 @@ defmodule AshSqlite.Join do
query = AshSqlite.DataLayer.add_binding(query, binding_data)
used_calculations =
Ash.Filter.used_calculations(
filter,
relationship.destination,
full_path
)
use_root_query_bindings? = true
root_bindings =
@ -707,7 +669,6 @@ defmodule AshSqlite.Join do
relationship_destination =
relationship_destination
|> Ecto.Queryable.to_query()
|> set_join_prefix(query, relationship.destination)
binding_kinds =
case kind do

View file

@ -536,7 +536,7 @@ defmodule AshSqlite.MigrationGenerator do
grouped =
snapshots
|> Enum.group_by(fn snapshot ->
{snapshot.table, snapshot.schema}
snapshot.table
end)
old_snapshots =
@ -679,8 +679,7 @@ defmodule AshSqlite.MigrationGenerator do
on_delete: merge_uniq!(references, table, :on_delete, name),
on_update: merge_uniq!(references, table, :on_update, name),
name: merge_uniq!(references, table, :name, name),
table: merge_uniq!(references, table, :table, name),
schema: merge_uniq!(references, table, :schema, name)
table: merge_uniq!(references, table, :table, name)
}
end
end
@ -1049,7 +1048,6 @@ defmodule AshSqlite.MigrationGenerator do
attribute: %{
source: name
},
schema: schema,
table: table
} = add
| rest
@ -1062,7 +1060,7 @@ defmodule AshSqlite.MigrationGenerator do
false
op ->
op.table == table && op.schema == schema
op.table == table
end)
|> Enum.with_index()
|> Enum.find(fn
@ -1101,45 +1099,45 @@ defmodule AshSqlite.MigrationGenerator do
defp group_into_phases(
[
%Operation.CreateTable{table: table, schema: schema, multitenancy: multitenancy} | rest
%Operation.CreateTable{table: table, multitenancy: multitenancy} | rest
],
nil,
acc
) do
group_into_phases(
rest,
%Phase.Create{table: table, schema: schema, multitenancy: multitenancy},
%Phase.Create{table: table, multitenancy: multitenancy},
acc
)
end
defp group_into_phases(
[%Operation.AddAttribute{table: table, schema: schema} = op | rest],
%{table: table, schema: schema} = phase,
[%Operation.AddAttribute{table: table} = op | rest],
%{table: table} = phase,
acc
) do
group_into_phases(rest, %{phase | operations: [op | phase.operations]}, acc)
end
defp group_into_phases(
[%Operation.AlterAttribute{table: table, schema: schema} = op | rest],
%Phase.Alter{table: table, schema: schema} = phase,
[%Operation.AlterAttribute{table: table} = op | rest],
%Phase.Alter{table: table} = phase,
acc
) do
group_into_phases(rest, %{phase | operations: [op | phase.operations]}, acc)
end
defp group_into_phases(
[%Operation.RenameAttribute{table: table, schema: schema} = op | rest],
%Phase.Alter{table: table, schema: schema} = phase,
[%Operation.RenameAttribute{table: table} = op | rest],
%Phase.Alter{table: table} = phase,
acc
) do
group_into_phases(rest, %{phase | operations: [op | phase.operations]}, acc)
end
defp group_into_phases(
[%Operation.RemoveAttribute{table: table, schema: schema} = op | rest],
%{table: table, schema: schema} = phase,
[%Operation.RemoveAttribute{table: table} = op | rest],
%{table: table} = phase,
acc
) do
group_into_phases(rest, %{phase | operations: [op | phase.operations]}, acc)
@ -1153,8 +1151,7 @@ defmodule AshSqlite.MigrationGenerator do
phase = %Phase.Alter{
operations: [operation],
multitenancy: operation.multitenancy,
table: operation.table,
schema: operation.schema
table: operation.table
}
group_into_phases(rest, phase, acc)
@ -1220,27 +1217,25 @@ defmodule AshSqlite.MigrationGenerator do
do: true
defp after?(
%Operation.AddAttribute{attribute: %{order: l}, table: table, schema: schema},
%Operation.AddAttribute{attribute: %{order: r}, table: table, schema: schema}
%Operation.AddAttribute{attribute: %{order: l}, table: table},
%Operation.AddAttribute{attribute: %{order: r}, table: table}
),
do: l > r
defp after?(
%Operation.RenameUniqueIndex{
table: table,
schema: schema
table: table
},
%{table: table, schema: schema}
%{table: table}
) do
true
end
defp after?(
%Operation.AddUniqueIndex{
table: table,
schema: schema
table: table
},
%{table: table, schema: schema}
%{table: table}
) do
true
end
@ -1249,10 +1244,9 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.AddCheckConstraint{
constraint: %{attribute: attribute_or_attributes},
table: table,
multitenancy: multitenancy,
schema: schema
multitenancy: multitenancy
},
%Operation.AddAttribute{table: table, attribute: %{source: source}, schema: schema}
%Operation.AddAttribute{table: table, attribute: %{source: source}}
) do
source in List.wrap(attribute_or_attributes) ||
(multitenancy.attribute && multitenancy.attribute in List.wrap(attribute_or_attributes))
@ -1260,10 +1254,9 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddCustomIndex{
table: table,
schema: schema
table: table
},
%Operation.AddAttribute{table: table, schema: schema}
%Operation.AddAttribute{table: table}
) do
true
end
@ -1271,14 +1264,12 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddCustomIndex{
table: table,
schema: schema,
index: %{
concurrently: true
}
},
%Operation.AddCustomIndex{
table: table,
schema: schema,
index: %{
concurrently: false
}
@ -1288,10 +1279,9 @@ defmodule AshSqlite.MigrationGenerator do
end
defp after?(
%Operation.AddCheckConstraint{table: table, schema: schema, constraint: %{name: name}},
%Operation.AddCheckConstraint{table: table, constraint: %{name: name}},
%Operation.RemoveCheckConstraint{
table: table,
schema: schema,
constraint: %{
name: name
}
@ -1302,22 +1292,20 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.RemoveCheckConstraint{
table: table,
schema: schema,
constraint: %{
name: name
}
},
%Operation.AddCheckConstraint{table: table, schema: schema, constraint: %{name: name}}
%Operation.AddCheckConstraint{table: table, constraint: %{name: name}}
),
do: false
defp after?(
%Operation.AddCheckConstraint{
constraint: %{attribute: attribute_or_attributes},
table: table,
schema: schema
table: table
},
%Operation.AlterAttribute{table: table, new_attribute: %{source: source}, schema: schema}
%Operation.AlterAttribute{table: table, new_attribute: %{source: source}}
) do
source in List.wrap(attribute_or_attributes)
end
@ -1325,28 +1313,26 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddCheckConstraint{
constraint: %{attribute: attribute_or_attributes},
table: table,
schema: schema
table: table
},
%Operation.RenameAttribute{
table: table,
new_attribute: %{source: source},
schema: schema
new_attribute: %{source: source}
}
) do
source in List.wrap(attribute_or_attributes)
end
defp after?(
%Operation.RemoveUniqueIndex{table: table, schema: schema},
%Operation.AddUniqueIndex{table: table, schema: schema}
%Operation.RemoveUniqueIndex{table: table},
%Operation.AddUniqueIndex{table: table}
) do
false
end
defp after?(
%Operation.RemoveUniqueIndex{table: table, schema: schema},
%{table: table, schema: schema}
%Operation.RemoveUniqueIndex{table: table},
%{table: table}
) do
true
end
@ -1354,10 +1340,9 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.RemoveCheckConstraint{
constraint: %{attribute: attributes},
table: table,
schema: schema
table: table
},
%Operation.RemoveAttribute{table: table, attribute: %{source: source}, schema: schema}
%Operation.RemoveAttribute{table: table, attribute: %{source: source}}
) do
source in List.wrap(attributes)
end
@ -1365,30 +1350,26 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.RemoveCheckConstraint{
constraint: %{attribute: attributes},
table: table,
schema: schema
table: table
},
%Operation.RenameAttribute{
table: table,
old_attribute: %{source: source},
schema: schema
old_attribute: %{source: source}
}
) do
source in List.wrap(attributes)
end
defp after?(%Operation.AlterAttribute{table: table, schema: schema}, %Operation.DropForeignKey{
defp after?(%Operation.AlterAttribute{table: table}, %Operation.DropForeignKey{
table: table,
schema: schema,
direction: :up
}),
do: true
defp after?(
%Operation.AlterAttribute{table: table, schema: schema},
%Operation.AlterAttribute{table: table},
%Operation.DropForeignKey{
table: table,
schema: schema,
direction: :down
}
),
@ -1397,17 +1378,15 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.DropForeignKey{
table: table,
schema: schema,
direction: :down
},
%Operation.AlterAttribute{table: table, schema: schema}
%Operation.AlterAttribute{table: table}
),
do: true
defp after?(%Operation.AddAttribute{table: table, schema: schema}, %Operation.CreateTable{
table: table,
schema: schema
}) do
defp after?(%Operation.AddAttribute{table: table}, %Operation.CreateTable{
table: table
}) do
true
end
@ -1424,25 +1403,22 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: false
}
},
%Operation.AddAttribute{schema: schema, table: table, attribute: %{primary_key?: true}}
%Operation.AddAttribute{table: table, attribute: %{primary_key?: true}}
),
do: true
defp after?(
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: true
}
},
%Operation.RemoveAttribute{
schema: schema,
table: table,
attribute: %{primary_key?: true}
}
@ -1452,13 +1428,11 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: true
}
},
%Operation.AlterAttribute{
schema: schema,
table: table,
new_attribute: %{primary_key?: false},
old_attribute: %{primary_key?: true}
@ -1469,13 +1443,11 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: true
}
},
%Operation.AlterAttribute{
schema: schema,
table: table,
new_attribute: %{primary_key?: false},
old_attribute: %{primary_key?: true}
@ -1485,13 +1457,11 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.RemoveAttribute{
schema: schema,
table: table,
attribute: %{primary_key?: true}
},
%Operation.AlterAttribute{
table: table,
schema: schema,
new_attribute: %{
primary_key?: true
},
@ -1504,7 +1474,6 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AlterAttribute{
schema: schema,
table: table,
new_attribute: %{primary_key?: false},
old_attribute: %{
@ -1513,7 +1482,6 @@ defmodule AshSqlite.MigrationGenerator do
},
%Operation.AlterAttribute{
table: table,
schema: schema,
new_attribute: %{
primary_key?: true
},
@ -1526,7 +1494,6 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AlterAttribute{
schema: schema,
table: table,
new_attribute: %{primary_key?: false},
old_attribute: %{
@ -1535,7 +1502,6 @@ defmodule AshSqlite.MigrationGenerator do
},
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: true
}
@ -1546,13 +1512,11 @@ defmodule AshSqlite.MigrationGenerator do
defp after?(
%Operation.AlterAttribute{
table: table,
schema: schema,
new_attribute: %{primary_key?: false},
old_attribute: %{primary_key?: true}
},
%Operation.AddAttribute{
table: table,
schema: schema,
attribute: %{
primary_key?: true
}
@ -1619,10 +1583,9 @@ defmodule AshSqlite.MigrationGenerator do
),
do: true
defp after?(%Operation.AddCheckConstraint{table: table, schema: schema}, %Operation.CreateTable{
table: table,
schema: schema
}) do
defp after?(%Operation.AddCheckConstraint{table: table}, %Operation.CreateTable{
table: table
}) do
true
end
@ -1650,21 +1613,10 @@ defmodule AshSqlite.MigrationGenerator do
defp do_fetch_operations(snapshot, existing_snapshot, opts, acc \\ [])
defp do_fetch_operations(
%{schema: new_schema} = snapshot,
%{schema: old_schema},
opts,
[]
)
when new_schema != old_schema do
do_fetch_operations(snapshot, nil, opts, [])
end
defp do_fetch_operations(snapshot, nil, opts, acc) do
empty_snapshot = %{
attributes: [],
identities: [],
schema: nil,
custom_indexes: [],
custom_statements: [],
check_constraints: [],
@ -1682,7 +1634,6 @@ defmodule AshSqlite.MigrationGenerator do
do_fetch_operations(snapshot, empty_snapshot, opts, [
%Operation.CreateTable{
table: snapshot.table,
schema: snapshot.schema,
multitenancy: snapshot.multitenancy,
old_multitenancy: empty_snapshot.multitenancy
}
@ -1737,7 +1688,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.AddCustomIndex{
index: custom_index,
table: snapshot.table,
schema: snapshot.schema,
multitenancy: snapshot.multitenancy,
base_filter: snapshot.base_filter
}
@ -1754,7 +1704,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.RemoveCustomIndex{
index: custom_index,
table: old_snapshot.table,
schema: old_snapshot.schema,
multitenancy: old_snapshot.multitenancy,
base_filter: old_snapshot.base_filter
}
@ -1775,8 +1724,7 @@ defmodule AshSqlite.MigrationGenerator do
|> Enum.map(fn identity ->
%Operation.RemoveUniqueIndex{
identity: identity,
table: snapshot.table,
schema: snapshot.schema
table: snapshot.table
}
end)
@ -1799,7 +1747,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.RenameUniqueIndex{
old_identity: old_identity,
new_identity: new_identity,
schema: snapshot.schema,
table: snapshot.table
}
end)
@ -1819,7 +1766,6 @@ defmodule AshSqlite.MigrationGenerator do
|> Enum.map(fn identity ->
%Operation.AddUniqueIndex{
identity: identity,
schema: snapshot.schema,
table: snapshot.table
}
end)
@ -1834,8 +1780,7 @@ defmodule AshSqlite.MigrationGenerator do
|> Enum.map(fn constraint ->
%Operation.AddCheckConstraint{
constraint: constraint,
table: snapshot.table,
schema: snapshot.schema
table: snapshot.table
}
end)
@ -1849,8 +1794,7 @@ defmodule AshSqlite.MigrationGenerator do
|> Enum.map(fn old_constraint ->
%Operation.RemoveCheckConstraint{
constraint: old_constraint,
table: old_snapshot.table,
schema: old_snapshot.schema
table: old_snapshot.table
}
end)
@ -1930,8 +1874,8 @@ defmodule AshSqlite.MigrationGenerator do
if must_drop_pkey? do
[
%Operation.RemovePrimaryKey{schema: snapshot.schema, table: snapshot.table},
%Operation.RemovePrimaryKeyDown{schema: snapshot.schema, table: snapshot.table}
%Operation.RemovePrimaryKey{ table: snapshot.table},
%Operation.RemovePrimaryKeyDown{ table: snapshot.table}
]
else
[]
@ -1970,8 +1914,7 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.RenameAttribute{
new_attribute: new,
old_attribute: old,
table: snapshot.table,
schema: snapshot.schema
table: snapshot.table
}
end)
@ -1983,13 +1926,11 @@ defmodule AshSqlite.MigrationGenerator do
[
%Operation.AlterDeferrability{
table: snapshot.table,
schema: snapshot.schema,
references: attribute.references,
direction: :up
},
%Operation.AlterDeferrability{
table: snapshot.table,
schema: snapshot.schema,
references: Map.get(attribute, :references),
direction: :down
}
@ -2001,19 +1942,16 @@ defmodule AshSqlite.MigrationGenerator do
[
%Operation.AddAttribute{
attribute: Map.delete(attribute, :references),
schema: snapshot.schema,
table: snapshot.table
},
%Operation.AlterAttribute{
old_attribute: Map.delete(attribute, :references),
new_attribute: attribute,
schema: snapshot.schema,
table: snapshot.table
},
%Operation.DropForeignKey{
attribute: attribute,
table: snapshot.table,
schema: snapshot.schema,
multitenancy: Map.get(attribute, :multitenancy),
direction: :down
}
@ -2022,8 +1960,7 @@ defmodule AshSqlite.MigrationGenerator do
[
%Operation.AddAttribute{
attribute: attribute,
table: snapshot.table,
schema: snapshot.schema
table: snapshot.table
}
]
end
@ -2036,13 +1973,11 @@ defmodule AshSqlite.MigrationGenerator do
[
%Operation.AlterDeferrability{
table: snapshot.table,
schema: snapshot.schema,
references: new_attribute.references,
direction: :up
},
%Operation.AlterDeferrability{
table: snapshot.table,
schema: snapshot.schema,
references: Map.get(old_attribute, :references),
direction: :down
}
@ -2060,7 +1995,6 @@ defmodule AshSqlite.MigrationGenerator do
[
%Operation.AlterDeferrability{
table: snapshot.table,
schema: snapshot.schema,
references: new_attribute.references,
direction: :up
}
@ -2072,14 +2006,12 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.DropForeignKey{
attribute: old_attribute,
table: snapshot.table,
schema: snapshot.schema,
multitenancy: old_snapshot.multitenancy,
direction: :up
},
%Operation.AlterAttribute{
new_attribute: new_attribute,
old_attribute: old_attribute,
schema: snapshot.schema,
table: snapshot.table
}
] ++ redo_deferrability
@ -2089,7 +2021,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.DropForeignKey{
attribute: new_attribute,
table: snapshot.table,
schema: snapshot.schema,
multitenancy: snapshot.multitenancy,
direction: :down
}
@ -2105,7 +2036,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.AlterAttribute{
new_attribute: Map.delete(new_attribute, :references),
old_attribute: Map.delete(old_attribute, :references),
schema: snapshot.schema,
table: snapshot.table
}
]
@ -2118,7 +2048,6 @@ defmodule AshSqlite.MigrationGenerator do
%Operation.RemoveAttribute{
attribute: attribute,
table: snapshot.table,
schema: snapshot.schema,
commented?: !opts.drop_columns
}
end)
@ -2157,7 +2086,7 @@ defmodule AshSqlite.MigrationGenerator do
left != right
end
defp clean_for_equality(attribute, repo) do
defp clean_for_equality(attribute, _repo) do
cond do
attribute[:source] ->
Map.put(attribute, :name, attribute[:source])
@ -2173,7 +2102,6 @@ defmodule AshSqlite.MigrationGenerator do
true ->
attribute
end
|> add_schema(repo)
|> add_ignore()
|> then(fn
# only :integer cares about `destination_attribute_generated`
@ -2196,25 +2124,12 @@ defmodule AshSqlite.MigrationGenerator do
attribute
end
defp add_schema(%{references: references} = attribute, repo) when is_map(references) do
schema = Map.get(references, :schema) || repo.config()[:default_prefix] || "public"
%{
attribute
| references: Map.put(references, :schema, schema)
}
end
defp add_schema(attribute, _) do
attribute
end
def changing_multitenancy_affects_identities?(snapshot, old_snapshot) do
snapshot.multitenancy != old_snapshot.multitenancy ||
snapshot.base_filter != old_snapshot.base_filter
end
def has_reference?(multitenancy, attribute) do
def has_reference?(_multitenancy, attribute) do
not is_nil(Map.get(attribute, :references))
end
@ -2367,8 +2282,7 @@ defmodule AshSqlite.MigrationGenerator do
|> Enum.map(fn relationship ->
resource
|> do_snapshot(
relationship.context[:data_layer][:table],
relationship.context[:data_layer][:schema]
relationship.context[:data_layer][:table]
)
|> Map.update!(:identities, fn identities ->
identity_index_names = AshSqlite.DataLayer.Info.identity_index_names(resource)
@ -2405,7 +2319,6 @@ defmodule AshSqlite.MigrationGenerator do
destination_attribute_generated: source_attribute.generated?,
multitenancy: multitenancy(relationship.source),
table: AshSqlite.DataLayer.Info.table(relationship.source),
schema: AshSqlite.DataLayer.Info.schema(relationship.source),
on_delete: AshSqlite.DataLayer.Info.polymorphic_on_delete(relationship.source),
on_update: AshSqlite.DataLayer.Info.polymorphic_on_update(relationship.source),
primary_key?: source_attribute.primary_key?,
@ -2424,12 +2337,11 @@ defmodule AshSqlite.MigrationGenerator do
end
end
defp do_snapshot(resource, table, schema \\ nil) do
defp do_snapshot(resource, table) do
snapshot = %{
attributes: attributes(resource, table),
identities: identities(resource),
table: table || AshSqlite.DataLayer.Info.table(resource),
schema: schema || AshSqlite.DataLayer.Info.schema(resource),
check_constraints: check_constraints(resource),
custom_indexes: custom_indexes(resource),
custom_statements: custom_statements(resource),
@ -2617,12 +2529,6 @@ defmodule AshSqlite.MigrationGenerator do
on_update: configured_reference.on_update,
name: configured_reference.name,
primary_key?: destination_attribute.primary_key?,
schema:
relationship.context[:data_layer][:schema] ||
AshSqlite.DataLayer.Info.schema(relationship.destination) ||
AshSqlite.DataLayer.Info.repo(relationship.destination).config()[
:default_prefix
],
table:
relationship.context[:data_layer][:table] ||
AshSqlite.DataLayer.Info.table(relationship.destination)
@ -2641,10 +2547,6 @@ defmodule AshSqlite.MigrationGenerator do
on_delete: nil,
on_update: nil,
deferrable: false,
schema:
relationship.context[:data_layer][:schema] ||
AshSqlite.DataLayer.Info.schema(relationship.destination) ||
AshSqlite.DataLayer.Info.repo(relationship.destination).config()[:default_prefix],
name: nil,
ignore?: false
})
@ -2847,7 +2749,6 @@ defmodule AshSqlite.MigrationGenerator do
defp sanitize_snapshot(snapshot) do
snapshot
|> Map.put_new(:has_create_action, true)
|> Map.put_new(:schema, nil)
|> Map.update!(:identities, fn identities ->
Enum.map(identities, &load_identity(&1, snapshot.table))
end)
@ -2961,7 +2862,6 @@ defmodule AshSqlite.MigrationGenerator do
"initially" -> :initially
other -> other
end)
|> Map.put_new(:schema, nil)
|> Map.put_new(:destination_attribute_default, "nil")
|> Map.put_new(:destination_attribute_generated, false)
|> Map.put_new(:on_delete, nil)

View file

@ -20,9 +20,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
def maybe_add_null(false), do: "null: false"
def maybe_add_null(_), do: nil
def maybe_add_prefix(nil), do: nil
def maybe_add_prefix(prefix), do: "prefix: #{prefix}"
def in_quotes(nil), do: nil
def in_quotes(value), do: "\"#{value}\""
@ -70,12 +67,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule CreateTable do
@moduledoc false
defstruct [:table, :schema, :multitenancy, :old_multitenancy]
defstruct [:table, :multitenancy, :old_multitenancy]
end
defmodule AddAttribute do
@moduledoc false
defstruct [:attribute, :table, :schema, :multitenancy, :old_multitenancy]
defstruct [:attribute, :table, :multitenancy, :old_multitenancy]
import Helper
@ -87,7 +84,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
%{
table: table,
destination_attribute: reference_attribute,
schema: destination_schema,
multitenancy: %{strategy: :attribute, attribute: destination_attribute}
} = reference
} = attribute
@ -110,7 +106,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
with_match,
"name: #{inspect(reference.name)}",
"type: #{inspect(reference_type(attribute, reference))}",
option("prefix", destination_schema),
on_delete(reference),
on_update(reference),
size
@ -129,7 +124,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
references:
%{
table: table,
schema: destination_schema,
destination_attribute: destination_attribute
} = reference
} = attribute
@ -146,7 +140,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
"column: #{inspect(destination_attribute)}",
"name: #{inspect(reference.name)}",
"type: #{inspect(reference_type(attribute, reference))}",
option("prefix", destination_schema),
size,
on_delete(reference),
on_update(reference)
@ -214,7 +207,7 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule AlterDeferrability do
@moduledoc false
defstruct [:table, :schema, :references, :direction, no_phase: true]
defstruct [:table, :references, :direction, no_phase: true]
def up(%{direction: :up, table: table, references: %{name: name, deferrable: true}}) do
"execute(\"ALTER TABLE #{table} alter CONSTRAINT #{name} DEFERRABLE INITIALLY IMMEDIATE\");"
@ -240,7 +233,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
:old_attribute,
:new_attribute,
:table,
:schema,
:multitenancy,
:old_multitenancy
]
@ -280,13 +272,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
def up(%{
multitenancy: multitenancy,
old_attribute: old_attribute,
new_attribute: attribute,
schema: schema
}) do
new_attribute: attribute
}) do
type_or_reference =
if AshSqlite.MigrationGenerator.has_reference?(multitenancy, attribute) and
Map.get(old_attribute, :references) != Map.get(attribute, :references) do
reference(multitenancy, attribute, schema)
reference(multitenancy, attribute)
else
inspect(attribute.type)
end
@ -301,17 +292,10 @@ defmodule AshSqlite.MigrationGenerator.Operation do
%{
multitenancy: %{strategy: :attribute, attribute: destination_attribute},
table: table,
schema: destination_schema,
destination_attribute: reference_attribute
} = reference
} = attribute,
schema
) do
destination_schema =
if schema != destination_schema do
destination_schema
end
} = attribute
) do
with_match =
if destination_attribute != reference_attribute do
"with: [#{as_atom(source_attribute)}: :#{as_atom(destination_attribute)}], match: :full"
@ -328,7 +312,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
"name: #{inspect(reference.name)}",
"type: #{inspect(reference_type(attribute, reference))}",
size,
option("prefix", destination_schema),
on_delete(reference),
on_update(reference),
")"
@ -341,17 +324,10 @@ defmodule AshSqlite.MigrationGenerator.Operation do
references:
%{
table: table,
destination_attribute: destination_attribute,
schema: destination_schema
destination_attribute: destination_attribute
} = reference
} = attribute,
schema
) do
destination_schema =
if schema != destination_schema do
destination_schema
end
} = attribute
) do
size =
if attribute[:size] do
"size: #{attribute[:size]}"
@ -362,7 +338,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
"name: #{inspect(reference.name)}",
"type: #{inspect(reference_type(attribute, reference))}",
size,
option("prefix", destination_schema),
on_delete(reference),
on_update(reference),
")"
@ -385,12 +360,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
# We only run this migration in one direction, based on the input
# This is because the creation of a foreign key is handled by `references/3`
# We only need to drop it before altering an attribute with `references/3`
defstruct [:attribute, :schema, :table, :multitenancy, :direction, no_phase: true]
defstruct [:attribute, :table, :multitenancy, :direction, no_phase: true]
import Helper
def up(%{table: table, schema: schema, attribute: %{references: reference}, direction: :up}) do
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name), option("prefix", schema)])})"
def up(%{table: table, attribute: %{references: reference}, direction: :up}) do
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name)])})"
end
def up(_) do
@ -399,11 +374,10 @@ defmodule AshSqlite.MigrationGenerator.Operation do
def down(%{
table: table,
schema: schema,
attribute: %{references: reference},
direction: :down
}) do
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name), option("prefix", schema)])})"
"drop constraint(:#{as_atom(table)}, #{join([inspect(reference.name)])})"
end
def down(_) do
@ -417,7 +391,6 @@ defmodule AshSqlite.MigrationGenerator.Operation do
:old_attribute,
:new_attribute,
:table,
:schema,
:multitenancy,
:old_multitenancy,
no_phase: true
@ -428,10 +401,9 @@ defmodule AshSqlite.MigrationGenerator.Operation do
def up(%{
old_attribute: old_attribute,
new_attribute: new_attribute,
schema: schema,
table: table
}) do
table_statement = join([":#{as_atom(table)}", option("prefix", schema)])
table_statement = join([":#{as_atom(table)}"])
"rename table(#{table_statement}), #{inspect(old_attribute.source)}, to: #{inspect(new_attribute.source)}"
end
@ -448,7 +420,7 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule RemoveAttribute do
@moduledoc false
defstruct [:attribute, :schema, :table, :multitenancy, :old_multitenancy, commented?: true]
defstruct [:attribute, :table, :multitenancy, :old_multitenancy, commented?: true]
def up(%{attribute: attribute, commented?: true}) do
"""
@ -482,12 +454,11 @@ defmodule AshSqlite.MigrationGenerator.Operation do
prefix <> "\n" <> contents
end
def down(%{attribute: attribute, multitenancy: multitenancy, table: table, schema: schema}) do
def down(%{attribute: attribute, multitenancy: multitenancy, table: table}) do
AshSqlite.MigrationGenerator.Operation.AddAttribute.up(
%AshSqlite.MigrationGenerator.Operation.AddAttribute{
attribute: attribute,
table: table,
schema: schema,
multitenancy: multitenancy
}
)
@ -496,14 +467,13 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule AddUniqueIndex do
@moduledoc false
defstruct [:identity, :table, :schema, :multitenancy, :old_multitenancy, no_phase: true]
defstruct [:identity, :table, :multitenancy, :old_multitenancy, no_phase: true]
import Helper
def up(%{
identity: %{name: name, keys: keys, base_filter: base_filter, index_name: index_name},
table: table,
schema: schema,
multitenancy: multitenancy
}) do
keys =
@ -518,16 +488,15 @@ defmodule AshSqlite.MigrationGenerator.Operation do
index_name = index_name || "#{table}_#{name}_index"
if base_filter do
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], where: \"#{base_filter}\", #{join(["name: \"#{index_name}\"", option("prefix", schema)])})"
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], where: \"#{base_filter}\", #{join(["name: \"#{index_name}\""])})"
else
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option("prefix", schema)])})"
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
end
def down(%{
identity: %{name: name, keys: keys, index_name: index_name},
table: table,
schema: schema,
multitenancy: multitenancy
}) do
keys =
@ -541,7 +510,7 @@ defmodule AshSqlite.MigrationGenerator.Operation do
index_name = index_name || "#{table}_#{name}_index"
"drop_if_exists unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option("prefix", schema)])})"
"drop_if_exists unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
end
@ -589,13 +558,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule AddCustomIndex do
@moduledoc false
defstruct [:table, :schema, :index, :base_filter, :multitenancy, no_phase: true]
defstruct [:table, :index, :base_filter, :multitenancy, no_phase: true]
import Helper
def up(%{
index: index,
table: table,
schema: schema,
base_filter: base_filter,
multitenancy: multitenancy
}) do
@ -621,10 +589,8 @@ defmodule AshSqlite.MigrationGenerator.Operation do
option(:unique, index.unique),
option(:concurrently, index.concurrently),
option(:using, index.using),
option(:prefix, index.prefix),
option(:where, index.where),
option(:include, index.include),
option(:prefix, schema)
option(:include, index.include)
])
if opts == "",
@ -633,7 +599,7 @@ defmodule AshSqlite.MigrationGenerator.Operation do
"create index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{opts})"
end
def down(%{schema: schema, index: index, table: table, multitenancy: multitenancy}) do
def down(%{index: index, table: table, multitenancy: multitenancy}) do
index_name = AshSqlite.CustomIndex.name(table, index)
keys =
@ -645,20 +611,16 @@ defmodule AshSqlite.MigrationGenerator.Operation do
Enum.map(index.fields, &to_string/1)
end
"drop_if_exists index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option(:prefix, schema)])})"
"drop_if_exists index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
end
defmodule RemovePrimaryKey do
@moduledoc false
defstruct [:schema, :table, no_phase: true]
defstruct [:table, no_phase: true]
def up(%{schema: schema, table: table}) do
if schema do
"drop constraint(#{inspect(table)}, \"#{table}_pkey\", prefix: \"#{schema}\")"
else
"drop constraint(#{inspect(table)}, \"#{table}_pkey\")"
end
def up(%{ table: table}) do
"drop constraint(#{inspect(table)}, \"#{table}_pkey\")"
end
def down(_) do
@ -668,27 +630,23 @@ defmodule AshSqlite.MigrationGenerator.Operation do
defmodule RemovePrimaryKeyDown do
@moduledoc false
defstruct [:schema, :table, no_phase: true]
defstruct [:table, no_phase: true]
def up(_) do
""
end
def down(%{schema: schema, table: table}) do
if schema do
"drop constraint(#{inspect(table)}, \"#{table}_pkey\", prefix: \"#{schema}\")"
else
def down(%{table: table}) do
"drop constraint(#{inspect(table)}, \"#{table}_pkey\")"
end
end
end
defmodule RemoveCustomIndex do
@moduledoc false
defstruct [:schema, :table, :index, :base_filter, :multitenancy, no_phase: true]
defstruct [:table, :index, :base_filter, :multitenancy, no_phase: true]
import Helper
def up(%{index: index, table: table, multitenancy: multitenancy, schema: schema}) do
def up(%{index: index, table: table, multitenancy: multitenancy}) do
index_name = AshSqlite.CustomIndex.name(table, index)
keys =
@ -700,13 +658,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
Enum.map(index.fields, &to_string/1)
end
"drop_if_exists index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option(:prefix, schema)])})"
"drop_if_exists index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
def down(%{
index: index,
table: table,
schema: schema,
base_filter: base_filter,
multitenancy: multitenancy
}) do
@ -732,10 +689,8 @@ defmodule AshSqlite.MigrationGenerator.Operation do
option(:unique, index.unique),
option(:concurrently, index.concurrently),
option(:using, index.using),
option(:prefix, index.prefix),
option(:where, index.where),
option(:include, index.include),
option(:prefix, schema)
option(:include, index.include)
])
if opts == "" do
@ -752,55 +707,43 @@ defmodule AshSqlite.MigrationGenerator.Operation do
:new_identity,
:old_identity,
:table,
:schema,
:multitenancy,
:old_multitenancy,
no_phase: true
]
defp prefix_name(name, prefix) do
if prefix do
"#{prefix}.#{name}"
else
name
end
end
def up(%{
old_identity: %{index_name: old_index_name, name: old_name},
new_identity: %{index_name: new_index_name},
schema: schema,
table: table
}) do
old_index_name = old_index_name || "#{table}_#{old_name}_index"
"execute(\"ALTER INDEX #{prefix_name(old_index_name, schema)} " <>
"RENAME TO #{prefix_name(new_index_name, schema)}\")\n"
"execute(\"ALTER INDEX #{old_index_name} " <>
"RENAME TO #{new_index_name}\")\n"
end
def down(%{
old_identity: %{index_name: old_index_name, name: old_name},
new_identity: %{index_name: new_index_name},
schema: schema,
table: table
}) do
old_index_name = old_index_name || "#{table}_#{old_name}_index"
"execute(\"ALTER INDEX #{prefix_name(new_index_name, schema)} " <>
"RENAME TO #{prefix_name(old_index_name, schema)}\")\n"
"execute(\"ALTER INDEX #{new_index_name} " <>
"RENAME TO #{old_index_name}\")\n"
end
end
defmodule RemoveUniqueIndex do
@moduledoc false
defstruct [:identity, :schema, :table, :multitenancy, :old_multitenancy, no_phase: true]
defstruct [:identity, :table, :multitenancy, :old_multitenancy, no_phase: true]
import Helper
def up(%{
identity: %{name: name, keys: keys, index_name: index_name},
table: table,
schema: schema,
old_multitenancy: multitenancy
}) do
keys =
@ -814,13 +757,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
index_name = index_name || "#{table}_#{name}_index"
"drop_if_exists unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option(:prefix, schema)])})"
"drop_if_exists unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
def down(%{
identity: %{name: name, keys: keys, base_filter: base_filter, index_name: index_name},
table: table,
schema: schema,
multitenancy: multitenancy
}) do
keys =
@ -835,21 +777,20 @@ defmodule AshSqlite.MigrationGenerator.Operation do
index_name = index_name || "#{table}_#{name}_index"
if base_filter do
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], where: \"#{base_filter}\", #{join(["name: \"#{index_name}\"", option(:prefix, schema)])})"
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], where: \"#{base_filter}\", #{join(["name: \"#{index_name}\""])})"
else
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\"", option(:prefix, schema)])})"
"create unique_index(:#{as_atom(table)}, [#{Enum.map_join(keys, ", ", &inspect/1)}], #{join(["name: \"#{index_name}\""])})"
end
end
end
defmodule AddCheckConstraint do
@moduledoc false
defstruct [:table, :schema, :constraint, :multitenancy, :old_multitenancy, no_phase: true]
defstruct [:table, :constraint, :multitenancy, :old_multitenancy, no_phase: true]
import Helper
def up(%{
schema: schema,
constraint: %{
name: name,
check: check,
@ -858,29 +799,28 @@ defmodule AshSqlite.MigrationGenerator.Operation do
table: table
}) do
if base_filter do
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{base_filter} AND #{check}\")", option(:prefix, schema)])}"
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{base_filter} AND #{check}\")"])}"
else
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")", option(:prefix, schema)])}"
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")"])}"
end
end
def down(%{
constraint: %{name: name},
schema: schema,
table: table
}) do
"drop_if_exists constraint(:#{as_atom(table)}, #{join([":#{as_atom(name)}", option(:prefix, schema)])})"
"drop_if_exists constraint(:#{as_atom(table)}, #{join([":#{as_atom(name)}"])})"
end
end
defmodule RemoveCheckConstraint do
@moduledoc false
defstruct [:table, :schema, :constraint, :multitenancy, :old_multitenancy, no_phase: true]
defstruct [:table, :constraint, :multitenancy, :old_multitenancy, no_phase: true]
import Helper
def up(%{constraint: %{name: name}, schema: schema, table: table}) do
"drop_if_exists constraint(:#{as_atom(table)}, #{join([":#{as_atom(name)}", option(:prefix, schema)])})"
def up(%{constraint: %{name: name}, table: table}) do
"drop_if_exists constraint(:#{as_atom(table)}, #{join([":#{as_atom(name)}"])})"
end
def down(%{
@ -889,13 +829,12 @@ defmodule AshSqlite.MigrationGenerator.Operation do
check: check,
base_filter: base_filter
},
schema: schema,
table: table
}) do
if base_filter do
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{base_filter} AND #{check}\")", option(:prefix, schema)])}"
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{base_filter} AND #{check}\")"])}"
else
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")", option(:prefix, schema)])}"
"create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")"])}"
end
end
end

View file

@ -3,30 +3,20 @@ defmodule AshSqlite.MigrationGenerator.Phase do
defmodule Create do
@moduledoc false
defstruct [:table, :schema, :multitenancy, operations: [], commented?: false]
defstruct [:table, :multitenancy, operations: [], commented?: false]
import AshSqlite.MigrationGenerator.Operation.Helper, only: [as_atom: 1]
def up(%{schema: schema, table: table, operations: operations, multitenancy: multitenancy}) do
opts =
if schema do
", prefix: \"#{schema}\""
else
""
end
def up(%{table: table, operations: operations}) do
opts = ""
"create table(:#{as_atom(table)}, primary_key: false#{opts}) do\n" <>
Enum.map_join(operations, "\n", fn operation -> operation.__struct__.up(operation) end) <>
"\nend"
end
def down(%{schema: schema, table: table, multitenancy: multitenancy}) do
opts =
if schema do
", prefix: \"#{schema}\""
else
""
end
def down(%{ table: table}) do
opts = ""
"drop table(:#{as_atom(table)}#{opts})"
end
@ -34,11 +24,11 @@ defmodule AshSqlite.MigrationGenerator.Phase do
defmodule Alter do
@moduledoc false
defstruct [:schema, :table, :multitenancy, operations: [], commented?: false]
defstruct [:table, :multitenancy, operations: [], commented?: false]
import AshSqlite.MigrationGenerator.Operation.Helper, only: [as_atom: 1]
def up(%{table: table, schema: schema, operations: operations, multitenancy: multitenancy}) do
def up(%{table: table, operations: operations}) do
body =
operations
|> Enum.map_join("\n", fn operation -> operation.__struct__.up(operation) end)
@ -47,12 +37,7 @@ defmodule AshSqlite.MigrationGenerator.Phase do
if body == "" do
""
else
opts =
if schema do
", prefix: \"#{schema}\""
else
""
end
opts = ""
"alter table(:#{as_atom(table)}#{opts}) do\n" <>
body <>
@ -60,7 +45,7 @@ defmodule AshSqlite.MigrationGenerator.Phase do
end
end
def down(%{table: table, schema: schema, operations: operations, multitenancy: multitenancy}) do
def down(%{table: table, operations: operations}) do
body =
operations
|> Enum.reverse()
@ -70,12 +55,7 @@ defmodule AshSqlite.MigrationGenerator.Phase do
if body == "" do
""
else
opts =
if schema do
", prefix: \"#{schema}\""
else
""
end
opts = ""
"alter table(:#{as_atom(table)}#{opts}) do\n" <>
body <>

View file

@ -43,7 +43,6 @@ defmodule Mix.Tasks.AshSqlite.GenerateMigrations do
#### Conflicts/Multiple Resources
The migration generator can support multiple schemas using the same table.
It will raise on conflicts that it can't resolve, like the same field with different
types. It will prompt to resolve conflicts that can be resolved with human input.
For example, if you remove an attribute and add an attribute, it will ask you if you are renaming

View file

@ -15,7 +15,6 @@ defmodule Mix.Tasks.AshSqlite.Migrate do
step: :integer,
to: :integer,
quiet: :boolean,
prefix: :string,
pool_size: :integer,
log_sql: :boolean,
strict_version_order: :boolean,

View file

@ -35,7 +35,6 @@ defmodule Mix.Tasks.AshSqlite.Rollback do
* `--step` / `-n` - revert n number of applied migrations
* `--to` / `-v` - revert all migrations down to and including version
* `--quiet` - do not log migration commands
* `--prefix` - the prefix to run migrations on
* `--pool-size` - the pool size if the repository is started only for the task (defaults to 1)
* `--log-sql` - log the raw sql migrations are running
"""
@ -50,7 +49,6 @@ defmodule Mix.Tasks.AshSqlite.Rollback do
to: :integer,
start: :boolean,
quiet: :boolean,
prefix: :string,
pool_size: :integer,
log_sql: :boolean
],

View file

@ -741,7 +741,7 @@ defmodule AshSqlite.FilterTest do
end
end
describe "like and ilike" do
describe "like" do
test "like builds and matches" do
Post
|> Ash.Changeset.new(%{title: "MaTcH"})
@ -761,54 +761,6 @@ defmodule AshSqlite.FilterTest do
assert [] = results
end
test "ilike builds and matches" do
Post
|> Ash.Changeset.new(%{title: "MaTcH"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(ilike(title, "%aTc%"))
|> Api.read!()
assert [%Post{title: "MaTcH"}] = results
results =
Post
|> Ash.Query.filter(ilike(title, "%atc%"))
|> Api.read!()
assert [%Post{title: "MaTcH"}] = results
end
end
describe "trigram_similarity" do
test "it works on matches" do
Post
|> Ash.Changeset.new(%{title: "match"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(trigram_similarity(title, "match") > 0.9)
|> Api.read!()
assert [%Post{title: "match"}] = results
end
test "it works on non-matches" do
Post
|> Ash.Changeset.new(%{title: "match"})
|> Api.create!()
results =
Post
|> Ash.Query.filter(trigram_similarity(title, "match") < 0.1)
|> Api.read!()
assert [] = results
end
end
describe "fragments" do

View file

@ -151,86 +151,6 @@ defmodule AshSqlite.MigrationGeneratorTest do
end
end
describe "creating initial snapshots for resources with a schema" do
setup do
on_exit(fn ->
File.rm_rf!("test_snapshots_path")
File.rm_rf!("test_migration_path")
end)
defposts do
sqlite do
migration_types(second_title: {:varchar, 16})
schema("example")
end
identities do
identity(:title, [:title])
end
attributes do
uuid_primary_key(:id)
attribute(:title, :string)
attribute(:second_title, :string)
end
end
defapi([Post])
Mix.shell(Mix.Shell.Process)
{:ok, _} =
Ecto.Adapters.SQL.query(
AshSqlite.TestRepo,
"""
CREATE SCHEMA IF NOT EXISTS example;
"""
)
AshSqlite.MigrationGenerator.generate(Api,
snapshot_path: "test_snapshots_path",
migration_path: "test_migration_path",
quiet: true,
format: false
)
:ok
end
test "the migration sets up resources correctly" do
# the snapshot exists and contains valid json
assert File.read!(Path.wildcard("test_snapshots_path/test_repo/posts/*.json"))
|> Jason.decode!(keys: :atoms!)
assert [file] = Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")
file_contents = File.read!(file)
# the migration creates the table
assert file_contents =~ "create table(:posts, primary_key: false, prefix: \"example\") do"
# the migration sets up the custom_indexes
assert file_contents =~
~S{create index(:posts, ["id"], name: "test_unique_index", unique: true, prefix: "example")}
assert file_contents =~ ~S{create index(:posts, ["id"]}
# the migration adds the id, with its default
assert file_contents =~
~S[add :id, :uuid, null: false, default: fragment("uuid_generate_v4()"), primary_key: true]
# the migration adds other attributes
assert file_contents =~ ~S[add :title, :text]
# the migration adds custom attributes
assert file_contents =~ ~S[add :second_title, :varchar, size: 16]
# the migration creates unique_indexes based on the identities of the resource
assert file_contents =~
~S{create unique_index(:posts, [:title], name: "posts_title_index", prefix: "example")}
end
end
describe "custom_indexes with `concurrently: true`" do
setup do
on_exit(fn ->
@ -275,68 +195,6 @@ defmodule AshSqlite.MigrationGeneratorTest do
end
end
describe "creating follow up migrations with a schema" do
setup do
on_exit(fn ->
File.rm_rf!("test_snapshots_path")
File.rm_rf!("test_migration_path")
end)
defposts do
sqlite do
schema("example")
end
attributes do
uuid_primary_key(:id)
attribute(:title, :string)
end
end
defapi([Post])
Mix.shell(Mix.Shell.Process)
AshSqlite.MigrationGenerator.generate(Api,
snapshot_path: "test_snapshots_path",
migration_path: "test_migration_path",
quiet: true,
format: false
)
:ok
end
test "when renaming a field, it asks if you are renaming it, and renames it if you are" do
defposts do
sqlite do
schema("example")
end
attributes do
uuid_primary_key(:id)
attribute(:name, :string, allow_nil?: false)
end
end
defapi([Post])
send(self(), {:mix_shell_input, :yes?, true})
AshSqlite.MigrationGenerator.generate(Api,
snapshot_path: "test_snapshots_path",
migration_path: "test_migration_path",
quiet: true,
format: false
)
assert [_file1, file2] =
Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs"))
assert File.read!(file2) =~ ~S[rename table(:posts, prefix: "example"), :title, to: :name]
end
end
describe "creating follow up migrations" do
setup do
on_exit(fn ->
@ -539,93 +397,6 @@ defmodule AshSqlite.MigrationGeneratorTest do
~S[add :subject, :text, null: false]
end
test "when multiple schemas apply to the same table, all attributes are added" do
defposts do
attributes do
uuid_primary_key(:id)
attribute(:title, :string)
attribute(:foobar, :string)
end
end
defposts Post2 do
attributes do
uuid_primary_key(:id)
attribute(:name, :string)
end
end
defapi([Post, Post2])
AshSqlite.MigrationGenerator.generate(Api,
snapshot_path: "test_snapshots_path",
migration_path: "test_migration_path",
quiet: true,
format: false
)
assert [_file1, file2] =
Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs"))
assert File.read!(file2) =~
~S[add :foobar, :text]
assert File.read!(file2) =~
~S[add :foobar, :text]
end
test "when multiple schemas apply to the same table, all identities are added" do
defposts do
attributes do
uuid_primary_key(:id)
attribute(:title, :string)
end
identities do
identity(:unique_title, [:title])
end
end
defposts Post2 do
attributes do
uuid_primary_key(:id)
attribute(:name, :string)
end
identities do
identity(:unique_name, [:name])
end
end
defapi([Post, Post2])
AshSqlite.MigrationGenerator.generate(Api,
snapshot_path: "test_snapshots_path",
migration_path: "test_migration_path",
quiet: true,
format: false
)
assert [file1, file2] =
Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs"))
file1_content = File.read!(file1)
assert file1_content =~
"create unique_index(:posts, [:title], name: \"posts_title_index\")"
file2_content = File.read!(file2)
assert file2_content =~
"drop_if_exists unique_index(:posts, [:title], name: \"posts_title_index\")"
assert file2_content =~
"create unique_index(:posts, [:name], name: \"posts_unique_name_index\")"
assert file2_content =~
"create unique_index(:posts, [:title], name: \"posts_unique_title_index\")"
end
test "when an attribute exists only on some of the resources that use the same table, it isn't marked as null: false" do
defposts do
attributes do
@ -767,7 +538,7 @@ defmodule AshSqlite.MigrationGeneratorTest do
assert [file] = Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")
assert File.read!(file) =~
~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :uuid, prefix: "public")]
~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :uuid)]
end
test "references are inferred automatically if the attribute has a different type" do
@ -802,7 +573,7 @@ defmodule AshSqlite.MigrationGeneratorTest do
assert [file] = Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")
assert File.read!(file) =~
~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :text, prefix: "public")]
~S[references(:posts, column: :id, name: "posts_post_id_fkey", type: :text)]
end
test "when modified, the foreign key is dropped before modification" do
@ -866,7 +637,7 @@ defmodule AshSqlite.MigrationGeneratorTest do
|> File.read!()
assert file =~
~S[references(:posts, column: :id, name: "special_post_fkey", type: :uuid, prefix: "public", on_delete: :delete_all, on_update: :update_all)]
~S[references(:posts, column: :id, name: "special_post_fkey", type: :uuid, on_delete: :delete_all, on_update: :update_all)]
assert file =~ ~S[drop constraint(:posts, "posts_post_id_fkey")]
@ -1078,7 +849,7 @@ defmodule AshSqlite.MigrationGeneratorTest do
assert [file] = Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")
assert File.read!(file) =~
~S[references(:post_comments, column: :id, name: "posts_best_comment_id_fkey", type: :uuid, prefix: "public")]
~S[references(:post_comments, column: :id, name: "posts_best_comment_id_fkey", type: :uuid)]
end
end
@ -1277,7 +1048,7 @@ defmodule AshSqlite.MigrationGeneratorTest do
assert after_index_drop =~ ~S[modify :id, :uuid, null: true, primary_key: false]
assert after_index_drop =~
~S[modify :post_id, references(:posts, column: :id, name: "comments_post_id_fkey", type: :uuid, prefix: "public")]
~S[modify :post_id, references(:posts, column: :id, name: "comments_post_id_fkey", type: :uuid)]
end
end
end

View file

@ -5,7 +5,6 @@ defmodule AshSqlite.Test.Profile do
sqlite do
table("profile")
schema("profiles")
repo(AshSqlite.TestRepo)
end