> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Store interface

> Write Squid SDK indexed data to Postgres, BigQuery, or files through Store interfaces.

`Store` is a generic interface exposed by [`DataHandlerContext`](../batch-processor#handler-context) at `.store`. It is used in the batch handler to persist data. Its concrete type is inferred from the `Database` argument of the [`run()` processor method](../batch-processor#run-and-processor):

```typescript theme={"system"}
function run<Block, Store>(
  src: DataSource<Block>,
  db: Database<Store>,
  handler: (ctx: DataHandlerContext<Block, Store>) => Promise<void>
): void
```

The `Database` implementation supplied here defines the store and the way the processor [persists its status](../../faq-troubleshooting#how-do-squids-keep-track-of-their-sync-progress). Squid SDK supports `Database` implementations for:

* [`TypeORM`-compatible databases](./typeorm-store)
* [file-based datasets](./file-store)
* [Google BigQuery](./bigquery-store)

Support for more databases and analytics storage will be added in the future.

## Custom `Database`

A custom implementation of the `Database` interface is the recommended solution for squids with multiple data sinks and/or for non-transactional or non-relational databases. In such a case, the inferred `Store` facade exposed to the handlers may provide multiple targets for persisting the data. `Database.transact` should handle potential edge-cases when writes to either of the data sinks fail.

In order to implement a custom data sink adapter, it suffices to implement the `Database` interface:

```ts theme={"system"}
export type Database<S> = FinalDatabase<S> | HotDatabase<S>

export interface FinalDatabase<S> {
    supportsHotBlocks?: false
    connect(): Promise<HashAndHeight>
    transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>
}

export interface HotDatabase<S> {
    supportsHotBlocks: true
    connect(): Promise<HotDatabaseState>
    transact(info: FinalTxInfo, cb: (store: S) => Promise<void>): Promise<void>

    /** @deprecated Implement transactHot2 when possible. */
    transactHot(info: HotTxInfo, cb: (store: S, block: HashAndHeight) => Promise<void>): Promise<void>

    transactHot2?(
        info: HotTxInfo,
        cb: (store: S, blockSliceStart: number, blockSliceEnd: number) => Promise<void>
    ): Promise<void>
}
```

`HotTxInfo` describes a fork-aware update:

```ts theme={"system"}
export interface HotTxInfo {
    finalizedHead: HashAndHeight
    baseHead: HashAndHeight
    newBlocks: HashAndHeight[]
}
```

`transactHot2()` lets the database group several consecutive blocks into one store transaction. Each callback receives a half-open `[blockSliceStart, blockSliceEnd)` range of indexes into `info.newBlocks`. Calling `cb(store, 0, info.newBlocks.length)` processes the entire update as one slice. An adapter may call the callback more than once when it needs smaller transactions.

The processor maps the same slice of fetched blocks into the handler. The database implementation is responsible for rolling back to `baseHead`, invoking the callback for the blocks it commits, and persisting the resulting finalized and unfinalized heads atomically where the storage system supports transactions.

<Info>
  The interface above is the compatibility surface used by chain-specific processors such as `@subsquid/substrate-processor`: deprecated `transactHot()` remains required and `transactHot2()` is optional. The Portal-native [`@subsquid/batch-processor`](../batch-processor#finalized-and-hot-block-databases) interface requires `transactHot2()` and does not include the deprecated fallback.
</Info>

Consult [this file](https://github.com/subsquid/squid-sdk/blob/master/util/util-internal-processor-tools/src/database.ts) for details.

The interface only defines how the processor advances with the indexing and connects to the data sink. The following is left as implementation details:

* persisting the indexing status
* opening and rolling back the transaction (if applicable)

Consult these implementations for details:

* (Transactional) Postgres-based [TypeormDatabase](https://github.com/subsquid/squid-sdk/blob/master/typeorm/typeorm-store/src/database.ts)
* (Non-transactional) [File-based database](https://github.com/subsquid/squid-csv-store/blob/main/src/database.ts)
