Skip to content

Commit 25cb777

Browse files
Copilothotlong
andcommitted
Add query capability flags to driver and datasource schemas
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 46d6487 commit 25cb777

File tree

3 files changed

+201
-6
lines changed

3 files changed

+201
-6
lines changed

packages/spec/src/system/datasource.zod.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,50 @@ export const DriverDefinitionSchema = z.object({
5151
* and what to compute in memory.
5252
*/
5353
export const DatasourceCapabilities = z.object({
54-
/** Can execute SQL-like joins natively? */
55-
joins: z.boolean().default(false),
54+
// ============================================================================
55+
// Transaction & Connection Management
56+
// ============================================================================
57+
5658
/** Can handle ACID transactions? */
5759
transactions: z.boolean().default(false),
60+
61+
// ============================================================================
62+
// Query Operations
63+
// ============================================================================
64+
65+
/** Can execute WHERE clause filters natively? */
66+
queryFilters: z.boolean().default(false),
67+
68+
/** Can perform aggregation (group by, sum, avg)? */
69+
queryAggregations: z.boolean().default(false),
70+
71+
/** Can perform ORDER BY sorting? */
72+
querySorting: z.boolean().default(false),
73+
74+
/** Can perform LIMIT/OFFSET pagination? */
75+
queryPagination: z.boolean().default(false),
76+
77+
/** Can perform window functions? */
78+
queryWindowFunctions: z.boolean().default(false),
79+
80+
/** Can perform subqueries? */
81+
querySubqueries: z.boolean().default(false),
82+
83+
/** Can execute SQL-like joins natively? */
84+
joins: z.boolean().default(false),
85+
86+
// ============================================================================
87+
// Advanced Features
88+
// ============================================================================
89+
5890
/** Can perform full-text search? */
5991
fullTextSearch: z.boolean().default(false),
60-
/** Can perform aggregation (group by, sum, avg)? */
61-
aggregation: z.boolean().default(false),
62-
/** Is scheme-less (needs schema inference)? */
63-
dynamicSchema: z.boolean().default(false),
92+
6493
/** Is read-only? */
6594
readOnly: z.boolean().default(false),
95+
96+
/** Is scheme-less (needs schema inference)? */
97+
dynamicSchema: z.boolean().default(false),
6698
});
6799

68100
/**

packages/spec/src/system/driver.test.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ describe('DriverCapabilitiesSchema', () => {
1010
it('should accept valid capabilities', () => {
1111
const capabilities: DriverCapabilities = {
1212
transactions: true,
13+
queryFilters: true,
14+
queryAggregations: true,
15+
querySorting: true,
16+
queryPagination: true,
17+
queryWindowFunctions: true,
18+
querySubqueries: true,
1319
joins: true,
1420
fullTextSearch: true,
1521
jsonFields: true,
@@ -22,6 +28,12 @@ describe('DriverCapabilitiesSchema', () => {
2228
it('should accept minimal capabilities', () => {
2329
const capabilities: DriverCapabilities = {
2430
transactions: false,
31+
queryFilters: false,
32+
queryAggregations: false,
33+
querySorting: false,
34+
queryPagination: false,
35+
queryWindowFunctions: false,
36+
querySubqueries: false,
2537
joins: false,
2638
fullTextSearch: false,
2739
jsonFields: false,
@@ -35,6 +47,7 @@ describe('DriverCapabilitiesSchema', () => {
3547
const incomplete = {
3648
transactions: true,
3749
joins: true,
50+
queryFilters: true,
3851
// missing other fields
3952
};
4053

@@ -79,6 +92,12 @@ describe('DriverInterfaceSchema', () => {
7992
dropTable: async () => {},
8093
supports: {
8194
transactions: true,
95+
queryFilters: true,
96+
queryAggregations: true,
97+
querySorting: true,
98+
queryPagination: true,
99+
queryWindowFunctions: true,
100+
querySubqueries: true,
82101
joins: true,
83102
fullTextSearch: true,
84103
jsonFields: true,
@@ -114,6 +133,12 @@ describe('DriverInterfaceSchema', () => {
114133
dropTable: async (object: string) => {},
115134
supports: {
116135
transactions: false,
136+
queryFilters: false,
137+
queryAggregations: false,
138+
querySorting: false,
139+
queryPagination: false,
140+
queryWindowFunctions: false,
141+
querySubqueries: false,
117142
joins: false,
118143
fullTextSearch: false,
119144
jsonFields: false,
@@ -212,6 +237,12 @@ describe('DriverInterfaceSchema', () => {
212237
dropTable: async () => {},
213238
supports: {
214239
transactions: false,
240+
queryFilters: false,
241+
queryAggregations: false,
242+
querySorting: false,
243+
queryPagination: false,
244+
queryWindowFunctions: false,
245+
querySubqueries: false,
215246
joins: false,
216247
fullTextSearch: false,
217248
jsonFields: false,
@@ -285,6 +316,12 @@ describe('DriverInterfaceSchema', () => {
285316
dropTable: async () => {},
286317
supports: {
287318
transactions: false,
319+
queryFilters: false,
320+
queryAggregations: false,
321+
querySorting: false,
322+
queryPagination: false,
323+
queryWindowFunctions: false,
324+
querySubqueries: false,
288325
joins: false,
289326
fullTextSearch: false,
290327
jsonFields: false,
@@ -341,6 +378,12 @@ describe('DriverInterfaceSchema', () => {
341378
dropTable: async () => {},
342379
supports: {
343380
transactions: false,
381+
queryFilters: false,
382+
queryAggregations: false,
383+
querySorting: false,
384+
queryPagination: false,
385+
queryWindowFunctions: false,
386+
querySubqueries: false,
344387
joins: false,
345388
fullTextSearch: false,
346389
jsonFields: false,
@@ -375,6 +418,12 @@ describe('DriverInterfaceSchema', () => {
375418
dropTable: async () => {},
376419
supports: {
377420
transactions: true,
421+
queryFilters: true,
422+
queryAggregations: true,
423+
querySorting: true,
424+
queryPagination: true,
425+
queryWindowFunctions: false,
426+
querySubqueries: true,
378427
joins: true,
379428
fullTextSearch: false,
380429
jsonFields: true,
@@ -411,6 +460,12 @@ describe('DriverInterfaceSchema', () => {
411460
dropTable: async (object) => {},
412461
supports: {
413462
transactions: true,
463+
queryFilters: true,
464+
queryAggregations: true,
465+
querySorting: true,
466+
queryPagination: true,
467+
queryWindowFunctions: true,
468+
querySubqueries: true,
414469
joins: true,
415470
fullTextSearch: true,
416471
jsonFields: true,
@@ -445,6 +500,12 @@ describe('DriverInterfaceSchema', () => {
445500
dropTable: async (object) => {},
446501
supports: {
447502
transactions: true,
503+
queryFilters: true,
504+
queryAggregations: true,
505+
querySorting: true,
506+
queryPagination: true,
507+
queryWindowFunctions: false, // MongoDB has limited window function support
508+
querySubqueries: true,
448509
joins: false, // MongoDB has limited join support
449510
fullTextSearch: true,
450511
jsonFields: true, // Native JSON support
@@ -479,6 +540,12 @@ describe('DriverInterfaceSchema', () => {
479540
dropTable: async (object) => {},
480541
supports: {
481542
transactions: false, // Salesforce doesn't support transactions
543+
queryFilters: true, // SOQL WHERE clause
544+
queryAggregations: true, // SOQL GROUP BY
545+
querySorting: true, // SOQL ORDER BY
546+
queryPagination: true, // SOQL LIMIT/OFFSET
547+
queryWindowFunctions: false, // No window functions
548+
querySubqueries: true, // SOQL supports subqueries
482549
joins: true, // SOQL supports relationships
483550
fullTextSearch: true, // SOSL
484551
jsonFields: false, // No native JSON type
@@ -513,6 +580,12 @@ describe('DriverInterfaceSchema', () => {
513580
dropTable: async (object) => {},
514581
supports: {
515582
transactions: true, // Redis supports transactions
583+
queryFilters: false, // Limited query support - key-based lookup
584+
queryAggregations: false, // No aggregation support
585+
querySorting: false, // No native sorting
586+
queryPagination: false, // No pagination support
587+
queryWindowFunctions: false, // No window functions
588+
querySubqueries: false, // No subqueries
516589
joins: false, // No join support
517590
fullTextSearch: false, // No native full-text search
518591
jsonFields: true, // RedisJSON module
@@ -522,5 +595,45 @@ describe('DriverInterfaceSchema', () => {
522595

523596
expect(() => DriverInterfaceSchema.parse(redisDriver)).not.toThrow();
524597
});
598+
599+
it('should accept memory-like driver with limited query support', () => {
600+
const memoryDriver: DriverInterface = {
601+
name: 'memory',
602+
version: '1.0.0',
603+
connect: async () => {},
604+
disconnect: async () => {},
605+
checkHealth: async () => true,
606+
execute: async () => ({}),
607+
find: async (object, query) => [],
608+
findOne: async (object, query) => null,
609+
create: async (object, data) => data,
610+
update: async (object, id, data) => data,
611+
delete: async (object, id) => true,
612+
count: async () => 0,
613+
bulkCreate: async (object, data) => data,
614+
bulkUpdate: async (object, updates) => updates,
615+
bulkDelete: async (object, ids) => {},
616+
beginTransaction: async () => ({}),
617+
commit: async (tx) => {},
618+
rollback: async (tx) => {},
619+
syncSchema: async (object, schema) => {},
620+
dropTable: async (object) => {},
621+
supports: {
622+
transactions: false, // No transactions in memory
623+
queryFilters: false, // Memory driver doesn't support query conditions - all filtering done in-memory
624+
queryAggregations: false, // No aggregation support
625+
querySorting: false, // No native sorting
626+
queryPagination: false, // No pagination support
627+
queryWindowFunctions: false, // No window functions
628+
querySubqueries: false, // No subqueries
629+
joins: false, // No join support - joins done in-memory
630+
fullTextSearch: false, // No full-text search
631+
jsonFields: true, // Memory can store any type
632+
arrayFields: true, // Memory can store any type
633+
},
634+
};
635+
636+
expect(() => DriverInterfaceSchema.parse(memoryDriver)).not.toThrow();
637+
});
525638
});
526639
});

packages/spec/src/system/driver.zod.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,68 @@ export const DriverOptionsSchema = z.object({
3030
* This allows ObjectQL to adapt its behavior based on underlying database capabilities.
3131
*/
3232
export const DriverCapabilitiesSchema = z.object({
33+
// ============================================================================
34+
// Transaction & Connection Management
35+
// ============================================================================
36+
3337
/**
3438
* Whether the driver supports database transactions.
3539
* If true, beginTransaction, commit, and rollback must be implemented.
3640
*/
3741
transactions: z.boolean().describe('Supports transactions'),
3842

43+
// ============================================================================
44+
// Query Operations
45+
// ============================================================================
46+
47+
/**
48+
* Whether the driver supports WHERE clause filters.
49+
* If false, ObjectQL will fetch all records and filter in memory.
50+
*
51+
* Example: Memory driver might not support complex filter conditions.
52+
*/
53+
queryFilters: z.boolean().describe('Supports WHERE clause filtering'),
54+
55+
/**
56+
* Whether the driver supports aggregation functions (COUNT, SUM, AVG, etc.).
57+
* If false, ObjectQL will compute aggregations in memory.
58+
*/
59+
queryAggregations: z.boolean().describe('Supports GROUP BY and aggregation functions'),
60+
61+
/**
62+
* Whether the driver supports ORDER BY sorting.
63+
* If false, ObjectQL will sort results in memory.
64+
*/
65+
querySorting: z.boolean().describe('Supports ORDER BY sorting'),
66+
67+
/**
68+
* Whether the driver supports LIMIT/OFFSET pagination.
69+
* If false, ObjectQL will fetch all records and paginate in memory.
70+
*/
71+
queryPagination: z.boolean().describe('Supports LIMIT/OFFSET pagination'),
72+
73+
/**
74+
* Whether the driver supports window functions (ROW_NUMBER, RANK, LAG, LEAD, etc.).
75+
* If false, ObjectQL will compute window functions in memory.
76+
*/
77+
queryWindowFunctions: z.boolean().describe('Supports window functions with OVER clause'),
78+
79+
/**
80+
* Whether the driver supports subqueries (nested SELECT statements).
81+
* If false, ObjectQL will execute queries separately and combine results.
82+
*/
83+
querySubqueries: z.boolean().describe('Supports subqueries'),
84+
3985
/**
4086
* Whether the driver supports SQL-style joins.
4187
* If false, ObjectQL will fetch related data separately and join in memory.
4288
*/
4389
joins: z.boolean().describe('Supports SQL joins'),
4490

91+
// ============================================================================
92+
// Advanced Features
93+
// ============================================================================
94+
4595
/**
4696
* Whether the driver supports full-text search.
4797
* If true, text search queries can be pushed to the database.

0 commit comments

Comments
 (0)