Skip to content

Commit bff8e7b

Browse files
Copilothotlong
andcommitted
address review: add documentation comments and findStream streaming test
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> Agent-Logs-Url: https://github.com/objectstack-ai/spec/sessions/01412f6e-dbc1-4384-a4d7-5b6bd4a575b0
1 parent 31c0792 commit bff8e7b

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

packages/plugins/driver-sql/src/sql-driver.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ export class SqlDriver implements IDataDriver {
243243
return null;
244244
}
245245

246+
/**
247+
* Stream records matching a structured query.
248+
* NOTE: Current implementation fetches all results then yields them.
249+
* TODO: Use Knex .stream() for true cursor-based streaming on large datasets.
250+
*/
246251
async *findStream(object: string, query: QueryInput, options?: DriverOptions): AsyncGenerator<Record<string, any>> {
247252
const results = await this.find(object, query, options);
248253
for (const row of results) {
@@ -321,6 +326,11 @@ export class SqlDriver implements IDataDriver {
321326
return await builder.insert(data).returning('*');
322327
}
323328

329+
/**
330+
* Batch-update multiple records by ID.
331+
* NOTE: Current implementation performs sequential updates for correctness.
332+
* TODO: Optimize with SQL CASE statements or batched transactions for performance.
333+
*/
324334
async bulkUpdate(object: string, updates: Array<{ id: string | number; data: Record<string, any> }>, options?: DriverOptions): Promise<Record<string, any>[]> {
325335
const results: Record<string, any>[] = [];
326336
for (const { id, data } of updates) {

packages/spec/src/contracts/data-engine.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,5 +272,46 @@ describe('Data Engine Contract', () => {
272272
expect(await driver.count('users')).toBe(42);
273273
expect(driver.explain).toBeDefined();
274274
});
275+
276+
it('should support findStream with yielded values', async () => {
277+
const records = [{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }];
278+
const driver: DriverInterface = {
279+
name: 'streamer',
280+
version: '1.0.0',
281+
supports: { ...minimalCapabilities, streaming: true },
282+
connect: async () => {},
283+
disconnect: async () => {},
284+
checkHealth: async () => true,
285+
execute: async () => ({}),
286+
find: async () => records,
287+
findStream: () => (async function* () {
288+
for (const r of records) yield r;
289+
})(),
290+
findOne: async () => null,
291+
create: async (_obj, data) => ({ id: '1', ...data }),
292+
update: async (_obj, _id, data) => ({ id: '1', ...data }),
293+
upsert: async (_obj, data) => ({ id: '1', ...data }),
294+
delete: async () => true,
295+
count: async () => records.length,
296+
bulkCreate: async () => [],
297+
bulkUpdate: async () => [],
298+
bulkDelete: async () => {},
299+
beginTransaction: async () => ({}),
300+
commit: async () => {},
301+
rollback: async () => {},
302+
syncSchema: async () => {},
303+
dropTable: async () => {},
304+
};
305+
306+
const stream = driver.findStream('users', {} as any);
307+
const collected: any[] = [];
308+
for await (const row of stream as AsyncIterable<any>) {
309+
collected.push(row);
310+
}
311+
312+
expect(collected).toHaveLength(2);
313+
expect(collected[0].name).toBe('Alice');
314+
expect(collected[1].name).toBe('Bob');
315+
});
275316
});
276317
});

0 commit comments

Comments
 (0)