返回文档入口

接入

用 drizzle-solid 读写 Pod 数据

把官方 README 的最小读写路径整理成可照做的顺序,同时说清我们没有执行过这个示例。

这一页把官方 README 的最小读写路径整理成可以照着走的顺序,并标明每一步的前提。

先说清楚:我们没有执行过下面的示例。包名、类型、命令和示例代码都摘自官方仓库的 README 与文档,我们引用了原文,但没有安装这个包、没有连过 Pod,也没有跑过 examples/01-quick-start.ts。能不能跑通、会报什么错,我们无法替你确认。要核实请直接看本页列出的官方来源。

用哪个版本,从哪里装

  • 包名:@undefineds.co/drizzle-solid。注意 scope 是 @undefineds.co,不是同名的非 scope 包。

  • 版本:我们核对时的最新发布版本是 0.3.24。

  • 依赖:drizzle-orm。

  • 官方安装来源是 npm,README 给出两种写法:

    npm install @undefineds.co/drizzle-solid drizzle-orm
    
    # 需要内置 SPARQL 引擎时可选
    npm install @comunica/query-sparql-solid
    yarn add @undefineds.co/drizzle-solid drizzle-orm
    
    # 需要内置 SPARQL 引擎时可选
    yarn add @comunica/query-sparql-solid
  • @comunica/query-sparql-solid 是可选的 peer dependency。官方当前支持 4.x,3.x 不在支持矩阵里。如果运行环境里已经装了 Comunica,官方建议直接注入那个引擎,不要再装第二份。

  • npm 页面:https://www.npmjs.com/package/@undefineds.co/drizzle-solid

前提:一个已经认证过的 session

官方快速开始里,pod(session) 和 drizzle(session) 都接收一个 session。也就是说,你得先有一个连到目标 Pod、并且已经通过认证的会话。

  • Pod 从哪来:可以是你自己部署的 Xpod,也可以是其他 Solid 服务。Xpod 的部署步骤见自部署 Xpod,是否与当前版本兼容以示例使用的版本为准。
  • session 怎么拿到:官方安装在 docs/guides/installation.md。我们没有执行过认证流程,所以这里不给猜测的登录命令。
  • 应用用的是某个具体用户的身份和权限,读写都受 Pod 的访问控制约束。这部分说明在保存、访问和迁移说明里。

读写目标在哪里

每个模型同时描述「长什么样」和「放在哪」。官方 README 里的三个字段:

  • base:文档存放的位置,例如 https://alice.example/data/posts/。
  • id:相对 base 的资源 id,例如 post-1.ttl,也可以是 chat-1/messages.ttl#msg-1 这样带片段的形式。
  • type:写入时使用的主要 rdf:type。

subjectTemplate 已经废弃,只为兼容旧布局保留。新写的 schema 应当把准确路径放进 id 字段。

还有一条官方 README 标为「最重要的运行时规则」的约定:列表和过滤用集合读取,即 client.collection(table).list(...)、db.select().from(table)...、db.query.<resource>.findMany(...);要操作某一个具体实体,用精确目标方法,即 client.entity(resource, iri)、findById、findByIri、updateById、deleteById、updateByIri、deleteByIri。不要用 where({ id: ... }) 或 where(eq(table.id, ...)) 当作精确查找的替代。

官方最小示例

下面是官方 README 的 Quick start 原文,我们没有运行过:

import { pod, podTable, string, datetime } from '@undefineds.co/drizzle-solid';

const posts = podTable('posts', {
  id: string('id').primaryKey(),
  title: string('title').predicate('http://schema.org/headline'),
  content: string('content').predicate('http://schema.org/text'),
  createdAt: datetime('createdAt').predicate('http://schema.org/dateCreated'),
}, {
  base: 'https://alice.example/data/posts/',
  type: 'http://schema.org/CreativeWork',
});

const client = pod(session);
await client.init(posts);

const created = await client.collection(posts).create({
  id: 'post-1.ttl',
  title: 'Hello Solid',
  content: 'Stored as RDF in a Pod document.',
  createdAt: new Date(),
});

if (!created) {
  throw new Error('Create failed');
}

const post = client.entity(posts, created['@id']);

console.log(await post.get());
await post.update({ title: 'Updated title' });
await post.delete();

习惯 Drizzle 写法的话,官方 README 还给出 drizzle(session) 版本,用 insert(posts).values(...)、findById、updateById、deleteById。

这段示例在做什么

以下解释只是读代码得到的,不代表我们跑通过:

  • 写:client.collection(posts).create(...) 往 base 下写一个 post-1.ttl 文档,字段通过 predicate 映射到 RDF 谓词。
  • 读回:client.entity(posts, created['@id']) 拿到刚创建的那条,再用 post.get() 读回来。
  • 改和删:post.update({ title: 'Updated title' }) 和 post.delete()。
  • 失败判断:示例用 if (!created) throw new Error('Create failed') 处理写入没有返回结果的情况。

状态:我们没有验证过