# `Electric.Shapes.Shape`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.6.2/packages/sync-service/lib/electric/shapes/shape.ex#L1)

Struct describing the requested shape

# `comparable`

```elixir
@type comparable() :: term()
```

# `flag`

```elixir
@type flag() ::
  :selects_all_columns
  | :selects_generated_columns
  | :non_primitive_columns_in_where
```

# `handle`

```elixir
@type handle() :: String.t()
```

# `json_relation`

```elixir
@type json_relation() :: [String.t(), ...]
```

# `json_safe`

```elixir
@type json_safe() :: %{
  version: non_neg_integer(),
  root_table: json_relation(),
  root_table_id: non_neg_integer(),
  root_pks: [String.t(), ...],
  root_column_count: non_neg_integer(),
  where: String.t(),
  selected_columns: [String.t(), ...],
  flags: %{optional(flag()) =&gt; boolean()},
  replica: String.t(),
  storage: storage_config() | nil,
  shape_dependencies: [json_safe(), ...],
  log_mode: log_mode()
}
```

# `json_table_info`

```elixir
@type json_table_info() :: table_info() | json_relation()
```

# `json_table_list`

```elixir
@type json_table_list() :: [json_table_info(), ...]
```

# `log_mode`

```elixir
@type log_mode() :: :changes_only | :full
```

# `replica`

```elixir
@type replica() :: :full | :default
```

# `storage_config`

```elixir
@type storage_config() :: %{compaction: :enabled | :disabled}
```

# `t`

```elixir
@type t() :: %Electric.Shapes.Shape{
  explicitly_selected_columns: [String.t(), ...],
  flags: %{optional(flag()) =&gt; boolean()},
  log_mode: log_mode(),
  replica: replica(),
  root_column_count: non_neg_integer(),
  root_pk: [String.t(), ...],
  root_table: Electric.relation(),
  root_table_id: Electric.relation_id(),
  selected_columns: [String.t(), ...],
  shape_dependencies: [t(), ...],
  shape_dependencies_handles: term(),
  storage: storage_config() | nil,
  subquery_comparison_expressions: term(),
  tag_structure: [String.t() | [String.t(), ...]],
  where: Electric.Replication.Eval.Expr.t() | nil
}
```

# `table_info`

```elixir
@type table_info() :: %{
  columns: [Electric.Postgres.Inspector.column_info(), ...],
  pk: [String.t(), ...]
}
```

# `affected_tables`

```elixir
@spec affected_tables(t()) :: [Electric.relation()]
```

List tables that are a part of this shape.

# `are_deps_filled`
*macro* 

# `comparable`

```elixir
@spec comparable(t()) :: comparable()
```

Return a comparable representation of the shape.

This is used to compare shapes for equality as an ETS key - and thus it'll be
matched in some cases, not just compared equal. This representation must
therefore not contain any maps (as they are matched when one is missing a key
for example).

This representation must contain all the information that identifies
user-specified properties of the shape. We're omitting storage configuration
and other internal state.

# `comparable_hash`

# `convert_change`

Convert a change to be correctly represented within the shape.

New or deleted changes are either propagated as-is, or filtered out completely.
Updates, on the other hand, may be converted to an "new record" or a "deleted record"
if the previous/new version of the updated row isn't in the shape.

# `default_replica_mode`

# `dependency_handles_known?`

# `fill_move_tags`

# `from_json_safe`

```elixir
@spec from_json_safe(map()) :: {:ok, t()} | {:error, String.t()}
```

# `generate_id`

# `get_row_metadata`

# `has_dependencies`
*macro* 

# `hash`

# `is_affected_by_relation_change?`

# `list_relations`

```elixir
@spec list_relations(t()) :: [Electric.oid_relation()]
```

List all relations that are a part of this shape, as oid-name tuples.

# `new`

# `new`

# `new!`

# `pk`

# `schema_options`

# `verify_replica`

---

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