---
title: "数据库"
canonical_url: "https://tiptap.zhcndoc.com/hocuspocus/server/extensions/database"
---

# 数据库

使用通用数据库扩展，将数据存储在您已有的数据存储中。\
它需要一个 Promise 来获取数据，另一个 Promise 来存储数据，仅此而已。Hocuspocus 会处理剩余的部分。

## 安装

像下面这样安装数据库扩展：

```bash
npm install @hocuspocus/extension-database
```

## 配置

**fetch**

期望一个异步函数（或 Promise），返回一个兼容 Y.js 的 Uint8Array（二进制数组）或 null。\
确保返回与在 store() 中保存的相同的 Uint8Array，且不要创建新的 Ydoc，\
否则会导致新历史记录（以及内容重复）。

如果你想基于原始文本/JSON 初始创建一个 Ydoc，可以使用你选择的转换器在这里完成，\
例如 `TiptapTransformer.toYdoc` 或 `ProsemirrorTransformer.toYdoc`。

**store**

期望一个异步函数（或 Promise），将 Y.js 的二进制数据持久化存储到某处。

## 使用示例

以下示例使用 SQLite 存储和检索数据。你可以用任何其他数据存储替换这部分。\
只要返回一个 Promise，都可以使用 PostgreSQL、MySQL、MongoDB、S3 等存储数据。\
如果你确实想使用 SQLite，可以参考 [SQLite 扩展](https://tiptap.zhcndoc.com/hocuspocus/server/extensions/sqlite.md)。

```js
import { Server } from "@hocuspocus/server";
import { Database } from "@hocuspocus/extension-database";
import sqlite3 from "sqlite3";

const server = new Server({
  extensions: [
    new Database({
      // 返回一个 Promise 用于获取数据 …
      fetch: async ({ documentName }) => {
        return new Promise((resolve, reject) => {
          this.db?.get(
            `
            SELECT data FROM "documents" WHERE name = $name ORDER BY rowid DESC
          `,
            {
              $name: documentName,
            },
            (error, row) => {
              if (error) {
                reject(error);
              }

              resolve(row?.data);
            }
          );
        });
      },
      // … 以及一个 Promise 用于存储数据：
      store: async ({ documentName, state }) => {
        this.db?.run(
          `
          INSERT INTO "documents" ("name", "data") VALUES ($name, $data)
            ON CONFLICT(name) DO UPDATE SET data = $data
        `,
          {
            $name: documentName,
            $data: state,
          }
        );
      },
    }),
  ],
});

server.listen();
```
