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

# Interface: GenericDatabaseReader<DataModel>

> An interface to read from the database within Bijection query functions.

[server](/api/modules/server).GenericDatabaseReader

An interface to read from the database within Bijection query functions.

Available as `ctx.db` in queries (read-only) and mutations (read-write).
You should generally use the `DatabaseReader` type from
`"./_generated/server"`.

The two entry points are:

* [get](/api/interfaces/server.GenericDatabaseReader#get), which fetches a single document
  by table name and [GenericId](/api/modules/values#genericid).
* [query](/api/interfaces/server.GenericDatabaseReader#query), which starts building a query.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Fetch a single document by ID:
const user = await ctx.db.get("users", userId);

// Query documents with an index:
const messages = await ctx.db
  .query("messages")
  .withIndex("by_channel", (q) => q.eq("channelId", channelId))
  .order("desc")
  .take(50);
```

**Best practice:** Use `.withIndex()` instead of `.filter()` for efficient
queries. Define indexes in your schema for fields you query frequently.

**`See`**

[https://docs.bijection.com/database/reading-data](/database/reading-data/reading-data)

## Type parameters

| Name | Type |
| :- | :- |
| `DataModel` | extends [`GenericDataModel`](/api/modules/server#genericdatamodel) |

## Hierarchy

* `BaseDatabaseReader`\<`DataModel`>

  ↳ **`GenericDatabaseReader`**

  ↳↳ [`GenericDatabaseWriter`](/api/interfaces/server.GenericDatabaseWriter)

## Properties

### system

• **system**: `BaseDatabaseReader`\<[`SystemDataModel`](/api/interfaces/server.SystemDataModel)>

An interface to read from the system tables within Bijection query functions.

System tables include `_storage` (file metadata) and
`_scheduled_functions` (scheduled function state). Use `ctx.db.system.get()`
and `ctx.db.system.query()` just like regular tables.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Get file metadata from the _storage system table:
const metadata = await ctx.db.system.get("_storage", storageId);
// metadata has: _id, _creationTime, contentType, sha256, size
```

## Methods

### get

▸ **get**\<`TableName`, `Fields`>(`table`, `id`, `options`): `Promise`\<`null` | [`SelectedDocument`](/api/modules/server#selecteddocument)\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>, `Fields`>>

Fetch selected top-level properties, retaining `_id` and `_creationTime`.
Property and object access is enforced before disclosure. Null means the
document is absent; refused access is an error, never a redacted document.

#### Type parameters

| Name | Type |
| :- | :- |
| `TableName` | extends `string` |
| `Fields` | extends `string` |

#### Parameters

| Name | Type |
| :- | :- |
| `table` | `TableName` |
| `id` | [`TableKey`](/api/modules/server#tablekey)\<`DataModel`, `NonUnion`\<`TableName`>> |
| `options` | `Object` |
| `options.select` | readonly `Fields`\[] |

#### Returns

`Promise`\<`null` | [`SelectedDocument`](/api/modules/server#selecteddocument)\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>, `Fields`>>

#### Inherited from

BaseDatabaseReader.get

▸ **get**\<`TableName`>(`table`, `id`): `Promise`\<`null` | [`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>>

Fetch a single document from the database by table name and
[GenericId](/api/modules/values#genericid).

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
const user = await ctx.db.get("users", userId);
```

#### Type parameters

| Name | Type |
| :- | :- |
| `TableName` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `table` | `TableName` | The name of the table to fetch the document from. |
| `id` | [`TableKey`](/api/modules/server#tablekey)\<`DataModel`, `NonUnion`\<`TableName`>> | The [GenericId](/api/modules/values#genericid) of the document to fetch from the database. |

#### Returns

`Promise`\<`null` | [`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>>

* The [GenericDocument](/api/modules/server#genericdocument) of the document at the given [GenericId](/api/modules/values#genericid), or `null` if it no longer exists.

#### Inherited from

BaseDatabaseReader.get

▸ **get**\<`TableName`>(`id`): `Promise`\<`null` | [`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>>

Fetch a single document from the database by its [GenericId](/api/modules/values#genericid).

Supported for backwards compatibility. Prefer `db.get(tableName, id)` in
new code, or `db.system.get(tableName, id)` for system tables.

#### Type parameters

| Name | Type |
| :- | :- |
| `TableName` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `id` | [`GenericId`](/api/modules/values#genericid)\<`TableName`> | The [GenericId](/api/modules/values#genericid) of the document to fetch from the database. |

#### Returns

`Promise`\<`null` | [`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>>

* The [GenericDocument](/api/modules/server#genericdocument) of the document at the given [GenericId](/api/modules/values#genericid), or `null` if it no longer exists.

#### Inherited from

BaseDatabaseReader.get

***

### query

▸ **query**\<`TableName`>(`tableName`): [`SelectableQueryInitializer`](/api/interfaces/server.SelectableQueryInitializer)\<[`NamedTableInfo`](/api/modules/server#namedtableinfo)\<`DataModel`, `TableName`>>

Begin a query for the given table name.

Queries don't execute immediately, so calling this method and extending its
query are free until the results are actually used.

#### Type parameters

| Name | Type |
| :- | :- |
| `TableName` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `tableName` | `TableName` | The name of the table to query. |

#### Returns

[`SelectableQueryInitializer`](/api/interfaces/server.SelectableQueryInitializer)\<[`NamedTableInfo`](/api/modules/server#namedtableinfo)\<`DataModel`, `TableName`>>

* A [QueryInitializer](/api/interfaces/server.QueryInitializer) object to start building a query.

#### Inherited from

BaseDatabaseReader.query

***

### normalizeId

▸ **normalizeId**\<`TableName`>(`tableName`, `id`): `null` | [`TableKey`](/api/modules/server#tablekey)\<`DataModel`, `TableName`>

Returns the string ID format for the ID in a given table, or null if the ID
is from a different table or is not a valid ID.

This accepts the string ID format as well as the `.toString()` representation
of the legacy class-based ID format.

This does not guarantee that the ID exists (i.e. `db.get(tableName, id)` may return `null`).

#### Type parameters

| Name | Type |
| :- | :- |
| `TableName` | extends `string` |

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `tableName` | `TableName` | The name of the table. |
| `id` | `string` | The ID string. |

#### Returns

`null` | [`TableKey`](/api/modules/server#tablekey)\<`DataModel`, `TableName`>

#### Inherited from

BaseDatabaseReader.normalizeId
