# `Electric.Postgres.SnapshotQuery`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.6.2/packages/sync-service/lib/electric/postgres/snapshot_query.ex#L1)

# `pg_snapshot`

```elixir
@type pg_snapshot() ::
  {xmin :: pos_integer(), xmax :: pos_integer(), xip_list :: [pos_integer()]}
```

# `execute_for_shape`

```elixir
@spec execute_for_shape(
  Postgrex.conn(),
  Electric.Shapes.Shape.handle(),
  Electric.Shapes.Shape.t(),
  [
    option
  ]
) :: {:ok, result} | {:error, any()}
when result: term(),
     option:
       {:snapshot_info_fn,
        (Electric.Shapes.Shape.handle(), pg_snapshot, pos_integer() -&gt; any())}
       | {:query_fn, (Postgrex.conn(), pg_snapshot, pos_integer() -&gt; result)}
       | {:stack_id, Electric.stack_id()},
     pg_snapshot:
       {xmin :: pos_integer(), xmax :: pos_integer(),
        xip_list :: [pos_integer()]}
```

Execute a snapshot query for a shape in a isolated readonly transaction.

This function operates on two callbacks: `snapshot_info_fn` and `query_fn`.

`snapshot_info_fn` is called with the shape handle, the pg_snapshot, and the lsn as soon
as the snapshot information for the started transaction is available.

`query_fn` is called with the connection, the pg_snapshot, and the lsn and
is expected to do all the work querying and dealing with the results.

The query function is executed within a transaction, so it shouldn't return
a stream (as it will fail to be read after the transaction is committed), but
rather should execute all desired side-effects or materialize the results.

Query will be executed within a REPEATABLE READ READ ONLY transaction, with
correct display settings set.

Options:
- `:query_fn` - the function to execute the query.
- `:snapshot_info_fn` - the function to call with the snapshot information.
- `:stack_id` - the stack id for this shape.

---

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