# `AshScylla.Migration`
[🔗](https://github.com/ohhi-vn/ash_scylla/blob/main/lib/ash_scylla/migration.ex#L15)

CQL schema generation helpers for ScyllaDB.

This module generates raw CQL DDL statements (CREATE TABLE, CREATE INDEX,
CREATE TYPE, etc.) from Ash resource definitions. It is NOT an Ecto SQL
migration runner — CQL has no transactional DDL concept.

These helpers return CQL strings that you execute via `AshScylla.Migrator.run/3`
in your migration modules, or directly through your repo at runtime.

## Example Migration

    defmodule MyApp.Repo.Migrations.CreateUsers do
      def change do
        AshScylla.Migration.create_table_cql(MyApp.User)
        |> then(&AshScylla.Migrator.run!/3)
      end
    end

## Important Note on `create_table_cql/1`

This function reads compile-time module attributes set by the Ash resource DSL.
For runtime use, prefer `Ash.Resource.Info.attributes/1` combined with
`AshScylla.DataLayer.Dsl.table/1`.

## Functions

- `create_table_cql/1` — Generate `CREATE TABLE IF NOT EXISTS` CQL
- `create_secondary_indexes_cql/1` — Generate `CREATE INDEX IF NOT EXISTS` CQL
- `create_type/2` — Generate `CREATE TYPE IF NOT EXISTS` CQL
- `drop_type/1` — Generate `DROP TYPE IF NOT EXISTS` CQL
- `alter_type_cql/3` — Generate `ALTER TYPE` CQL (add/rename fields)
- `quote_name/1` — Safely quote CQL identifiers
- `ash_type_to_cql_type/2` — Convert Ash type to CQL type string

# `alter_type_cql`

```elixir
@spec alter_type_cql(String.t() | atom(), :add | :rename, [{atom(), atom()}]) ::
  String.t()
```

Generates CQL for altering a UDT (add or rename fields).

## Examples

    alter_type_cql("address", :add, [country: :text])
    alter_type_cql("address", :rename, [new_zip: :zip_code])

# `ash_type_to_cql_type`

```elixir
@spec ash_type_to_cql_type(
  atom(),
  keyword()
) :: String.t()
```

Converts an Ash type atom to its CQL type string representation.

Delegates to `AshScylla.DataLayer.Types.ash_type_to_cql_type/2`.

## Examples

    iex> AshScylla.Migration.ash_type_to_cql_type(:uuid, [])
    "UUID"

    iex> AshScylla.Migration.ash_type_to_cql_type(:string, [])
    "TEXT"

    iex> AshScylla.Migration.ash_type_to_cql_type(:map, key_type: "TEXT", value_type: "INT")
    "MAP<TEXT, INT>"

# `create_secondary_indexes_cql`

```elixir
@spec create_secondary_indexes_cql(module()) :: [String.t()]
```

Generates CQL CREATE INDEX statements for secondary indexes.

Returns a list of CQL strings that should be executed in migrations.

## Example

    defmodule MyApp.Repo.Migrations.CreateUserIndexes do
      def change do
        AshScylla.Migration.create_secondary_indexes_cql(MyApp.User)
        |> Enum.each(&AshScylla.Migrator.run!/3)
      end
    end

# `create_table_cql`

```elixir
@spec create_table_cql(module()) :: String.t()
```

Generates a CQL CREATE TABLE statement for an Ash resource.

Returns a raw CQL string. Execute it in a migration via `AshScylla.Migrator.run/3`
or directly through your repo at runtime.

# `create_table_cql`

```elixir
@spec create_table_cql(
  module(),
  keyword()
) :: String.t()
```

# `create_type`

```elixir
@spec create_type(
  String.t(),
  keyword()
) :: String.t()
@spec create_type(String.t() | atom(), [{atom(), atom()}]) :: String.t()
```

Define a User Defined Type (UDT) in ScyllaDB.

Supports two calling styles:

## Keyword-list style (with do block)

    create_type "full_name" do
      field :first_name, :text
      field :last_name, :text
    end

## Explicit field-list style

    create_type("address", city: :text, street: :text, zip: :text)

Both generate:

    CREATE TYPE IF NOT EXISTS <name> (field1 TYPE1, field2 TYPE2)

# `create_type_cql`

```elixir
@spec create_type_cql(String.t() | atom(), [{atom(), atom()}]) :: String.t()
```

Generates CQL for creating a UDT from a type name and field specs.

Returns a raw CQL string.

# `drop_secondary_index_cql`

```elixir
@spec drop_secondary_index_cql(module(), String.t()) :: String.t()
```

Generates a CQL DROP INDEX statement for a secondary index.

# `drop_type`

```elixir
@spec drop_type(String.t()) :: String.t()
```

Drop a User Defined Type (UDT) in ScyllaDB.

# `drop_type_cql`

```elixir
@spec drop_type_cql(String.t() | atom()) :: String.t()
```

Generates CQL for dropping a UDT.

Returns a raw CQL string.

# `execute`

```elixir
@spec execute(
  [String.t()],
  keyword()
) :: {:ok, [term()]} | {:error, term()}
```

Executes migration CQL via the Migrator.

# `keyspace`

```elixir
@spec keyspace(module()) :: String.t() | nil
```

Returns the keyspace for a resource if configured via DSL.

# `list_types_cql`

```elixir
@spec list_types_cql() :: String.t()
```

Generates CQL to list all UDTs in the keyspace.

Returns a raw CQL string.

# `quote_name`

```elixir
@spec quote_name(atom() | String.t()) :: String.t()
```

# `type_exists_cql`

```elixir
@spec type_exists_cql(String.t() | atom()) :: String.t()
```

Generates CQL to check if a UDT exists.

Returns a raw CQL string.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
