@objectql/core 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/IMPLEMENTATION_STATUS.md +364 -0
  3. package/README.md +31 -9
  4. package/RUNTIME_INTEGRATION.md +391 -0
  5. package/dist/ai-agent.d.ts +4 -3
  6. package/dist/ai-agent.js +10 -3
  7. package/dist/ai-agent.js.map +1 -1
  8. package/dist/app.d.ts +29 -6
  9. package/dist/app.js +117 -58
  10. package/dist/app.js.map +1 -1
  11. package/dist/formula-engine.d.ts +7 -0
  12. package/dist/formula-engine.js +9 -2
  13. package/dist/formula-engine.js.map +1 -1
  14. package/dist/formula-plugin.d.ts +52 -0
  15. package/dist/formula-plugin.js +107 -0
  16. package/dist/formula-plugin.js.map +1 -0
  17. package/dist/index.d.ts +13 -3
  18. package/dist/index.js +14 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/plugin.d.ts +89 -0
  21. package/dist/plugin.js +99 -0
  22. package/dist/plugin.js.map +1 -0
  23. package/dist/query/filter-translator.d.ts +37 -0
  24. package/dist/query/filter-translator.js +135 -0
  25. package/dist/query/filter-translator.js.map +1 -0
  26. package/dist/query/index.d.ts +22 -0
  27. package/dist/query/index.js +39 -0
  28. package/dist/query/index.js.map +1 -0
  29. package/dist/query/query-analyzer.d.ts +186 -0
  30. package/dist/query/query-analyzer.js +349 -0
  31. package/dist/query/query-analyzer.js.map +1 -0
  32. package/dist/query/query-builder.d.ts +27 -0
  33. package/dist/query/query-builder.js +71 -0
  34. package/dist/query/query-builder.js.map +1 -0
  35. package/dist/query/query-service.d.ts +150 -0
  36. package/dist/query/query-service.js +268 -0
  37. package/dist/query/query-service.js.map +1 -0
  38. package/dist/repository.d.ts +23 -2
  39. package/dist/repository.js +62 -13
  40. package/dist/repository.js.map +1 -1
  41. package/dist/util.d.ts +7 -0
  42. package/dist/util.js +18 -3
  43. package/dist/util.js.map +1 -1
  44. package/dist/validator-plugin.d.ts +56 -0
  45. package/dist/validator-plugin.js +106 -0
  46. package/dist/validator-plugin.js.map +1 -0
  47. package/dist/validator.d.ts +7 -0
  48. package/dist/validator.js +10 -8
  49. package/dist/validator.js.map +1 -1
  50. package/jest.config.js +16 -0
  51. package/package.json +8 -5
  52. package/src/ai-agent.ts +8 -0
  53. package/src/app.ts +136 -72
  54. package/src/formula-engine.ts +8 -0
  55. package/src/formula-plugin.ts +141 -0
  56. package/src/index.ts +25 -3
  57. package/src/plugin.ts +179 -0
  58. package/src/query/filter-translator.ts +147 -0
  59. package/src/query/index.ts +24 -0
  60. package/src/query/query-analyzer.ts +535 -0
  61. package/src/query/query-builder.ts +80 -0
  62. package/src/query/query-service.ts +392 -0
  63. package/src/repository.ts +81 -17
  64. package/src/util.ts +19 -3
  65. package/src/validator-plugin.ts +140 -0
  66. package/src/validator.ts +12 -5
  67. package/test/__mocks__/@objectstack/runtime.ts +255 -0
  68. package/test/app.test.ts +23 -35
  69. package/test/filter-syntax.test.ts +233 -0
  70. package/test/formula-engine.test.ts +8 -0
  71. package/test/formula-integration.test.ts +8 -0
  72. package/test/formula-plugin.test.ts +197 -0
  73. package/test/introspection.test.ts +8 -0
  74. package/test/mock-driver.ts +8 -0
  75. package/test/plugin-integration.test.ts +213 -0
  76. package/test/repository-validation.test.ts +8 -0
  77. package/test/repository.test.ts +8 -0
  78. package/test/util.test.ts +9 -1
  79. package/test/utils.ts +8 -0
  80. package/test/validator-plugin.test.ts +126 -0
  81. package/test/validator.test.ts +8 -0
  82. package/tsconfig.json +9 -0
  83. package/tsconfig.tsbuildinfo +1 -1
  84. package/dist/action.d.ts +0 -7
  85. package/dist/action.js +0 -23
  86. package/dist/action.js.map +0 -1
  87. package/dist/hook.d.ts +0 -8
  88. package/dist/hook.js +0 -25
  89. package/dist/hook.js.map +0 -1
  90. package/dist/object.d.ts +0 -3
  91. package/dist/object.js +0 -28
  92. package/dist/object.js.map +0 -1
  93. package/src/action.ts +0 -40
  94. package/src/hook.ts +0 -42
  95. package/src/object.ts +0 -26
  96. package/test/action.test.ts +0 -276
  97. package/test/hook.test.ts +0 -343
  98. package/test/object.test.ts +0 -183
