Skip to content

Commit 1f7b4da

Browse files
Merge pull request #169 from objectstack-ai/copilot/migrate-driver-redis
2 parents d1309dd + 4c738f5 commit 1f7b4da

5 files changed

Lines changed: 814 additions & 9 deletions

File tree

packages/drivers/redis/README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
> ⚠️ **Note**: This is an **example/template implementation** to demonstrate how to create custom ObjectQL drivers. It is not production-ready and serves as a reference for driver development.
44
5+
**Version 4.0.0** - Now compliant with DriverInterface from @objectstack/spec
6+
57
## Overview
68

79
The Redis Driver is a reference implementation showing how to adapt a key-value store (Redis) to work with ObjectQL's universal data protocol. While Redis is primarily designed for caching and simple key-value operations, this driver demonstrates how to map ObjectQL's rich query interface to a simpler database model.
810

11+
This driver implements both the legacy Driver interface from @objectql/types and the standard DriverInterface from @objectstack/spec for full compatibility with the new kernel-based plugin system.
12+
913
## Features
1014

1115
- ✅ Basic CRUD operations (Create, Read, Update, Delete)
16+
-**v4.0**: executeQuery() with QueryAST support
17+
-**v4.0**: executeCommand() with unified command interface
18+
-**v4.0**: Bulk operations (bulkCreate, bulkUpdate, bulkDelete) using Redis PIPELINE
1219
- ✅ Query filtering (in-memory)
1320
- ✅ Sorting (in-memory)
1421
- ✅ Pagination (skip/limit)
@@ -136,6 +143,7 @@ new RedisDriver(config: RedisDriverConfig)
136143

137144
All standard Driver interface methods are implemented:
138145

146+
**Legacy Driver Interface:**
139147
- `find(objectName, query, options)` - Query multiple records
140148
- `findOne(objectName, id, query, options)` - Get single record by ID
141149
- `create(objectName, data, options)` - Create new record
@@ -144,6 +152,110 @@ All standard Driver interface methods are implemented:
144152
- `count(objectName, filters, options)` - Count matching records
145153
- `disconnect()` - Close Redis connection
146154

155+
**DriverInterface v4.0 Methods:**
156+
- `executeQuery(ast, options)` - Execute queries using QueryAST format
157+
- `executeCommand(command, options)` - Execute commands (create, update, delete, bulk operations)
158+
159+
### executeQuery Examples
160+
161+
The new `executeQuery` method uses the QueryAST format from @objectstack/spec:
162+
163+
```typescript
164+
// Basic query
165+
const result = await driver.executeQuery({
166+
object: 'users',
167+
fields: ['name', 'email']
168+
});
169+
console.log(result.value); // Array of users
170+
console.log(result.count); // Number of results
171+
172+
// Query with filters
173+
const result = await driver.executeQuery({
174+
object: 'users',
175+
filters: {
176+
type: 'comparison',
177+
field: 'age',
178+
operator: '>',
179+
value: 18
180+
},
181+
sort: [{ field: 'name', order: 'asc' }],
182+
top: 10,
183+
skip: 0
184+
});
185+
186+
// Complex filters (AND/OR)
187+
const result = await driver.executeQuery({
188+
object: 'users',
189+
filters: {
190+
type: 'and',
191+
children: [
192+
{ type: 'comparison', field: 'role', operator: '=', value: 'user' },
193+
{ type: 'comparison', field: 'age', operator: '>', value: 30 }
194+
]
195+
}
196+
});
197+
```
198+
199+
### executeCommand Examples
200+
201+
The new `executeCommand` method provides a unified interface for mutations:
202+
203+
```typescript
204+
// Create a record
205+
const result = await driver.executeCommand({
206+
type: 'create',
207+
object: 'users',
208+
data: { name: 'Alice', email: 'alice@example.com' }
209+
});
210+
console.log(result.success); // true
211+
console.log(result.data); // Created user object
212+
console.log(result.affected); // 1
213+
214+
// Update a record
215+
const result = await driver.executeCommand({
216+
type: 'update',
217+
object: 'users',
218+
id: 'user-123',
219+
data: { email: 'newemail@example.com' }
220+
});
221+
222+
// Delete a record
223+
const result = await driver.executeCommand({
224+
type: 'delete',
225+
object: 'users',
226+
id: 'user-123'
227+
});
228+
229+
// Bulk create (uses Redis PIPELINE for performance)
230+
const result = await driver.executeCommand({
231+
type: 'bulkCreate',
232+
object: 'users',
233+
records: [
234+
{ name: 'Alice', age: 30 },
235+
{ name: 'Bob', age: 25 },
236+
{ name: 'Charlie', age: 35 }
237+
]
238+
});
239+
console.log(result.affected); // 3
240+
241+
// Bulk update
242+
const result = await driver.executeCommand({
243+
type: 'bulkUpdate',
244+
object: 'users',
245+
updates: [
246+
{ id: 'user-1', data: { age: 31 } },
247+
{ id: 'user-2', data: { age: 26 } }
248+
]
249+
});
250+
251+
// Bulk delete
252+
const result = await driver.executeCommand({
253+
type: 'bulkDelete',
254+
object: 'users',
255+
ids: ['user-1', 'user-2', 'user-3']
256+
});
257+
```
258+
147259
## Example: Using as Cache Layer
148260

149261
Redis works great as a caching layer in front of another driver:

packages/drivers/redis/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@objectql/driver-redis",
3-
"version": "3.0.1",
4-
"description": "Redis driver for ObjectQL - Example implementation for key-value storage",
3+
"version": "4.0.0",
4+
"description": "Redis driver for ObjectQL - Example implementation for key-value storage with DriverInterface v4.0 compliance",
55
"keywords": [
66
"objectql",
77
"driver",
@@ -20,6 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@objectql/types": "workspace:*",
23+
"@objectstack/spec": "^0.2.0",
2324
"redis": "^4.6.0"
2425
},
2526
"devDependencies": {

0 commit comments

Comments
 (0)