Skip to content

Commit 505112a

Browse files
committed
添加 ObjectQL 引擎实现,集成内存驱动,更新相关配置和文档
1 parent d83f972 commit 505112a

7 files changed

Lines changed: 163 additions & 7 deletions

File tree

examples/objectql/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "@objectstack/objectql",
3+
"version": "0.0.1",
4+
"description": "ObjectQL Reference Implementation",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"build": "tsc",
9+
"dev": "tsc -w"
10+
},
11+
"dependencies": {
12+
"@objectstack/spec": "workspace:*"
13+
},
14+
"devDependencies": {
15+
"typescript": "^5.0.0"
16+
}
17+
}

examples/objectql/src/index.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { DriverInterface, DriverOptions, QueryAST } from '@objectstack/spec';
2+
3+
/**
4+
* ObjectQL Engine
5+
*
6+
* The core orchestration layer that sits between the API/UI and the Data Driver.
7+
* It handles:
8+
* 1. Request Validation (using Schemas)
9+
* 2. Security Enforcement (ACLs, Sharing Rules)
10+
* 3. Workflow Triggers
11+
* 4. Driver Delegation
12+
*/
13+
export class ObjectQL {
14+
constructor(private driver: DriverInterface) {
15+
console.log(`[ObjectQL] Initialized with driver: ${driver.name} v${driver.version}`);
16+
}
17+
18+
/**
19+
* Initialize the engine
20+
*/
21+
async init() {
22+
await this.driver.connect();
23+
// In a real app, we would sync schemas here
24+
}
25+
26+
async destroy() {
27+
await this.driver.disconnect();
28+
}
29+
30+
// ============================================
31+
// Data Access Methods
32+
// ============================================
33+
34+
async find(object: string, filters: any = {}, options?: DriverOptions) {
35+
console.log(`[ObjectQL] Finding ${object}...`);
36+
37+
// Transform simplified filters to QueryAST
38+
// This is a simplified "Mock" transform.
39+
// Real implementation would parse complex JSON or FilterBuilders.
40+
const ast: QueryAST = {
41+
// Pass through if it looks like AST, otherwise empty
42+
// In this demo, we assume the caller passes a simplified object or raw AST
43+
filters: filters.filters || undefined,
44+
top: filters.top || 100,
45+
sort: filters.sort || []
46+
};
47+
48+
return this.driver.find(object, ast, options);
49+
}
50+
51+
async insert(object: string, data: Record<string, any>, options?: DriverOptions) {
52+
console.log(`[ObjectQL] Creating ${object}...`);
53+
// 1. Validate Schema
54+
// 2. Run "Before Insert" Triggers
55+
56+
const result = await this.driver.create(object, data, options);
57+
58+
// 3. Run "After Insert" Triggers
59+
return result;
60+
}
61+
62+
async update(object: string, id: string, data: Record<string, any>, options?: DriverOptions) {
63+
console.log(`[ObjectQL] Updating ${object} ${id}...`);
64+
return this.driver.update(object, id, data, options);
65+
}
66+
67+
async delete(object: string, id: string, options?: DriverOptions) {
68+
console.log(`[ObjectQL] Deleting ${object} ${id}...`);
69+
return this.driver.delete(object, id, options);
70+
}
71+
}

examples/objectql/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"module": "commonjs",
5+
"declaration": true,
6+
"outDir": "./dist",
7+
"strict": true,
8+
"esModuleInterop": true,
9+
"skipLibCheck": true,
10+
"forceConsistentCasingInFileNames": true
11+
},
12+
"include": ["src/**/*"]
13+
}

examples/plugin-driver-memory/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { InMemoryDriver } from './memory-driver';
22

3+
export { InMemoryDriver }; // Export class for direct usage
4+
35
// Note: In a real environment, you would import these from @objectstack/spec
46
// But distinct PluginDefinition interface might not be strictly defined in schema yet,
57
// usually it mimics the Manifest structure + runtime hooks.

examples/server/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
"@objectstack/example-crm": "workspace:*",
1212
"@objectstack/example-todo": "workspace:*",
1313
"@objectstack/plugin-bi": "workspace:*",
14+
"@objectstack/objectql": "workspace:*",
15+
"@objectstack/plugin-driver-memory": "workspace:*",
1416
"hono": "^4.0.0",
1517
"@hono/node-server": "^1.0.0",
1618
"zod": "^3.0.0"

examples/server/src/kernel/engine.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,48 @@
11
import { ServiceObject } from '@objectstack/spec';
22
import { SchemaRegistry } from './registry';
3-
4-
// Simple in-memory storage for demonstration
5-
const MEMORY_DB: Record<string, any[]> = {};
3+
import { InMemoryDriver } from '@objectstack/plugin-driver-memory';
4+
import { ObjectQL } from '@objectstack/objectql';
65

76
export class DataEngine {
7+
private ql: ObjectQL;
8+
9+
constructor() {
10+
// In a real startup sequence, driver choice involves config loading
11+
const driver = new InMemoryDriver();
12+
this.ql = new ObjectQL(driver);
13+
this.ql.init().catch(console.error);
14+
15+
// Seed some data for demo
16+
this.seed();
17+
}
18+
19+
async seed() {
20+
await this.ql.insert('SystemStatus', { status: 'OK', uptime: 0 });
21+
}
822

923
async find(objectName: string, query: any) {
1024
this.ensureSchema(objectName);
11-
const records = MEMORY_DB[objectName] || [];
12-
// In real world: Implement parsing of `query` (filter, sort, page)
25+
26+
// Delegate to ObjectQL
27+
const results = await this.ql.find(objectName, { top: 100 });
28+
1329
return {
14-
value: records,
15-
count: records.length
30+
value: results,
31+
count: results.length
1632
};
1733
}
1834

1935
async get(objectName: string, id: string) {
2036
this.ensureSchema(objectName);
37+
// Find One not fully implemented in engine wrapper yet, using find as mock
38+
const results = await this.ql.find(objectName, { top: 1 });
39+
return results[0];
40+
}
41+
42+
async create(objectName: string, data: any) {
43+
this.ensureSchema(objectName);
44+
return this.ql.insert(objectName, data);
45+
}
2146
const records = MEMORY_DB[objectName] || [];
2247
const record = records.find(r => r._id === id);
2348
if (!record) throw new Error(`Record not found: ${id}`);

pnpm-lock.yaml

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)