@housekit/orm 0.1.47 → 0.1.49

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 (79) hide show
  1. package/README.md +120 -5
  2. package/dist/builders/delete.js +112 -0
  3. package/dist/builders/insert.d.ts +0 -91
  4. package/dist/builders/insert.js +393 -0
  5. package/dist/builders/prepared.d.ts +1 -2
  6. package/dist/builders/prepared.js +30 -0
  7. package/dist/builders/select.d.ts +0 -161
  8. package/dist/builders/select.js +562 -0
  9. package/dist/builders/select.types.js +1 -0
  10. package/dist/builders/update.js +136 -0
  11. package/dist/client.d.ts +0 -6
  12. package/dist/client.js +140 -0
  13. package/dist/codegen/zod.js +107 -0
  14. package/dist/column.d.ts +1 -25
  15. package/dist/column.js +133 -0
  16. package/dist/compiler.d.ts +0 -7
  17. package/dist/compiler.js +513 -0
  18. package/dist/core.js +6 -0
  19. package/dist/data-types.d.ts +0 -61
  20. package/dist/data-types.js +127 -0
  21. package/dist/dictionary.d.ts +0 -149
  22. package/dist/dictionary.js +158 -0
  23. package/dist/engines.d.ts +0 -385
  24. package/dist/engines.js +292 -0
  25. package/dist/expressions.d.ts +0 -10
  26. package/dist/expressions.js +268 -0
  27. package/dist/external.d.ts +0 -112
  28. package/dist/external.js +224 -0
  29. package/dist/index.d.ts +0 -51
  30. package/dist/index.js +139 -6853
  31. package/dist/logger.js +36 -0
  32. package/dist/materialized-views.d.ts +0 -188
  33. package/dist/materialized-views.js +380 -0
  34. package/dist/metadata.js +59 -0
  35. package/dist/modules/aggregates.d.ts +0 -164
  36. package/dist/modules/aggregates.js +121 -0
  37. package/dist/modules/array.d.ts +0 -98
  38. package/dist/modules/array.js +71 -0
  39. package/dist/modules/conditional.d.ts +0 -84
  40. package/dist/modules/conditional.js +138 -0
  41. package/dist/modules/conversion.d.ts +0 -147
  42. package/dist/modules/conversion.js +109 -0
  43. package/dist/modules/geo.d.ts +0 -164
  44. package/dist/modules/geo.js +112 -0
  45. package/dist/modules/hash.js +4 -0
  46. package/dist/modules/index.js +12 -0
  47. package/dist/modules/json.d.ts +0 -106
  48. package/dist/modules/json.js +76 -0
  49. package/dist/modules/math.d.ts +0 -16
  50. package/dist/modules/math.js +16 -0
  51. package/dist/modules/string.d.ts +0 -136
  52. package/dist/modules/string.js +89 -0
  53. package/dist/modules/time.d.ts +0 -123
  54. package/dist/modules/time.js +91 -0
  55. package/dist/modules/types.d.ts +0 -133
  56. package/dist/modules/types.js +114 -0
  57. package/dist/modules/window.js +140 -0
  58. package/dist/relational.d.ts +0 -82
  59. package/dist/relational.js +290 -0
  60. package/dist/relations.js +21 -0
  61. package/dist/schema-builder.d.ts +0 -90
  62. package/dist/schema-builder.js +140 -0
  63. package/dist/table.d.ts +0 -42
  64. package/dist/table.js +406 -0
  65. package/dist/utils/background-batcher.js +75 -0
  66. package/dist/utils/batch-transform.js +51 -0
  67. package/dist/utils/binary-reader.d.ts +0 -6
  68. package/dist/utils/binary-reader.js +334 -0
  69. package/dist/utils/binary-serializer.d.ts +0 -125
  70. package/dist/utils/binary-serializer.js +637 -0
  71. package/dist/utils/binary-worker-code.js +1 -0
  72. package/dist/utils/binary-worker-pool.d.ts +0 -34
  73. package/dist/utils/binary-worker-pool.js +206 -0
  74. package/dist/utils/binary-worker.d.ts +0 -11
  75. package/dist/utils/binary-worker.js +63 -0
  76. package/dist/utils/insert-processing.d.ts +0 -2
  77. package/dist/utils/insert-processing.js +163 -0
  78. package/dist/utils/lru-cache.js +30 -0
  79. package/package.json +68 -3
@@ -0,0 +1,513 @@
1
+ import { ClickHouseColumn } from './core';
2
+ import { LRUCache } from './utils/lru-cache';
3
+ import { PreparedQuery } from './builders/prepared';
4
+ const queryCache = new LRUCache({ max: 1000 });
5
+ export class QueryCompiler {
6
+ paramCounter = 0;
7
+ reset() {
8
+ this.paramCounter = 0;
9
+ }
10
+ getNextParamName() {
11
+ return `p_${++this.paramCounter}`;
12
+ }
13
+ compileWithCache(state, client) {
14
+ const { key, values } = this.generateFingerprint(state);
15
+ let template = queryCache.get(key);
16
+ if (!template) {
17
+ const result = this.performFullCompilation(state);
18
+ const paramCount = Object.keys(result.params).length;
19
+ const paramKeys = Array.from({ length: paramCount }, (_, i) => `p_${i + 1}`);
20
+ template = {
21
+ sql: result.sql,
22
+ paramKeys,
23
+ suggestions: result.suggestions,
24
+ columnNames: result.columnNames,
25
+ columnTypes: result.columnTypes
26
+ };
27
+ queryCache.set(key, template);
28
+ }
29
+ const cachedQuery = new PreparedQuery(client, template.sql, template.paramKeys, template.suggestions, template.columnNames, template.columnTypes);
30
+ return { cachedQuery, values };
31
+ }
32
+ compileSelect(state) {
33
+ const { key, values } = this.generateFingerprint(state);
34
+ let template = queryCache.get(key);
35
+ if (!template) {
36
+ const result = this.performFullCompilation(state);
37
+ const paramCount = Object.keys(result.params).length;
38
+ const paramKeys = Array.from({ length: paramCount }, (_, i) => `p_${i + 1}`);
39
+ template = {
40
+ sql: result.sql,
41
+ paramKeys,
42
+ suggestions: result.suggestions,
43
+ columnNames: result.columnNames,
44
+ columnTypes: result.columnTypes
45
+ };
46
+ queryCache.set(key, template);
47
+ }
48
+ const params = {};
49
+ for (let i = 0; i < template.paramKeys.length; i++) {
50
+ if (i < values.length) {
51
+ params[template.paramKeys[i]] = values[i];
52
+ }
53
+ }
54
+ return {
55
+ sql: template.sql,
56
+ params,
57
+ suggestions: template.suggestions
58
+ };
59
+ }
60
+ generateFingerprint(state) {
61
+ const values = [];
62
+ const visitor = (val, type) => values.push(val);
63
+ let key = 'SELECT';
64
+ if (state.ctes.length > 0) {
65
+ key += '|CTES:';
66
+ for (const cte of state.ctes) {
67
+ if (cte.query && typeof cte.query.toSQL === 'function') {
68
+ const { sql, params } = cte.query.toSQL();
69
+ key += `(${cte.name}:${sql})`;
70
+ if (params) {
71
+ for (const [, val] of Object.entries(params)) {
72
+ values.push(val);
73
+ }
74
+ }
75
+ }
76
+ else {
77
+ key += `(${cte.name}:unknown)`;
78
+ }
79
+ }
80
+ }
81
+ if (state.select) {
82
+ key += '|SEL:';
83
+ if (state.distinct)
84
+ key += 'DISTINCT:';
85
+ const keys = Object.keys(state.select);
86
+ for (const alias of keys) {
87
+ const item = state.select[alias];
88
+ key += `${alias}=`;
89
+ if (item instanceof ClickHouseColumn) {
90
+ key += `COL:${item.tableName}.${item.name}`;
91
+ }
92
+ else if (item && typeof item === 'object' && 'walk' in item) {
93
+ key += `EXPR:${item.walk(visitor)}`;
94
+ }
95
+ else {
96
+ key += `RAW:${String(item)}`;
97
+ }
98
+ key += ';';
99
+ }
100
+ }
101
+ else {
102
+ key += '|SEL:*';
103
+ }
104
+ if (state.table) {
105
+ const t = state.table;
106
+ if (t.$options?.kind === 'subquery' && t.$options?.subquery) {
107
+ const { sql, params } = t.$options.subquery.toSQL();
108
+ key += `|FROM:SUB(${sql})`;
109
+ if (params) {
110
+ for (const [, val] of Object.entries(params)) {
111
+ values.push(val);
112
+ }
113
+ }
114
+ }
115
+ else {
116
+ key += `|FROM:${state.table.$table}`;
117
+ if (state.final)
118
+ key += ':FINAL';
119
+ }
120
+ }
121
+ if (state.joins.length > 0) {
122
+ key += '|JOINS:';
123
+ for (const join of state.joins) {
124
+ key += `${join.type}:${join.table}`;
125
+ if (join.on) {
126
+ key += `ON:${join.on.walk(visitor)}`;
127
+ }
128
+ key += ';';
129
+ }
130
+ }
131
+ if (state.arrayJoins.length > 0) {
132
+ key += '|AJOINS:';
133
+ for (const aj of state.arrayJoins) {
134
+ if (aj.column instanceof ClickHouseColumn) {
135
+ key += `COL:${aj.column.tableName}.${aj.column.name}`;
136
+ }
137
+ else {
138
+ key += `EXPR:${aj.column.walk(visitor)}`;
139
+ }
140
+ if (aj.alias)
141
+ key += `AS:${aj.alias}`;
142
+ key += ';';
143
+ }
144
+ }
145
+ if (state.prewhere) {
146
+ key += `|PREWHERE:${state.prewhere.walk(visitor)}`;
147
+ }
148
+ if (state.where) {
149
+ key += `|WHERE:${state.where.walk(visitor)}`;
150
+ }
151
+ if (state.groupBy.length > 0) {
152
+ key += '|GROUP:';
153
+ for (const g of state.groupBy) {
154
+ if (g instanceof ClickHouseColumn) {
155
+ key += `COL:${g.tableName}.${g.name}`;
156
+ }
157
+ else {
158
+ key += `EXPR:${g.walk(visitor)}`;
159
+ }
160
+ key += ';';
161
+ }
162
+ }
163
+ if (state.having) {
164
+ key += `|HAVING:${state.having.walk(visitor)}`;
165
+ }
166
+ if (state.orderBy.length > 0) {
167
+ key += '|ORDER:';
168
+ for (const o of state.orderBy) {
169
+ if (o.col instanceof ClickHouseColumn) {
170
+ key += `COL:${o.col.tableName}.${o.col.name}`;
171
+ }
172
+ else {
173
+ key += `EXPR:${o.col.walk(visitor)}`;
174
+ }
175
+ key += `:${o.dir};`;
176
+ }
177
+ }
178
+ if (state.limit !== null)
179
+ key += `|LIMIT:${state.limit}`;
180
+ if (state.offset !== null)
181
+ key += `|OFFSET:${state.offset}`;
182
+ if (state.sample !== null) {
183
+ key += `|SAMPLE:${state.sample.ratio}:${state.sample.offset}`;
184
+ }
185
+ if (state.settings) {
186
+ key += '|SETTINGS:';
187
+ const sortedKeys = Object.keys(state.settings).sort();
188
+ for (const k of sortedKeys) {
189
+ key += `${k}=${state.settings[k]};`;
190
+ }
191
+ }
192
+ if (Object.keys(state.windows).length > 0) {
193
+ key += '|WINDOWS:';
194
+ const sortedKeys = Object.keys(state.windows).sort();
195
+ for (const k of sortedKeys) {
196
+ key += `${k}=${state.windows[k]};`;
197
+ }
198
+ }
199
+ return { key, values };
200
+ }
201
+ performFullCompilation(state) {
202
+ const table = state.table;
203
+ if (!table)
204
+ throw new Error('❌ .from() is required');
205
+ const getAlias = (fallback, item) => {
206
+ if (item && typeof item === 'object' && typeof item._alias === 'string') {
207
+ return item._alias;
208
+ }
209
+ return fallback;
210
+ };
211
+ this.reset();
212
+ const params = {};
213
+ let withSql = '';
214
+ if (state.ctes.length > 0) {
215
+ const cteParts = state.ctes.map(cte => {
216
+ const { query: originalQuery, params: cteParams } = cte.query.toSQL();
217
+ const renamedParams = {};
218
+ let query = originalQuery;
219
+ for (const [key, value] of Object.entries(cteParams)) {
220
+ const newKey = this.getNextParamName();
221
+ renamedParams[newKey] = value;
222
+ query = query.replace(new RegExp(`\\{${key}:`, 'g'), `{${newKey}:`);
223
+ }
224
+ Object.assign(params, renamedParams);
225
+ return `${cte.name} AS (${query})`;
226
+ });
227
+ withSql = `WITH ${cteParts.join(', ')}`;
228
+ }
229
+ const distinctKeyword = state.distinct ? 'DISTINCT ' : '';
230
+ let selectSql = '*';
231
+ const columnNames = [];
232
+ const columnTypes = [];
233
+ if (state.select) {
234
+ selectSql = Object.keys(state.select)
235
+ .map(alias => {
236
+ let item = state.select[alias];
237
+ const targetAlias = getAlias(alias, item);
238
+ const isColumnByInstanceof = item instanceof ClickHouseColumn;
239
+ const isColumnByProperties = item && typeof item === 'object' &&
240
+ 'name' in item && 'type' in item && 'toSQL' in item &&
241
+ typeof item.name === 'string' && typeof item.type === 'string';
242
+ const isColumn = isColumnByInstanceof || isColumnByProperties;
243
+ const isExpression = item && typeof item === 'object' && 'toSQL' in item && !isColumn;
244
+ if (!isColumn && !isExpression) {
245
+ const resolved = this.resolveColumn(item, alias, table);
246
+ if (resolved) {
247
+ item = resolved;
248
+ }
249
+ }
250
+ if (item === undefined || item === null) {
251
+ const availableColumns = Object.keys(table.$columns).map(key => {
252
+ const col = table.$columns[key];
253
+ return `${key} (column: ${col.name})`;
254
+ }).join(', ');
255
+ const directProps = Object.keys(table).filter(k => !k.startsWith('$')).join(', ');
256
+ throw new Error(`Field "${alias}" in SELECT is undefined. ` +
257
+ `The value you passed for "${alias}" is undefined. ` +
258
+ `Make sure you're accessing the column correctly:\n` +
259
+ ` - Use table.columnName (e.g., myTable.columnName)\n` +
260
+ ` - Or use table.$columns.columnName (e.g., myTable.$columns.columnName)\n` +
261
+ ` - Available column properties: ${directProps}\n` +
262
+ ` - Available columns (property -> column): ${availableColumns}\n` +
263
+ ` - Example: client.select({ my_column: myTable.columnName }).from(myTable)`);
264
+ }
265
+ columnNames.push(targetAlias);
266
+ if (item instanceof ClickHouseColumn || isColumnByProperties) {
267
+ const col = item;
268
+ columnTypes.push(col.type);
269
+ const colSql = this.formatColumn(col);
270
+ return `${colSql} AS \`${targetAlias}\``;
271
+ }
272
+ else if (item && typeof item === 'object' && 'toSQL' in item) {
273
+ const res = item.toSQL({ table });
274
+ Object.assign(params, res.params);
275
+ columnTypes.push(item.type || 'String');
276
+ return `${res.sql} AS \`${targetAlias}\``;
277
+ }
278
+ else {
279
+ throw new Error(`Field "${alias}" in SELECT must be a ClickHouseColumn or SQLExpression, ` +
280
+ `but got ${typeof item}. ` +
281
+ `Make sure you're using table.columnName (e.g., myTable.columnName) correctly.`);
282
+ }
283
+ })
284
+ .join(', ');
285
+ }
286
+ else if (table) {
287
+ for (const [key, col] of Object.entries(table.$columns)) {
288
+ const column = col;
289
+ columnNames.push(column.name);
290
+ columnTypes.push(column.type);
291
+ }
292
+ }
293
+ const isSubquery = table?.$options?.kind === 'subquery' && table?.$options?.subquery;
294
+ const tableName = table.$table;
295
+ let fromSql;
296
+ if (isSubquery) {
297
+ const { sql: subSql, params: subParams } = table.$options.subquery.toSQL();
298
+ Object.assign(params, subParams);
299
+ fromSql = `(${subSql}) AS \`${tableName}\``;
300
+ }
301
+ else {
302
+ fromSql = `\`${tableName}\``;
303
+ if (state.final) {
304
+ fromSql += ' FINAL';
305
+ }
306
+ }
307
+ if (state.joins.length > 0) {
308
+ const joinParts = state.joins.map(join => {
309
+ if (join.type === 'CROSS' || !join.on) {
310
+ return `${join.type} JOIN \`${join.table}\``;
311
+ }
312
+ const onRes = join.on.toSQL({ table });
313
+ Object.assign(params, onRes.params);
314
+ return `${join.type} JOIN \`${join.table}\` ON ${onRes.sql}`;
315
+ });
316
+ fromSql += ' ' + joinParts.join(' ');
317
+ }
318
+ if (state.arrayJoins.length > 0) {
319
+ const arrayJoinParts = state.arrayJoins.map(aj => {
320
+ const isColumn = aj.column instanceof ClickHouseColumn ||
321
+ (aj.column && typeof aj.column === 'object' && 'name' in aj.column && 'type' in aj.column);
322
+ let columnSql;
323
+ if (isColumn) {
324
+ columnSql = this.formatColumn(aj.column);
325
+ }
326
+ else {
327
+ const res = aj.column.toSQL({ table });
328
+ Object.assign(params, res.params);
329
+ columnSql = res.sql;
330
+ }
331
+ return aj.alias ? `${columnSql} AS \`${aj.alias}\`` : columnSql;
332
+ });
333
+ fromSql += ' ARRAY JOIN ' + arrayJoinParts.join(', ');
334
+ }
335
+ let prewhereSql = '';
336
+ if (state.prewhere) {
337
+ const res = state.prewhere.toSQL({ table });
338
+ prewhereSql = `PREWHERE ${res.sql}`;
339
+ Object.assign(params, res.params);
340
+ }
341
+ let whereSql = '';
342
+ if (state.where) {
343
+ const res = state.where.toSQL({ table });
344
+ whereSql = `WHERE ${res.sql}`;
345
+ Object.assign(params, res.params);
346
+ }
347
+ let groupBySql = '';
348
+ if (state.groupBy.length > 0) {
349
+ const parts = state.groupBy.map(c => {
350
+ const isColumn = c instanceof ClickHouseColumn ||
351
+ (c && typeof c === 'object' && 'name' in c && 'type' in c);
352
+ if (isColumn) {
353
+ return this.formatColumn(c);
354
+ }
355
+ else {
356
+ const res = c.toSQL({ table });
357
+ Object.assign(params, res.params);
358
+ return res.sql;
359
+ }
360
+ });
361
+ groupBySql = `GROUP BY ${parts.join(', ')}`;
362
+ }
363
+ let havingSql = '';
364
+ if (state.having) {
365
+ const res = state.having.toSQL({ table });
366
+ havingSql = `HAVING ${res.sql}`;
367
+ Object.assign(params, res.params);
368
+ }
369
+ let orderSql = '';
370
+ if (state.orderBy.length > 0) {
371
+ const parts = state.orderBy.map(o => {
372
+ let colSql;
373
+ const isColumn = o.col instanceof ClickHouseColumn ||
374
+ (o.col && typeof o.col === 'object' && 'name' in o.col && 'type' in o.col);
375
+ if (isColumn) {
376
+ colSql = this.formatColumn(o.col);
377
+ }
378
+ else {
379
+ const res = o.col.toSQL({ table });
380
+ Object.assign(params, res.params);
381
+ colSql = res.sql;
382
+ }
383
+ const sqlUpper = colSql.trim().toUpperCase();
384
+ const alreadyHasDirection = sqlUpper.endsWith(' ASC') || sqlUpper.endsWith(' DESC');
385
+ if (alreadyHasDirection) {
386
+ return colSql;
387
+ }
388
+ return `${colSql} ${o.dir}`;
389
+ });
390
+ orderSql = `ORDER BY ${parts.join(', ')}`;
391
+ }
392
+ let limitSql = '';
393
+ if (state.limit !== null) {
394
+ limitSql = `LIMIT ${state.limit}`;
395
+ if (state.offset !== null) {
396
+ limitSql += ` OFFSET ${state.offset}`;
397
+ }
398
+ }
399
+ let sampleSql = '';
400
+ if (state.sample !== null) {
401
+ sampleSql = `SAMPLE ${state.sample.ratio}`;
402
+ if (state.sample.offset !== undefined) {
403
+ sampleSql += ` OFFSET ${state.sample.offset}`;
404
+ }
405
+ }
406
+ let settingsSql = '';
407
+ const finalSettings = { ...(state.settings || {}) };
408
+ if (table.$options?.projections && table.$options.projections.length > 0) {
409
+ if (finalSettings.use_projection === undefined) {
410
+ finalSettings.use_projection = 1;
411
+ state.suggestions.push(`💡 This table has projections. Automatically enabled 'use_projection = 1' for potentially faster execution.`);
412
+ }
413
+ }
414
+ if (Object.keys(finalSettings).length > 0) {
415
+ const parts = Object.entries(finalSettings).map(([k, v]) => `${k} = ${v}`);
416
+ settingsSql = `SETTINGS ${parts.join(', ')}`;
417
+ }
418
+ let windowSql = '';
419
+ if (Object.keys(state.windows).length > 0) {
420
+ const parts = Object.entries(state.windows).map(([name, def]) => `${name} AS (${def})`);
421
+ windowSql = `WINDOW ${parts.join(', ')}`;
422
+ }
423
+ const queryParts = [
424
+ withSql,
425
+ `SELECT ${distinctKeyword}${selectSql}`,
426
+ `FROM ${fromSql}`,
427
+ prewhereSql,
428
+ whereSql,
429
+ groupBySql,
430
+ havingSql,
431
+ orderSql,
432
+ limitSql,
433
+ sampleSql,
434
+ windowSql,
435
+ settingsSql
436
+ ].filter(part => part !== '');
437
+ return {
438
+ sql: queryParts.join(' '),
439
+ params,
440
+ suggestions: state.suggestions,
441
+ columnNames,
442
+ columnTypes
443
+ };
444
+ }
445
+ formatColumn(col) {
446
+ const colName = 'name' in col ? col.name : col.name;
447
+ const tableName = 'tableName' in col ? col.tableName : col.tableName;
448
+ return tableName ? `\`${tableName}\`.\`${colName}\`` : `\`${colName}\``;
449
+ }
450
+ resolveColumn(value, alias, table) {
451
+ if (value instanceof ClickHouseColumn) {
452
+ return value;
453
+ }
454
+ if (value && typeof value === 'object' && 'toSQL' in value) {
455
+ return value;
456
+ }
457
+ if (table) {
458
+ if (table.$columns[alias]) {
459
+ const col = table.$columns[alias];
460
+ if (col instanceof ClickHouseColumn) {
461
+ return col;
462
+ }
463
+ }
464
+ try {
465
+ const tableProp = table[alias];
466
+ if (tableProp instanceof ClickHouseColumn) {
467
+ return tableProp;
468
+ }
469
+ }
470
+ catch (e) { }
471
+ const aliasCamelCase = alias.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
472
+ if (aliasCamelCase !== alias) {
473
+ if (table.$columns[aliasCamelCase]) {
474
+ return table.$columns[aliasCamelCase];
475
+ }
476
+ try {
477
+ const tableProp = table[aliasCamelCase];
478
+ if (tableProp instanceof ClickHouseColumn) {
479
+ return tableProp;
480
+ }
481
+ }
482
+ catch (e) { }
483
+ }
484
+ const aliasSnakeCase = alias.replace(/([A-Z])/g, '_$1').toLowerCase();
485
+ if (aliasSnakeCase !== alias && aliasSnakeCase !== aliasCamelCase) {
486
+ if (table.$columns[aliasSnakeCase]) {
487
+ return table.$columns[aliasSnakeCase];
488
+ }
489
+ try {
490
+ const tableProp = table[aliasSnakeCase];
491
+ if (tableProp instanceof ClickHouseColumn) {
492
+ return tableProp;
493
+ }
494
+ }
495
+ catch (e) { }
496
+ }
497
+ for (const [, col] of Object.entries(table.$columns)) {
498
+ const column = col;
499
+ if (column.name === alias || column.name === aliasCamelCase || column.name === aliasSnakeCase) {
500
+ return column;
501
+ }
502
+ }
503
+ const aliasLower = alias.toLowerCase();
504
+ for (const [key, col] of Object.entries(table.$columns)) {
505
+ const column = col;
506
+ if (key.toLowerCase() === aliasLower || column.name.toLowerCase() === aliasLower) {
507
+ return column;
508
+ }
509
+ }
510
+ }
511
+ return null;
512
+ }
513
+ }
package/dist/core.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './column';
2
+ export * from './table';
3
+ export * from './engines';
4
+ export * from './materialized-views';
5
+ export * from './dictionary';
6
+ export * from './external';
@@ -5,55 +5,22 @@ export declare const int16: (name: string) => ClickHouseColumn<number, true, fal
5
5
  export declare const integer: (name: string) => ClickHouseColumn<number, true, false>;
6
6
  export declare const int32: (name: string) => ClickHouseColumn<number, true, false>;
7
7
  export declare const int64: (name: string) => ClickHouseColumn<number, true, false>;
8
- /**
9
- * ⚠️ Advanced: Very wide integer type (128-bit).
10
- * Use only if you need to store numbers larger than 2^63-1.
11
- * For most cases, `int64` is sufficient.
12
- */
13
8
  export declare const int128: (name: string) => ClickHouseColumn<number, true, false>;
14
- /**
15
- * ⚠️ Advanced: Extremely wide integer type (256-bit).
16
- * Use only if you need to store numbers larger than 2^127-1.
17
- * For most cases, `int64` is sufficient.
18
- */
19
9
  export declare const int256: (name: string) => ClickHouseColumn<number, true, false>;
20
10
  export declare const uint8: (name: string) => ClickHouseColumn<number, true, false>;
21
11
  export declare const uint16: (name: string) => ClickHouseColumn<number, true, false>;
22
12
  export declare const uint32: (name: string) => ClickHouseColumn<number, true, false>;
23
13
  export declare const uint64: (name: string) => ClickHouseColumn<number, true, false>;
24
- /**
25
- * ⚠️ Advanced: Very wide unsigned integer type (128-bit).
26
- * Use only if you need to store numbers larger than 2^64-1.
27
- * For most cases, `uint64` is sufficient.
28
- */
29
14
  export declare const uint128: (name: string) => ClickHouseColumn<number, true, false>;
30
- /**
31
- * ⚠️ Advanced: Extremely wide unsigned integer type (256-bit).
32
- * Use only if you need to store numbers larger than 2^128-1.
33
- * For most cases, `uint64` is sufficient.
34
- */
35
15
  export declare const uint256: (name: string) => ClickHouseColumn<number, true, false>;
36
16
  export declare const float32: (name: string) => ClickHouseColumn<number, true, false>;
37
17
  export declare const float: (name: string) => ClickHouseColumn<number, true, false>;
38
18
  export declare const float64: (name: string) => ClickHouseColumn<number, true, false>;
39
- /**
40
- * ⚠️ Advanced: Brain Floating Point (16-bit).
41
- * Primarily used for machine learning applications.
42
- * Lower precision than `float32`. Use only if you know exactly why.
43
- */
44
19
  export declare const bfloat16: (name: string) => ClickHouseColumn<number, true, false>;
45
20
  export declare const decimal: (name: string, precision?: number, scale?: number) => ClickHouseColumn<number, true, false>;
46
21
  export declare const decimal32: (name: string, scale?: number) => ClickHouseColumn<number, true, false>;
47
22
  export declare const decimal64: (name: string, scale?: number) => ClickHouseColumn<number, true, false>;
48
- /**
49
- * ⚠️ Advanced: High precision decimal.
50
- * Use only if you need more precision than `decimal64`.
51
- */
52
23
  export declare const decimal128: (name: string, scale?: number) => ClickHouseColumn<number, true, false>;
53
- /**
54
- * ⚠️ Advanced: Extreme precision decimal.
55
- * Use only if you need more precision than `decimal128`.
56
- */
57
24
  export declare const decimal256: (name: string, scale?: number) => ClickHouseColumn<number, true, false>;
58
25
  export declare const text: (name: string) => ClickHouseColumn<string, true, false>;
59
26
  export declare const string: (name: string) => ClickHouseColumn<string, true, false>;
@@ -75,11 +42,6 @@ export declare const nested: (name: string, fields: Record<string, string>) => C
75
42
  export declare const nullable: <T, TNotNull extends boolean, TAutoGenerated extends boolean>(col: ClickHouseColumn<T, TNotNull, TAutoGenerated>) => ClickHouseColumn<T, false, TAutoGenerated>;
76
43
  export declare const lowCardinality: <T, TNotNull extends boolean, TAutoGenerated extends boolean>(col: ClickHouseColumn<T, TNotNull, TAutoGenerated>) => ClickHouseColumn<T, TNotNull, TAutoGenerated>;
77
44
  export declare const json: <TSchema = JsonValue>(name: string) => ClickHouseColumn<TSchema, false, false>;
78
- /**
79
- * ⚠️ Advanced: Dynamic typing (experimental/niche).
80
- * Allows storing values of different types in the same column.
81
- * This is still evolving in ClickHouse. Use with caution.
82
- */
83
45
  export declare const dynamic: (name: string, maxTypes?: number) => ClickHouseColumn<any, true, false>;
