Spaces:
Running
Running
Download source/teaql-ts/tests/sql-stream.test.ts from teaql/browser-sqlite-playground: direct link, hf CLI and curl.
- Browser
- Download file 4.92 kB
-
https://huggingface.co/spaces/teaql/browser-sqlite-playground/resolve/main/source/teaql-ts/tests/sql-stream.test.ts
- Command line
-
hf download hf://spaces/teaql/browser-sqlite-playground/source/teaql-ts/tests/sql-stream.test.ts
-
curl -L -o sql-stream.test.ts https://huggingface.co/spaces/teaql/browser-sqlite-playground/resolve/main/source/teaql-ts/tests/sql-stream.test.ts
4.92 kB
| import { UserContext } from '../src/core/context'; | |
| import { OrderBy, SelectQuery } from '../src/core/ast'; | |
| import { EntitySchema, SQLExecutionEvidenceStore } from '../src/sql/core'; | |
| import { QueryRequest } from '../src/core/request-intent'; | |
| import { SQLiteTeaQLClient } from '../src/sql/sqlite'; | |
| import { PostgreSQLDriver } from '../src/sql/postgres'; | |
| import { MySQLDriver } from '../src/sql/mysql'; | |
| const schemas: Record<string, EntitySchema> = { | |
| Order: { | |
| table: 'orders', | |
| columns: { | |
| id: { columnName: 'id', logicalType: 'integer', decode: 'string' }, | |
| version: { columnName: 'version', logicalType: 'integer', decode: 'number' }, | |
| }, | |
| }, | |
| }; | |
| describe('SQLite true streaming query', () => { | |
| it.each([true, false])('preserves a native named-count owner on a real cursor, logging=%p', async logging => { | |
| const client = new SQLiteTeaQLClient(':memory:', schemas).setDiagnosticSQLLogSink(undefined); | |
| try { | |
| await new UserContext().insertResource('dataService', client).ensureSchema(); | |
| for (const id of ['1', '2']) await client.executeMutation({entity:'Order', action:'Create', id, | |
| payload:{}, comment:'seed native cursor fixture'}); | |
| const evidence = new SQLExecutionEvidenceStore(), diagnostics: unknown[] = []; | |
| client.setRuntimeTelemetrySink(evidence).setDiagnosticSQLLogSink({write: entry => diagnostics.push(entry)}) | |
| .setQueryLoggingEnabled(logging); | |
| const root = new QueryRequest(new SelectQuery('Order').comment('load order totals').purpose('render totals')); | |
| const counted = root.deriveOperation(root.query.forExactCount('totalOrders'), | |
| {kind:'named-count',method:'countAs',alias:'totalOrders'}); | |
| const chunks: any[][] = []; | |
| for await (const chunk of client.executeForStream(counted.query, 1)) chunks.push(chunk); | |
| expect(chunks.flat().map(row=>row.totalOrders)).toEqual([2]); | |
| const entries = evidence.snapshot(); | |
| expect(entries).toHaveLength(1); expect(diagnostics).toHaveLength(logging ? 1 : 0); | |
| expect(entries[0].traceChain?.map(node=>node.detail)).toEqual(['render totals','load order totals',"countAs('totalOrders')"]); | |
| expect(entries[0].executionOutcome).toBe('success'); | |
| expect((entries[0].tracePath ?? []).some(node=>node.kind==='relation')).toBe(false); | |
| expect(root.traceChain).toHaveLength(2); | |
| } finally { await client.close(); } | |
| }); | |
| it('yields bounded chunks from the statement iterator', async () => { | |
| const client = new SQLiteTeaQLClient(':memory:', schemas); | |
| await new UserContext().insertResource('dataService', client).ensureSchema(); | |
| for (let id = 1; id <= 5; id++) { | |
| await client.executeMutation({ | |
| entity: 'Order', action: 'Create', id: String(id), payload: {}, comment: 'seed stream fixture', | |
| }); | |
| } | |
| const query = new SelectQuery('Order') | |
| .comment('stream orders') | |
| .purpose('verify cursor streaming') | |
| .order(OrderBy.asc('id')); | |
| const chunks: any[][] = []; | |
| for await (const chunk of client.executeForStream(query, 2)) chunks.push(chunk); | |
| expect(chunks.map(chunk => chunk.length)).toEqual([2, 2, 1]); | |
| expect(chunks.flat().map(row => row.id)).toEqual(['1', '2', '3', '4', '5']); | |
| await client.close(); | |
| }); | |
| it('rejects missing governance and invalid chunk sizes at iteration time', async () => { | |
| const client = new SQLiteTeaQLClient(':memory:', schemas); | |
| await new UserContext().insertResource('dataService', client).ensureSchema(); | |
| const consume = async (stream: AsyncIterable<any[]>) => { | |
| for await (const _chunk of stream) { /* consume */ } | |
| }; | |
| await expect(consume(client.executeForStream(new SelectQuery('Order'), 10))) | |
| .rejects.toMatchObject({ code: 'REQUEST_COMMENT_REQUIRED', field: 'comment', requestKind: 'query' }); | |
| const query = new SelectQuery('Order').comment('invalid size').purpose('verify validation'); | |
| await expect(consume(client.executeForStream(query, 0))).rejects.toThrow(/positive integer/); | |
| await client.close(); | |
| }); | |
| }); | |
| describe('real SQL driver streams', () => { | |
| for (const [name, envName, createDriver, sql] of [ | |
| ['PostgreSQL', 'TEAQL_TEST_POSTGRES_URL', (url: string) => new PostgreSQLDriver(url), | |
| 'SELECT id FROM (VALUES (1), (2), (3), (4), (5)) AS fixture(id) ORDER BY id'], | |
| ['MySQL', 'TEAQL_TEST_MYSQL_URL', (url: string) => new MySQLDriver(url), | |
| 'SELECT id FROM (SELECT 1 id UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) fixture ORDER BY id'], | |
| ] as const) (process.env[envName] ? it : it.skip)(`streams rows from ${name}`, async () => { | |
| const url = process.env[envName]; | |
| const driver = createDriver(url!); | |
| const ids: number[] = []; | |
| try { | |
| for await (const row of driver.stream(sql)) ids.push(Number(row.id)); | |
| } finally { | |
| await driver.close(); | |
| } | |
| expect(ids).toEqual([1, 2, 3, 4, 5]); | |
| }); | |
| }); | |