@housekit/orm 0.1.17 → 0.1.21
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 +21 -12
- package/dist/builders/delete.d.ts +2 -2
- package/dist/builders/insert.d.ts +13 -6
- package/dist/builders/select.d.ts +10 -7
- package/dist/builders/update.d.ts +2 -2
- package/dist/client.d.ts +7 -12
- package/dist/index.d.ts +32 -3
- package/dist/index.js +420 -261
- package/dist/relational.d.ts +35 -3
- package/dist/relations.d.ts +7 -4
- package/dist/schema-builder.d.ts +36 -6
- package/dist/table.d.ts +38 -9
- package/dist/utils/background-batcher.d.ts +2 -2
- package/dist/utils/insert-processing.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -192,8 +192,8 @@ class BinaryReader {
|
|
|
192
192
|
return new Date(Number(ms));
|
|
193
193
|
}
|
|
194
194
|
readNullable(reader) {
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
195
|
+
const isNull2 = this.readUInt8();
|
|
196
|
+
if (isNull2 === 1)
|
|
197
197
|
return null;
|
|
198
198
|
return reader();
|
|
199
199
|
}
|
|
@@ -2157,6 +2157,144 @@ function generateRandom(structure, randomSeed, maxStringLength = 10, maxArrayLen
|
|
|
2157
2157
|
};
|
|
2158
2158
|
}
|
|
2159
2159
|
|
|
2160
|
+
// src/modules/conditional.ts
|
|
2161
|
+
function ifNull(col, alt) {
|
|
2162
|
+
return sql`ifNull(${col}, ${alt})`;
|
|
2163
|
+
}
|
|
2164
|
+
function sqlIf(condition, trueVal, falseVal) {
|
|
2165
|
+
return sql`if(${condition}, ${trueVal}, ${falseVal})`;
|
|
2166
|
+
}
|
|
2167
|
+
function multiIf(...args) {
|
|
2168
|
+
if (args.length < 3) {
|
|
2169
|
+
throw new Error("multiIf requires at least 3 arguments: condition, value, default");
|
|
2170
|
+
}
|
|
2171
|
+
if (args.length % 2 === 0) {
|
|
2172
|
+
throw new Error("multiIf requires an odd number of arguments: condition-value pairs plus a default value");
|
|
2173
|
+
}
|
|
2174
|
+
const params = args.map((arg) => sql`${arg}`).join(", ");
|
|
2175
|
+
return sql`multiIf(${params})`;
|
|
2176
|
+
}
|
|
2177
|
+
function caseWhen() {
|
|
2178
|
+
return new CaseWhenBuilder;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
class CaseWhenBuilder {
|
|
2182
|
+
conditions = [];
|
|
2183
|
+
values = [];
|
|
2184
|
+
defaultValue;
|
|
2185
|
+
when(condition, value) {
|
|
2186
|
+
this.conditions.push(condition);
|
|
2187
|
+
this.values.push(value);
|
|
2188
|
+
return this;
|
|
2189
|
+
}
|
|
2190
|
+
otherwise(value) {
|
|
2191
|
+
this.defaultValue = value;
|
|
2192
|
+
return this.build();
|
|
2193
|
+
}
|
|
2194
|
+
build() {
|
|
2195
|
+
if (!this.defaultValue) {
|
|
2196
|
+
throw new Error("CaseWhenBuilder requires a default value via .otherwise()");
|
|
2197
|
+
}
|
|
2198
|
+
const args = [];
|
|
2199
|
+
for (let i = 0;i < this.conditions.length; i++) {
|
|
2200
|
+
args.push(this.conditions[i]);
|
|
2201
|
+
args.push(this.values[i]);
|
|
2202
|
+
}
|
|
2203
|
+
args.push(this.defaultValue);
|
|
2204
|
+
return multiIf(...args);
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
function coalesce(...args) {
|
|
2208
|
+
const chunks = ["coalesce("];
|
|
2209
|
+
const params = [];
|
|
2210
|
+
args.forEach((arg, i) => {
|
|
2211
|
+
params.push(arg);
|
|
2212
|
+
if (i < args.length - 1) {
|
|
2213
|
+
chunks.push(", ");
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
chunks.push(")");
|
|
2217
|
+
return new SQL(chunks, params);
|
|
2218
|
+
}
|
|
2219
|
+
function greatest(...args) {
|
|
2220
|
+
const chunks = ["greatest("];
|
|
2221
|
+
const params = [];
|
|
2222
|
+
args.forEach((arg, i) => {
|
|
2223
|
+
params.push(arg);
|
|
2224
|
+
if (i < args.length - 1) {
|
|
2225
|
+
chunks.push(", ");
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
chunks.push(")");
|
|
2229
|
+
return new SQL(chunks, params);
|
|
2230
|
+
}
|
|
2231
|
+
function least(...args) {
|
|
2232
|
+
const chunks = ["least("];
|
|
2233
|
+
const params = [];
|
|
2234
|
+
args.forEach((arg, i) => {
|
|
2235
|
+
params.push(arg);
|
|
2236
|
+
if (i < args.length - 1) {
|
|
2237
|
+
chunks.push(", ");
|
|
2238
|
+
}
|
|
2239
|
+
});
|
|
2240
|
+
chunks.push(")");
|
|
2241
|
+
return new SQL(chunks, params);
|
|
2242
|
+
}
|
|
2243
|
+
function isNull(col) {
|
|
2244
|
+
return sql`${col} IS NULL`;
|
|
2245
|
+
}
|
|
2246
|
+
function isNotNull(col) {
|
|
2247
|
+
return sql`${col} IS NOT NULL`;
|
|
2248
|
+
}
|
|
2249
|
+
function nullIf(condition, col) {
|
|
2250
|
+
return sql`nullIf(${col}, ${condition})`;
|
|
2251
|
+
}
|
|
2252
|
+
function nullIfEqual(col, value) {
|
|
2253
|
+
return sql`nullIf(${col}, ${value})`;
|
|
2254
|
+
}
|
|
2255
|
+
function not(expr) {
|
|
2256
|
+
return sql`NOT (${expr})`;
|
|
2257
|
+
}
|
|
2258
|
+
function and(...exprs) {
|
|
2259
|
+
const filtered = exprs.filter((e) => !!e);
|
|
2260
|
+
if (filtered.length === 0)
|
|
2261
|
+
return;
|
|
2262
|
+
if (filtered.length === 1)
|
|
2263
|
+
return filtered[0];
|
|
2264
|
+
const finalChunks = ["("];
|
|
2265
|
+
const finalParams = [];
|
|
2266
|
+
filtered.forEach((e, i) => {
|
|
2267
|
+
finalParams.push(e);
|
|
2268
|
+
if (i < filtered.length - 1) {
|
|
2269
|
+
finalChunks.push(") AND (");
|
|
2270
|
+
} else {
|
|
2271
|
+
finalChunks.push(")");
|
|
2272
|
+
}
|
|
2273
|
+
});
|
|
2274
|
+
return new SQL(finalChunks, finalParams);
|
|
2275
|
+
}
|
|
2276
|
+
function or(...exprs) {
|
|
2277
|
+
const filtered = exprs.filter((e) => !!e);
|
|
2278
|
+
if (filtered.length === 0)
|
|
2279
|
+
return;
|
|
2280
|
+
if (filtered.length === 1)
|
|
2281
|
+
return filtered[0];
|
|
2282
|
+
const finalChunks = ["("];
|
|
2283
|
+
const finalParams = [];
|
|
2284
|
+
filtered.forEach((e, i) => {
|
|
2285
|
+
finalParams.push(e);
|
|
2286
|
+
if (i < filtered.length - 1) {
|
|
2287
|
+
finalChunks.push(") OR (");
|
|
2288
|
+
} else {
|
|
2289
|
+
finalChunks.push(")");
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2292
|
+
return new SQL(finalChunks, finalParams);
|
|
2293
|
+
}
|
|
2294
|
+
function xor(expr1, expr2) {
|
|
2295
|
+
return sql`xor(${expr1}, ${expr2})`;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2160
2298
|
// src/utils/lru-cache.ts
|
|
2161
2299
|
class LRUCache {
|
|
2162
2300
|
map = new Map;
|
|
@@ -2731,6 +2869,7 @@ class QueryCompiler {
|
|
|
2731
2869
|
class ClickHouseQueryBuilder {
|
|
2732
2870
|
client;
|
|
2733
2871
|
_select = null;
|
|
2872
|
+
_selectResolver = null;
|
|
2734
2873
|
_table = null;
|
|
2735
2874
|
_prewhere = null;
|
|
2736
2875
|
_sample = null;
|
|
@@ -2753,7 +2892,17 @@ class ClickHouseQueryBuilder {
|
|
|
2753
2892
|
}
|
|
2754
2893
|
select(fields) {
|
|
2755
2894
|
if (fields) {
|
|
2895
|
+
if (typeof fields === "function") {
|
|
2896
|
+
if (!this._table) {
|
|
2897
|
+
this._selectResolver = fields;
|
|
2898
|
+
return this;
|
|
2899
|
+
}
|
|
2900
|
+
this._select = fields(this._table.$columns);
|
|
2901
|
+
this._selectResolver = null;
|
|
2902
|
+
return this;
|
|
2903
|
+
}
|
|
2756
2904
|
this._select = fields;
|
|
2905
|
+
this._selectResolver = null;
|
|
2757
2906
|
return this;
|
|
2758
2907
|
}
|
|
2759
2908
|
return this;
|
|
@@ -2767,16 +2916,48 @@ class ClickHouseQueryBuilder {
|
|
|
2767
2916
|
if (defaultFinal !== undefined) {
|
|
2768
2917
|
this._final = Boolean(defaultFinal);
|
|
2769
2918
|
}
|
|
2919
|
+
this.resolveSelect();
|
|
2770
2920
|
return this;
|
|
2771
2921
|
}
|
|
2772
2922
|
fromSubquery(subquery, alias) {
|
|
2773
2923
|
this._table = this.createSubqueryTable(alias, subquery);
|
|
2774
2924
|
this._final = false;
|
|
2925
|
+
this.resolveSelect();
|
|
2775
2926
|
return this;
|
|
2776
2927
|
}
|
|
2928
|
+
resolveSelect() {
|
|
2929
|
+
if (!this._selectResolver)
|
|
2930
|
+
return;
|
|
2931
|
+
if (!this._table) {
|
|
2932
|
+
throw new Error("Call .from() before using callback select");
|
|
2933
|
+
}
|
|
2934
|
+
this._select = this._selectResolver(this._table.$columns);
|
|
2935
|
+
this._selectResolver = null;
|
|
2936
|
+
}
|
|
2777
2937
|
where(expression) {
|
|
2778
|
-
if (expression)
|
|
2938
|
+
if (!expression)
|
|
2939
|
+
return this;
|
|
2940
|
+
if (typeof expression === "object" && "toSQL" in expression) {
|
|
2779
2941
|
this._where = expression;
|
|
2942
|
+
return this;
|
|
2943
|
+
}
|
|
2944
|
+
if (typeof expression === "object") {
|
|
2945
|
+
const table = this._table;
|
|
2946
|
+
if (!table)
|
|
2947
|
+
return this;
|
|
2948
|
+
const chunks = [];
|
|
2949
|
+
const columns = table.$columns || table;
|
|
2950
|
+
for (const [key, value] of Object.entries(expression)) {
|
|
2951
|
+
const column = table[key] || columns?.[key];
|
|
2952
|
+
if (column) {
|
|
2953
|
+
chunks.push(eq(column, value));
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
if (chunks.length > 0) {
|
|
2957
|
+
const combined = chunks.length === 1 ? chunks[0] : and(...chunks);
|
|
2958
|
+
if (combined)
|
|
2959
|
+
this._where = combined;
|
|
2960
|
+
}
|
|
2780
2961
|
}
|
|
2781
2962
|
return this;
|
|
2782
2963
|
}
|
|
@@ -3012,6 +3193,7 @@ class ClickHouseQueryBuilder {
|
|
|
3012
3193
|
return buildTable(alias);
|
|
3013
3194
|
}
|
|
3014
3195
|
getState() {
|
|
3196
|
+
this.resolveSelect();
|
|
3015
3197
|
return {
|
|
3016
3198
|
select: this._select,
|
|
3017
3199
|
table: this._table,
|
|
@@ -3728,8 +3910,8 @@ class BinaryWriter {
|
|
|
3728
3910
|
const ticks = typeof value === "number" ? BigInt(Math.round(value * multiplier)) : BigInt(Math.round(value.getTime() * multiplier / 1000));
|
|
3729
3911
|
this.writeInt64(ticks);
|
|
3730
3912
|
}
|
|
3731
|
-
writeNullable(
|
|
3732
|
-
this.writeUInt8(
|
|
3913
|
+
writeNullable(isNull2) {
|
|
3914
|
+
this.writeUInt8(isNull2 ? 1 : 0);
|
|
3733
3915
|
}
|
|
3734
3916
|
writeArrayLength(length) {
|
|
3735
3917
|
this.writeUInt64(length);
|
|
@@ -4329,7 +4511,7 @@ var globalBatcher = (client) => {
|
|
|
4329
4511
|
};
|
|
4330
4512
|
|
|
4331
4513
|
// src/builders/insert.ts
|
|
4332
|
-
import { v4 as uuidv42, v7 as uuidv7 } from "uuid";
|
|
4514
|
+
import { v1 as uuidv1, v4 as uuidv42, v6 as uuidv6, v7 as uuidv7 } from "uuid";
|
|
4333
4515
|
|
|
4334
4516
|
class BinaryTransform extends Transform2 {
|
|
4335
4517
|
serializer;
|
|
@@ -4379,6 +4561,7 @@ class ClickHouseInsertBuilder {
|
|
|
4379
4561
|
_batchSize = 1000;
|
|
4380
4562
|
_batchConfig = null;
|
|
4381
4563
|
_forceJson = false;
|
|
4564
|
+
_returning = false;
|
|
4382
4565
|
constructor(client, table) {
|
|
4383
4566
|
this.client = client;
|
|
4384
4567
|
this.table = table;
|
|
@@ -4394,6 +4577,13 @@ class ClickHouseInsertBuilder {
|
|
|
4394
4577
|
this._values = value;
|
|
4395
4578
|
return this;
|
|
4396
4579
|
}
|
|
4580
|
+
async insert(data) {
|
|
4581
|
+
return this.values(data);
|
|
4582
|
+
}
|
|
4583
|
+
returning() {
|
|
4584
|
+
this._returning = true;
|
|
4585
|
+
return this;
|
|
4586
|
+
}
|
|
4397
4587
|
syncInsert() {
|
|
4398
4588
|
this._async = false;
|
|
4399
4589
|
return this;
|
|
@@ -4459,6 +4649,23 @@ class ClickHouseInsertBuilder {
|
|
|
4459
4649
|
throw new Error("❌ No values to insert");
|
|
4460
4650
|
}
|
|
4461
4651
|
const plan = buildInsertPlan(this.table);
|
|
4652
|
+
if (this._returning) {
|
|
4653
|
+
if (this._batchConfig) {
|
|
4654
|
+
throw new Error("❌ returning() cannot be used with background batching");
|
|
4655
|
+
}
|
|
4656
|
+
const { processedRows, resultRows } = await this.collectReturningRows(plan);
|
|
4657
|
+
const stream = Readable.from(processedRows, { objectMode: true });
|
|
4658
|
+
await this.client.insert({
|
|
4659
|
+
table: this.table.$table,
|
|
4660
|
+
values: stream,
|
|
4661
|
+
format: "JSONEachRow",
|
|
4662
|
+
clickhouse_settings: {
|
|
4663
|
+
async_insert: this._async ? 1 : 0,
|
|
4664
|
+
wait_for_async_insert: this._waitForAsync ? 1 : 0
|
|
4665
|
+
}
|
|
4666
|
+
});
|
|
4667
|
+
return resultRows;
|
|
4668
|
+
}
|
|
4462
4669
|
if (this._batchConfig && !this._forceJson) {
|
|
4463
4670
|
const batcher = globalBatcher(this.client);
|
|
4464
4671
|
const rowIterator = this.processRows(plan);
|
|
@@ -4474,6 +4681,7 @@ class ClickHouseInsertBuilder {
|
|
|
4474
4681
|
} else {
|
|
4475
4682
|
await this.executeJsonInsert(plan, tableName, format);
|
|
4476
4683
|
}
|
|
4684
|
+
return;
|
|
4477
4685
|
}
|
|
4478
4686
|
resolveFormat(plan) {
|
|
4479
4687
|
if (this._format !== "auto") {
|
|
@@ -4566,13 +4774,73 @@ class ClickHouseInsertBuilder {
|
|
|
4566
4774
|
yield processedRow;
|
|
4567
4775
|
}
|
|
4568
4776
|
}
|
|
4777
|
+
async collectReturningRows(plan) {
|
|
4778
|
+
const processedRows = [];
|
|
4779
|
+
const resultRows = [];
|
|
4780
|
+
const values2 = this._values;
|
|
4781
|
+
const iterable = values2 instanceof Readable ? values2 : Array.isArray(values2) ? values2 : isIterable(values2) ? values2 : isAsyncIterable(values2) ? values2 : [values2];
|
|
4782
|
+
for await (const row of iterable) {
|
|
4783
|
+
const processed = processRowWithPlan(row, plan, "json");
|
|
4784
|
+
for (const col of plan.columns) {
|
|
4785
|
+
if (processed[col.columnName] !== undefined)
|
|
4786
|
+
continue;
|
|
4787
|
+
const expr = col.column.meta?.defaultExpr;
|
|
4788
|
+
if (!expr)
|
|
4789
|
+
continue;
|
|
4790
|
+
const resolved = this.resolveClientDefaultExpr(expr);
|
|
4791
|
+
if (resolved !== undefined) {
|
|
4792
|
+
processed[col.columnName] = col.transform(resolved);
|
|
4793
|
+
}
|
|
4794
|
+
}
|
|
4795
|
+
this.assertReturningRow(row, processed, plan);
|
|
4796
|
+
processedRows.push(processed);
|
|
4797
|
+
const resultRow = {};
|
|
4798
|
+
for (const col of plan.columns) {
|
|
4799
|
+
const value = processed[col.columnName];
|
|
4800
|
+
resultRow[col.propKey] = value;
|
|
4801
|
+
}
|
|
4802
|
+
resultRows.push(resultRow);
|
|
4803
|
+
}
|
|
4804
|
+
return { processedRows, resultRows };
|
|
4805
|
+
}
|
|
4806
|
+
assertReturningRow(rawRow, processed, plan) {
|
|
4807
|
+
for (const col of plan.columns) {
|
|
4808
|
+
const hasValue = rawRow[col.propKey] !== undefined || rawRow[col.columnName] !== undefined;
|
|
4809
|
+
if (hasValue)
|
|
4810
|
+
continue;
|
|
4811
|
+
if (processed[col.columnName] !== undefined) {
|
|
4812
|
+
continue;
|
|
4813
|
+
}
|
|
4814
|
+
if (col.defaultFn || col.autoUUIDVersion !== null && !col.useServerUUID || col.hasDefault) {
|
|
4815
|
+
continue;
|
|
4816
|
+
}
|
|
4817
|
+
if (col.useServerUUID || col.column.meta?.defaultExpr) {
|
|
4818
|
+
throw new Error(`❌ returning() cannot infer column '${col.columnName}' because it uses a server-side default. Provide a value or remove the default expression.`);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
resolveClientDefaultExpr(expr) {
|
|
4823
|
+
const normalized = expr.replace(/\s+/g, "").toLowerCase();
|
|
4824
|
+
if (normalized === "now()" || normalized === "now64()" || normalized.startsWith("now64(")) {
|
|
4825
|
+
return new Date;
|
|
4826
|
+
}
|
|
4827
|
+
if (normalized === "generateuuidv4()")
|
|
4828
|
+
return uuidv42();
|
|
4829
|
+
if (normalized === "generateuuidv7()")
|
|
4830
|
+
return uuidv7();
|
|
4831
|
+
if (normalized === "generateuuidv1()")
|
|
4832
|
+
return uuidv1();
|
|
4833
|
+
if (normalized === "generateuuidv6()")
|
|
4834
|
+
return uuidv6();
|
|
4835
|
+
return;
|
|
4836
|
+
}
|
|
4569
4837
|
async then(onfulfilled, onrejected) {
|
|
4570
4838
|
try {
|
|
4571
|
-
await this.execute();
|
|
4839
|
+
const result = await this.execute();
|
|
4572
4840
|
if (onfulfilled) {
|
|
4573
|
-
return Promise.resolve(onfulfilled());
|
|
4841
|
+
return Promise.resolve(onfulfilled(result));
|
|
4574
4842
|
}
|
|
4575
|
-
return Promise.resolve();
|
|
4843
|
+
return Promise.resolve(result);
|
|
4576
4844
|
} catch (error) {
|
|
4577
4845
|
if (onrejected) {
|
|
4578
4846
|
return Promise.resolve(onrejected(error));
|
|
@@ -4833,159 +5101,21 @@ function wrapClientWithLogger(client, logger) {
|
|
|
4833
5101
|
return wrapped;
|
|
4834
5102
|
}
|
|
4835
5103
|
|
|
4836
|
-
// src/
|
|
4837
|
-
function
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
if (
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
if (args.length % 2 === 0) {
|
|
4848
|
-
throw new Error("multiIf requires an odd number of arguments: condition-value pairs plus a default value");
|
|
4849
|
-
}
|
|
4850
|
-
const params = args.map((arg) => sql`${arg}`).join(", ");
|
|
4851
|
-
return sql`multiIf(${params})`;
|
|
4852
|
-
}
|
|
4853
|
-
function caseWhen() {
|
|
4854
|
-
return new CaseWhenBuilder;
|
|
5104
|
+
// src/relational.ts
|
|
5105
|
+
function buildJoinCondition(fields, references) {
|
|
5106
|
+
if (!fields || !references || fields.length === 0 || references.length === 0)
|
|
5107
|
+
return null;
|
|
5108
|
+
const pairs = fields.map((f, i) => sql`${f} = ${references[i]}`);
|
|
5109
|
+
const filtered = pairs.filter((p) => Boolean(p));
|
|
5110
|
+
if (filtered.length === 0)
|
|
5111
|
+
return null;
|
|
5112
|
+
if (filtered.length === 1)
|
|
5113
|
+
return filtered[0];
|
|
5114
|
+
return and(...filtered) || null;
|
|
4855
5115
|
}
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
values = [];
|
|
4860
|
-
defaultValue;
|
|
4861
|
-
when(condition, value) {
|
|
4862
|
-
this.conditions.push(condition);
|
|
4863
|
-
this.values.push(value);
|
|
4864
|
-
return this;
|
|
4865
|
-
}
|
|
4866
|
-
otherwise(value) {
|
|
4867
|
-
this.defaultValue = value;
|
|
4868
|
-
return this.build();
|
|
4869
|
-
}
|
|
4870
|
-
build() {
|
|
4871
|
-
if (!this.defaultValue) {
|
|
4872
|
-
throw new Error("CaseWhenBuilder requires a default value via .otherwise()");
|
|
4873
|
-
}
|
|
4874
|
-
const args = [];
|
|
4875
|
-
for (let i = 0;i < this.conditions.length; i++) {
|
|
4876
|
-
args.push(this.conditions[i]);
|
|
4877
|
-
args.push(this.values[i]);
|
|
4878
|
-
}
|
|
4879
|
-
args.push(this.defaultValue);
|
|
4880
|
-
return multiIf(...args);
|
|
4881
|
-
}
|
|
4882
|
-
}
|
|
4883
|
-
function coalesce(...args) {
|
|
4884
|
-
const chunks = ["coalesce("];
|
|
4885
|
-
const params = [];
|
|
4886
|
-
args.forEach((arg, i) => {
|
|
4887
|
-
params.push(arg);
|
|
4888
|
-
if (i < args.length - 1) {
|
|
4889
|
-
chunks.push(", ");
|
|
4890
|
-
}
|
|
4891
|
-
});
|
|
4892
|
-
chunks.push(")");
|
|
4893
|
-
return new SQL(chunks, params);
|
|
4894
|
-
}
|
|
4895
|
-
function greatest(...args) {
|
|
4896
|
-
const chunks = ["greatest("];
|
|
4897
|
-
const params = [];
|
|
4898
|
-
args.forEach((arg, i) => {
|
|
4899
|
-
params.push(arg);
|
|
4900
|
-
if (i < args.length - 1) {
|
|
4901
|
-
chunks.push(", ");
|
|
4902
|
-
}
|
|
4903
|
-
});
|
|
4904
|
-
chunks.push(")");
|
|
4905
|
-
return new SQL(chunks, params);
|
|
4906
|
-
}
|
|
4907
|
-
function least(...args) {
|
|
4908
|
-
const chunks = ["least("];
|
|
4909
|
-
const params = [];
|
|
4910
|
-
args.forEach((arg, i) => {
|
|
4911
|
-
params.push(arg);
|
|
4912
|
-
if (i < args.length - 1) {
|
|
4913
|
-
chunks.push(", ");
|
|
4914
|
-
}
|
|
4915
|
-
});
|
|
4916
|
-
chunks.push(")");
|
|
4917
|
-
return new SQL(chunks, params);
|
|
4918
|
-
}
|
|
4919
|
-
function isNull(col) {
|
|
4920
|
-
return sql`${col} IS NULL`;
|
|
4921
|
-
}
|
|
4922
|
-
function isNotNull(col) {
|
|
4923
|
-
return sql`${col} IS NOT NULL`;
|
|
4924
|
-
}
|
|
4925
|
-
function nullIf(condition, col) {
|
|
4926
|
-
return sql`nullIf(${col}, ${condition})`;
|
|
4927
|
-
}
|
|
4928
|
-
function nullIfEqual(col, value) {
|
|
4929
|
-
return sql`nullIf(${col}, ${value})`;
|
|
4930
|
-
}
|
|
4931
|
-
function not(expr) {
|
|
4932
|
-
return sql`NOT (${expr})`;
|
|
4933
|
-
}
|
|
4934
|
-
function and(...exprs) {
|
|
4935
|
-
const filtered = exprs.filter((e) => !!e);
|
|
4936
|
-
if (filtered.length === 0)
|
|
4937
|
-
return;
|
|
4938
|
-
if (filtered.length === 1)
|
|
4939
|
-
return filtered[0];
|
|
4940
|
-
const finalChunks = ["("];
|
|
4941
|
-
const finalParams = [];
|
|
4942
|
-
filtered.forEach((e, i) => {
|
|
4943
|
-
finalParams.push(e);
|
|
4944
|
-
if (i < filtered.length - 1) {
|
|
4945
|
-
finalChunks.push(") AND (");
|
|
4946
|
-
} else {
|
|
4947
|
-
finalChunks.push(")");
|
|
4948
|
-
}
|
|
4949
|
-
});
|
|
4950
|
-
return new SQL(finalChunks, finalParams);
|
|
4951
|
-
}
|
|
4952
|
-
function or(...exprs) {
|
|
4953
|
-
const filtered = exprs.filter((e) => !!e);
|
|
4954
|
-
if (filtered.length === 0)
|
|
4955
|
-
return;
|
|
4956
|
-
if (filtered.length === 1)
|
|
4957
|
-
return filtered[0];
|
|
4958
|
-
const finalChunks = ["("];
|
|
4959
|
-
const finalParams = [];
|
|
4960
|
-
filtered.forEach((e, i) => {
|
|
4961
|
-
finalParams.push(e);
|
|
4962
|
-
if (i < filtered.length - 1) {
|
|
4963
|
-
finalChunks.push(") OR (");
|
|
4964
|
-
} else {
|
|
4965
|
-
finalChunks.push(")");
|
|
4966
|
-
}
|
|
4967
|
-
});
|
|
4968
|
-
return new SQL(finalChunks, finalParams);
|
|
4969
|
-
}
|
|
4970
|
-
function xor(expr1, expr2) {
|
|
4971
|
-
return sql`xor(${expr1}, ${expr2})`;
|
|
4972
|
-
}
|
|
4973
|
-
|
|
4974
|
-
// src/relational.ts
|
|
4975
|
-
function buildJoinCondition(fields, references) {
|
|
4976
|
-
if (!fields || !references || fields.length === 0 || references.length === 0)
|
|
4977
|
-
return null;
|
|
4978
|
-
const pairs = fields.map((f, i) => sql`${f} = ${references[i]}`);
|
|
4979
|
-
const filtered = pairs.filter((p) => Boolean(p));
|
|
4980
|
-
if (filtered.length === 0)
|
|
4981
|
-
return null;
|
|
4982
|
-
if (filtered.length === 1)
|
|
4983
|
-
return filtered[0];
|
|
4984
|
-
return and(...filtered) || null;
|
|
4985
|
-
}
|
|
4986
|
-
function isDistributedTable(tableDef) {
|
|
4987
|
-
const options = tableDef.$options;
|
|
4988
|
-
return !!(options?.onCluster || options?.shardKey);
|
|
5116
|
+
function isDistributedTable(tableDef) {
|
|
5117
|
+
const options = tableDef.$options;
|
|
5118
|
+
return !!(options?.onCluster || options?.shardKey);
|
|
4989
5119
|
}
|
|
4990
5120
|
function buildRelationalAPI(client, schema) {
|
|
4991
5121
|
if (!schema)
|
|
@@ -5207,7 +5337,7 @@ function createHousekitClient(config) {
|
|
|
5207
5337
|
const builder = new ClickHouseQueryBuilder(client);
|
|
5208
5338
|
if (!fieldsOrTable)
|
|
5209
5339
|
return builder.select();
|
|
5210
|
-
if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable
|
|
5340
|
+
if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable) {
|
|
5211
5341
|
return builder.select().from(fieldsOrTable);
|
|
5212
5342
|
}
|
|
5213
5343
|
return builder.select(fieldsOrTable);
|
|
@@ -5260,6 +5390,105 @@ function createHousekitClient(config) {
|
|
|
5260
5390
|
return baseClient;
|
|
5261
5391
|
}
|
|
5262
5392
|
var createClientFromConfigObject = createHousekitClient;
|
|
5393
|
+
|
|
5394
|
+
// src/codegen/zod.ts
|
|
5395
|
+
import { z } from "zod";
|
|
5396
|
+
function mapClickHouseTypeToZod(column) {
|
|
5397
|
+
const type = column.type.toLowerCase();
|
|
5398
|
+
let zodType;
|
|
5399
|
+
if (type.startsWith("nullable(")) {
|
|
5400
|
+
const innerType = column.type.slice("nullable(".length, -1);
|
|
5401
|
+
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
5402
|
+
zodType = mapClickHouseTypeToZod(innerColumn).nullable();
|
|
5403
|
+
} else if (type.startsWith("array(")) {
|
|
5404
|
+
const innerType = column.type.slice("array(".length, -1);
|
|
5405
|
+
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
5406
|
+
zodType = z.array(mapClickHouseTypeToZod(innerColumn));
|
|
5407
|
+
} else if (type.startsWith("fixedstring")) {
|
|
5408
|
+
zodType = z.string();
|
|
5409
|
+
} else if (type.startsWith("enum")) {
|
|
5410
|
+
if (column.meta?.enumValues) {
|
|
5411
|
+
zodType = z.enum(column.meta.enumValues);
|
|
5412
|
+
} else {
|
|
5413
|
+
zodType = z.string();
|
|
5414
|
+
}
|
|
5415
|
+
} else if (type.startsWith("datetime64")) {
|
|
5416
|
+
zodType = z.date();
|
|
5417
|
+
} else if (type.startsWith("decimal")) {
|
|
5418
|
+
zodType = z.string().refine((val) => !isNaN(parseFloat(val)), {
|
|
5419
|
+
message: "Must be a valid decimal number string"
|
|
5420
|
+
});
|
|
5421
|
+
} else {
|
|
5422
|
+
switch (type) {
|
|
5423
|
+
case "uuid":
|
|
5424
|
+
case "string":
|
|
5425
|
+
case "json":
|
|
5426
|
+
case "ipv4":
|
|
5427
|
+
case "ipv6":
|
|
5428
|
+
zodType = z.string();
|
|
5429
|
+
break;
|
|
5430
|
+
case "int8":
|
|
5431
|
+
case "uint8":
|
|
5432
|
+
case "int16":
|
|
5433
|
+
case "uint16":
|
|
5434
|
+
case "int32":
|
|
5435
|
+
case "uint32":
|
|
5436
|
+
case "float32":
|
|
5437
|
+
case "float64":
|
|
5438
|
+
zodType = z.number();
|
|
5439
|
+
break;
|
|
5440
|
+
case "int64":
|
|
5441
|
+
case "uint64":
|
|
5442
|
+
case "int128":
|
|
5443
|
+
case "uint128":
|
|
5444
|
+
case "int256":
|
|
5445
|
+
case "uint256":
|
|
5446
|
+
zodType = z.bigint();
|
|
5447
|
+
break;
|
|
5448
|
+
case "boolean":
|
|
5449
|
+
case "bool":
|
|
5450
|
+
zodType = z.boolean();
|
|
5451
|
+
break;
|
|
5452
|
+
case "date":
|
|
5453
|
+
case "datetime":
|
|
5454
|
+
zodType = z.date();
|
|
5455
|
+
break;
|
|
5456
|
+
default:
|
|
5457
|
+
zodType = z.string();
|
|
5458
|
+
break;
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
if (column.isNull && !type.startsWith("nullable(")) {
|
|
5462
|
+
zodType = zodType.nullable();
|
|
5463
|
+
}
|
|
5464
|
+
return zodType;
|
|
5465
|
+
}
|
|
5466
|
+
function generateSelectSchema(table) {
|
|
5467
|
+
const shape = {};
|
|
5468
|
+
for (const key in table.$columns) {
|
|
5469
|
+
if (Object.prototype.hasOwnProperty.call(table.$columns, key)) {
|
|
5470
|
+
const column = table.$columns[key];
|
|
5471
|
+
shape[key] = mapClickHouseTypeToZod(column);
|
|
5472
|
+
}
|
|
5473
|
+
}
|
|
5474
|
+
return z.object(shape);
|
|
5475
|
+
}
|
|
5476
|
+
function generateInsertSchema(table) {
|
|
5477
|
+
const shape = {};
|
|
5478
|
+
for (const key in table.$columns) {
|
|
5479
|
+
if (Object.prototype.hasOwnProperty.call(table.$columns, key)) {
|
|
5480
|
+
const column = table.$columns[key];
|
|
5481
|
+
let zodType = mapClickHouseTypeToZod(column);
|
|
5482
|
+
const isOptionalBySchema = !column.isNull && (column.meta?.default !== undefined || column.meta?.defaultFn !== undefined || column.meta?.defaultExpr !== undefined || column.meta?.autoGenerate !== undefined);
|
|
5483
|
+
const isOptionalByNullable = column.isNull;
|
|
5484
|
+
if (isOptionalBySchema || isOptionalByNullable) {
|
|
5485
|
+
zodType = zodType.optional();
|
|
5486
|
+
} else {}
|
|
5487
|
+
shape[key] = zodType;
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
return z.object(shape);
|
|
5491
|
+
}
|
|
5263
5492
|
// src/modules/array.ts
|
|
5264
5493
|
function arrayJoin(separator, col) {
|
|
5265
5494
|
if (col) {
|
|
@@ -6266,7 +6495,21 @@ var t = {
|
|
|
6266
6495
|
ring: (name) => new ClickHouseColumn(name, "Ring"),
|
|
6267
6496
|
polygon: (name) => new ClickHouseColumn(name, "Polygon"),
|
|
6268
6497
|
multiPolygon: (name) => new ClickHouseColumn(name, "MultiPolygon"),
|
|
6269
|
-
enum: (name, values2) => new ClickHouseColumn(name, "String", true, { enumValues: values2 })
|
|
6498
|
+
enum: (name, values2) => new ClickHouseColumn(name, "String", true, { enumValues: values2 }),
|
|
6499
|
+
timestamps: () => ({
|
|
6500
|
+
created_at: new ClickHouseColumn("created_at", "DateTime").default("now()"),
|
|
6501
|
+
updated_at: new ClickHouseColumn("updated_at", "DateTime").default("now()")
|
|
6502
|
+
}),
|
|
6503
|
+
primaryUuid: (name) => {
|
|
6504
|
+
const colName = name ?? "id";
|
|
6505
|
+
return {
|
|
6506
|
+
[colName]: new ClickHouseColumn(colName, "UUID").autoGenerate().primaryKey().default("generateUUIDv4()")
|
|
6507
|
+
};
|
|
6508
|
+
},
|
|
6509
|
+
softDeletes: () => ({
|
|
6510
|
+
is_deleted: new ClickHouseColumn("is_deleted", "Bool").default(false),
|
|
6511
|
+
deleted_at: new ClickHouseColumn("deleted_at", "DateTime").nullable()
|
|
6512
|
+
})
|
|
6270
6513
|
};
|
|
6271
6514
|
function defineTable(tableName, columnsOrCallback, options) {
|
|
6272
6515
|
const columns = typeof columnsOrCallback === "function" ? columnsOrCallback(t) : columnsOrCallback;
|
|
@@ -6303,104 +6546,6 @@ function relations(table2, relationsBuilder) {
|
|
|
6303
6546
|
table2.$relations = rels;
|
|
6304
6547
|
return rels;
|
|
6305
6548
|
}
|
|
6306
|
-
// src/codegen/zod.ts
|
|
6307
|
-
import { z } from "zod";
|
|
6308
|
-
function mapClickHouseTypeToZod(column) {
|
|
6309
|
-
const type = column.type.toLowerCase();
|
|
6310
|
-
let zodType;
|
|
6311
|
-
if (type.startsWith("nullable(")) {
|
|
6312
|
-
const innerType = column.type.slice("nullable(".length, -1);
|
|
6313
|
-
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
6314
|
-
zodType = mapClickHouseTypeToZod(innerColumn).nullable();
|
|
6315
|
-
} else if (type.startsWith("array(")) {
|
|
6316
|
-
const innerType = column.type.slice("array(".length, -1);
|
|
6317
|
-
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
6318
|
-
zodType = z.array(mapClickHouseTypeToZod(innerColumn));
|
|
6319
|
-
} else if (type.startsWith("fixedstring")) {
|
|
6320
|
-
zodType = z.string();
|
|
6321
|
-
} else if (type.startsWith("enum")) {
|
|
6322
|
-
if (column.meta?.enumValues) {
|
|
6323
|
-
zodType = z.enum(column.meta.enumValues);
|
|
6324
|
-
} else {
|
|
6325
|
-
zodType = z.string();
|
|
6326
|
-
}
|
|
6327
|
-
} else if (type.startsWith("datetime64")) {
|
|
6328
|
-
zodType = z.date();
|
|
6329
|
-
} else if (type.startsWith("decimal")) {
|
|
6330
|
-
zodType = z.string().refine((val) => !isNaN(parseFloat(val)), {
|
|
6331
|
-
message: "Must be a valid decimal number string"
|
|
6332
|
-
});
|
|
6333
|
-
} else {
|
|
6334
|
-
switch (type) {
|
|
6335
|
-
case "uuid":
|
|
6336
|
-
case "string":
|
|
6337
|
-
case "json":
|
|
6338
|
-
case "ipv4":
|
|
6339
|
-
case "ipv6":
|
|
6340
|
-
zodType = z.string();
|
|
6341
|
-
break;
|
|
6342
|
-
case "int8":
|
|
6343
|
-
case "uint8":
|
|
6344
|
-
case "int16":
|
|
6345
|
-
case "uint16":
|
|
6346
|
-
case "int32":
|
|
6347
|
-
case "uint32":
|
|
6348
|
-
case "float32":
|
|
6349
|
-
case "float64":
|
|
6350
|
-
zodType = z.number();
|
|
6351
|
-
break;
|
|
6352
|
-
case "int64":
|
|
6353
|
-
case "uint64":
|
|
6354
|
-
case "int128":
|
|
6355
|
-
case "uint128":
|
|
6356
|
-
case "int256":
|
|
6357
|
-
case "uint256":
|
|
6358
|
-
zodType = z.bigint();
|
|
6359
|
-
break;
|
|
6360
|
-
case "boolean":
|
|
6361
|
-
case "bool":
|
|
6362
|
-
zodType = z.boolean();
|
|
6363
|
-
break;
|
|
6364
|
-
case "date":
|
|
6365
|
-
case "datetime":
|
|
6366
|
-
zodType = z.date();
|
|
6367
|
-
break;
|
|
6368
|
-
default:
|
|
6369
|
-
zodType = z.string();
|
|
6370
|
-
break;
|
|
6371
|
-
}
|
|
6372
|
-
}
|
|
6373
|
-
if (column.isNull && !type.startsWith("nullable(")) {
|
|
6374
|
-
zodType = zodType.nullable();
|
|
6375
|
-
}
|
|
6376
|
-
return zodType;
|
|
6377
|
-
}
|
|
6378
|
-
function generateSelectSchema(table2) {
|
|
6379
|
-
const shape = {};
|
|
6380
|
-
for (const key in table2.$columns) {
|
|
6381
|
-
if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
|
|
6382
|
-
const column = table2.$columns[key];
|
|
6383
|
-
shape[key] = mapClickHouseTypeToZod(column);
|
|
6384
|
-
}
|
|
6385
|
-
}
|
|
6386
|
-
return z.object(shape);
|
|
6387
|
-
}
|
|
6388
|
-
function generateInsertSchema(table2) {
|
|
6389
|
-
const shape = {};
|
|
6390
|
-
for (const key in table2.$columns) {
|
|
6391
|
-
if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
|
|
6392
|
-
const column = table2.$columns[key];
|
|
6393
|
-
let zodType = mapClickHouseTypeToZod(column);
|
|
6394
|
-
const isOptionalBySchema = !column.isNull && (column.meta?.default !== undefined || column.meta?.defaultFn !== undefined || column.meta?.defaultExpr !== undefined || column.meta?.autoGenerate !== undefined);
|
|
6395
|
-
const isOptionalByNullable = column.isNull;
|
|
6396
|
-
if (isOptionalBySchema || isOptionalByNullable) {
|
|
6397
|
-
zodType = zodType.optional();
|
|
6398
|
-
} else {}
|
|
6399
|
-
shape[key] = zodType;
|
|
6400
|
-
}
|
|
6401
|
-
}
|
|
6402
|
-
return z.object(shape);
|
|
6403
|
-
}
|
|
6404
6549
|
// src/index.ts
|
|
6405
6550
|
async function createClientFromConfig(databaseName = "default") {
|
|
6406
6551
|
const config = await loadConfig();
|
|
@@ -6416,6 +6561,18 @@ async function createClientFromConfig(databaseName = "default") {
|
|
|
6416
6561
|
};
|
|
6417
6562
|
return createClientFromConfigObject(clientConfig);
|
|
6418
6563
|
}
|
|
6564
|
+
function housekit(config, options) {
|
|
6565
|
+
return createHousekitClient({
|
|
6566
|
+
...config,
|
|
6567
|
+
schema: options?.schema
|
|
6568
|
+
});
|
|
6569
|
+
}
|
|
6570
|
+
function createSchema(table2) {
|
|
6571
|
+
return {
|
|
6572
|
+
select: generateSelectSchema(table2),
|
|
6573
|
+
insert: generateInsertSchema(table2)
|
|
6574
|
+
};
|
|
6575
|
+
}
|
|
6419
6576
|
async function loadConfig() {
|
|
6420
6577
|
const root = process.cwd();
|
|
6421
6578
|
const extensions = ["ts", "js", "mjs", "cjs"];
|
|
@@ -6725,6 +6882,7 @@ export {
|
|
|
6725
6882
|
htmlEscape,
|
|
6726
6883
|
housekitMetadataSchemas,
|
|
6727
6884
|
housekitMetadataDefaults,
|
|
6885
|
+
housekit,
|
|
6728
6886
|
hdfs,
|
|
6729
6887
|
hasAny,
|
|
6730
6888
|
hasAll,
|
|
@@ -6794,6 +6952,7 @@ export {
|
|
|
6794
6952
|
dateDiff,
|
|
6795
6953
|
dateAdd,
|
|
6796
6954
|
createdAt,
|
|
6955
|
+
createSchema,
|
|
6797
6956
|
createMigrationBridge,
|
|
6798
6957
|
createHousekitClient,
|
|
6799
6958
|
createClients,
|