بنقرة واحدة
drizzle-solid
Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use when designing, implementing, reviewing, testing, or using the Xpod CLI; especially docs/cli-spec.md, raw Pod resource commands, server commands, auth and JSON output contracts, RDF/obj/secret boundaries, marketplace plugin metadata, and release/install validation.
Use when designing or reviewing Solid Pod, RDF, Linked Data, drizzle-solid, or LinX shared model schemas; especially for deciding URI vs id fields, inverse links, chat/thread/message modeling, Pod persistence boundaries, and cross-app data semantics.
Xpod Components.js 变量和组件配置专家,处理 CLI 参数、变量解析、组件配置等问题
| name | drizzle-solid |
| description | Drizzle Solid ORM 专家,处理 Pod 数据 CRUD、Schema 定义、查询优化、SPARQL 端点配置等问题 |
| allowed-tools | Read, Write, Edit, Grep, Glob |
你是 XPod 项目的 Drizzle Solid ORM 专家。帮助设计和实现基于 drizzle-solid 的 Pod 数据访问层。
drizzle-solid 是一个为 Solid Pod 设计的类型安全 ORM,基于 Drizzle ORM 构建,让你能够像操作传统数据库一样操作 Solid Pod 中的 RDF 数据。
| 能力 | 原生 CSS | xpod |
|---|---|---|
| 基础 CRUD | ✅ LDP 模式 | ✅ LDP 模式 |
| SPARQL SELECT | ❌ 不支持(Comunica 客户端执行) | ✅ 服务端索引下推 |
| SPARQL UPDATE | ⚠️ 仅 BGP 写入 | ✅ 完整支持 |
| 条件查询 (where) | Comunica 读文件到内存 | 索引下推(单 Pod) |
| 聚合函数 (count/sum/avg) | Comunica 读文件到内存 | 索引下推(单 Pod) |
| SPARQL 端点 | ❌ 不支持 | ✅ /-/sparql Sidecar |
import { podTable, string, int, datetime, uri } from '@undefineds.co/drizzle-solid';
const userTable = podTable('users', {
id: string('id').primaryKey(),
name: string('name'),
email: string('email'),
age: int('age'),
createdAt: datetime('createdAt'),
}, {
base: '/data/users/', // 容器或资源路径
type: 'https://schema.org/Person', // RDF 类型
namespace: UDFS_NAMESPACE, // 自定义命名空间
subjectTemplate: '{id}.ttl#this', // subject URI 模板
sparqlEndpoint: '/data/users/-/sparql', // xpod SPARQL 端点
typeIndex: 'private', // TypeIndex 注册
autoRegister: true, // 自动注册到 TypeIndex
});
// 每个用户一个文件: /users/alice.ttl, /users/bob.ttl
const userTable = podTable('users', { ... }, {
base: '/users/',
subjectTemplate: '{id}.ttl', // 或 '{id}.ttl#this'
});
// 按日期分片: /logs/2026/01/17/log-001.ttl
const logTable = podTable('logs', { ... }, {
base: '/logs/',
subjectTemplate: '{yyyy}/{MM}/{dd}/{id}.ttl',
});
// 所有消息在同一文件: /chat/room.ttl#msg-1, /chat/room.ttl#msg-2
const messageTable = podTable('messages', { ... }, {
base: '/chat/room.ttl',
subjectTemplate: '#{id}', // 强制 fragment 模式
});
当需要将关联数据存储在同一文件时:
// Thread 和 Message 存储在同一文件
const ChatThread = podTable('ChatThread', {
id: string('id').primaryKey(),
title: string('title'),
}, {
base: '/chat/',
subjectTemplate: '{id}.ttl#this', // /chat/thread-1.ttl#this
});
const ChatMessage = podTable('ChatMessage', {
id: string('id').primaryKey(),
threadId: string('threadId'),
content: string('content'),
}, {
base: '/chat/',
subjectTemplate: '{threadId}.ttl#{id}', // /chat/thread-1.ttl#msg-1
});
注意:使用 {threadId} 等外键变量时,查询需要配合 sparqlEndpoint 才能跨文件查询。
LDP 和 SPARQL 完全兼容:
const postsTable = podTable('posts', { ... }, {
base: '/data/posts.ttl',
subjectTemplate: '#{id}',
sparqlEndpoint: '/data/posts.ttl/-/sparql',
});
用于跨文件查询:
const usersTable = podTable('users', { ... }, {
base: '/data/users/',
subjectTemplate: '{id}.ttl#this',
sparqlEndpoint: '/data/users/-/sparql', // 容器级 SPARQL 端点
});
重要:Document Mode 下,SPARQL 写操作与 LDP 文件视图不兼容!
import { drizzle, eq, and, gte } from '@undefineds.co/drizzle-solid';
const db = drizzle(session, { schema });
// 查询所有
const users = await db.select().from(userTable);
// 条件查询
const adults = await db.select()
.from(userTable)
.where(gte(userTable.age, 18));
// 复合条件
const result = await db.select()
.from(userTable)
.where(and(
eq(userTable.status, 'active'),
gte(userTable.age, 18)
));
// 插入
await db.insert(userTable).values({
id: 'user-1',
name: 'Alice',
email: 'alice@example.com',
});
// 更新
await db.update(userTable)
.set({ name: 'Alice Smith' })
.where(eq(userTable.id, 'user-1'));
// 删除
await db.delete(userTable)
.where(eq(userTable.id, 'user-1'));
const db = drizzle(session, { schema });
// findMany
const users = await db.query.users.findMany({
where: { verified: true },
orderBy: [{ column: schema.users.name, direction: 'asc' }],
with: { posts: true }, // 关联查询
});
// findFirst
const user = await db.query.users.findFirst({
where: eq(schema.users.id, 'user-1'),
});
// findByIri
const alice = await db.findByIri(schema.users, 'https://pod.example/data/users.ttl#alice');
import { count, max, sum, avg } from '@undefineds.co/drizzle-solid';
const stats = await db
.select({
totalUsers: count(),
oldestAge: max(userTable.age),
})
.from(userTable);
// 初始化表(创建容器、资源,注册 TypeIndex)
await db.init([userTable, postTable]);
// 手动确保容器存在
// drizzle-solid 会自动处理,但如果需要手动控制:
// 1. 先 HEAD 检查容器是否存在
// 2. 不存在则 PUT 创建
可能原因:
sparqlEndpoint解决方案:
// 配置容器级 SPARQL 端点
const table = podTable('items', { ... }, {
base: '/data/items/',
sparqlEndpoint: '/data/items/-/sparql',
});
可能原因:Document Mode 下混用了 SPARQL 写入和 LDP 读取
解决方案:
正确用法:
// 使用 {id} 引用主键
subjectTemplate: '{id}.ttl#this'
// 使用其他字段(如 threadId)
subjectTemplate: '{threadId}.ttl#{id}'
注意:变量必须是 schema 中定义的字段名。
检查:
typeIndex: 'private' 或 'public' 已设置autoRegister: true(默认)// 推荐:所有数据在一个文件
const table = podTable('items', { ... }, {
base: '/data/items.ttl',
subjectTemplate: '#{id}',
sparqlEndpoint: '/data/items.ttl/-/sparql',
});
// 每条记录独立文件,但通过 SPARQL 端点聚合查询
const table = podTable('items', { ... }, {
base: '/data/items/',
subjectTemplate: '{id}.ttl#this',
sparqlEndpoint: '/data/items/-/sparql',
});
// Thread 和 Message 在同一文件,便于原子操作
const ChatThread = podTable('ChatThread', { ... }, {
base: '/chat/',
subjectTemplate: '{id}.ttl#this',
});
const ChatMessage = podTable('ChatMessage', { ... }, {
base: '/chat/',
subjectTemplate: '{threadId}.ttl#{id}',
});
import { UDFS_NAMESPACE } from '@/vocab';
const table = podTable('items', {
status: string('status'), // 映射到 udfs:status
}, {
namespace: UDFS_NAMESPACE,
});
node_modules/@undefineds.co/drizzle-solid/README.mdsrc/vocab/src/api/chatkit/schema.ts, src/credential/schema/tables.ts如果发现 drizzle-solid 设计不合理或存在 bug,通过 git MCP 向 drizzle-solid 仓库提 issue:
仓库: undefinedsco/drizzle-solid
提 issue 时请包含: