metal-orm 1.1.1 → 1.1.3
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.
- package/README.md +17 -6
- package/dist/index.cjs +288 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -13
- package/dist/index.d.ts +140 -13
- package/dist/index.js +292 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/src/cache/adapters/keyv-cache-adapter.ts +5 -0
- package/src/cache/adapters/memory-cache-adapter.ts +5 -0
- package/src/cache/adapters/redis-cache-adapter.ts +233 -0
- package/src/cache/cache-interfaces.ts +11 -0
- package/src/cache/index.ts +2 -0
- package/src/core/ast/expression-builders.ts +62 -55
- package/src/dto/execute-filtered-paged.ts +206 -0
- package/src/dto/index.ts +40 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metal-orm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"engines": {
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"pg": "^8.0.0",
|
|
45
45
|
"sqlite3": "^5.1.6",
|
|
46
46
|
"tedious": "^19.0.0",
|
|
47
|
-
"keyv": "^5.6.0"
|
|
47
|
+
"keyv": "^5.6.0",
|
|
48
|
+
"ioredis": "^5.0.0"
|
|
48
49
|
},
|
|
49
50
|
"peerDependenciesMeta": {
|
|
50
51
|
"mysql2": {
|
|
@@ -61,6 +62,9 @@
|
|
|
61
62
|
},
|
|
62
63
|
"keyv": {
|
|
63
64
|
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"ioredis": {
|
|
67
|
+
"optional": true
|
|
64
68
|
}
|
|
65
69
|
},
|
|
66
70
|
"devDependencies": {
|
|
@@ -70,6 +74,8 @@
|
|
|
70
74
|
"@vitest/ui": "^4.0.18",
|
|
71
75
|
"eslint": "^9.39.2",
|
|
72
76
|
"express": "^5.2.1",
|
|
77
|
+
"ioredis": "^5.6.1",
|
|
78
|
+
"ioredis-mock": "^8.9.0",
|
|
73
79
|
"keyv": "^5.6.0",
|
|
74
80
|
"mysql-memory-server": "^1.14.0",
|
|
75
81
|
"mysql2": "^3.16.2",
|
|
@@ -11,6 +11,11 @@ interface CacheEntry<T> {
|
|
|
11
11
|
*/
|
|
12
12
|
export class MemoryCacheAdapter implements CacheProvider {
|
|
13
13
|
readonly name = 'memory';
|
|
14
|
+
readonly capabilities = {
|
|
15
|
+
tags: true,
|
|
16
|
+
prefix: true,
|
|
17
|
+
ttl: true,
|
|
18
|
+
};
|
|
14
19
|
private storage: Map<string, CacheEntry<unknown>> = new Map();
|
|
15
20
|
private tagIndex: Map<string, Set<string>> = new Map();
|
|
16
21
|
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type { CacheProvider } from '../cache-interfaces.js';
|
|
2
|
+
|
|
3
|
+
// Tipos mínimos para ioredis (para evitar dependência obrigatória)
|
|
4
|
+
interface RedisLike {
|
|
5
|
+
get(key: string): Promise<string | null>;
|
|
6
|
+
set(key: string, value: string, ...args: (string | number)[]): Promise<string | null>;
|
|
7
|
+
del(...keys: string[]): Promise<number>;
|
|
8
|
+
sadd(key: string, ...members: string[]): Promise<number>;
|
|
9
|
+
smembers(key: string): Promise<string[]>;
|
|
10
|
+
srem(key: string, ...members: string[]): Promise<number>;
|
|
11
|
+
scan(cursor: string | number, ...args: (string | number)[]): Promise<[string, string[]]>;
|
|
12
|
+
quit(): Promise<string>;
|
|
13
|
+
disconnect(): void;
|
|
14
|
+
isReady?: boolean;
|
|
15
|
+
status?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface RedisOptions {
|
|
19
|
+
host?: string;
|
|
20
|
+
port?: number;
|
|
21
|
+
password?: string;
|
|
22
|
+
db?: number;
|
|
23
|
+
keyPrefix?: string;
|
|
24
|
+
lazyConnect?: boolean;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Adapter para Redis usando ioredis
|
|
30
|
+
*
|
|
31
|
+
* Suporta:
|
|
32
|
+
* - Tags via Redis Sets (SADD, SMEMBERS, SREM)
|
|
33
|
+
* - Prefix invalidation via SCAN
|
|
34
|
+
* - TTL nativo do Redis
|
|
35
|
+
*
|
|
36
|
+
* Instalação:
|
|
37
|
+
* npm install ioredis
|
|
38
|
+
*
|
|
39
|
+
* Para testes (dev):
|
|
40
|
+
* npm install --save-dev ioredis-mock
|
|
41
|
+
*/
|
|
42
|
+
export class RedisCacheAdapter implements CacheProvider {
|
|
43
|
+
readonly name = 'redis';
|
|
44
|
+
readonly capabilities = {
|
|
45
|
+
tags: true,
|
|
46
|
+
prefix: true,
|
|
47
|
+
ttl: true,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
private redis: RedisLike;
|
|
51
|
+
private ownsConnection: boolean;
|
|
52
|
+
private tagPrefix: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Cria um adapter Redis
|
|
56
|
+
*
|
|
57
|
+
* @param redis - Instância do ioredis OU opções de conexão
|
|
58
|
+
* @param options - Opções adicionais
|
|
59
|
+
* @param options.tagPrefix - Prefixo para chaves de tag (default: 'tag:')
|
|
60
|
+
*
|
|
61
|
+
* Exemplos:
|
|
62
|
+
*
|
|
63
|
+
* // Com instância existente (recomendado para connection pooling):
|
|
64
|
+
* const redis = new Redis({ host: 'localhost', port: 6379 });
|
|
65
|
+
* const adapter = new RedisCacheAdapter(redis);
|
|
66
|
+
*
|
|
67
|
+
* // Com opções (adapter gerencia conexão):
|
|
68
|
+
* const adapter = new RedisCacheAdapter({ host: 'localhost', port: 6379 });
|
|
69
|
+
*
|
|
70
|
+
* // Para testes com ioredis-mock:
|
|
71
|
+
* import Redis from 'ioredis-mock';
|
|
72
|
+
* const adapter = new RedisCacheAdapter(new Redis());
|
|
73
|
+
*/
|
|
74
|
+
constructor(
|
|
75
|
+
redis: RedisLike | RedisOptions,
|
|
76
|
+
options?: { tagPrefix?: string }
|
|
77
|
+
) {
|
|
78
|
+
this.tagPrefix = options?.tagPrefix ?? 'tag:';
|
|
79
|
+
|
|
80
|
+
if (this.isRedisInstance(redis)) {
|
|
81
|
+
// Recebeu uma instância existente
|
|
82
|
+
this.redis = redis;
|
|
83
|
+
this.ownsConnection = false;
|
|
84
|
+
} else {
|
|
85
|
+
// Recebeu opções, precisa criar a conexão
|
|
86
|
+
this.redis = this.createRedis(redis);
|
|
87
|
+
this.ownsConnection = true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private isRedisInstance(obj: unknown): obj is RedisLike {
|
|
92
|
+
return (
|
|
93
|
+
typeof obj === 'object' &&
|
|
94
|
+
obj !== null &&
|
|
95
|
+
'get' in obj &&
|
|
96
|
+
'set' in obj &&
|
|
97
|
+
'del' in obj &&
|
|
98
|
+
typeof (obj as RedisLike).get === 'function'
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private createRedis(options: RedisOptions): RedisLike {
|
|
103
|
+
// Dynamic import para evitar dependência obrigatória
|
|
104
|
+
try {
|
|
105
|
+
const Redis = require('ioredis');
|
|
106
|
+
return new Redis(options) as RedisLike;
|
|
107
|
+
} catch {
|
|
108
|
+
throw new Error(
|
|
109
|
+
'ioredis is required for RedisCacheAdapter. ' +
|
|
110
|
+
'Install it with: npm install ioredis'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async get<T>(key: string): Promise<T | undefined> {
|
|
116
|
+
const value = await this.redis.get(key);
|
|
117
|
+
if (value === null) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
return JSON.parse(value) as T;
|
|
122
|
+
} catch {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async has(key: string): Promise<boolean> {
|
|
128
|
+
const value = await this.redis.get(key);
|
|
129
|
+
return value !== null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async set<T>(
|
|
133
|
+
key: string,
|
|
134
|
+
value: T,
|
|
135
|
+
ttlMs?: number,
|
|
136
|
+
tags?: string[]
|
|
137
|
+
): Promise<void> {
|
|
138
|
+
const serialized = JSON.stringify(value);
|
|
139
|
+
|
|
140
|
+
if (ttlMs) {
|
|
141
|
+
// EX = seconds, PX = milliseconds
|
|
142
|
+
await this.redis.set(key, serialized, 'PX', ttlMs);
|
|
143
|
+
} else {
|
|
144
|
+
await this.redis.set(key, serialized);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Registra tags se fornecidas
|
|
148
|
+
if (tags && tags.length > 0) {
|
|
149
|
+
await this.registerTags(key, tags);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async delete(key: string): Promise<void> {
|
|
154
|
+
await this.redis.del(key);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async invalidate(key: string): Promise<void> {
|
|
158
|
+
await this.delete(key);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async invalidateTags(tags: string[]): Promise<void> {
|
|
162
|
+
const keysToDelete = new Set<string>();
|
|
163
|
+
|
|
164
|
+
for (const tag of tags) {
|
|
165
|
+
const tagKey = `${this.tagPrefix}${tag}`;
|
|
166
|
+
const keys = await this.redis.smembers(tagKey);
|
|
167
|
+
|
|
168
|
+
for (const key of keys) {
|
|
169
|
+
keysToDelete.add(key);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Deleta o set da tag
|
|
173
|
+
await this.redis.del(tagKey);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Deleta todas as chaves associadas
|
|
177
|
+
if (keysToDelete.size > 0) {
|
|
178
|
+
await this.redis.del(...Array.from(keysToDelete));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async invalidatePrefix(prefix: string): Promise<void> {
|
|
183
|
+
const keysToDelete: string[] = [];
|
|
184
|
+
let cursor = '0';
|
|
185
|
+
|
|
186
|
+
do {
|
|
187
|
+
const [nextCursor, keys] = await this.redis.scan(
|
|
188
|
+
cursor,
|
|
189
|
+
'MATCH',
|
|
190
|
+
`${prefix}*`,
|
|
191
|
+
'COUNT',
|
|
192
|
+
100
|
|
193
|
+
);
|
|
194
|
+
cursor = nextCursor;
|
|
195
|
+
keysToDelete.push(...keys);
|
|
196
|
+
} while (cursor !== '0');
|
|
197
|
+
|
|
198
|
+
if (keysToDelete.length > 0) {
|
|
199
|
+
// Deleta em batches de 1000 para evitar bloqueio
|
|
200
|
+
const batchSize = 1000;
|
|
201
|
+
for (let i = 0; i < keysToDelete.length; i += batchSize) {
|
|
202
|
+
const batch = keysToDelete.slice(i, i + batchSize);
|
|
203
|
+
await this.redis.del(...batch);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private async registerTags(key: string, tags: string[]): Promise<void> {
|
|
209
|
+
for (const tag of tags) {
|
|
210
|
+
const tagKey = `${this.tagPrefix}${tag}`;
|
|
211
|
+
await this.redis.sadd(tagKey, key);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async dispose(): Promise<void> {
|
|
216
|
+
if (this.ownsConnection) {
|
|
217
|
+
try {
|
|
218
|
+
await this.redis.quit();
|
|
219
|
+
} catch {
|
|
220
|
+
// Se quit falhar, tenta disconnect
|
|
221
|
+
this.redis.disconnect?.();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Retorna a instância Redis subjacente
|
|
228
|
+
* Útil para operações avançadas ou health checks
|
|
229
|
+
*/
|
|
230
|
+
getRedis(): RedisLike {
|
|
231
|
+
return this.redis;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -27,11 +27,22 @@ export interface CacheInvalidator {
|
|
|
27
27
|
invalidatePrefix(prefix: string): Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Capabilities de um cache provider
|
|
32
|
+
* Permite detectar funcionalidades suportadas em runtime
|
|
33
|
+
*/
|
|
34
|
+
export interface CacheCapabilities {
|
|
35
|
+
tags: boolean;
|
|
36
|
+
prefix: boolean;
|
|
37
|
+
ttl: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
/**
|
|
31
41
|
* Interface completa para implementações full-featured
|
|
32
42
|
*/
|
|
33
43
|
export interface CacheProvider extends CacheReader, CacheWriter, CacheInvalidator {
|
|
34
44
|
readonly name: string;
|
|
45
|
+
readonly capabilities: CacheCapabilities;
|
|
35
46
|
dispose?(): Promise<void>;
|
|
36
47
|
}
|
|
37
48
|
|
package/src/cache/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type {
|
|
|
4
4
|
CacheWriter,
|
|
5
5
|
CacheInvalidator,
|
|
6
6
|
CacheProvider,
|
|
7
|
+
CacheCapabilities,
|
|
7
8
|
Duration,
|
|
8
9
|
CacheOptions,
|
|
9
10
|
InvalidationStrategy,
|
|
@@ -20,6 +21,7 @@ export { DefaultCacheStrategy } from './strategies/default-cache-strategy.js';
|
|
|
20
21
|
// Adapters
|
|
21
22
|
export { MemoryCacheAdapter } from './adapters/memory-cache-adapter.js';
|
|
22
23
|
export { KeyvCacheAdapter } from './adapters/keyv-cache-adapter.js';
|
|
24
|
+
export { RedisCacheAdapter } from './adapters/redis-cache-adapter.js';
|
|
23
25
|
|
|
24
26
|
// Manager
|
|
25
27
|
export { QueryCacheManager } from './query-cache-manager.js';
|
|
@@ -24,10 +24,13 @@ import {
|
|
|
24
24
|
CollateExpressionNode
|
|
25
25
|
} from './expression-nodes.js';
|
|
26
26
|
|
|
27
|
-
export type LiteralValue = LiteralNode['value'];
|
|
28
|
-
export type ValueOperandInput = OperandNode | LiteralValue;
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
export type LiteralValue = LiteralNode['value'];
|
|
28
|
+
export type ValueOperandInput = OperandNode | LiteralValue;
|
|
29
|
+
type ScalarComparable = string | number | boolean | Date | Buffer | null;
|
|
30
|
+
type OrderedComparable = string | number | Date | Buffer;
|
|
31
|
+
type NotArray<T> = T extends readonly unknown[] ? never : T;
|
|
32
|
+
|
|
33
|
+
export type TypedLike<T> = { tsType?: T } | { __tsType: T };
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* Type guard to check if a value is a literal value
|
|
@@ -68,20 +71,27 @@ const columnRefToNode = (col: ColumnRef): ColumnNode => {
|
|
|
68
71
|
* @param value - Value to convert (OperandNode, ColumnRef, or literal value)
|
|
69
72
|
* @returns OperandNode representing the value
|
|
70
73
|
*/
|
|
71
|
-
const toOperandNode = (value: OperandNode | ColumnRef | LiteralValue): OperandNode => {
|
|
72
|
-
// Already an operand node
|
|
73
|
-
if (isOperandNode(value)) {
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
74
|
+
const toOperandNode = (value: OperandNode | ColumnRef | LiteralValue): OperandNode => {
|
|
75
|
+
// Already an operand node
|
|
76
|
+
if (isOperandNode(value)) {
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
76
79
|
|
|
77
80
|
// Literal value
|
|
78
|
-
if (isLiteralValue(value)) {
|
|
79
|
-
return toLiteralNode(value);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
if (isLiteralValue(value)) {
|
|
82
|
+
return toLiteralNode(value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (Array.isArray(value)) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
'Array operands are not supported in scalar comparisons. ' +
|
|
88
|
+
'Use inList/notInList for array matching.'
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Must be ColumnRef
|
|
93
|
+
return columnRefToNode(value as ColumnRef);
|
|
94
|
+
};
|
|
85
95
|
|
|
86
96
|
/**
|
|
87
97
|
* Converts a primitive or existing operand into an operand node
|
|
@@ -151,12 +161,12 @@ export const aliasRef = (name: string): AliasRefNode => ({
|
|
|
151
161
|
*/
|
|
152
162
|
export const correlateBy = (table: string, column: string): ColumnNode => outerRef({ name: column, table });
|
|
153
163
|
|
|
154
|
-
const createBinaryExpression = (
|
|
155
|
-
operator: SqlOperator,
|
|
156
|
-
left: OperandNode | ColumnRef,
|
|
157
|
-
right: OperandNode | ColumnRef |
|
|
158
|
-
escape?: string
|
|
159
|
-
): BinaryExpressionNode => {
|
|
164
|
+
const createBinaryExpression = (
|
|
165
|
+
operator: SqlOperator,
|
|
166
|
+
left: OperandNode | ColumnRef,
|
|
167
|
+
right: OperandNode | ColumnRef | LiteralValue,
|
|
168
|
+
escape?: string
|
|
169
|
+
): BinaryExpressionNode => {
|
|
160
170
|
const node: BinaryExpressionNode = {
|
|
161
171
|
type: 'BinaryExpression',
|
|
162
172
|
left: toOperandNode(left),
|
|
@@ -187,11 +197,11 @@ const createBinaryExpression = (
|
|
|
187
197
|
* // With strict typing (typescript will error if types mismatch)
|
|
188
198
|
* eq(users.firstName, 'Ada');
|
|
189
199
|
*/
|
|
190
|
-
export function eq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
191
|
-
export function eq(left: OperandNode | ColumnRef, right:
|
|
192
|
-
export function eq(left: OperandNode | ColumnRef | TypedLike<unknown>, right:
|
|
193
|
-
return createBinaryExpression('=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef |
|
|
194
|
-
}
|
|
200
|
+
export function eq<T extends ScalarComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
201
|
+
export function eq<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
202
|
+
export function eq(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
203
|
+
return createBinaryExpression('=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
204
|
+
}
|
|
195
205
|
|
|
196
206
|
/**
|
|
197
207
|
* Creates a not equal expression (`left != right`).
|
|
@@ -203,14 +213,11 @@ export function eq(left: OperandNode | ColumnRef | TypedLike<unknown>, right: Op
|
|
|
203
213
|
* @example
|
|
204
214
|
* neq(users.status, 'inactive');
|
|
205
215
|
*/
|
|
206
|
-
export function neq<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
207
|
-
export function neq(left: OperandNode | ColumnRef, right:
|
|
208
|
-
export function neq(
|
|
209
|
-
left
|
|
210
|
-
|
|
211
|
-
): BinaryExpressionNode {
|
|
212
|
-
return createBinaryExpression('!=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | string | number | boolean);
|
|
213
|
-
}
|
|
216
|
+
export function neq<T extends ScalarComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
217
|
+
export function neq<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
218
|
+
export function neq(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
219
|
+
return createBinaryExpression('!=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
220
|
+
}
|
|
214
221
|
|
|
215
222
|
/**
|
|
216
223
|
* Creates a greater-than expression (`left > right`).
|
|
@@ -222,11 +229,11 @@ export function neq(
|
|
|
222
229
|
* @example
|
|
223
230
|
* gt(users.age, 18);
|
|
224
231
|
*/
|
|
225
|
-
export function gt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
226
|
-
export function gt(left: OperandNode | ColumnRef, right:
|
|
227
|
-
export function gt(left: OperandNode | ColumnRef | TypedLike<unknown>, right:
|
|
228
|
-
return createBinaryExpression('>', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef |
|
|
229
|
-
}
|
|
232
|
+
export function gt<T extends OrderedComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
233
|
+
export function gt<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
234
|
+
export function gt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
235
|
+
return createBinaryExpression('>', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
236
|
+
}
|
|
230
237
|
|
|
231
238
|
/**
|
|
232
239
|
* Creates a greater-than-or-equal expression (`left >= right`).
|
|
@@ -238,11 +245,11 @@ export function gt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: Op
|
|
|
238
245
|
* @example
|
|
239
246
|
* gte(users.score, 100);
|
|
240
247
|
*/
|
|
241
|
-
export function gte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
242
|
-
export function gte(left: OperandNode | ColumnRef, right:
|
|
243
|
-
export function gte(left: OperandNode | ColumnRef | TypedLike<unknown>, right:
|
|
244
|
-
return createBinaryExpression('>=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef |
|
|
245
|
-
}
|
|
248
|
+
export function gte<T extends OrderedComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
249
|
+
export function gte<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
250
|
+
export function gte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
251
|
+
return createBinaryExpression('>=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
252
|
+
}
|
|
246
253
|
|
|
247
254
|
/**
|
|
248
255
|
* Creates a less-than expression (`left < right`).
|
|
@@ -254,11 +261,11 @@ export function gte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: O
|
|
|
254
261
|
* @example
|
|
255
262
|
* lt(inventory.stock, 5);
|
|
256
263
|
*/
|
|
257
|
-
export function lt<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
258
|
-
export function lt(left: OperandNode | ColumnRef, right:
|
|
259
|
-
export function lt(left: OperandNode | ColumnRef | TypedLike<unknown>, right:
|
|
260
|
-
return createBinaryExpression('<', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef |
|
|
261
|
-
}
|
|
264
|
+
export function lt<T extends OrderedComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
265
|
+
export function lt<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
266
|
+
export function lt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
267
|
+
return createBinaryExpression('<', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
268
|
+
}
|
|
262
269
|
|
|
263
270
|
/**
|
|
264
271
|
* Creates a less-than-or-equal expression (`left <= right`).
|
|
@@ -270,11 +277,11 @@ export function lt(left: OperandNode | ColumnRef | TypedLike<unknown>, right: Op
|
|
|
270
277
|
* @example
|
|
271
278
|
* lte(products.price, 50.00);
|
|
272
279
|
*/
|
|
273
|
-
export function lte<T>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
274
|
-
export function lte(left: OperandNode | ColumnRef, right:
|
|
275
|
-
export function lte(left: OperandNode | ColumnRef | TypedLike<unknown>, right:
|
|
276
|
-
return createBinaryExpression('<=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef |
|
|
277
|
-
}
|
|
280
|
+
export function lte<T extends OrderedComparable>(left: TypedLike<T>, right: T | TypedLike<T>): BinaryExpressionNode;
|
|
281
|
+
export function lte<T>(left: OperandNode | ColumnRef, right: T & NotArray<T>): BinaryExpressionNode;
|
|
282
|
+
export function lte(left: OperandNode | ColumnRef | TypedLike<unknown>, right: unknown): BinaryExpressionNode {
|
|
283
|
+
return createBinaryExpression('<=', left as OperandNode | ColumnRef, right as OperandNode | ColumnRef | LiteralValue);
|
|
284
|
+
}
|
|
278
285
|
|
|
279
286
|
/**
|
|
280
287
|
* Creates a `LIKE` pattern matching expression.
|