AshScylla.DataLayer.SchemaMigration (AshScylla v0.7.0)

Copy Markdown View Source

Automatic schema migration support for AshScylla.

Compares Ash resource definitions against the live ScyllaDB schema and generates the necessary DDL statements to bring the schema in sync.

Since CQL has no transactional DDL, each statement is executed independently.

Usage

# Generate migration DDL for a resource
statements = AshScylla.DataLayer.SchemaMigration.generate(MyApp.User)

# Execute the migration
AshScylla.Migrator.run(nodes, statements)

# Or use the convenience function
AshScylla.DataLayer.SchemaMigration.migrate(MyApp.User, repo)

# Check what would change without executing
AshScylla.DataLayer.SchemaMigration.plan(MyApp.User, repo)

Summary

Functions

Generates DDL statements by comparing resource against live schema.

Compares resource attributes against live columns and returns lists of columns to add, type-change, etc.

Fetches existing indexes for a table.

Fetches existing materialized views for a table.

Fetches the current table schema from ScyllaDB.

Generates all DDL statements needed to bring a resource's schema in sync.

Generates ALTER TABLE ADD statements for new columns.

Generates CREATE INDEX statements for new secondary indexes.

Generates CREATE MATERIALIZED VIEW statements for new views.

Executes all migration DDL for a resource against a repo.

Returns a list of DDL statements that would be executed without running them.

Functions

diff(resource, repo)

@spec diff(module(), module()) :: [String.t()]

Generates DDL statements by comparing resource against live schema.

Only returns statements for actual changes needed.

diff_columns(attributes, live_columns)

@spec diff_columns([Ash.Resource.Attribute.t()], [map()]) :: %{
  add: [atom()],
  remove: [atom()],
  change_type: [atom()]
}

Compares resource attributes against live columns and returns lists of columns to add, type-change, etc.

fetch_indexes(resource, repo)

@spec fetch_indexes(module(), module()) :: {:ok, [map()]} | {:error, term()}

Fetches existing indexes for a table.

fetch_materialized_views(resource, repo)

@spec fetch_materialized_views(module(), module()) ::
  {:ok, [map()]} | {:error, term()}

Fetches existing materialized views for a table.

fetch_table_schema(resource, repo)

@spec fetch_table_schema(module(), module()) :: {:ok, map()} | {:error, term()}

Fetches the current table schema from ScyllaDB.

Returns a map with column definitions.

generate(resource)

@spec generate(module()) :: [String.t()]

Generates all DDL statements needed to bring a resource's schema in sync.

Returns a list of CQL statement strings. This includes:

  • CREATE TABLE IF NOT EXISTS
  • ALTER TABLE ADD for new columns
  • CREATE INDEX IF NOT EXISTS for new secondary indexes
  • CREATE MATERIALIZED VIEW IF NOT EXISTS for new views
  • CREATE TYPE IF NOT EXISTS for UDTs

generate_add_columns(resource, columns)

@spec generate_add_columns(module(), [atom()]) :: [String.t()]

Generates ALTER TABLE ADD statements for new columns.

generate_new_indexes(resource, live_indexes)

@spec generate_new_indexes(module(), [map()]) :: [String.t()]

Generates CREATE INDEX statements for new secondary indexes.

generate_new_views(resource, live_views)

@spec generate_new_views(module(), [map()]) :: [String.t()]

Generates CREATE MATERIALIZED VIEW statements for new views.

migrate(resource, repo, opts \\ [])

@spec migrate(module(), module(), keyword()) :: {:ok, [term()]} | {:error, term()}

Executes all migration DDL for a resource against a repo.

Options:

  • :nodes - Override nodes (defaults to repo nodes)
  • :keyspace - Override keyspace (defaults to repo keyspace)
  • :dry_run - If true, only log statements without executing

plan(resource, repo)

@spec plan(module(), module()) :: {:ok, [String.t()]} | {:error, term()}

Returns a list of DDL statements that would be executed without running them.