Skip to main content

lib/ex_sql/ast/create_table.ex

defmodule ExSQL.AST.CreateTable do
  @moduledoc "A `CREATE TABLE` statement."

  @typedoc """
  A table-level constraint, after the column list.

    * `{:primary_key, name | nil, [col_name]}` — composite PK
    * `{:unique, name | nil, [col_name]}` — composite UNIQUE
    * `{:check, name | nil, expr}` — CHECK expression
    * `{:foreign_key, name | nil, [col_name], ref_table, [ref_col], actions}` — table FK;
      `actions` is `%{on_delete: action, on_update: action, deferred: boolean}` with
      action one of `:no_action | :restrict | :set_null | :set_default | :cascade`
  """
  @type fk_action :: :no_action | :restrict | :set_null | :set_default | :cascade
  @type fk_actions :: %{on_delete: fk_action(), on_update: fk_action(), deferred: boolean()}

  @type table_constraint ::
          {:primary_key, String.t() | nil, [String.t()]}
          | {:unique, String.t() | nil, [String.t()]}
          | {:check, String.t() | nil, ExSQL.Parser.expr()}
          | {:foreign_key, String.t() | nil, [String.t()], String.t(), [String.t()], fk_actions()}

  defstruct name: nil,
            schema: nil,
            columns: [],
            if_not_exists: false,
            constraints: [],
            without_rowid: false,
            strict: false,
            query: nil

  @type t :: %__MODULE__{
          name: String.t(),
          schema: String.t() | nil,
          columns: [ExSQL.AST.ColumnDef.t()],
          if_not_exists: boolean(),
          constraints: [table_constraint()],
          without_rowid: boolean(),
          strict: boolean(),
          query: ExSQL.Parser.statement() | nil
        }
end