@housekit/orm 0.1.18 → 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 +19 -6
- package/dist/builders/delete.d.ts +2 -2
- package/dist/builders/insert.d.ts +9 -4
- 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 +417 -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 +31 -20
- 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;
|
|
@@ -4397,6 +4580,10 @@ class ClickHouseInsertBuilder {
|
|
|
4397
4580
|
async insert(data) {
|
|
4398
4581
|
return this.values(data);
|
|
4399
4582
|
}
|
|
4583
|
+
returning() {
|
|
4584
|
+
this._returning = true;
|
|
4585
|
+
return this;
|
|
4586
|
+
}
|
|
4400
4587
|
syncInsert() {
|
|
4401
4588
|
this._async = false;
|
|
4402
4589
|
return this;
|
|
@@ -4462,6 +4649,23 @@ class ClickHouseInsertBuilder {
|
|
|
4462
4649
|
throw new Error("❌ No values to insert");
|
|
4463
4650
|
}
|
|
4464
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
|
+
}
|
|
4465
4669
|
if (this._batchConfig && !this._forceJson) {
|
|
4466
4670
|
const batcher = globalBatcher(this.client);
|
|
4467
4671
|
const rowIterator = this.processRows(plan);
|
|
@@ -4477,6 +4681,7 @@ class ClickHouseInsertBuilder {
|
|
|
4477
4681
|
} else {
|
|
4478
4682
|
await this.executeJsonInsert(plan, tableName, format);
|
|
4479
4683
|
}
|
|
4684
|
+
return;
|
|
4480
4685
|
}
|
|
4481
4686
|
resolveFormat(plan) {
|
|
4482
4687
|
if (this._format !== "auto") {
|
|
@@ -4569,13 +4774,73 @@ class ClickHouseInsertBuilder {
|
|
|
4569
4774
|
yield processedRow;
|
|
4570
4775
|
}
|
|
4571
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
|
+
}
|
|
4572
4837
|
async then(onfulfilled, onrejected) {
|
|
4573
4838
|
try {
|
|
4574
|
-
await this.execute();
|
|
4839
|
+
const result = await this.execute();
|
|
4575
4840
|
if (onfulfilled) {
|
|
4576
|
-
return Promise.resolve(onfulfilled());
|
|
4841
|
+
return Promise.resolve(onfulfilled(result));
|
|
4577
4842
|
}
|
|
4578
|
-
return Promise.resolve();
|
|
4843
|
+
return Promise.resolve(result);
|
|
4579
4844
|
} catch (error) {
|
|
4580
4845
|
if (onrejected) {
|
|
4581
4846
|
return Promise.resolve(onrejected(error));
|
|
@@ -4836,159 +5101,21 @@ function wrapClientWithLogger(client, logger) {
|
|
|
4836
5101
|
return wrapped;
|
|
4837
5102
|
}
|
|
4838
5103
|
|
|
4839
|
-
// src/
|
|
4840
|
-
function
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
if (
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
if (args.length % 2 === 0) {
|
|
4851
|
-
throw new Error("multiIf requires an odd number of arguments: condition-value pairs plus a default value");
|
|
4852
|
-
}
|
|
4853
|
-
const params = args.map((arg) => sql`${arg}`).join(", ");
|
|
4854
|
-
return sql`multiIf(${params})`;
|
|
4855
|
-
}
|
|
4856
|
-
function caseWhen() {
|
|
4857
|
-
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;
|
|
4858
5115
|
}
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
values = [];
|
|
4863
|
-
defaultValue;
|
|
4864
|
-
when(condition, value) {
|
|
4865
|
-
this.conditions.push(condition);
|
|
4866
|
-
this.values.push(value);
|
|
4867
|
-
return this;
|
|
4868
|
-
}
|
|
4869
|
-
otherwise(value) {
|
|
4870
|
-
this.defaultValue = value;
|
|
4871
|
-
return this.build();
|
|
4872
|
-
}
|
|
4873
|
-
build() {
|
|
4874
|
-
if (!this.defaultValue) {
|
|
4875
|
-
throw new Error("CaseWhenBuilder requires a default value via .otherwise()");
|
|
4876
|
-
}
|
|
4877
|
-
const args = [];
|
|
4878
|
-
for (let i = 0;i < this.conditions.length; i++) {
|
|
4879
|
-
args.push(this.conditions[i]);
|
|
4880
|
-
args.push(this.values[i]);
|
|
4881
|
-
}
|
|
4882
|
-
args.push(this.defaultValue);
|
|
4883
|
-
return multiIf(...args);
|
|
4884
|
-
}
|
|
4885
|
-
}
|
|
4886
|
-
function coalesce(...args) {
|
|
4887
|
-
const chunks = ["coalesce("];
|
|
4888
|
-
const params = [];
|
|
4889
|
-
args.forEach((arg, i) => {
|
|
4890
|
-
params.push(arg);
|
|
4891
|
-
if (i < args.length - 1) {
|
|
4892
|
-
chunks.push(", ");
|
|
4893
|
-
}
|
|
4894
|
-
});
|
|
4895
|
-
chunks.push(")");
|
|
4896
|
-
return new SQL(chunks, params);
|
|
4897
|
-
}
|
|
4898
|
-
function greatest(...args) {
|
|
4899
|
-
const chunks = ["greatest("];
|
|
4900
|
-
const params = [];
|
|
4901
|
-
args.forEach((arg, i) => {
|
|
4902
|
-
params.push(arg);
|
|
4903
|
-
if (i < args.length - 1) {
|
|
4904
|
-
chunks.push(", ");
|
|
4905
|
-
}
|
|
4906
|
-
});
|
|
4907
|
-
chunks.push(")");
|
|
4908
|
-
return new SQL(chunks, params);
|
|
4909
|
-
}
|
|
4910
|
-
function least(...args) {
|
|
4911
|
-
const chunks = ["least("];
|
|
4912
|
-
const params = [];
|
|
4913
|
-
args.forEach((arg, i) => {
|
|
4914
|
-
params.push(arg);
|
|
4915
|
-
if (i < args.length - 1) {
|
|
4916
|
-
chunks.push(", ");
|
|
4917
|
-
}
|
|
4918
|
-
});
|
|
4919
|
-
chunks.push(")");
|
|
4920
|
-
return new SQL(chunks, params);
|
|
4921
|
-
}
|
|
4922
|
-
function isNull(col) {
|
|
4923
|
-
return sql`${col} IS NULL`;
|
|
4924
|
-
}
|
|
4925
|
-
function isNotNull(col) {
|
|
4926
|
-
return sql`${col} IS NOT NULL`;
|
|
4927
|
-
}
|
|
4928
|
-
function nullIf(condition, col) {
|
|
4929
|
-
return sql`nullIf(${col}, ${condition})`;
|
|
4930
|
-
}
|
|
4931
|
-
function nullIfEqual(col, value) {
|
|
4932
|
-
return sql`nullIf(${col}, ${value})`;
|
|
4933
|
-
}
|
|
4934
|
-
function not(expr) {
|
|
4935
|
-
return sql`NOT (${expr})`;
|
|
4936
|
-
}
|
|
4937
|
-
function and(...exprs) {
|
|
4938
|
-
const filtered = exprs.filter((e) => !!e);
|
|
4939
|
-
if (filtered.length === 0)
|
|
4940
|
-
return;
|
|
4941
|
-
if (filtered.length === 1)
|
|
4942
|
-
return filtered[0];
|
|
4943
|
-
const finalChunks = ["("];
|
|
4944
|
-
const finalParams = [];
|
|
4945
|
-
filtered.forEach((e, i) => {
|
|
4946
|
-
finalParams.push(e);
|
|
4947
|
-
if (i < filtered.length - 1) {
|
|
4948
|
-
finalChunks.push(") AND (");
|
|
4949
|
-
} else {
|
|
4950
|
-
finalChunks.push(")");
|
|
4951
|
-
}
|
|
4952
|
-
});
|
|
4953
|
-
return new SQL(finalChunks, finalParams);
|
|
4954
|
-
}
|
|
4955
|
-
function or(...exprs) {
|
|
4956
|
-
const filtered = exprs.filter((e) => !!e);
|
|
4957
|
-
if (filtered.length === 0)
|
|
4958
|
-
return;
|
|
4959
|
-
if (filtered.length === 1)
|
|
4960
|
-
return filtered[0];
|
|
4961
|
-
const finalChunks = ["("];
|
|
4962
|
-
const finalParams = [];
|
|
4963
|
-
filtered.forEach((e, i) => {
|
|
4964
|
-
finalParams.push(e);
|
|
4965
|
-
if (i < filtered.length - 1) {
|
|
4966
|
-
finalChunks.push(") OR (");
|
|
4967
|
-
} else {
|
|
4968
|
-
finalChunks.push(")");
|
|
4969
|
-
}
|
|
4970
|
-
});
|
|
4971
|
-
return new SQL(finalChunks, finalParams);
|
|
4972
|
-
}
|
|
4973
|
-
function xor(expr1, expr2) {
|
|
4974
|
-
return sql`xor(${expr1}, ${expr2})`;
|
|
4975
|
-
}
|
|
4976
|
-
|
|
4977
|
-
// src/relational.ts
|
|
4978
|
-
function buildJoinCondition(fields, references) {
|
|
4979
|
-
if (!fields || !references || fields.length === 0 || references.length === 0)
|
|
4980
|
-
return null;
|
|
4981
|
-
const pairs = fields.map((f, i) => sql`${f} = ${references[i]}`);
|
|
4982
|
-
const filtered = pairs.filter((p) => Boolean(p));
|
|
4983
|
-
if (filtered.length === 0)
|
|
4984
|
-
return null;
|
|
4985
|
-
if (filtered.length === 1)
|
|
4986
|
-
return filtered[0];
|
|
4987
|
-
return and(...filtered) || null;
|
|
4988
|
-
}
|
|
4989
|
-
function isDistributedTable(tableDef) {
|
|
4990
|
-
const options = tableDef.$options;
|
|
4991
|
-
return !!(options?.onCluster || options?.shardKey);
|
|
5116
|
+
function isDistributedTable(tableDef) {
|
|
5117
|
+
const options = tableDef.$options;
|
|
5118
|
+
return !!(options?.onCluster || options?.shardKey);
|
|
4992
5119
|
}
|
|
4993
5120
|
function buildRelationalAPI(client, schema) {
|
|
4994
5121
|
if (!schema)
|
|
@@ -5210,7 +5337,7 @@ function createHousekitClient(config) {
|
|
|
5210
5337
|
const builder = new ClickHouseQueryBuilder(client);
|
|
5211
5338
|
if (!fieldsOrTable)
|
|
5212
5339
|
return builder.select();
|
|
5213
|
-
if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable
|
|
5340
|
+
if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable) {
|
|
5214
5341
|
return builder.select().from(fieldsOrTable);
|
|
5215
5342
|
}
|
|
5216
5343
|
return builder.select(fieldsOrTable);
|
|
@@ -5263,6 +5390,105 @@ function createHousekitClient(config) {
|
|
|
5263
5390
|
return baseClient;
|
|
5264
5391
|
}
|
|
5265
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
|
+
}
|
|
5266
5492
|
// src/modules/array.ts
|
|
5267
5493
|
function arrayJoin(separator, col) {
|
|
5268
5494
|
if (col) {
|
|
@@ -6269,7 +6495,21 @@ var t = {
|
|
|
6269
6495
|
ring: (name) => new ClickHouseColumn(name, "Ring"),
|
|
6270
6496
|
polygon: (name) => new ClickHouseColumn(name, "Polygon"),
|
|
6271
6497
|
multiPolygon: (name) => new ClickHouseColumn(name, "MultiPolygon"),
|
|
6272
|
-
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
|
+
})
|
|
6273
6513
|
};
|
|
6274
6514
|
function defineTable(tableName, columnsOrCallback, options) {
|
|
6275
6515
|
const columns = typeof columnsOrCallback === "function" ? columnsOrCallback(t) : columnsOrCallback;
|
|
@@ -6306,104 +6546,6 @@ function relations(table2, relationsBuilder) {
|
|
|
6306
6546
|
table2.$relations = rels;
|
|
6307
6547
|
return rels;
|
|
6308
6548
|
}
|
|
6309
|
-
// src/codegen/zod.ts
|
|
6310
|
-
import { z } from "zod";
|
|
6311
|
-
function mapClickHouseTypeToZod(column) {
|
|
6312
|
-
const type = column.type.toLowerCase();
|
|
6313
|
-
let zodType;
|
|
6314
|
-
if (type.startsWith("nullable(")) {
|
|
6315
|
-
const innerType = column.type.slice("nullable(".length, -1);
|
|
6316
|
-
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
6317
|
-
zodType = mapClickHouseTypeToZod(innerColumn).nullable();
|
|
6318
|
-
} else if (type.startsWith("array(")) {
|
|
6319
|
-
const innerType = column.type.slice("array(".length, -1);
|
|
6320
|
-
const innerColumn = new ClickHouseColumn(column.name, innerType);
|
|
6321
|
-
zodType = z.array(mapClickHouseTypeToZod(innerColumn));
|
|
6322
|
-
} else if (type.startsWith("fixedstring")) {
|
|
6323
|
-
zodType = z.string();
|
|
6324
|
-
} else if (type.startsWith("enum")) {
|
|
6325
|
-
if (column.meta?.enumValues) {
|
|
6326
|
-
zodType = z.enum(column.meta.enumValues);
|
|
6327
|
-
} else {
|
|
6328
|
-
zodType = z.string();
|
|
6329
|
-
}
|
|
6330
|
-
} else if (type.startsWith("datetime64")) {
|
|
6331
|
-
zodType = z.date();
|
|
6332
|
-
} else if (type.startsWith("decimal")) {
|
|
6333
|
-
zodType = z.string().refine((val) => !isNaN(parseFloat(val)), {
|
|
6334
|
-
message: "Must be a valid decimal number string"
|
|
6335
|
-
});
|
|
6336
|
-
} else {
|
|
6337
|
-
switch (type) {
|
|
6338
|
-
case "uuid":
|
|
6339
|
-
case "string":
|
|
6340
|
-
case "json":
|
|
6341
|
-
case "ipv4":
|
|
6342
|
-
case "ipv6":
|
|
6343
|
-
zodType = z.string();
|
|
6344
|
-
break;
|
|
6345
|
-
case "int8":
|
|
6346
|
-
case "uint8":
|
|
6347
|
-
case "int16":
|
|
6348
|
-
case "uint16":
|
|
6349
|
-
case "int32":
|
|
6350
|
-
case "uint32":
|
|
6351
|
-
case "float32":
|
|
6352
|
-
case "float64":
|
|
6353
|
-
zodType = z.number();
|
|
6354
|
-
break;
|
|
6355
|
-
case "int64":
|
|
6356
|
-
case "uint64":
|
|
6357
|
-
case "int128":
|
|
6358
|
-
case "uint128":
|
|
6359
|
-
case "int256":
|
|
6360
|
-
case "uint256":
|
|
6361
|
-
zodType = z.bigint();
|
|
6362
|
-
break;
|
|
6363
|
-
case "boolean":
|
|
6364
|
-
case "bool":
|
|
6365
|
-
zodType = z.boolean();
|
|
6366
|
-
break;
|
|
6367
|
-
case "date":
|
|
6368
|
-
case "datetime":
|
|
6369
|
-
zodType = z.date();
|
|
6370
|
-
break;
|
|
6371
|
-
default:
|
|
6372
|
-
zodType = z.string();
|
|
6373
|
-
break;
|
|
6374
|
-
}
|
|
6375
|
-
}
|
|
6376
|
-
if (column.isNull && !type.startsWith("nullable(")) {
|
|
6377
|
-
zodType = zodType.nullable();
|
|
6378
|
-
}
|
|
6379
|
-
return zodType;
|
|
6380
|
-
}
|
|
6381
|
-
function generateSelectSchema(table2) {
|
|
6382
|
-
const shape = {};
|
|
6383
|
-
for (const key in table2.$columns) {
|
|
6384
|
-
if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
|
|
6385
|
-
const column = table2.$columns[key];
|
|
6386
|
-
shape[key] = mapClickHouseTypeToZod(column);
|
|
6387
|
-
}
|
|
6388
|
-
}
|
|
6389
|
-
return z.object(shape);
|
|
6390
|
-
}
|
|
6391
|
-
function generateInsertSchema(table2) {
|
|
6392
|
-
const shape = {};
|
|
6393
|
-
for (const key in table2.$columns) {
|
|
6394
|
-
if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
|
|
6395
|
-
const column = table2.$columns[key];
|
|
6396
|
-
let zodType = mapClickHouseTypeToZod(column);
|
|
6397
|
-
const isOptionalBySchema = !column.isNull && (column.meta?.default !== undefined || column.meta?.defaultFn !== undefined || column.meta?.defaultExpr !== undefined || column.meta?.autoGenerate !== undefined);
|
|
6398
|
-
const isOptionalByNullable = column.isNull;
|
|
6399
|
-
if (isOptionalBySchema || isOptionalByNullable) {
|
|
6400
|
-
zodType = zodType.optional();
|
|
6401
|
-
} else {}
|
|
6402
|
-
shape[key] = zodType;
|
|
6403
|
-
}
|
|
6404
|
-
}
|
|
6405
|
-
return z.object(shape);
|
|
6406
|
-
}
|
|
6407
6549
|
// src/index.ts
|
|
6408
6550
|
async function createClientFromConfig(databaseName = "default") {
|
|
6409
6551
|
const config = await loadConfig();
|
|
@@ -6419,6 +6561,18 @@ async function createClientFromConfig(databaseName = "default") {
|
|
|
6419
6561
|
};
|
|
6420
6562
|
return createClientFromConfigObject(clientConfig);
|
|
6421
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
|
+
}
|
|
6422
6576
|
async function loadConfig() {
|
|
6423
6577
|
const root = process.cwd();
|
|
6424
6578
|
const extensions = ["ts", "js", "mjs", "cjs"];
|
|
@@ -6728,6 +6882,7 @@ export {
|
|
|
6728
6882
|
htmlEscape,
|
|
6729
6883
|
housekitMetadataSchemas,
|
|
6730
6884
|
housekitMetadataDefaults,
|
|
6885
|
+
housekit,
|
|
6731
6886
|
hdfs,
|
|
6732
6887
|
hasAny,
|
|
6733
6888
|
hasAll,
|
|
@@ -6797,6 +6952,7 @@ export {
|
|
|
6797
6952
|
dateDiff,
|
|
6798
6953
|
dateAdd,
|
|
6799
6954
|
createdAt,
|
|
6955
|
+
createSchema,
|
|
6800
6956
|
createMigrationBridge,
|
|
6801
6957
|
createHousekitClient,
|
|
6802
6958
|
createClients,
|