@@ -0,0 +1,89 @@
1
+ /**
2
+ * ObjectQL Plugin
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import type { RuntimePlugin, RuntimeContext } from '@objectstack/runtime';
9
+ import { ValidatorPluginConfig } from './validator-plugin';
10
+ import { FormulaPluginConfig } from './formula-plugin';
11
+ import type { Driver } from '@objectql/types';
12
+ /**
13
+ * Configuration for the ObjectQL Plugin
14
+ */
15
+ export interface ObjectQLPluginConfig {
16
+ /**
17
+ * Enable repository pattern for data access
18
+ * @default true
19
+ */
20
+ enableRepository?: boolean;
21
+ /**
22
+ * Enable validation engine
23
+ * @default true
24
+ */
25
+ enableValidator?: boolean;
26
+ /**
27
+ * Validator plugin configuration
28
+ * Only used if enableValidator is not false
29
+ */
30
+ validatorConfig?: ValidatorPluginConfig;
31
+ /**
32
+ * Enable formula engine
33
+ * @default true
34
+ */
35
+ enableFormulas?: boolean;
36
+ /**
37
+ * Formula plugin configuration
38
+ * Only used if enableFormulas is not false
39
+ */
40
+ formulaConfig?: FormulaPluginConfig;
41
+ /**
42
+ * Enable AI integration
43
+ * @default true
44
+ */
45
+ enableAI?: boolean;
46
+ /**
47
+ * Enable query service and analyzer
48
+ * @default true
49
+ */
50
+ enableQueryService?: boolean;
51
+ /**
52
+ * Datasources for query service
53
+ * Required if enableQueryService is true
54
+ */
55
+ datasources?: Record<string, Driver>;
56
+ }
57
+ /**
58
+ * ObjectQL Plugin
59
+ *
60
+ * Implements the RuntimePlugin interface from @objectstack/runtime
61
+ * to provide ObjectQL's enhanced features (Repository, Validator, Formula, AI)
62
+ * on top of the ObjectStack kernel.
63
+ */
64
+ export declare class ObjectQLPlugin implements RuntimePlugin {
65
+ private config;
66
+ name: string;
67
+ version: string;
68
+ constructor(config?: ObjectQLPluginConfig);
69
+ /**
70
+ * Install the plugin into the kernel
71
+ * This is called during kernel initialization
72
+ */
73
+ install(ctx: RuntimeContext): Promise<void>;
74
+ /**
75
+ * Called when the kernel starts
76
+ * This is the initialization phase
77
+ */
78
+ onStart(ctx: RuntimeContext): Promise<void>;
79
+ /**
80
+ * Register the Repository pattern
81
+ * @private
82
+ */
83
+ private registerRepository;
84
+ /**
85
+ * Register AI integration
86
+ * @private
87
+ */
88
+ private registerAI;
89
+ }
package/dist/plugin.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL Plugin
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ObjectQLPlugin = void 0;
11
+ const validator_plugin_1 = require("./validator-plugin");
12
+ const formula_plugin_1 = require("./formula-plugin");
13
+ const query_service_1 = require("./query/query-service");
14
+ const query_analyzer_1 = require("./query/query-analyzer");
15
+ /**
16
+ * ObjectQL Plugin
17
+ *
18
+ * Implements the RuntimePlugin interface from @objectstack/runtime
19
+ * to provide ObjectQL's enhanced features (Repository, Validator, Formula, AI)
20
+ * on top of the ObjectStack kernel.
21
+ */
22
+ class ObjectQLPlugin {
23
+ constructor(config = {}) {
24
+ this.config = config;
25
+ this.name = '@objectql/core';
26
+ this.version = '4.0.0';
27
+ // Set defaults
28
+ this.config = {
29
+ enableRepository: true,
30
+ enableValidator: true,
31
+ enableFormulas: true,
32
+ enableAI: true,
33
+ enableQueryService: true,
34
+ ...config
35
+ };
36
+ }
37
+ /**
38
+ * Install the plugin into the kernel
39
+ * This is called during kernel initialization
40
+ */
41
+ async install(ctx) {
42
+ console.log(`[${this.name}] Installing plugin...`);
43
+ const kernel = ctx.engine;
44
+ // Register QueryService and QueryAnalyzer if enabled
45
+ if (this.config.enableQueryService !== false && this.config.datasources) {
46
+ const queryService = new query_service_1.QueryService(this.config.datasources, kernel.metadata);
47
+ kernel.queryService = queryService;
48
+ const queryAnalyzer = new query_analyzer_1.QueryAnalyzer(queryService, kernel.metadata);
49
+ kernel.queryAnalyzer = queryAnalyzer;
50
+ console.log(`[${this.name}] QueryService and QueryAnalyzer registered`);
51
+ }
52
+ // Register components based on configuration
53
+ if (this.config.enableRepository !== false) {
54
+ await this.registerRepository(ctx.engine);
55
+ }
56
+ // Install validator plugin if enabled
57
+ if (this.config.enableValidator !== false) {
58
+ const validatorPlugin = new validator_plugin_1.ValidatorPlugin(this.config.validatorConfig || {});
59
+ await validatorPlugin.install(ctx);
60
+ }
61
+ // Install formula plugin if enabled
62
+ if (this.config.enableFormulas !== false) {
63
+ const formulaPlugin = new formula_plugin_1.FormulaPlugin(this.config.formulaConfig || {});
64
+ await formulaPlugin.install(ctx);
65
+ }
66
+ if (this.config.enableAI !== false) {
67
+ await this.registerAI(ctx.engine);
68
+ }
69
+ console.log(`[${this.name}] Plugin installed successfully`);
70
+ }
71
+ /**
72
+ * Called when the kernel starts
73
+ * This is the initialization phase
74
+ */
75
+ async onStart(ctx) {
76
+ console.log(`[${this.name}] Starting plugin...`);
77
+ // Additional startup logic can be added here
78
+ }
79
+ /**
80
+ * Register the Repository pattern
81
+ * @private
82
+ */
83
+ async registerRepository(kernel) {
84
+ // TODO: Implement repository registration
85
+ // For now, this is a placeholder to establish the structure
86
+ console.log(`[${this.name}] Repository pattern registered`);
87
+ }
88
+ /**
89
+ * Register AI integration
90
+ * @private
91
+ */
92
+ async registerAI(kernel) {
93
+ // TODO: Implement AI registration
94
+ // For now, this is a placeholder to establish the structure
95
+ console.log(`[${this.name}] AI integration registered`);
96
+ }
97
+ }
98
+ exports.ObjectQLPlugin = ObjectQLPlugin;
99
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import type { Filter } from '@objectql/types';
9
+ import type { FilterNode } from '@objectstack/spec';
10
+ /**
11
+ * Filter Translator
12
+ *
13
+ * Translates ObjectQL Filter (FilterCondition) to ObjectStack FilterNode format.
14
+ * Converts modern object-based syntax to legacy array-based syntax for backward compatibility.
15
+ *
16
+ * @example
17
+ * Input: { age: { $gte: 18 }, $or: [{ status: "active" }, { role: "admin" }] }
18
+ * Output: [["age", ">=", 18], "or", [["status", "=", "active"], "or", ["role", "=", "admin"]]]
19
+ */
20
+ export declare class FilterTranslator {
21
+ /**
22
+ * Translate filters from ObjectQL format to ObjectStack FilterNode format
23
+ */
24
+ translate(filters?: Filter): FilterNode | undefined;
25
+ /**
26
+ * Recursively converts FilterCondition to FilterNode array format
27
+ */
28
+ private convertToNode;
29
+ /**
30
+ * Interleaves filter nodes with a logical operator
31
+ */
32
+ private interleaveWithOperator;
33
+ /**
34
+ * Maps modern $-prefixed operators to legacy format
35
+ */
36
+ private mapOperatorToLegacy;
37
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FilterTranslator = void 0;
11
+ const types_1 = require("@objectql/types");
12
+ /**
13
+ * Filter Translator
14
+ *
15
+ * Translates ObjectQL Filter (FilterCondition) to ObjectStack FilterNode format.
16
+ * Converts modern object-based syntax to legacy array-based syntax for backward compatibility.
17
+ *
18
+ * @example
19
+ * Input: { age: { $gte: 18 }, $or: [{ status: "active" }, { role: "admin" }] }
20
+ * Output: [["age", ">=", 18], "or", [["status", "=", "active"], "or", ["role", "=", "admin"]]]
21
+ */
22
+ class FilterTranslator {
23
+ /**
24
+ * Translate filters from ObjectQL format to ObjectStack FilterNode format
25
+ */
26
+ translate(filters) {
27
+ if (!filters) {
28
+ return undefined;
29
+ }
30
+ // Backward compatibility: if it's already an array (old format), pass through
31
+ if (Array.isArray(filters)) {
32
+ return filters;
33
+ }
34
+ // If it's an empty object, return undefined
35
+ if (typeof filters === 'object' && Object.keys(filters).length === 0) {
36
+ return undefined;
37
+ }
38
+ return this.convertToNode(filters);
39
+ }
40
+ /**
41
+ * Recursively converts FilterCondition to FilterNode array format
42
+ */
43
+ convertToNode(filter) {
44
+ const nodes = [];
45
+ // Process logical operators first
46
+ if (filter.$and) {
47
+ const andNodes = filter.$and.map((f) => this.convertToNode(f));
48
+ nodes.push(...this.interleaveWithOperator(andNodes, 'and'));
49
+ }
50
+ if (filter.$or) {
51
+ const orNodes = filter.$or.map((f) => this.convertToNode(f));
52
+ if (nodes.length > 0) {
53
+ nodes.push('and');
54
+ }
55
+ nodes.push(...this.interleaveWithOperator(orNodes, 'or'));
56
+ }
57
+ // Note: $not operator is not currently supported in the legacy FilterNode format
58
+ if (filter.$not) {
59
+ throw new types_1.ObjectQLError({
60
+ code: 'UNSUPPORTED_OPERATOR',
61
+ message: '$not operator is not supported. Use $ne for field negation instead.'
62
+ });
63
+ }
64
+ // Process field conditions
65
+ for (const [field, value] of Object.entries(filter)) {
66
+ if (field.startsWith('$')) {
67
+ continue; // Skip logical operators (already processed)
68
+ }
69
+ if (nodes.length > 0) {
70
+ nodes.push('and');
71
+ }
72
+ // Handle field value
73
+ if (value === null || value === undefined) {
74
+ nodes.push([field, '=', value]);
75
+ }
76
+ else if (typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {
77
+ // Explicit operators - multiple operators on same field are AND-ed together
78
+ const entries = Object.entries(value);
79
+ for (let i = 0; i < entries.length; i++) {
80
+ const [op, opValue] = entries[i];
81
+ // Add 'and' before each operator (except the very first node)
82
+ if (nodes.length > 0 || i > 0) {
83
+ nodes.push('and');
84
+ }
85
+ const legacyOp = this.mapOperatorToLegacy(op);
86
+ nodes.push([field, legacyOp, opValue]);
87
+ }
88
+ }
89
+ else {
90
+ // Implicit equality
91
+ nodes.push([field, '=', value]);
92
+ }
93
+ }
94
+ // Return as FilterNode (type assertion for backward compatibility)
95
+ return (nodes.length === 1 ? nodes[0] : nodes);
96
+ }
97
+ /**
98
+ * Interleaves filter nodes with a logical operator
99
+ */
100
+ interleaveWithOperator(nodes, operator) {
101
+ if (nodes.length === 0)
102
+ return [];
103
+ if (nodes.length === 1)
104
+ return [nodes[0]];
105
+ const result = [nodes[0]];
106
+ for (let i = 1; i < nodes.length; i++) {
107
+ result.push(operator, nodes[i]);
108
+ }
109
+ return result;
110
+ }
111
+ /**
112
+ * Maps modern $-prefixed operators to legacy format
113
+ */
114
+ mapOperatorToLegacy(operator) {
115
+ const mapping = {
116
+ '$eq': '=',
117
+ '$ne': '!=',
118
+ '$gt': '>',
119
+ '$gte': '>=',
120
+ '$lt': '<',
121
+ '$lte': '<=',
122
+ '$in': 'in',
123
+ '$nin': 'nin',
124
+ '$contains': 'contains',
125
+ '$startsWith': 'startswith',
126
+ '$endsWith': 'endswith',
127
+ '$null': 'is_null',
128
+ '$exist': 'is_not_null',
129
+ '$between': 'between',
130
+ };
131
+ return mapping[operator] || operator.replace('$', '');
132
+ }
133
+ }
134
+ exports.FilterTranslator = FilterTranslator;
135
+ //# sourceMappingURL=filter-translator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-translator.js","sourceRoot":"","sources":["../../src/query/filter-translator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * Query Module
10
+ *
11
+ * This module contains ObjectQL's query-specific functionality:
12
+ * - FilterTranslator: Converts ObjectQL filters to ObjectStack FilterNode
13
+ * - QueryBuilder: Builds ObjectStack QueryAST from ObjectQL UnifiedQuery
14
+ * - QueryService: Executes queries via drivers with profiling support
15
+ * - QueryAnalyzer: Provides query performance analysis and optimization suggestions
16
+ *
17
+ * These are the core components that differentiate ObjectQL from generic runtime systems.
18
+ */
19
+ export * from './filter-translator';
20
+ export * from './query-builder';
21
+ export * from './query-service';
22
+ export * from './query-analyzer';
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ /**
25
+ * Query Module
26
+ *
27
+ * This module contains ObjectQL's query-specific functionality:
28
+ * - FilterTranslator: Converts ObjectQL filters to ObjectStack FilterNode
29
+ * - QueryBuilder: Builds ObjectStack QueryAST from ObjectQL UnifiedQuery
30
+ * - QueryService: Executes queries via drivers with profiling support
31
+ * - QueryAnalyzer: Provides query performance analysis and optimization suggestions
32
+ *
33
+ * These are the core components that differentiate ObjectQL from generic runtime systems.
34
+ */
35
+ __exportStar(require("./filter-translator"), exports);
36
+ __exportStar(require("./query-builder"), exports);
37
+ __exportStar(require("./query-service"), exports);
38
+ __exportStar(require("./query-analyzer"), exports);
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH;;;;;;;;;;GAUG;AAEH,sDAAoC;AACpC,kDAAgC;AAChC,kDAAgC;AAChC,mDAAiC"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * ObjectQL Query Analyzer
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import type { UnifiedQuery, MetadataRegistry } from '@objectql/types';
9
+ import type { QueryAST } from '@objectstack/spec';
10
+ import { QueryService, QueryOptions } from './query-service';
11
+ /**
12
+ * Query execution plan
13
+ */
14
+ export interface QueryPlan {
15
+ /**
16
+ * The compiled QueryAST
17
+ */
18
+ ast: QueryAST;
19
+ /**
20
+ * Estimated number of rows to be scanned
21
+ */
22
+ estimatedRows?: number;
23
+ /**
24
+ * Indexes that could be used for this query
25
+ */
26
+ indexes: string[];
27
+ /**
28
+ * Warnings about potential performance issues
29
+ */
30
+ warnings: string[];
31
+ /**
32
+ * Suggestions for optimization
33
+ */
34
+ suggestions: string[];
35
+ /**
36
+ * Complexity score (0-100, higher is more complex)
37
+ */
38
+ complexity: number;
39
+ }
40
+ /**
41
+ * Query profile result with execution statistics
42
+ */
43
+ export interface ProfileResult {
44
+ /**
45
+ * Execution time in milliseconds
46
+ */
47
+ executionTime: number;
48
+ /**
49
+ * Number of rows scanned by the database
50
+ */
51
+ rowsScanned: number;
52
+ /**
53
+ * Number of rows returned
54
+ */
55
+ rowsReturned: number;
56
+ /**
57
+ * Whether an index was used
58
+ */
59
+ indexUsed: boolean;
60
+ /**
61
+ * The query plan
62
+ */
63
+ plan: QueryPlan;
64
+ /**
65
+ * Efficiency ratio (rowsReturned / rowsScanned)
66
+ * Higher is better (1.0 is perfect, 0.0 is worst)
67
+ */
68
+ efficiency: number;
69
+ }
70
+ /**
71
+ * Aggregated query statistics
72
+ */
73
+ export interface QueryStats {
74
+ /**
75
+ * Total number of queries executed
76
+ */
77
+ totalQueries: number;
78
+ /**
79
+ * Average execution time in milliseconds
80
+ */
81
+ avgExecutionTime: number;
82
+ /**
83
+ * Slowest query execution time
84
+ */
85
+ slowestQuery: number;
86
+ /**
87
+ * Fastest query execution time
88
+ */
89
+ fastestQuery: number;
90
+ /**
91
+ * Queries by object
92
+ */
93
+ byObject: Record<string, {
94
+ count: number;
95
+ avgTime: number;
96
+ }>;
97
+ /**
98
+ * Top slow queries
99
+ */
100
+ slowQueries: Array<{
101
+ objectName: string;
102
+ executionTime: number;
103
+ query: UnifiedQuery;
104
+ timestamp: Date;
105
+ }>;
106
+ }
107
+ /**
108
+ * Query Analyzer
109
+ *
110
+ * Provides query performance analysis and profiling capabilities.
111
+ * This class helps developers optimize queries by:
112
+ * - Analyzing query plans
113
+ * - Profiling execution performance
114
+ * - Tracking statistics
115
+ * - Providing optimization suggestions
116
+ */
117
+ export declare class QueryAnalyzer {
118
+ private queryService;
119
+ private metadata;
120
+ private stats;
121
+ private executionTimes;
122
+ private readonly MAX_SLOW_QUERIES;
123
+ constructor(queryService: QueryService, metadata: MetadataRegistry);
124
+ /**
125
+ * Analyze a query and generate an execution plan
126
+ *
127
+ * @param objectName - The object to query
128
+ * @param query - The unified query
129
+ * @returns Query plan with optimization suggestions
130
+ */
131
+ explain(objectName: string, query: UnifiedQuery): Promise<QueryPlan>;
132
+ /**
133
+ * Profile a query execution
134
+ *
135
+ * @param objectName - The object to query
136
+ * @param query - The unified query
137
+ * @param options - Query execution options
138
+ * @returns Profile result with execution statistics
139
+ */
140
+ profile(objectName: string, query: UnifiedQuery, options?: QueryOptions): Promise<ProfileResult>;
141
+ /**
142
+ * Get aggregated query statistics
143
+ *
144
+ * @returns Current query statistics
145
+ */
146
+ getStatistics(): QueryStats;
147
+ /**
148
+ * Reset statistics
149
+ */
150
+ resetStatistics(): void;
151
+ /**
152
+ * Get schema for an object
153
+ * @private
154
+ */
155
+ private getSchema;
156
+ /**
157
+ * Find indexes that could be used for the query
158
+ * @private
159
+ */
160
+ private findApplicableIndexes;
161
+ /**
162
+ * Analyze query for potential issues
163
+ * @private
164
+ */
165
+ private analyzeWarnings;
166
+ /**
167
+ * Generate optimization suggestions
168
+ * @private
169
+ */
170
+ private generateSuggestions;
171
+ /**
172
+ * Calculate query complexity score (0-100)
173
+ * @private
174
+ */
175
+ private calculateComplexity;
176
+ /**
177
+ * Estimate number of rows (very rough heuristic)
178
+ * @private
179
+ */
180
+ private estimateRows;
181
+ /**
182
+ * Record a query execution for statistics
183
+ * @private
184
+ */
185
+ private recordExecution;
186
+ }