84
46
  export declare const aggregateFunction: (name: string, funcName: string, ...argTypes: string[]) => ClickHouseColumn<any, true, false>;
85
47
  export declare const simpleAggregateFunction: (name: string, funcName: string, argType: string) => ClickHouseColumn<any, true, false>;
@@ -97,48 +59,25 @@ export interface TTLRule {
97
59
  target?: string;
98
60
  }
99
61
  export declare const ttl: {
100
- /**
101
- * Delete rows after a time interval
102
- * @example ttl.delete(events.timestamp, { days: 30 })
103
- */
104
62
  delete: (column: ClickHouseColumn, interval: {
105
63
  days?: number;
106
64
  hours?: number;
107
65
  months?: number;
108
66
  years?: number;
109
67
  }) => TTLRule;
110
- /**
111
- * Move rows to cold storage after a time interval
112
- * @example ttl.toDisk(events.timestamp, { days: 7 }, 'cold_storage')
113
- */
114
68
  toDisk: (column: ClickHouseColumn, interval: {
115
69
  days?: number;
116
70
  hours?: number;
117
71
  months?: number;
118
72
  years?: number;
119
73
  }, disk: string) => TTLRule;
120
- /**
121
- * Move rows to a volume after a time interval
122
- * @example ttl.toVolume(events.timestamp, { days: 30 }, 'archive')
123
- */
124
74
  toVolume: (column: ClickHouseColumn, interval: {
125
75
  days?: number;
126
76
  hours?: number;
127
77
  months?: number;
128
78
  years?: number;
129
79
  }, volume: string) => TTLRule;
130
- /**
131
- * Custom TTL expression
132
- * @example ttl.custom('created_at + INTERVAL 1 YEAR')
133
- */
134
80
  custom: (expression: string) => TTLRule;
135
- /**
136
- * Combine multiple TTL rules (tiered storage)
137
- * @example ttl.tiered(events.timestamp, [
138
- * { days: 7, action: 'toDisk', target: 'cold' },
139
- * { days: 30, action: 'delete' }
140
- * ])
141
- */
142
81
  tiered: (column: ClickHouseColumn, tiers: Array<{
143
82
  days?: number;
144
83
  hours?: number;