> ## 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: GenericDatabaseWriter<DataModel>

> An interface to read from and write to the database within Bijection mutation functions.

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

An interface to read from and write to the database within Bijection mutation
functions.

Available as `ctx.db` in mutations. You should generally use the
`DatabaseWriter` type from `"./_generated/server"`.

Extends [GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader)
with write operations. All reads and writes within a single mutation are
executed **atomically**, you never have to worry about partial writes
leaving your data in an inconsistent state.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Insert a new document:
const userId = await ctx.db.insert("users", { name: "Alice", email: "alice@example.com" });

// Update specific fields (shallow merge):
await ctx.db.patch("users", userId, { name: "Alice Smith" });

// Replace entire document (all non-system fields):
await ctx.db.replace("users", userId, { name: "Bob", email: "bob@example.com" });

// Delete a document:
await ctx.db.delete("users", userId);

// Delete multiple documents (collect first, then delete each):
const oldTasks = await ctx.db
  .query("tasks")
  .withIndex("by_completed", (q) => q.eq("completed", true))
  .collect();
for (const task of oldTasks) {
  await ctx.db.delete("tasks", task._id);
}
```

**`See`**

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

## Type parameters

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

## Hierarchy

* [`GenericDatabaseReader`](/api/interfaces/server.GenericDatabaseReader)\<`DataModel`>

  ↳ **`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
```

#### Inherited from

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[system](/api/interfaces/server.GenericDatabaseReader#system)

***

### vars

• **vars**: `Object`

Values that are not known until the mutation commits.

#### Type declaration

| Name | Type | Description |
| :- | :- | :- |
| `commitTs` | [`CommitTsPlaceholder`](/api/classes/values.CommitTsPlaceholder) | The placeholder for the transaction's commit timestamp. Written into a document field via `db.insert`, it resolves at commit to an int64 (`bigint`) ordered by commit order. Within the writing mutation, reading the field back yields the placeholder, which cannot be used as a number. |

## 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

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[get](/api/interfaces/server.GenericDatabaseReader#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

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[get](/api/interfaces/server.GenericDatabaseReader#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

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[get](/api/interfaces/server.GenericDatabaseReader#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

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[query](/api/interfaces/server.GenericDatabaseReader#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

[GenericDatabaseReader](/api/interfaces/server.GenericDatabaseReader).[normalizeId](/api/interfaces/server.GenericDatabaseReader#normalizeid)

***

### insert

▸ **insert**\<`TableName`>(`table`, `value`): `Promise`\<[`GenericId`](/api/modules/values#genericid)\<`TableName`>>

Insert a new document into a table.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
const taskId = await ctx.db.insert("tasks", {
  text: "Buy groceries",
  completed: false,
});
```

#### Type parameters

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

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `table` | `TableName` | The name of the table to insert a new document into. |
| `value` | [`WithoutSystemFields`](/api/modules/server#withoutsystemfields)\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>> | The document to insert. System fields (`_id`, `_creationTime`) are added automatically and should not be included. |

#### Returns

`Promise`\<[`GenericId`](/api/modules/values#genericid)\<`TableName`>>

The [GenericId](/api/modules/values#genericid) of the new document.

***

### patch

▸ **patch**\<`TableName`>(`table`, `id`, `value`): `Promise`\<`void`>

Patch an existing document, shallow merging it with the given partial
document.

New fields are added. Existing fields are overwritten. Fields set to
`undefined` are removed. Fields not specified in the patch are left
unchanged.

This method will throw if the document does not exist.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Update only the "completed" field, leaving other fields unchanged:
await ctx.db.patch("tasks", taskId, { completed: true });

// Remove an optional field by setting it to undefined:
await ctx.db.patch("tasks", taskId, { assignee: undefined });
```

**Tip:** Use `patch` for partial updates. Use `replace` when you want to
overwrite the entire document.

#### Type parameters

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

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `table` | `TableName` | The name of the table the document is in. |
| `id` | [`GenericId`](/api/modules/values#genericid)\<`NonUnion`\<`TableName`>> | The [GenericId](/api/modules/values#genericid) of the document to patch. |
| `value` | `PatchValue`\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>> | The partial document to merge into the existing document. |

#### Returns

`Promise`\<`void`>

▸ **patch**\<`TableName`>(`id`, `value`): `Promise`\<`void`>

Patch an existing document, shallow merging it with the given partial
document.

New fields are added. Existing fields are overwritten. Fields set to
`undefined` are removed. Fields not specified in the patch are left
unchanged.

This method will throw if the document does not exist.

Supported for backwards compatibility. Prefer `db.patch(tableName, id, value)`
in new code.

#### 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 patch. |
| `value` | `PatchValue`\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>> | The partial document to merge into the existing document. |

#### Returns

`Promise`\<`void`>

***

### replace

▸ **replace**\<`TableName`>(`table`, `id`, `value`): `Promise`\<`void`>

Replace the value of an existing document, overwriting its old value
completely.

Unlike `patch`, which does a shallow merge, `replace` overwrites the
entire document. Any fields not included in the new value will be removed
(except system fields `_id` and `_creationTime`).

This method will throw if the document does not exist.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Replace the entire document:
await ctx.db.replace("users", userId, {
  name: "New Name",
  email: "new@example.com",
});
```

#### Type parameters

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

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `table` | `TableName` | The name of the table the document is in. |
| `id` | [`GenericId`](/api/modules/values#genericid)\<`NonUnion`\<`TableName`>> | The [GenericId](/api/modules/values#genericid) of the document to replace. |
| `value` | [`WithOptionalSystemFields`](/api/modules/server#withoptionalsystemfields)\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>> | The new document. System fields can be omitted. |

#### Returns

`Promise`\<`void`>

▸ **replace**\<`TableName`>(`id`, `value`): `Promise`\<`void`>

Replace the value of an existing document, overwriting its old value
completely.

Unlike `patch`, which does a shallow merge, `replace` overwrites the
entire document.

Supported for backwards compatibility. Prefer `db.replace(tableName, id, value)`
in new code.

#### 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 replace. |
| `value` | [`WithOptionalSystemFields`](/api/modules/server#withoptionalsystemfields)\<[`DocumentByName`](/api/modules/server#documentbyname)\<`DataModel`, `TableName`>> | The new document. System fields can be omitted. |

#### Returns

`Promise`\<`void`>

***

### delete

▸ **delete**\<`TableName`>(`table`, `id`): `Promise`\<`void`>

Delete an existing document.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
await ctx.db.delete("tasks", taskId);
```

#### Type parameters

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

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `table` | `TableName` | The name of the table the document is in. |
| `id` | [`GenericId`](/api/modules/values#genericid)\<`NonUnion`\<`TableName`>> | The [GenericId](/api/modules/values#genericid) of the document to remove. |

#### Returns

`Promise`\<`void`>

▸ **delete**(`id`): `Promise`\<`void`>

Delete an existing document.

Supported for backwards compatibility. Prefer `db.delete(tableName, id)` in
new code.

**Note:** Bijection queries do not support `.delete()` directly on query
results. To delete multiple documents, `.collect()` them first, then
delete each one individually.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `id` | [`GenericId`](/api/modules/values#genericid)\<[`WritableTableNames`](/api/modules/server#writabletablenames)\<`DataModel`>> | The [GenericId](/api/modules/values#genericid) of the document to remove. |

#### Returns

`Promise`\<`void`>
