Skip to content

Commit 6647592

Browse files
committed
更新文档,完成 Driver 接口的实现指南,添加自定义驱动的构建步骤和示例
1 parent 2dd826b commit 6647592

File tree

5 files changed

+243
-3
lines changed

5 files changed

+243
-3
lines changed

QUICK_START_IMPLEMENTATION.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
|----------|----------|--------|--------|------|
1313
| **Field Widget Contract** | ⚠️ CRITICAL | 1-2 days | 🔴 Not Started | `packages/spec/src/ui/widget.zod.ts` |
1414
| **Plugin Lifecycle** | ⚠️ CRITICAL | 2-3 days | 🔴 Not Started | `packages/spec/src/system/plugin.zod.ts` |
15-
| **Driver Interface** | ⚠️ CRITICAL | 3-4 days | 🔴 Not Started | `packages/spec/src/system/driver.zod.ts` |
15+
| **Driver Interface** | ⚠️ CRITICAL | 3-4 days | ✅ Done | `packages/spec/src/system/driver.zod.ts` |
1616
| **Trigger Context** | 🟡 HIGH | 1-2 days | 🔴 Not Started | `packages/spec/src/data/trigger.zod.ts` |
1717

1818
**Total Estimated Effort**: 7-11 days (1 developer) or 2-3 days (4 developers in parallel)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: 构建自定义驱动
3+
description: 学习如何使用驱动接口为 ObjectStack 实现自定义数据库驱动。
4+
---
5+
6+
# 构建自定义驱动
7+
8+
驱动程序(Driver)是 **ObjectQL** 引擎与底层数据存储(SQL、NoSQL、API 等)之间的桥梁。通过实现 `DriverInterface`,您可以将 ObjectStack 连接到任何数据源。
9+
10+
本指南将以创建一个简单的 **内存驱动(In-Memory Driver)** 为例进行讲解。
11+
12+
## 先决条件
13+
14+
- 现有的 ObjectStack 工作区或插件包。
15+
- 依赖 `@objectstack/objectql``@objectstack/spec`
16+
17+
## 1. 驱动接口 (Driver Interface)
18+
19+
所有驱动程序必须实现规范中定义的 `DriverInterface`
20+
21+
```typescript
22+
import { DriverInterface, DriverOptions } from '@objectstack/spec';
23+
import { QueryAST, QueryResult } from '@objectstack/objectql';
24+
25+
export class MyCustomDriver implements DriverInterface {
26+
name = 'MyCustomDriver';
27+
28+
async connect() {
29+
// 初始化连接
30+
}
31+
32+
async disconnect() {
33+
// 关闭连接
34+
}
35+
36+
// ... CRUD 方法
37+
}
38+
```
39+
40+
## 2. 实现 CRUD 操作
41+
42+
您需要实现 `find`(查询)、`insert`(插入)、`update`(更新)和 `delete`(删除)方法。
43+
44+
### Find (查询)
45+
46+
`find` 方法接收一个 `QueryAST` 对象,其中包含结构化的查询信息(过滤、排序、分页)。
47+
48+
```typescript
49+
async find(object: string, query: QueryAST, options?: DriverOptions): Promise<QueryResult> {
50+
// 1. 将 QueryAST 转换为数据库的查询语言(例如 SQL)
51+
// 2. 执行查询
52+
// 3. 返回对象数组结果
53+
return [];
54+
}
55+
```
56+
57+
### Insert (插入)
58+
59+
```typescript
60+
async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
61+
// 将数据插入存储
62+
return data;
63+
}
64+
```
65+
66+
### Update (更新)
67+
68+
```typescript
69+
async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
70+
// 更新由 `id` 标识的记录
71+
return { id, ...data };
72+
}
73+
```
74+
75+
### Delete (删除)
76+
77+
```typescript
78+
async delete(object: string, id: string, options?: DriverOptions) {
79+
// 删除记录
80+
}
81+
```
82+
83+
## 3. 类型处理
84+
85+
使用 `@objectstack/objectql` 提供的类型以确保兼容性。
86+
87+
- `QueryAST`: 通用的查询抽象语法树。
88+
- `QueryResult`: `Record<string, any>[]`.
89+
90+
## 4. 注册驱动
91+
92+
在插件的运行时入口点(例如 `index.ts`)导出驱动程序,以便引擎使用。
93+
94+
```typescript
95+
import { MyCustomDriver } from './my-driver';
96+
97+
export default {
98+
drivers: [new MyCustomDriver()]
99+
};
100+
```
101+
102+
## 示例:内存驱动
103+
104+
请参考 `examples/plugin-driver-memory` 中的参考实现。
105+
106+
```typescript
107+
// examples/plugin-driver-memory/src/memory-driver.ts
108+
export class InMemoryDriver implements DriverInterface {
109+
name = 'InMemory';
110+
private store = new Map<string, Map<string, any>>();
111+
112+
async find(object: string, query: QueryAST) {
113+
const table = this.store.get(object) || new Map();
114+
// 简单的过滤实现...
115+
return Array.from(table.values());
116+
}
117+
// ...
118+
}
119+
```
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: Building a Custom Driver
3+
description: Learn how to implement a custom database driver for ObjectStack using the Driver Interface.
4+
---
5+
6+
# Building a Custom Driver
7+
8+
Drivers are the bridge between the **ObjectQL** engine and the underlying data storage (SQL, NoSQL, APIs, etc.). By implementing the `DriverInterface`, you can connect ObjectStack to any data source.
9+
10+
In this guide, we will walk through creating a simple **In-Memory Driver** as an example.
11+
12+
## Prerequisites
13+
14+
- Existing ObjectStack workspace or plugin package.
15+
- Dependency on `@objectstack/objectql` and `@objectstack/spec`.
16+
17+
## 1. The Driver Interface
18+
19+
All drivers must implement the `DriverInterface` defined in the specification.
20+
21+
```typescript
22+
import { DriverInterface, DriverOptions } from '@objectstack/spec';
23+
import { QueryAST, QueryResult } from '@objectstack/objectql';
24+
25+
export class MyCustomDriver implements DriverInterface {
26+
name = 'MyCustomDriver';
27+
28+
async connect() {
29+
// Initialize connection
30+
}
31+
32+
async disconnect() {
33+
// Close connection
34+
}
35+
36+
// ... CRUD Methods
37+
}
38+
```
39+
40+
## 2. Implementing CRUD Operations
41+
42+
You need to implement `find`, `insert`, `update`, and `delete` methods.
43+
44+
### Find (Query)
45+
46+
The `find` method receives a `QueryAST` object, which contains structured query information (filters, sorting, pagination).
47+
48+
```typescript
49+
async find(object: string, query: QueryAST, options?: DriverOptions): Promise<QueryResult> {
50+
// 1. Convert QueryAST to your database's query language (e.g., SQL)
51+
// 2. Execute query
52+
// 3. Return results as an array of objects
53+
return [];
54+
}
55+
```
56+
57+
### Insert (Create)
58+
59+
```typescript
60+
async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
61+
// Insert data into the storage
62+
return data;
63+
}
64+
```
65+
66+
### Update
67+
68+
```typescript
69+
async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
70+
// Update the record identified by `id`
71+
return { id, ...data };
72+
}
73+
```
74+
75+
### Delete
76+
77+
```typescript
78+
async delete(object: string, id: string, options?: DriverOptions) {
79+
// Remove the record
80+
}
81+
```
82+
83+
## 3. Handling Types
84+
85+
Use the types provided by `@objectstack/objectql` to ensure compatibility.
86+
87+
- `QueryAST`: The universal abstract syntax tree for queries.
88+
- `QueryResult`: `Record<string, any>[]`.
89+
90+
## 4. Registering the Driver
91+
92+
In your plugin's runtime entry point (e.g., `index.ts`), export the driver so it can be used by the engine.
93+
94+
```typescript
95+
import { MyCustomDriver } from './my-driver';
96+
97+
export default {
98+
drivers: [new MyCustomDriver()]
99+
};
100+
```
101+
102+
## Example: In-Memory Driver
103+
104+
See the reference implementation in `examples/plugin-driver-memory`.
105+
106+
```typescript
107+
// examples/plugin-driver-memory/src/memory-driver.ts
108+
export class InMemoryDriver implements DriverInterface {
109+
name = 'InMemory';
110+
private store = new Map<string, Map<string, any>>();
111+
112+
async find(object: string, query: QueryAST) {
113+
const table = this.store.get(object) || new Map();
114+
// Simple filter implementation...
115+
return Array.from(table.values());
116+
}
117+
// ...
118+
}
119+
```

content/docs/guides/meta.cn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"pages": [
55
"getting-started",
66
"installation",
7-
"project-structure"
7+
"project-structure",
8+
"custom-driver"
89
]
910
}

content/docs/guides/meta.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"pages": [
55
"getting-started",
66
"installation",
7-
"project-structure"
7+
"project-structure",
8+
"custom-driver"
89
]
910
}

0 commit comments

Comments
 (0)