bun-query-builder 0.2.28 → 0.2.29
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/dist/bin/cli.js +461 -355
- package/dist/browser.d.ts +2 -2
- package/dist/client.d.ts +7 -0
- package/dist/faker-compat.d.ts +83 -0
- package/dist/index.d.ts +1 -0
- package/dist/orm.d.ts +3 -3
- package/dist/schema.d.ts +2 -2
- package/dist/sql-fragments.d.ts +69 -0
- package/dist/src/index.js +461 -354
- package/dist/type-inference.d.ts +3 -3
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -12554,6 +12554,30 @@ var init_pivot = __esm(() => {
|
|
|
12554
12554
|
init_config();
|
|
12555
12555
|
});
|
|
12556
12556
|
|
|
12557
|
+
// src/sql-fragments.ts
|
|
12558
|
+
function renderWhereTerms(terms) {
|
|
12559
|
+
if (terms.length === 0)
|
|
12560
|
+
return "";
|
|
12561
|
+
const runs = [];
|
|
12562
|
+
for (const term of terms) {
|
|
12563
|
+
if (term.conn === "OR" && runs.length > 0)
|
|
12564
|
+
runs[runs.length - 1].push(term);
|
|
12565
|
+
else
|
|
12566
|
+
runs.push([term]);
|
|
12567
|
+
}
|
|
12568
|
+
return runs.map((run, i) => {
|
|
12569
|
+
const body = run.map((t) => t.sql).join(" OR ");
|
|
12570
|
+
const piece = run.length > 1 && runs.length > 1 ? `(${body})` : body;
|
|
12571
|
+
return i === 0 ? piece : `${run[0].conn} ${piece}`;
|
|
12572
|
+
}).join(" ");
|
|
12573
|
+
}
|
|
12574
|
+
function renderInPredicate(column, values, negated, placeholders) {
|
|
12575
|
+
if (values.length === 0)
|
|
12576
|
+
return negated ? TRUE_PREDICATE : FALSE_PREDICATE;
|
|
12577
|
+
return `${column} ${negated ? "NOT IN" : "IN"} (${placeholders})`;
|
|
12578
|
+
}
|
|
12579
|
+
var FALSE_PREDICATE = "1 = 0", TRUE_PREDICATE = "1 = 1";
|
|
12580
|
+
|
|
12557
12581
|
// src/client.ts
|
|
12558
12582
|
function isRawExpression(expr) {
|
|
12559
12583
|
return typeof expr === "object" && expr !== null && "raw" in expr && typeof expr.raw === "string";
|
|
@@ -12625,11 +12649,6 @@ function renderSelectColumn(col) {
|
|
|
12625
12649
|
}
|
|
12626
12650
|
throw new TypeError(`[query-builder] select(): unsupported column ${String(col)} \u2014 pass a column name, a string[], or a SQL fragment (e.g. sql\`count(*) as c\`)`);
|
|
12627
12651
|
}
|
|
12628
|
-
function renderInPredicate(column, values, negated, placeholders) {
|
|
12629
|
-
if (values.length === 0)
|
|
12630
|
-
return negated ? TRUE_PREDICATE : FALSE_PREDICATE;
|
|
12631
|
-
return `${column} ${negated ? "NOT IN" : "IN"} (${placeholders})`;
|
|
12632
|
-
}
|
|
12633
12652
|
function validateIdentifier(name, context) {
|
|
12634
12653
|
if (!SQL_PATTERNS.IDENTIFIER.test(name)) {
|
|
12635
12654
|
const contextMsg = context ? ` in ${context}` : "";
|
|
@@ -13106,20 +13125,125 @@ function createQueryBuilder(state) {
|
|
|
13106
13125
|
function makeSelect(table, columns) {
|
|
13107
13126
|
const sql = _sql;
|
|
13108
13127
|
let text = columns && columns.length > 0 ? `SELECT ${columns.join(", ")} FROM ${String(table)}` : `SELECT * FROM ${String(table)}`;
|
|
13128
|
+
const whereTerms = [];
|
|
13129
|
+
const whereParams = [];
|
|
13130
|
+
let whereTail = false;
|
|
13109
13131
|
let built = null;
|
|
13110
13132
|
const ensureBuilt = () => {
|
|
13111
13133
|
if (built === null) {
|
|
13112
|
-
const finalText = reorderSelectClauses(
|
|
13134
|
+
const finalText = reorderSelectClauses(currentSql());
|
|
13113
13135
|
built = whereParams.length > 0 ? _sql.unsafe(finalText, whereParams) : _sql.unsafe(finalText);
|
|
13114
13136
|
}
|
|
13115
13137
|
return built;
|
|
13116
13138
|
};
|
|
13139
|
+
const pushWhere = (conn, clause) => {
|
|
13140
|
+
whereTerms.push({ conn, sql: clause });
|
|
13141
|
+
built = null;
|
|
13142
|
+
};
|
|
13117
13143
|
const addWhereText = (prefix, clause) => {
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13144
|
+
pushWhere(prefix === "OR" ? "OR" : "AND", clause);
|
|
13145
|
+
};
|
|
13146
|
+
const TAIL_CLAUSE = /\(|\)|\b(?:GROUP\s+BY|HAVING|ORDER\s+BY|LIMIT|OFFSET|WINDOW|UNION|INTERSECT|EXCEPT|FOR\s+UPDATE|FOR\s+SHARE|LOCK\s+IN\s+SHARE\s+MODE)\b/gi;
|
|
13147
|
+
const firstTailIndex = (s) => {
|
|
13148
|
+
TAIL_CLAUSE.lastIndex = 0;
|
|
13149
|
+
let depth = 0;
|
|
13150
|
+
let m;
|
|
13151
|
+
while (m = TAIL_CLAUSE.exec(s)) {
|
|
13152
|
+
if (m[0] === "(") {
|
|
13153
|
+
depth++;
|
|
13154
|
+
} else if (m[0] === ")") {
|
|
13155
|
+
depth = Math.max(0, depth - 1);
|
|
13156
|
+
} else if (depth === 0) {
|
|
13157
|
+
return m.index;
|
|
13158
|
+
}
|
|
13159
|
+
}
|
|
13160
|
+
return -1;
|
|
13161
|
+
};
|
|
13162
|
+
const currentSql = () => {
|
|
13163
|
+
const body = renderWhereTerms(whereTerms);
|
|
13164
|
+
if (!body)
|
|
13165
|
+
return text;
|
|
13166
|
+
if (whereTail) {
|
|
13167
|
+
const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
13168
|
+
return `${text} ${kw} ${body}`;
|
|
13169
|
+
}
|
|
13170
|
+
const cut = firstTailIndex(text);
|
|
13171
|
+
return cut >= 0 ? `${text.slice(0, cut)}WHERE ${body} ${text.slice(cut)}` : `${text} WHERE ${body}`;
|
|
13172
|
+
};
|
|
13173
|
+
const addWhereGroup = (conn, cb) => {
|
|
13174
|
+
const sub = makeSelect(table);
|
|
13175
|
+
cb(sub);
|
|
13176
|
+
const st = sub.__whereState?.();
|
|
13177
|
+
if (!st || !st.body) {
|
|
13178
|
+
throw new TypeError("[query-builder] whereGroup(callback): the callback added no conditions. " + "Add at least one where()/orWhere() to the builder it receives.");
|
|
13179
|
+
}
|
|
13180
|
+
const offset = whereParams.length;
|
|
13181
|
+
const body = offset > 0 && config5.dialect === "postgres" ? st.body.replace(/\$(\d+)/g, (_m, n) => `$${Number(n) + offset}`) : st.body;
|
|
13182
|
+
whereParams.push(...st.params);
|
|
13183
|
+
pushWhere(conn, `(${body})`);
|
|
13184
|
+
};
|
|
13185
|
+
const addBooleanWhere = (self, conn, label, expr, op, value) => {
|
|
13186
|
+
if (typeof expr === "string" && op !== undefined) {
|
|
13187
|
+
validateIdentifier(String(expr), `${label}(column)`);
|
|
13188
|
+
assertSafeWhereOperator(op, `${label}(operator)`);
|
|
13189
|
+
const paramIndex = whereParams.length + 1;
|
|
13190
|
+
whereParams.push(value);
|
|
13191
|
+
pushWhere(conn, `${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
|
|
13192
|
+
return self;
|
|
13193
|
+
}
|
|
13194
|
+
if (Array.isArray(expr)) {
|
|
13195
|
+
const [col, rawOp, val] = expr;
|
|
13196
|
+
const colName = String(col);
|
|
13197
|
+
validateIdentifier(colName, `${label}(column)`);
|
|
13198
|
+
const operator = assertSafeWhereOperator(rawOp, `${label}(operator)`);
|
|
13199
|
+
if (operator === "in" || operator === "not in") {
|
|
13200
|
+
const values = Array.isArray(val) ? val : [val];
|
|
13201
|
+
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
13202
|
+
const clause = renderInPredicate(colName, values, operator === "not in", placeholders);
|
|
13203
|
+
whereParams.push(...values);
|
|
13204
|
+
pushWhere(conn, clause);
|
|
13205
|
+
} else {
|
|
13206
|
+
const paramIndex = whereParams.length + 1;
|
|
13207
|
+
whereParams.push(val);
|
|
13208
|
+
pushWhere(conn, `${colName} ${operator} ${getPlaceholder(paramIndex)}`);
|
|
13209
|
+
}
|
|
13210
|
+
return self;
|
|
13211
|
+
}
|
|
13212
|
+
if (typeof expr === "function") {
|
|
13213
|
+
addWhereGroup(conn, expr);
|
|
13214
|
+
return self;
|
|
13215
|
+
}
|
|
13216
|
+
if (expr && typeof expr === "object" && !("raw" in expr)) {
|
|
13217
|
+
const conditions = [];
|
|
13218
|
+
for (const key of Object.keys(expr)) {
|
|
13219
|
+
validateIdentifier(key, `${label}(column)`);
|
|
13220
|
+
const v = expr[key];
|
|
13221
|
+
if (Array.isArray(v)) {
|
|
13222
|
+
const placeholders = getPlaceholders(v.length, whereParams.length + 1);
|
|
13223
|
+
conditions.push(renderInPredicate(key, v, false, placeholders));
|
|
13224
|
+
whereParams.push(...v);
|
|
13225
|
+
} else {
|
|
13226
|
+
const paramIndex = whereParams.length + 1;
|
|
13227
|
+
conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
13228
|
+
whereParams.push(v);
|
|
13229
|
+
}
|
|
13230
|
+
}
|
|
13231
|
+
if (conditions.length > 0)
|
|
13232
|
+
pushWhere(conn, conditions.length > 1 ? `(${conditions.join(" AND ")})` : conditions[0]);
|
|
13233
|
+
return self;
|
|
13234
|
+
}
|
|
13235
|
+
if (expr && typeof expr.raw !== "undefined") {
|
|
13236
|
+
pushWhere(conn, expr.raw);
|
|
13237
|
+
return self;
|
|
13238
|
+
}
|
|
13239
|
+
return self;
|
|
13121
13240
|
};
|
|
13122
13241
|
const appendSetOp = (op, other) => {
|
|
13242
|
+
if (whereTerms.length > 0) {
|
|
13243
|
+
text = currentSql();
|
|
13244
|
+
whereTerms.length = 0;
|
|
13245
|
+
}
|
|
13246
|
+
whereTail = true;
|
|
13123
13247
|
const st = other.__rawState?.();
|
|
13124
13248
|
if (st) {
|
|
13125
13249
|
const offset = whereParams.length;
|
|
@@ -13209,8 +13333,6 @@ function createQueryBuilder(state) {
|
|
|
13209
13333
|
text = `${text} LEFT JOIN ${resolved.pivotTable} ON ${resolved.pivotTable}.${resolved.fkParent} = ${parentTable}.${parentPk}`;
|
|
13210
13334
|
joinedTables.add(resolved.pivotTable);
|
|
13211
13335
|
};
|
|
13212
|
-
const whereConditions = [];
|
|
13213
|
-
const whereParams = [];
|
|
13214
13336
|
const addToSelectClause = (columnsToAdd) => {
|
|
13215
13337
|
if (SQL_PATTERNS.SELECT_STAR.test(text)) {
|
|
13216
13338
|
text = text.replace(SQL_PATTERNS.SELECT_STAR, `SELECT *, ${columnsToAdd}`);
|
|
@@ -13834,10 +13956,7 @@ function createQueryBuilder(state) {
|
|
|
13834
13956
|
} else {
|
|
13835
13957
|
throw new Error(`[query-builder] Unsupported relationship type '${type}' for whereHas`);
|
|
13836
13958
|
}
|
|
13837
|
-
|
|
13838
|
-
try {
|
|
13839
|
-
addWhereText("WHERE", `EXISTS (${subquerySQL})`);
|
|
13840
|
-
} catch {}
|
|
13959
|
+
addWhereText("WHERE", `EXISTS (${subquerySQL})`);
|
|
13841
13960
|
return this;
|
|
13842
13961
|
},
|
|
13843
13962
|
whereDoesntHave(relation, callback) {
|
|
@@ -13870,10 +13989,7 @@ function createQueryBuilder(state) {
|
|
|
13870
13989
|
} else {
|
|
13871
13990
|
throw new Error(`[query-builder] Unsupported relationship type '${type}' for whereDoesntHave`);
|
|
13872
13991
|
}
|
|
13873
|
-
|
|
13874
|
-
try {
|
|
13875
|
-
addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
|
|
13876
|
-
} catch {}
|
|
13992
|
+
addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
|
|
13877
13993
|
return this;
|
|
13878
13994
|
},
|
|
13879
13995
|
has(relation) {
|
|
@@ -13904,10 +14020,7 @@ function createQueryBuilder(state) {
|
|
|
13904
14020
|
} else {
|
|
13905
14021
|
throw new Error(`[query-builder] Unsupported relationship type '${type}' for has`);
|
|
13906
14022
|
}
|
|
13907
|
-
|
|
13908
|
-
try {
|
|
13909
|
-
addWhereText("WHERE", `EXISTS (${subquerySQL})`);
|
|
13910
|
-
} catch {}
|
|
14023
|
+
addWhereText("WHERE", `EXISTS (${subquerySQL})`);
|
|
13911
14024
|
return this;
|
|
13912
14025
|
},
|
|
13913
14026
|
doesntHave(relation) {
|
|
@@ -13938,10 +14051,7 @@ function createQueryBuilder(state) {
|
|
|
13938
14051
|
} else {
|
|
13939
14052
|
throw new Error(`[query-builder] Unsupported relationship type '${type}' for doesntHave`);
|
|
13940
14053
|
}
|
|
13941
|
-
|
|
13942
|
-
try {
|
|
13943
|
-
addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
|
|
13944
|
-
} catch {}
|
|
14054
|
+
addWhereText("WHERE", `NOT EXISTS (${subquerySQL})`);
|
|
13945
14055
|
return this;
|
|
13946
14056
|
},
|
|
13947
14057
|
withCount(...relations) {
|
|
@@ -14024,17 +14134,14 @@ function createQueryBuilder(state) {
|
|
|
14024
14134
|
const val = value === undefined ? opOrValue : value;
|
|
14025
14135
|
const paramIndex = whereParams.length + 1;
|
|
14026
14136
|
const clause = `${resolved.pivotTable}.${column} ${op} ${getPlaceholder(paramIndex)}`;
|
|
14027
|
-
whereConditions.push(clause);
|
|
14028
14137
|
whereParams.push(val);
|
|
14029
|
-
|
|
14030
|
-
text = `${text} ${kw} ${clause}`;
|
|
14031
|
-
built = null;
|
|
14138
|
+
pushWhere("AND", clause);
|
|
14032
14139
|
if (resolved.hasConfig)
|
|
14033
14140
|
pivotConfigRelations.add(relation);
|
|
14034
14141
|
return this;
|
|
14035
14142
|
},
|
|
14036
14143
|
wherePivotIn(relation, column, values) {
|
|
14037
|
-
if (!meta || !Array.isArray(values)
|
|
14144
|
+
if (!meta || !Array.isArray(values))
|
|
14038
14145
|
return this;
|
|
14039
14146
|
const resolved = resolvePivotLocal(relation);
|
|
14040
14147
|
if (!resolved) {
|
|
@@ -14044,12 +14151,9 @@ function createQueryBuilder(state) {
|
|
|
14044
14151
|
validateIdentifier(column, "wherePivotIn (column)");
|
|
14045
14152
|
ensurePivotJoined(resolved);
|
|
14046
14153
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14047
|
-
const clause = `${resolved.pivotTable}.${column}
|
|
14048
|
-
whereConditions.push(clause);
|
|
14154
|
+
const clause = renderInPredicate(`${resolved.pivotTable}.${column}`, values, false, placeholders);
|
|
14049
14155
|
whereParams.push(...values);
|
|
14050
|
-
|
|
14051
|
-
text = `${text} ${kw} ${clause}`;
|
|
14052
|
-
built = null;
|
|
14156
|
+
pushWhere("AND", clause);
|
|
14053
14157
|
if (resolved.hasConfig)
|
|
14054
14158
|
pivotConfigRelations.add(relation);
|
|
14055
14159
|
return this;
|
|
@@ -14066,11 +14170,8 @@ function createQueryBuilder(state) {
|
|
|
14066
14170
|
ensurePivotJoined(resolved);
|
|
14067
14171
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14068
14172
|
const clause = `${resolved.pivotTable}.${column} NOT IN (${placeholders})`;
|
|
14069
|
-
whereConditions.push(clause);
|
|
14070
14173
|
whereParams.push(...values);
|
|
14071
|
-
|
|
14072
|
-
text = `${text} ${kw} ${clause}`;
|
|
14073
|
-
built = null;
|
|
14174
|
+
pushWhere("AND", clause);
|
|
14074
14175
|
if (resolved.hasConfig)
|
|
14075
14176
|
pivotConfigRelations.add(relation);
|
|
14076
14177
|
return this;
|
|
@@ -14085,11 +14186,7 @@ function createQueryBuilder(state) {
|
|
|
14085
14186
|
validateIdentifier(resolved.pivotTable, "wherePivotNull (pivot table)");
|
|
14086
14187
|
validateIdentifier(column, "wherePivotNull (column)");
|
|
14087
14188
|
ensurePivotJoined(resolved);
|
|
14088
|
-
|
|
14089
|
-
whereConditions.push(clause);
|
|
14090
|
-
const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14091
|
-
text = `${text} ${kw} ${clause}`;
|
|
14092
|
-
built = null;
|
|
14189
|
+
pushWhere("AND", `${resolved.pivotTable}.${column} IS NULL`);
|
|
14093
14190
|
if (resolved.hasConfig)
|
|
14094
14191
|
pivotConfigRelations.add(relation);
|
|
14095
14192
|
return this;
|
|
@@ -14104,17 +14201,12 @@ function createQueryBuilder(state) {
|
|
|
14104
14201
|
validateIdentifier(resolved.pivotTable, "wherePivotNotNull (pivot table)");
|
|
14105
14202
|
validateIdentifier(column, "wherePivotNotNull (column)");
|
|
14106
14203
|
ensurePivotJoined(resolved);
|
|
14107
|
-
|
|
14108
|
-
whereConditions.push(clause);
|
|
14109
|
-
const kw = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14110
|
-
text = `${text} ${kw} ${clause}`;
|
|
14111
|
-
built = null;
|
|
14204
|
+
pushWhere("AND", `${resolved.pivotTable}.${column} IS NOT NULL`);
|
|
14112
14205
|
if (resolved.hasConfig)
|
|
14113
14206
|
pivotConfigRelations.add(relation);
|
|
14114
14207
|
return this;
|
|
14115
14208
|
},
|
|
14116
14209
|
where(expr, op, value) {
|
|
14117
|
-
const getWhereKeyword = () => SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14118
14210
|
if (typeof expr === "string" && op !== undefined) {
|
|
14119
14211
|
validateIdentifier(String(expr), "where(column)");
|
|
14120
14212
|
assertSafeWhereOperator(op, "where(operator)");
|
|
@@ -14122,18 +14214,14 @@ function createQueryBuilder(state) {
|
|
|
14122
14214
|
if (operator === "in" || operator === "not in") {
|
|
14123
14215
|
const values = Array.isArray(value) ? value : [value];
|
|
14124
14216
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14125
|
-
const clause =
|
|
14126
|
-
whereConditions.push(clause);
|
|
14217
|
+
const clause = renderInPredicate(String(expr), values, operator === "not in", placeholders);
|
|
14127
14218
|
whereParams.push(...values);
|
|
14128
|
-
|
|
14129
|
-
built = null;
|
|
14219
|
+
pushWhere("AND", clause);
|
|
14130
14220
|
return this;
|
|
14131
14221
|
}
|
|
14132
14222
|
const paramIndex = whereParams.length + 1;
|
|
14133
|
-
whereConditions.push(`${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
|
|
14134
14223
|
whereParams.push(value);
|
|
14135
|
-
|
|
14136
|
-
built = null;
|
|
14224
|
+
pushWhere("AND", `${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
|
|
14137
14225
|
return this;
|
|
14138
14226
|
}
|
|
14139
14227
|
if (Array.isArray(expr)) {
|
|
@@ -14144,16 +14232,13 @@ function createQueryBuilder(state) {
|
|
|
14144
14232
|
if (operator === "in" || operator === "not in") {
|
|
14145
14233
|
const values = Array.isArray(val) ? val : [val];
|
|
14146
14234
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14147
|
-
|
|
14235
|
+
const clause = renderInPredicate(colName, values, operator === "not in", placeholders);
|
|
14148
14236
|
whereParams.push(...values);
|
|
14149
|
-
|
|
14150
|
-
built = null;
|
|
14237
|
+
pushWhere("AND", clause);
|
|
14151
14238
|
} else {
|
|
14152
14239
|
const paramIndex = whereParams.length + 1;
|
|
14153
|
-
whereConditions.push(`${colName} ${operator} ${getPlaceholder(paramIndex)}`);
|
|
14154
14240
|
whereParams.push(val);
|
|
14155
|
-
|
|
14156
|
-
built = null;
|
|
14241
|
+
pushWhere("AND", `${colName} ${operator} ${getPlaceholder(paramIndex)}`);
|
|
14157
14242
|
}
|
|
14158
14243
|
return this;
|
|
14159
14244
|
}
|
|
@@ -14166,30 +14251,25 @@ function createQueryBuilder(state) {
|
|
|
14166
14251
|
const value2 = whereObject[key];
|
|
14167
14252
|
if (Array.isArray(value2)) {
|
|
14168
14253
|
const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
|
|
14169
|
-
conditions.push(
|
|
14170
|
-
whereConditions.push(`${key} IN (${placeholders})`);
|
|
14254
|
+
conditions.push(renderInPredicate(key, value2, false, placeholders));
|
|
14171
14255
|
whereParams.push(...value2);
|
|
14172
14256
|
} else {
|
|
14173
14257
|
const paramIndex = whereParams.length + 1;
|
|
14174
14258
|
conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
14175
|
-
whereConditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
14176
14259
|
whereParams.push(value2);
|
|
14177
14260
|
}
|
|
14178
14261
|
}
|
|
14179
|
-
if (conditions.length > 0)
|
|
14180
|
-
|
|
14181
|
-
built = null;
|
|
14182
|
-
}
|
|
14262
|
+
if (conditions.length > 0)
|
|
14263
|
+
pushWhere("AND", conditions.length > 1 ? `(${conditions.join(" AND ")})` : conditions[0]);
|
|
14183
14264
|
return this;
|
|
14184
14265
|
}
|
|
14185
14266
|
if (isRawExpression(expr)) {
|
|
14186
|
-
|
|
14187
|
-
text = `${text} ${getWhereKeyword()} ${expr.raw}`;
|
|
14188
|
-
built = null;
|
|
14267
|
+
pushWhere("AND", expr.raw);
|
|
14189
14268
|
return this;
|
|
14190
14269
|
}
|
|
14191
14270
|
if (typeof expr === "function") {
|
|
14192
|
-
|
|
14271
|
+
addWhereGroup("AND", expr);
|
|
14272
|
+
return this;
|
|
14193
14273
|
}
|
|
14194
14274
|
if (expr === undefined || expr === null) {
|
|
14195
14275
|
throw new TypeError("where() was called with no condition.");
|
|
@@ -14201,61 +14281,83 @@ function createQueryBuilder(state) {
|
|
|
14201
14281
|
},
|
|
14202
14282
|
whereNull(column) {
|
|
14203
14283
|
validateIdentifier(String(column), "whereNull(column)");
|
|
14204
|
-
|
|
14205
|
-
text = `${text} ${keyword} ${String(column)} IS NULL`;
|
|
14206
|
-
built = null;
|
|
14284
|
+
pushWhere("AND", `${String(column)} IS NULL`);
|
|
14207
14285
|
return this;
|
|
14208
14286
|
},
|
|
14209
14287
|
whereNotNull(column) {
|
|
14210
14288
|
validateIdentifier(String(column), "whereNotNull(column)");
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14289
|
+
pushWhere("AND", `${String(column)} IS NOT NULL`);
|
|
14290
|
+
return this;
|
|
14291
|
+
},
|
|
14292
|
+
orWhereNull(column) {
|
|
14293
|
+
validateIdentifier(String(column), "orWhereNull(column)");
|
|
14294
|
+
pushWhere("OR", `${String(column)} IS NULL`);
|
|
14295
|
+
return this;
|
|
14296
|
+
},
|
|
14297
|
+
orWhereNotNull(column) {
|
|
14298
|
+
validateIdentifier(String(column), "orWhereNotNull(column)");
|
|
14299
|
+
pushWhere("OR", `${String(column)} IS NOT NULL`);
|
|
14214
14300
|
return this;
|
|
14215
14301
|
},
|
|
14216
14302
|
whereBetween(column, start, end) {
|
|
14217
14303
|
validateIdentifier(String(column), "whereBetween(column)");
|
|
14218
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14219
14304
|
const i = whereParams.length + 1;
|
|
14220
|
-
text = `${text} ${keyword} ${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
|
|
14221
14305
|
whereParams.push(start, end);
|
|
14222
|
-
|
|
14306
|
+
pushWhere("AND", `${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
|
|
14307
|
+
return this;
|
|
14308
|
+
},
|
|
14309
|
+
orWhereBetween(column, start, end) {
|
|
14310
|
+
validateIdentifier(String(column), "orWhereBetween(column)");
|
|
14311
|
+
const i = whereParams.length + 1;
|
|
14312
|
+
whereParams.push(start, end);
|
|
14313
|
+
pushWhere("OR", `${String(column)} BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
|
|
14223
14314
|
return this;
|
|
14224
14315
|
},
|
|
14225
14316
|
whereExists(subquery) {
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14317
|
+
pushWhere("AND", `EXISTS (${subquery.toSQL()})`);
|
|
14318
|
+
return this;
|
|
14319
|
+
},
|
|
14320
|
+
orWhereExists(subquery) {
|
|
14321
|
+
pushWhere("OR", `EXISTS (${subquery.toSQL()})`);
|
|
14322
|
+
return this;
|
|
14323
|
+
},
|
|
14324
|
+
whereGroup(cb) {
|
|
14325
|
+
addWhereGroup("AND", cb);
|
|
14326
|
+
return this;
|
|
14327
|
+
},
|
|
14328
|
+
orWhereGroup(cb) {
|
|
14329
|
+
addWhereGroup("OR", cb);
|
|
14229
14330
|
return this;
|
|
14230
14331
|
},
|
|
14332
|
+
__whereState() {
|
|
14333
|
+
return { body: renderWhereTerms(whereTerms), params: [...whereParams] };
|
|
14334
|
+
},
|
|
14231
14335
|
whereJsonContains(column, json) {
|
|
14232
14336
|
validateIdentifier(String(column), "whereJsonContains(column)");
|
|
14233
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14234
14337
|
const dialect = config5.dialect;
|
|
14235
14338
|
const idx = whereParams.length + 1;
|
|
14236
14339
|
if (dialect === "postgres") {
|
|
14237
14340
|
if (config5.sql?.jsonContainsMode === "function")
|
|
14238
|
-
|
|
14341
|
+
pushWhere("AND", `jsonb_contains(${column}, ${getPlaceholder(idx)})`);
|
|
14239
14342
|
else
|
|
14240
|
-
|
|
14343
|
+
pushWhere("AND", `${column} @> ${getPlaceholder(idx)}`);
|
|
14241
14344
|
whereParams.push(JSON.stringify(json));
|
|
14242
14345
|
} else if (isMysqlLike(dialect)) {
|
|
14243
|
-
|
|
14346
|
+
pushWhere("AND", `JSON_CONTAINS(${column}, ${getPlaceholder(idx)})`);
|
|
14244
14347
|
whereParams.push(JSON.stringify(json));
|
|
14245
14348
|
} else {
|
|
14246
14349
|
if (Array.isArray(json)) {
|
|
14247
14350
|
const conds = json.map((_, i) => `EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${getPlaceholder(idx + i)})`);
|
|
14248
|
-
|
|
14351
|
+
pushWhere("AND", `(${conds.join(" AND ")})`);
|
|
14249
14352
|
for (const v of json)
|
|
14250
14353
|
whereParams.push(v);
|
|
14251
14354
|
} else if (json !== null && typeof json === "object") {
|
|
14252
14355
|
throw new Error("[query-builder] whereJsonContains: object containment is not supported on SQLite \u2014 pass a scalar or array, or use whereJsonPath.");
|
|
14253
14356
|
} else {
|
|
14254
|
-
|
|
14357
|
+
pushWhere("AND", `EXISTS (SELECT 1 FROM json_each(${column}) WHERE json_each.value = ${getPlaceholder(idx)})`);
|
|
14255
14358
|
whereParams.push(json);
|
|
14256
14359
|
}
|
|
14257
14360
|
}
|
|
14258
|
-
built = null;
|
|
14259
14361
|
return this;
|
|
14260
14362
|
},
|
|
14261
14363
|
whereJsonPath(path, op, value) {
|
|
@@ -14265,17 +14367,14 @@ function createQueryBuilder(state) {
|
|
|
14265
14367
|
if (!/^[A-Za-z0-9_.[\]$'\->* ,]+$/.test(path))
|
|
14266
14368
|
throw new TypeError(`[query-builder] whereJsonPath(path): refusing to use '${path}' \u2014 contains characters outside the allowed JSON-path set`);
|
|
14267
14369
|
const dialect = config5.dialect;
|
|
14268
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14269
14370
|
const idx = whereParams.length + 1;
|
|
14270
|
-
if (dialect === "postgres")
|
|
14271
|
-
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
}
|
|
14371
|
+
if (dialect === "postgres")
|
|
14372
|
+
pushWhere("AND", `${path} ${op} ${getPlaceholder(idx)}`);
|
|
14373
|
+
else if (isMysqlLike(dialect))
|
|
14374
|
+
pushWhere("AND", `JSON_EXTRACT(${path}) ${op} ${getPlaceholder(idx)}`);
|
|
14375
|
+
else
|
|
14376
|
+
pushWhere("AND", `json_extract(${path}) ${op} ${getPlaceholder(idx)}`);
|
|
14277
14377
|
whereParams.push(value);
|
|
14278
|
-
built = null;
|
|
14279
14378
|
return this;
|
|
14280
14379
|
},
|
|
14281
14380
|
whereLike(column, pattern, caseSensitive = false) {
|
|
@@ -14348,51 +14447,41 @@ function createQueryBuilder(state) {
|
|
|
14348
14447
|
},
|
|
14349
14448
|
whereAny(cols, op, value) {
|
|
14350
14449
|
if (cols.length === 0) {
|
|
14351
|
-
|
|
14352
|
-
text += ` ${kw} (${FALSE_PREDICATE})`;
|
|
14353
|
-
built = null;
|
|
14450
|
+
pushWhere("AND", `(${FALSE_PREDICATE})`);
|
|
14354
14451
|
return this;
|
|
14355
14452
|
}
|
|
14356
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14357
14453
|
const idx = whereParams.length + 1;
|
|
14358
14454
|
const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
|
|
14359
|
-
text += ` ${keyword} (${conds.join(" OR ")})`;
|
|
14360
14455
|
for (let i = 0;i < cols.length; i++)
|
|
14361
14456
|
whereParams.push(value);
|
|
14362
|
-
|
|
14457
|
+
pushWhere("AND", `(${conds.join(" OR ")})`);
|
|
14363
14458
|
return this;
|
|
14364
14459
|
},
|
|
14365
14460
|
whereAll(cols, op, value) {
|
|
14366
14461
|
if (cols.length === 0)
|
|
14367
14462
|
return this;
|
|
14368
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14369
14463
|
const idx = whereParams.length + 1;
|
|
14370
14464
|
const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
|
|
14371
|
-
text += ` ${keyword} (${conds.join(" AND ")})`;
|
|
14372
14465
|
for (let i = 0;i < cols.length; i++)
|
|
14373
14466
|
whereParams.push(value);
|
|
14374
|
-
|
|
14467
|
+
pushWhere("AND", `(${conds.join(" AND ")})`);
|
|
14375
14468
|
return this;
|
|
14376
14469
|
},
|
|
14377
14470
|
whereNone(cols, op, value) {
|
|
14378
14471
|
if (cols.length === 0)
|
|
14379
14472
|
return this;
|
|
14380
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14381
14473
|
const idx = whereParams.length + 1;
|
|
14382
14474
|
const conds = cols.map((c, i) => `${c} ${op} ${getPlaceholder(idx + i)}`);
|
|
14383
|
-
text += ` ${keyword} NOT (${conds.join(" OR ")})`;
|
|
14384
14475
|
for (let i = 0;i < cols.length; i++)
|
|
14385
14476
|
whereParams.push(value);
|
|
14386
|
-
|
|
14477
|
+
pushWhere("AND", `NOT (${conds.join(" OR ")})`);
|
|
14387
14478
|
return this;
|
|
14388
14479
|
},
|
|
14389
14480
|
whereNotBetween(column, start, end) {
|
|
14390
14481
|
validateIdentifier(String(column), "whereNotBetween(column)");
|
|
14391
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14392
14482
|
const i = whereParams.length + 1;
|
|
14393
|
-
text += ` ${keyword} ${column} NOT BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`;
|
|
14394
14483
|
whereParams.push(start, end);
|
|
14395
|
-
|
|
14484
|
+
pushWhere("AND", `${column} NOT BETWEEN ${getPlaceholder(i)} AND ${getPlaceholder(i + 1)}`);
|
|
14396
14485
|
return this;
|
|
14397
14486
|
},
|
|
14398
14487
|
whereDate(column, op, date) {
|
|
@@ -14400,223 +14489,94 @@ function createQueryBuilder(state) {
|
|
|
14400
14489
|
const dateString = date instanceof Date ? date.toISOString() : typeof date === "string" ? date : (() => {
|
|
14401
14490
|
throw new TypeError(`[query-builder] whereDate(date): expected string or Date, got ${typeof date}`);
|
|
14402
14491
|
})();
|
|
14403
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14404
14492
|
const idx = whereParams.length + 1;
|
|
14405
|
-
text += ` ${keyword} ${column} ${op} ${getPlaceholder(idx)}`;
|
|
14406
14493
|
whereParams.push(dateString);
|
|
14407
|
-
|
|
14494
|
+
pushWhere("AND", `${column} ${op} ${getPlaceholder(idx)}`);
|
|
14408
14495
|
return this;
|
|
14409
14496
|
},
|
|
14410
14497
|
whereRaw(fragment) {
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14414
|
-
|
|
14498
|
+
pushWhere("AND", renderRawFragment(fragment, "whereRaw(fragment)"));
|
|
14499
|
+
return this;
|
|
14500
|
+
},
|
|
14501
|
+
orWhereRaw(fragment) {
|
|
14502
|
+
pushWhere("OR", renderRawFragment(fragment, "orWhereRaw(fragment)"));
|
|
14415
14503
|
return this;
|
|
14416
14504
|
},
|
|
14417
14505
|
whereColumn(left, op, right) {
|
|
14418
14506
|
validateIdentifier(left, "whereColumn(left)");
|
|
14419
14507
|
validateIdentifier(right, "whereColumn(right)");
|
|
14420
|
-
|
|
14421
|
-
text += ` ${keyword} ${left} ${op} ${right}`;
|
|
14422
|
-
built = null;
|
|
14508
|
+
pushWhere("AND", `${left} ${op} ${right}`);
|
|
14423
14509
|
return this;
|
|
14424
14510
|
},
|
|
14425
14511
|
orWhereColumn(left, op, right) {
|
|
14426
14512
|
validateIdentifier(left, "orWhereColumn(left)");
|
|
14427
14513
|
validateIdentifier(right, "orWhereColumn(right)");
|
|
14428
|
-
|
|
14429
|
-
built = null;
|
|
14514
|
+
pushWhere("OR", `${left} ${op} ${right}`);
|
|
14430
14515
|
return this;
|
|
14431
14516
|
},
|
|
14432
14517
|
whereIn(column, values) {
|
|
14433
14518
|
validateIdentifier(String(column), "whereIn(column)");
|
|
14434
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14435
14519
|
if (Array.isArray(values)) {
|
|
14436
14520
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14437
|
-
|
|
14521
|
+
const clause = renderInPredicate(column, values, false, placeholders);
|
|
14438
14522
|
whereParams.push(...values);
|
|
14523
|
+
pushWhere("AND", clause);
|
|
14439
14524
|
} else {
|
|
14440
|
-
|
|
14525
|
+
pushWhere("AND", `${column} IN (${String(values.toSQL())})`);
|
|
14441
14526
|
}
|
|
14442
|
-
built = null;
|
|
14443
14527
|
return this;
|
|
14444
14528
|
},
|
|
14445
14529
|
orWhereIn(column, values) {
|
|
14446
14530
|
validateIdentifier(String(column), "orWhereIn(column)");
|
|
14447
14531
|
if (Array.isArray(values)) {
|
|
14448
14532
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14449
|
-
|
|
14533
|
+
const clause = renderInPredicate(column, values, false, placeholders);
|
|
14450
14534
|
whereParams.push(...values);
|
|
14535
|
+
pushWhere("OR", clause);
|
|
14451
14536
|
} else {
|
|
14452
|
-
|
|
14537
|
+
pushWhere("OR", `${column} IN (${String(values.toSQL())})`);
|
|
14453
14538
|
}
|
|
14454
|
-
built = null;
|
|
14455
14539
|
return this;
|
|
14456
14540
|
},
|
|
14457
14541
|
whereNotIn(column, values) {
|
|
14458
14542
|
validateIdentifier(String(column), "whereNotIn(column)");
|
|
14459
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14460
14543
|
if (Array.isArray(values)) {
|
|
14461
14544
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14462
|
-
|
|
14545
|
+
const clause = renderInPredicate(column, values, true, placeholders);
|
|
14463
14546
|
whereParams.push(...values);
|
|
14547
|
+
pushWhere("AND", clause);
|
|
14464
14548
|
} else {
|
|
14465
|
-
|
|
14549
|
+
pushWhere("AND", `${column} NOT IN (${String(values.toSQL())})`);
|
|
14466
14550
|
}
|
|
14467
|
-
built = null;
|
|
14468
14551
|
return this;
|
|
14469
14552
|
},
|
|
14470
14553
|
orWhereNotIn(column, values) {
|
|
14471
14554
|
validateIdentifier(String(column), "orWhereNotIn(column)");
|
|
14472
14555
|
if (Array.isArray(values)) {
|
|
14473
14556
|
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14474
|
-
|
|
14557
|
+
const clause = renderInPredicate(column, values, true, placeholders);
|
|
14475
14558
|
whereParams.push(...values);
|
|
14559
|
+
pushWhere("OR", clause);
|
|
14476
14560
|
} else {
|
|
14477
|
-
|
|
14561
|
+
pushWhere("OR", `${column} NOT IN (${String(values.toSQL())})`);
|
|
14478
14562
|
}
|
|
14479
|
-
built = null;
|
|
14480
14563
|
return this;
|
|
14481
14564
|
},
|
|
14482
14565
|
whereNested(fragment) {
|
|
14483
|
-
const keyword = SQL_PATTERNS.WHERE.test(text) ? "AND" : "WHERE";
|
|
14484
14566
|
const inner = fragment.toSQL ? String(fragment.toSQL()) : String(fragment);
|
|
14485
|
-
|
|
14486
|
-
built = null;
|
|
14567
|
+
pushWhere("AND", `(${inner})`);
|
|
14487
14568
|
return this;
|
|
14488
14569
|
},
|
|
14489
14570
|
orWhereNested(fragment) {
|
|
14490
14571
|
const inner = fragment.toSQL ? String(fragment.toSQL()) : String(fragment);
|
|
14491
|
-
|
|
14492
|
-
built = null;
|
|
14572
|
+
pushWhere("OR", `(${inner})`);
|
|
14493
14573
|
return this;
|
|
14494
14574
|
},
|
|
14495
14575
|
andWhere(expr, op, value) {
|
|
14496
|
-
|
|
14497
|
-
validateIdentifier(String(expr), "andWhere(column)");
|
|
14498
|
-
assertSafeWhereOperator(op, "andWhere(operator)");
|
|
14499
|
-
const paramIndex = whereParams.length + 1;
|
|
14500
|
-
whereConditions.push(`${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
|
|
14501
|
-
whereParams.push(value);
|
|
14502
|
-
text = `${text} AND ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`;
|
|
14503
|
-
built = null;
|
|
14504
|
-
return this;
|
|
14505
|
-
}
|
|
14506
|
-
if (Array.isArray(expr)) {
|
|
14507
|
-
const [col, op2, val] = expr;
|
|
14508
|
-
const colName = String(col);
|
|
14509
|
-
validateIdentifier(colName, "andWhere(column)");
|
|
14510
|
-
const operator = assertSafeWhereOperator(op2, "andWhere(operator)");
|
|
14511
|
-
if (operator === "in" || operator === "not in") {
|
|
14512
|
-
const values = Array.isArray(val) ? val : [val];
|
|
14513
|
-
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14514
|
-
whereConditions.push(`${colName} ${operator.toUpperCase()} (${placeholders})`);
|
|
14515
|
-
whereParams.push(...values);
|
|
14516
|
-
text = `${text} AND ${colName} ${operator.toUpperCase()} (${placeholders})`;
|
|
14517
|
-
built = null;
|
|
14518
|
-
} else {
|
|
14519
|
-
const paramIndex = whereParams.length + 1;
|
|
14520
|
-
whereConditions.push(`${colName} ${operator} ${getPlaceholder(paramIndex)}`);
|
|
14521
|
-
whereParams.push(val);
|
|
14522
|
-
text = `${text} AND ${colName} ${operator} ${getPlaceholder(paramIndex)}`;
|
|
14523
|
-
built = null;
|
|
14524
|
-
}
|
|
14525
|
-
return this;
|
|
14526
|
-
}
|
|
14527
|
-
if (expr && typeof expr === "object" && !("raw" in expr)) {
|
|
14528
|
-
const keys = Object.keys(expr);
|
|
14529
|
-
const conditions = [];
|
|
14530
|
-
for (const key of keys) {
|
|
14531
|
-
const value2 = expr[key];
|
|
14532
|
-
if (Array.isArray(value2)) {
|
|
14533
|
-
const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
|
|
14534
|
-
conditions.push(`${key} IN (${placeholders})`);
|
|
14535
|
-
whereConditions.push(`${key} IN (${placeholders})`);
|
|
14536
|
-
whereParams.push(...value2);
|
|
14537
|
-
} else {
|
|
14538
|
-
const paramIndex = whereParams.length + 1;
|
|
14539
|
-
conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
14540
|
-
whereConditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
14541
|
-
whereParams.push(value2);
|
|
14542
|
-
}
|
|
14543
|
-
}
|
|
14544
|
-
if (conditions.length > 0) {
|
|
14545
|
-
text = `${text} AND ${conditions.join(" AND ")}`;
|
|
14546
|
-
built = null;
|
|
14547
|
-
}
|
|
14548
|
-
return this;
|
|
14549
|
-
}
|
|
14550
|
-
if (expr && typeof expr.raw !== "undefined") {
|
|
14551
|
-
whereConditions.push(expr.raw);
|
|
14552
|
-
text = `${text} AND ${expr.raw}`;
|
|
14553
|
-
built = null;
|
|
14554
|
-
return this;
|
|
14555
|
-
}
|
|
14556
|
-
return this;
|
|
14576
|
+
return addBooleanWhere(this, "AND", "andWhere", expr, op, value);
|
|
14557
14577
|
},
|
|
14558
14578
|
orWhere(expr, op, value) {
|
|
14559
|
-
|
|
14560
|
-
validateIdentifier(String(expr), "orWhere(column)");
|
|
14561
|
-
assertSafeWhereOperator(op, "orWhere(operator)");
|
|
14562
|
-
const paramIndex = whereParams.length + 1;
|
|
14563
|
-
whereConditions.push(`OR ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`);
|
|
14564
|
-
whereParams.push(value);
|
|
14565
|
-
text = `${text} OR ${String(expr)} ${String(op)} ${getPlaceholder(paramIndex)}`;
|
|
14566
|
-
built = null;
|
|
14567
|
-
return this;
|
|
14568
|
-
}
|
|
14569
|
-
if (Array.isArray(expr)) {
|
|
14570
|
-
const [col, op2, val] = expr;
|
|
14571
|
-
const colName = String(col);
|
|
14572
|
-
validateIdentifier(colName, "orWhere(column)");
|
|
14573
|
-
const operator = assertSafeWhereOperator(op2, "orWhere(operator)");
|
|
14574
|
-
if (operator === "in" || operator === "not in") {
|
|
14575
|
-
const values = Array.isArray(val) ? val : [val];
|
|
14576
|
-
const placeholders = getPlaceholders(values.length, whereParams.length + 1);
|
|
14577
|
-
whereConditions.push(`OR ${colName} ${operator.toUpperCase()} (${placeholders})`);
|
|
14578
|
-
whereParams.push(...values);
|
|
14579
|
-
text = `${text} OR ${colName} ${operator.toUpperCase()} (${placeholders})`;
|
|
14580
|
-
built = null;
|
|
14581
|
-
} else {
|
|
14582
|
-
const paramIndex = whereParams.length + 1;
|
|
14583
|
-
whereConditions.push(`OR ${colName} ${operator} ${getPlaceholder(paramIndex)}`);
|
|
14584
|
-
whereParams.push(val);
|
|
14585
|
-
text = `${text} OR ${colName} ${operator} ${getPlaceholder(paramIndex)}`;
|
|
14586
|
-
built = null;
|
|
14587
|
-
}
|
|
14588
|
-
return this;
|
|
14589
|
-
}
|
|
14590
|
-
if (expr && typeof expr === "object" && !("raw" in expr)) {
|
|
14591
|
-
const keys = Object.keys(expr);
|
|
14592
|
-
const conditions = [];
|
|
14593
|
-
for (const key of keys) {
|
|
14594
|
-
const value2 = expr[key];
|
|
14595
|
-
if (Array.isArray(value2)) {
|
|
14596
|
-
const placeholders = getPlaceholders(value2.length, whereParams.length + 1);
|
|
14597
|
-
conditions.push(`${key} IN (${placeholders})`);
|
|
14598
|
-
whereConditions.push(`OR ${key} IN (${placeholders})`);
|
|
14599
|
-
whereParams.push(...value2);
|
|
14600
|
-
} else {
|
|
14601
|
-
const paramIndex = whereParams.length + 1;
|
|
14602
|
-
conditions.push(`${key} = ${getPlaceholder(paramIndex)}`);
|
|
14603
|
-
whereConditions.push(`OR ${key} = ${getPlaceholder(paramIndex)}`);
|
|
14604
|
-
whereParams.push(value2);
|
|
14605
|
-
}
|
|
14606
|
-
}
|
|
14607
|
-
if (conditions.length > 0) {
|
|
14608
|
-
text = `${text} OR ${conditions.join(" AND ")}`;
|
|
14609
|
-
built = null;
|
|
14610
|
-
}
|
|
14611
|
-
return this;
|
|
14612
|
-
}
|
|
14613
|
-
if (expr && typeof expr.raw !== "undefined") {
|
|
14614
|
-
whereConditions.push(`OR ${expr.raw}`);
|
|
14615
|
-
text = `${text} OR ${expr.raw}`;
|
|
14616
|
-
built = null;
|
|
14617
|
-
return this;
|
|
14618
|
-
}
|
|
14619
|
-
return this;
|
|
14579
|
+
return addBooleanWhere(this, "OR", "orWhere", expr, op, value);
|
|
14620
14580
|
},
|
|
14621
14581
|
orderBy(column, direction = "asc") {
|
|
14622
14582
|
const dir = direction === "asc" ? "ASC" : "DESC";
|
|
@@ -14853,7 +14813,7 @@ function createQueryBuilder(state) {
|
|
|
14853
14813
|
return this;
|
|
14854
14814
|
},
|
|
14855
14815
|
toSQL() {
|
|
14856
|
-
const sqlText = reorderSelectClauses(
|
|
14816
|
+
const sqlText = reorderSelectClauses(currentSql());
|
|
14857
14817
|
return {
|
|
14858
14818
|
sql: sqlText,
|
|
14859
14819
|
toString: () => sqlText,
|
|
@@ -14899,7 +14859,7 @@ function createQueryBuilder(state) {
|
|
|
14899
14859
|
if (!Number.isFinite(page) || page < 1 || !Number.isInteger(page))
|
|
14900
14860
|
throw new TypeError(`[query-builder] paginate(page): expected integer >= 1, got ${page}`);
|
|
14901
14861
|
if (opts.tx) {
|
|
14902
|
-
const baseSql = reorderSelectClauses(
|
|
14862
|
+
const baseSql = reorderSelectClauses(currentSql());
|
|
14903
14863
|
const baseParams = [...whereParams];
|
|
14904
14864
|
const cRows2 = await opts.tx.unsafe(`SELECT COUNT(*) as c FROM (${baseSql}) as sub`, baseParams);
|
|
14905
14865
|
const total2 = Number(cRows2?.[0]?.c ?? 0);
|
|
@@ -15019,8 +14979,8 @@ function createQueryBuilder(state) {
|
|
|
15019
14979
|
};
|
|
15020
14980
|
const predicate = `${table}.${softDeleteColumn} IS NOT NULL`;
|
|
15021
14981
|
text = splice(text, predicate);
|
|
15022
|
-
const
|
|
15023
|
-
built = sql([splice(
|
|
14982
|
+
const currentSql2 = String(ensureBuilt());
|
|
14983
|
+
built = sql([splice(currentSql2, predicate)]);
|
|
15024
14984
|
return this;
|
|
15025
14985
|
},
|
|
15026
14986
|
scope(name, value) {
|
|
@@ -15063,7 +15023,7 @@ function createQueryBuilder(state) {
|
|
|
15063
15023
|
return ensureBuilt().simple();
|
|
15064
15024
|
},
|
|
15065
15025
|
toText() {
|
|
15066
|
-
return
|
|
15026
|
+
return currentSql();
|
|
15067
15027
|
},
|
|
15068
15028
|
async get() {
|
|
15069
15029
|
const hooks = activeHooks();
|
|
@@ -15071,11 +15031,12 @@ function createQueryBuilder(state) {
|
|
|
15071
15031
|
if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !hasQueryHooks) {
|
|
15072
15032
|
const prepareFn = _sql._prepareStatement;
|
|
15073
15033
|
if (prepareFn) {
|
|
15074
|
-
const stmt = prepareFn(
|
|
15034
|
+
const stmt = prepareFn(currentSql());
|
|
15075
15035
|
return hydratePivotRows(whereParams.length > 0 ? stmt.all(...whereParams) : stmt.all());
|
|
15076
15036
|
}
|
|
15077
15037
|
}
|
|
15078
|
-
|
|
15038
|
+
const getText = currentSql();
|
|
15039
|
+
built = whereParams.length > 0 ? _sql.unsafe(getText, whereParams) : _sql.unsafe(getText);
|
|
15079
15040
|
if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !hasQueryHooks) {
|
|
15080
15041
|
const stmt = ensureBuilt()._stmt;
|
|
15081
15042
|
const params = ensureBuilt()._params;
|
|
@@ -15092,9 +15053,9 @@ function createQueryBuilder(state) {
|
|
|
15092
15053
|
const col = config5.softDeletes.column;
|
|
15093
15054
|
const tbl = String(table);
|
|
15094
15055
|
const hasCol = schema ? Boolean(schema[tbl]?.columns?.[col]) : true;
|
|
15095
|
-
if (hasCol && !SQL_PATTERNS.DELETED_AT.test(
|
|
15096
|
-
finalQuery = sql`${ensureBuilt()} WHERE ${sql(String(col))} IS ${onlyTrashed ? sql`NOT NULL` : sql`NULL`}`;
|
|
15056
|
+
if (hasCol && !SQL_PATTERNS.DELETED_AT.test(currentSql())) {
|
|
15097
15057
|
addWhereText("WHERE", `${String(col)} IS ${onlyTrashed ? "NOT " : ""}NULL`);
|
|
15058
|
+
finalQuery = ensureBuilt();
|
|
15098
15059
|
}
|
|
15099
15060
|
}
|
|
15100
15061
|
const cacheKey = useCache ? `${String(finalQuery)}\x00${JSON.stringify(whereParams)}` : "";
|
|
@@ -15124,7 +15085,8 @@ function createQueryBuilder(state) {
|
|
|
15124
15085
|
if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !fHasQueryHooks) {
|
|
15125
15086
|
const prepareFn = _sql._prepareStatement;
|
|
15126
15087
|
if (prepareFn) {
|
|
15127
|
-
const
|
|
15088
|
+
const base2 = currentSql();
|
|
15089
|
+
const firstText = base2.includes(" LIMIT ") ? base2 : `${base2} LIMIT 1`;
|
|
15128
15090
|
const stmt = prepareFn(firstText);
|
|
15129
15091
|
const rows2 = whereParams.length > 0 ? stmt.all(...whereParams) : stmt.all();
|
|
15130
15092
|
return hydratePivotRow(rows2[0]);
|
|
@@ -15191,13 +15153,14 @@ function createQueryBuilder(state) {
|
|
|
15191
15153
|
return fn(this);
|
|
15192
15154
|
},
|
|
15193
15155
|
async count() {
|
|
15194
|
-
const
|
|
15195
|
-
const
|
|
15156
|
+
const src = currentSql();
|
|
15157
|
+
const fromIdx = src.indexOf(" FROM ");
|
|
15158
|
+
const hasGroupBy = / GROUP BY /i.test(src);
|
|
15196
15159
|
let countText;
|
|
15197
15160
|
if (hasGroupBy) {
|
|
15198
|
-
countText = `SELECT COUNT(*) as c FROM (${
|
|
15161
|
+
countText = `SELECT COUNT(*) as c FROM (${src}) AS _bqb_count_sub`;
|
|
15199
15162
|
} else if (fromIdx !== -1) {
|
|
15200
|
-
countText = `SELECT COUNT(*) as c${
|
|
15163
|
+
countText = `SELECT COUNT(*) as c${src.substring(fromIdx)}`;
|
|
15201
15164
|
} else {
|
|
15202
15165
|
countText = `SELECT COUNT(*) as c FROM ${table}`;
|
|
15203
15166
|
}
|
|
@@ -15217,8 +15180,9 @@ function createQueryBuilder(state) {
|
|
|
15217
15180
|
return Number(row?.c ?? 0);
|
|
15218
15181
|
},
|
|
15219
15182
|
async avg(column) {
|
|
15220
|
-
const
|
|
15221
|
-
const
|
|
15183
|
+
const src = currentSql();
|
|
15184
|
+
const fromIdx = src.indexOf(" FROM ");
|
|
15185
|
+
const avgText = fromIdx !== -1 ? `SELECT AVG(${column}) as a${src.substring(fromIdx)}` : `SELECT AVG(${column}) as a FROM ${table}`;
|
|
15222
15186
|
const aHooks = activeHooks();
|
|
15223
15187
|
const aHasHooks = aHooks && (aHooks.onQueryStart || aHooks.onQueryEnd || aHooks.onQueryError || aHooks.startSpan || hasSlowQueryHook(aHooks));
|
|
15224
15188
|
if (!config5.softDeletes?.enabled && !useCache && !timeoutMs && !abortSignal && !aHasHooks) {
|
|
@@ -15235,24 +15199,27 @@ function createQueryBuilder(state) {
|
|
|
15235
15199
|
return Number(row?.a ?? 0);
|
|
15236
15200
|
},
|
|
15237
15201
|
async sum(column) {
|
|
15238
|
-
const
|
|
15239
|
-
const
|
|
15202
|
+
const src = currentSql();
|
|
15203
|
+
const fromIdx = src.indexOf(" FROM ");
|
|
15204
|
+
const sumText = fromIdx !== -1 ? `SELECT SUM(${column}) as s${src.substring(fromIdx)}` : `SELECT SUM(${column}) as s FROM ${table}`;
|
|
15240
15205
|
const q = whereParams.length > 0 ? _sql.unsafe(sumText, whereParams) : _sql.unsafe(sumText);
|
|
15241
15206
|
const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
|
|
15242
15207
|
const [row] = rows;
|
|
15243
15208
|
return Number(row?.s ?? 0);
|
|
15244
15209
|
},
|
|
15245
15210
|
async max(column) {
|
|
15246
|
-
const
|
|
15247
|
-
const
|
|
15211
|
+
const src = currentSql();
|
|
15212
|
+
const fromIdx = src.indexOf(" FROM ");
|
|
15213
|
+
const maxText = fromIdx !== -1 ? `SELECT MAX(${column}) as m${src.substring(fromIdx)}` : `SELECT MAX(${column}) as m FROM ${table}`;
|
|
15248
15214
|
const q = whereParams.length > 0 ? _sql.unsafe(maxText, whereParams) : _sql.unsafe(maxText);
|
|
15249
15215
|
const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
|
|
15250
15216
|
const [row] = rows;
|
|
15251
15217
|
return row?.m;
|
|
15252
15218
|
},
|
|
15253
15219
|
async min(column) {
|
|
15254
|
-
const
|
|
15255
|
-
const
|
|
15220
|
+
const src = currentSql();
|
|
15221
|
+
const fromIdx = src.indexOf(" FROM ");
|
|
15222
|
+
const minText = fromIdx !== -1 ? `SELECT MIN(${column}) as m${src.substring(fromIdx)}` : `SELECT MIN(${column}) as m FROM ${table}`;
|
|
15256
15223
|
const q = whereParams.length > 0 ? _sql.unsafe(minText, whereParams) : _sql.unsafe(minText);
|
|
15257
15224
|
const rows = await runWithHooks(q, "select", { signal: abortSignal, timeoutMs });
|
|
15258
15225
|
const [row] = rows;
|
|
@@ -15291,7 +15258,7 @@ function createQueryBuilder(state) {
|
|
|
15291
15258
|
return [...whereParams];
|
|
15292
15259
|
},
|
|
15293
15260
|
__rawState() {
|
|
15294
|
-
return { sql: reorderSelectClauses(
|
|
15261
|
+
return { sql: reorderSelectClauses(currentSql()), params: [...whereParams] };
|
|
15295
15262
|
},
|
|
15296
15263
|
raw() {
|
|
15297
15264
|
return ensureBuilt().raw();
|
|
@@ -15335,8 +15302,6 @@ function createQueryBuilder(state) {
|
|
|
15335
15302
|
return () => receiver;
|
|
15336
15303
|
const column = chosen;
|
|
15337
15304
|
return (value) => {
|
|
15338
|
-
const expr = Array.isArray(value) ? sql`${sql(column)} IN ${sql(value)}` : sql`${sql(column)} = ${value}`;
|
|
15339
|
-
built = isOr ? sql`${ensureBuilt()} OR ${expr}` : isAnd ? sql`${ensureBuilt()} AND ${expr}` : sql`${ensureBuilt()} WHERE ${expr}`;
|
|
15340
15305
|
if (Array.isArray(value)) {
|
|
15341
15306
|
const phs = getPlaceholders(value.length, whereParams.length + 1);
|
|
15342
15307
|
addWhereText(isOr ? "OR" : isAnd ? "AND" : "WHERE", `${column} IN (${phs})`);
|
|
@@ -15391,8 +15356,7 @@ function createQueryBuilder(state) {
|
|
|
15391
15356
|
const subText = rawState?.sql ?? (typeof subExec === "string" ? subExec : subExec?.sql ?? String(subExec));
|
|
15392
15357
|
const subParams = rawState?.params ?? (Array.isArray(subExec?.values) ? subExec.values : []);
|
|
15393
15358
|
const baseText = `SELECT * FROM (${subText}) AS ${String(alias)}`;
|
|
15394
|
-
const appendWhere = (
|
|
15395
|
-
const kw = !hasWhere ? "WHERE" : connector === "WHERE" ? "AND" : connector;
|
|
15359
|
+
const appendWhere = (params, expr, op, value) => {
|
|
15396
15360
|
const out = [...params];
|
|
15397
15361
|
const cmp = (col, operator, val) => {
|
|
15398
15362
|
validateIdentifier(col, "selectFromSub where(column)");
|
|
@@ -15408,61 +15372,91 @@ function createQueryBuilder(state) {
|
|
|
15408
15372
|
return `${col} ${o} ${ph}`;
|
|
15409
15373
|
};
|
|
15410
15374
|
let clause;
|
|
15411
|
-
if (typeof expr === "string" && op !== undefined)
|
|
15375
|
+
if (typeof expr === "string" && op !== undefined) {
|
|
15412
15376
|
clause = cmp(expr, op, value);
|
|
15413
|
-
else if (Array.isArray(expr) && expr.length === 3)
|
|
15377
|
+
} else if (Array.isArray(expr) && expr.length === 3) {
|
|
15414
15378
|
clause = cmp(expr[0], expr[1], expr[2]);
|
|
15415
|
-
else if (expr && typeof expr === "object")
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15379
|
+
} else if (expr && typeof expr === "object") {
|
|
15380
|
+
const parts = Object.entries(expr).map(([k, v]) => cmp(k, "=", v));
|
|
15381
|
+
clause = parts.length > 1 ? `(${parts.join(" AND ")})` : parts[0];
|
|
15382
|
+
} else {
|
|
15383
|
+
return { clause: null, params };
|
|
15384
|
+
}
|
|
15385
|
+
return { clause, params: out };
|
|
15420
15386
|
};
|
|
15421
|
-
function makeSub(
|
|
15387
|
+
function makeSub(baseText2, terms, params, tail = "") {
|
|
15388
|
+
const body = renderWhereTerms(terms);
|
|
15389
|
+
const text = body ? `${baseText2} WHERE ${body}${tail}` : `${baseText2}${tail}`;
|
|
15422
15390
|
const build = () => params.length > 0 ? _sql.unsafe(text, params) : _sql.unsafe(text);
|
|
15391
|
+
const withTerm = (conn, expr, op, value) => {
|
|
15392
|
+
const r = appendWhere(params, expr, op, value);
|
|
15393
|
+
return r.clause === null ? makeSub(baseText2, terms, params, tail) : makeSub(baseText2, [...terms, { conn, sql: r.clause }], r.params, tail);
|
|
15394
|
+
};
|
|
15395
|
+
const withGroup = (conn, cb) => {
|
|
15396
|
+
const gTerms = [];
|
|
15397
|
+
let gParams = [...params];
|
|
15398
|
+
const add = (c) => (expr, op, value) => {
|
|
15399
|
+
const r = appendWhere(gParams, expr, op, value);
|
|
15400
|
+
if (r.clause !== null) {
|
|
15401
|
+
gTerms.push({ conn: c, sql: r.clause });
|
|
15402
|
+
gParams = r.params;
|
|
15403
|
+
}
|
|
15404
|
+
return collector;
|
|
15405
|
+
};
|
|
15406
|
+
const collector = { where: add("AND"), andWhere: add("AND"), orWhere: add("OR") };
|
|
15407
|
+
cb(collector);
|
|
15408
|
+
const body2 = renderWhereTerms(gTerms);
|
|
15409
|
+
if (!body2) {
|
|
15410
|
+
throw new TypeError("[query-builder] selectFromSub.whereGroup(callback): the callback added no conditions. " + "Add at least one where()/orWhere() to the builder it receives.");
|
|
15411
|
+
}
|
|
15412
|
+
return makeSub(baseText2, [...terms, { conn, sql: `(${body2})` }], gParams, tail);
|
|
15413
|
+
};
|
|
15423
15414
|
const base = {
|
|
15424
15415
|
distinct() {
|
|
15425
|
-
return makeSub(
|
|
15416
|
+
return makeSub(baseText2.replace(/^SELECT\s+/i, "SELECT DISTINCT "), terms, params, tail);
|
|
15426
15417
|
},
|
|
15427
15418
|
distinctOn(...columns) {
|
|
15428
15419
|
const cols = columns.map(String).join(", ");
|
|
15429
|
-
return makeSub(
|
|
15420
|
+
return makeSub(baseText2.replace(/^SELECT\s+/i, `SELECT DISTINCT ON (${cols}) `), terms, params, tail);
|
|
15430
15421
|
},
|
|
15431
15422
|
selectRaw(fragment) {
|
|
15432
15423
|
const frag = renderRawFragment(fragment, "selectFromSub.selectRaw(fragment)");
|
|
15433
|
-
const fromIdx =
|
|
15434
|
-
const
|
|
15435
|
-
return makeSub(
|
|
15424
|
+
const fromIdx = baseText2.indexOf(" FROM ");
|
|
15425
|
+
const newBase = fromIdx !== -1 ? `${baseText2.slice(0, fromIdx)}, ${frag}${baseText2.slice(fromIdx)}` : `${baseText2}, ${frag}`;
|
|
15426
|
+
return makeSub(newBase, terms, params, tail);
|
|
15436
15427
|
},
|
|
15437
15428
|
where(expr, op, value) {
|
|
15438
|
-
|
|
15439
|
-
return makeSub(r.text, r.params, true);
|
|
15429
|
+
return withTerm("AND", expr, op, value);
|
|
15440
15430
|
},
|
|
15441
15431
|
andWhere(expr, op, value) {
|
|
15442
|
-
|
|
15443
|
-
return makeSub(r.text, r.params, true);
|
|
15432
|
+
return withTerm("AND", expr, op, value);
|
|
15444
15433
|
},
|
|
15445
15434
|
orWhere(expr, op, value) {
|
|
15446
|
-
|
|
15447
|
-
|
|
15435
|
+
return withTerm("OR", expr, op, value);
|
|
15436
|
+
},
|
|
15437
|
+
whereGroup(cb) {
|
|
15438
|
+
return withGroup("AND", cb);
|
|
15439
|
+
},
|
|
15440
|
+
orWhereGroup(cb) {
|
|
15441
|
+
return withGroup("OR", cb);
|
|
15448
15442
|
},
|
|
15449
15443
|
orderBy(column, direction = "asc") {
|
|
15450
15444
|
validateIdentifier(String(column), "selectFromSub.orderBy(column)");
|
|
15451
15445
|
const dir = direction === "asc" ? "ASC" : "DESC";
|
|
15452
|
-
const
|
|
15453
|
-
return makeSub(
|
|
15446
|
+
const newTail = SQL_PATTERNS.ORDER_BY.test(tail) ? `${tail}, ${column} ${dir}` : `${tail} ORDER BY ${column} ${dir}`;
|
|
15447
|
+
return makeSub(baseText2, terms, params, newTail);
|
|
15454
15448
|
},
|
|
15455
15449
|
limit(n) {
|
|
15456
15450
|
if (!Number.isInteger(n) || n < 0)
|
|
15457
15451
|
throw new TypeError(`[query-builder] selectFromSub.limit(n): expected non-negative integer, got ${n}`);
|
|
15458
|
-
const
|
|
15459
|
-
return makeSub(
|
|
15452
|
+
const newTail = SQL_PATTERNS.LIMIT.test(tail) ? tail.replace(SQL_PATTERNS.LIMIT, ` LIMIT ${n}`) : `${tail} LIMIT ${n}`;
|
|
15453
|
+
return makeSub(baseText2, terms, params, newTail);
|
|
15460
15454
|
},
|
|
15461
15455
|
offset(n) {
|
|
15462
15456
|
if (!Number.isInteger(n) || n < 0)
|
|
15463
15457
|
throw new TypeError(`[query-builder] selectFromSub.offset(n): expected non-negative integer, got ${n}`);
|
|
15464
|
-
const
|
|
15465
|
-
return makeSub(
|
|
15458
|
+
const newTail = SQL_PATTERNS.OFFSET.test(tail) ? tail.replace(SQL_PATTERNS.OFFSET, ` OFFSET ${n}`) : `${tail} OFFSET ${n}`;
|
|
15459
|
+
return makeSub(baseText2, terms, params, newTail);
|
|
15466
15460
|
},
|
|
15467
15461
|
toSQL() {
|
|
15468
15462
|
return makeExecutableQuery(build(), text);
|
|
@@ -15545,8 +15539,13 @@ function createQueryBuilder(state) {
|
|
|
15545
15539
|
whereJsonContains: subqueryNotSupported("whereJsonContains"),
|
|
15546
15540
|
whereJsonPath: subqueryNotSupported("whereJsonPath"),
|
|
15547
15541
|
whereNull: subqueryNotSupported("whereNull"),
|
|
15542
|
+
orWhereNull: subqueryNotSupported("orWhereNull"),
|
|
15548
15543
|
whereNotNull: subqueryNotSupported("whereNotNull"),
|
|
15544
|
+
orWhereNotNull: subqueryNotSupported("orWhereNotNull"),
|
|
15549
15545
|
whereExists: subqueryNotSupported("whereExists"),
|
|
15546
|
+
orWhereExists: subqueryNotSupported("orWhereExists"),
|
|
15547
|
+
orWhereBetween: subqueryNotSupported("orWhereBetween"),
|
|
15548
|
+
orWhereRaw: subqueryNotSupported("orWhereRaw"),
|
|
15550
15549
|
whereJsonDoesntContain: subqueryNotSupported("whereJsonDoesntContain"),
|
|
15551
15550
|
whereJsonContainsKey: subqueryNotSupported("whereJsonContainsKey"),
|
|
15552
15551
|
whereJsonDoesntContainKey: subqueryNotSupported("whereJsonDoesntContainKey"),
|
|
@@ -15625,7 +15624,7 @@ function createQueryBuilder(state) {
|
|
|
15625
15624
|
};
|
|
15626
15625
|
return base;
|
|
15627
15626
|
}
|
|
15628
|
-
return makeSub(baseText, subParams);
|
|
15627
|
+
return makeSub(baseText, [], subParams);
|
|
15629
15628
|
},
|
|
15630
15629
|
insertInto(table) {
|
|
15631
15630
|
let built;
|
|
@@ -16730,7 +16729,7 @@ function clearQueryCache() {
|
|
|
16730
16729
|
function setQueryCacheMaxSize(size) {
|
|
16731
16730
|
queryCache.setMaxSize(size);
|
|
16732
16731
|
}
|
|
16733
|
-
var
|
|
16732
|
+
var SQL_PATTERNS, SAFE_WHERE_OPERATORS, warnedSqlFragmentContexts, queryCache, reorderCache, REORDER_CACHE_MAX = 500;
|
|
16734
16733
|
var init_client = __esm(() => {
|
|
16735
16734
|
init_config();
|
|
16736
16735
|
init_db();
|
|
@@ -19465,7 +19464,7 @@ var init_migrate = __esm(() => {
|
|
|
19465
19464
|
init_src2();
|
|
19466
19465
|
init_introspect_db();
|
|
19467
19466
|
init_workspace();
|
|
19468
|
-
NON_TRANSACTIONAL_SQL = /\bCONCURRENTLY\b|^\s*VACUUM\b/im;
|
|
19467
|
+
NON_TRANSACTIONAL_SQL = /\bCONCURRENTLY\b|^\s*VACUUM\b|^\s*BEGIN\s*(?:;|TRANSACTION\b)|^\s*PRAGMA\s+foreign_keys\b/im;
|
|
19469
19468
|
});
|
|
19470
19469
|
|
|
19471
19470
|
// src/actions/migrate-generate.ts
|
|
@@ -20524,6 +20523,135 @@ var init_actions = __esm(() => {
|
|
|
20524
20523
|
init_wait_ready();
|
|
20525
20524
|
});
|
|
20526
20525
|
|
|
20526
|
+
// src/faker-compat.ts
|
|
20527
|
+
function asStringOptions(value) {
|
|
20528
|
+
if (typeof value === "number")
|
|
20529
|
+
return { length: value };
|
|
20530
|
+
return value;
|
|
20531
|
+
}
|
|
20532
|
+
function asNumberOptions(value) {
|
|
20533
|
+
if (typeof value === "number")
|
|
20534
|
+
return { max: value };
|
|
20535
|
+
return value;
|
|
20536
|
+
}
|
|
20537
|
+
function callable(value) {
|
|
20538
|
+
return typeof value === "function";
|
|
20539
|
+
}
|
|
20540
|
+
function flattened(name) {
|
|
20541
|
+
return name.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
20542
|
+
}
|
|
20543
|
+
function withFractionDigits(value, options) {
|
|
20544
|
+
if (!options || typeof options.fractionDigits !== "number")
|
|
20545
|
+
return value;
|
|
20546
|
+
return Number(value.toFixed(options.fractionDigits));
|
|
20547
|
+
}
|
|
20548
|
+
function compatModule(underlying, overrides = {}) {
|
|
20549
|
+
if (!underlying)
|
|
20550
|
+
return overrides;
|
|
20551
|
+
return new Proxy(underlying, {
|
|
20552
|
+
get(target, property) {
|
|
20553
|
+
if (property in overrides)
|
|
20554
|
+
return overrides[property];
|
|
20555
|
+
const direct = target[property];
|
|
20556
|
+
if (direct !== undefined)
|
|
20557
|
+
return direct;
|
|
20558
|
+
const fallback = target[flattened(property)];
|
|
20559
|
+
if (callable(fallback))
|
|
20560
|
+
return fallback.bind(target);
|
|
20561
|
+
return;
|
|
20562
|
+
}
|
|
20563
|
+
});
|
|
20564
|
+
}
|
|
20565
|
+
function createFakerCompatLayer(underlying) {
|
|
20566
|
+
const pick = (items) => {
|
|
20567
|
+
const list = Array.isArray(items) ? items : [];
|
|
20568
|
+
const index = Math.floor(Math.random() * list.length);
|
|
20569
|
+
return list[index];
|
|
20570
|
+
};
|
|
20571
|
+
const strings = () => underlying.string;
|
|
20572
|
+
const numbers = () => underlying.number;
|
|
20573
|
+
const random = () => underlying.random;
|
|
20574
|
+
const compatString = compatModule(underlying.string, {
|
|
20575
|
+
alpha: (options) => strings()?.alpha?.(asStringOptions(options)),
|
|
20576
|
+
alphanumeric: (options) => strings()?.alphanumeric?.(asStringOptions(options)),
|
|
20577
|
+
numeric: (options) => strings()?.numeric?.(asStringOptions(options)),
|
|
20578
|
+
sample: (options) => strings()?.sample?.(asStringOptions(options)),
|
|
20579
|
+
hexadecimal: (options) => strings()?.hexadecimal?.(asStringOptions(options))
|
|
20580
|
+
});
|
|
20581
|
+
const compatNumber = compatModule(underlying.number, {
|
|
20582
|
+
int: (options) => numbers()?.int?.(asNumberOptions(options)),
|
|
20583
|
+
float: (options) => {
|
|
20584
|
+
const parsed = asNumberOptions(options);
|
|
20585
|
+
return withFractionDigits(Number(numbers()?.float?.(parsed) ?? 0), parsed);
|
|
20586
|
+
}
|
|
20587
|
+
});
|
|
20588
|
+
const compatHelpers = compatModule(underlying.helpers, {
|
|
20589
|
+
arrayElement: pick,
|
|
20590
|
+
arrayElements: (items, count) => {
|
|
20591
|
+
const list = [...Array.isArray(items) ? items : []];
|
|
20592
|
+
const wanted = typeof count === "number" ? count : Math.max(1, Math.floor(Math.random() * list.length));
|
|
20593
|
+
for (let at = list.length - 1;at > 0; at -= 1) {
|
|
20594
|
+
const swap = Math.floor(Math.random() * (at + 1));
|
|
20595
|
+
[list[at], list[swap]] = [list[swap], list[at]];
|
|
20596
|
+
}
|
|
20597
|
+
return list.slice(0, Math.min(wanted, list.length));
|
|
20598
|
+
},
|
|
20599
|
+
shuffle: (items) => {
|
|
20600
|
+
const list = [...Array.isArray(items) ? items : []];
|
|
20601
|
+
for (let at = list.length - 1;at > 0; at -= 1) {
|
|
20602
|
+
const swap = Math.floor(Math.random() * (at + 1));
|
|
20603
|
+
[list[at], list[swap]] = [list[swap], list[at]];
|
|
20604
|
+
}
|
|
20605
|
+
return list;
|
|
20606
|
+
},
|
|
20607
|
+
maybe: (produce, options) => {
|
|
20608
|
+
const probability = typeof options?.probability === "number" ? options.probability : 0.5;
|
|
20609
|
+
return Math.random() < probability ? produce() : undefined;
|
|
20610
|
+
},
|
|
20611
|
+
slugify: (text) => String(text ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")
|
|
20612
|
+
});
|
|
20613
|
+
const compatDatatype = {
|
|
20614
|
+
boolean: (options) => {
|
|
20615
|
+
const probability = typeof options === "number" ? options : options?.probability;
|
|
20616
|
+
if (typeof probability === "number")
|
|
20617
|
+
return Math.random() < probability;
|
|
20618
|
+
return Boolean(random()?.boolean?.());
|
|
20619
|
+
},
|
|
20620
|
+
number: (options) => Number(numbers()?.int?.(asNumberOptions(options)) ?? 0),
|
|
20621
|
+
float: (options) => withFractionDigits(Number(numbers()?.float?.(options) ?? 0), options),
|
|
20622
|
+
uuid: () => crypto.randomUUID(),
|
|
20623
|
+
string: (length) => String(strings()?.alphanumeric?.({ length: length ?? 10 }) ?? ""),
|
|
20624
|
+
hexadecimal: (options) => String(strings()?.hexadecimal?.(asStringOptions(options)) ?? ""),
|
|
20625
|
+
array: (length) => Array.from({ length: length ?? 3 }, () => strings()?.alphanumeric?.({ length: 8 })),
|
|
20626
|
+
json: () => JSON.stringify({ value: strings()?.alphanumeric?.({ length: 8 }) })
|
|
20627
|
+
};
|
|
20628
|
+
const modules = {
|
|
20629
|
+
string: compatString,
|
|
20630
|
+
number: compatNumber,
|
|
20631
|
+
helpers: compatHelpers,
|
|
20632
|
+
datatype: compatDatatype,
|
|
20633
|
+
location: compatModule(underlying.address),
|
|
20634
|
+
address: compatModule(underlying.address),
|
|
20635
|
+
vehicle: compatModule(underlying.vehicle, {
|
|
20636
|
+
vrm: () => underlying.vehicle?.registration?.()
|
|
20637
|
+
}),
|
|
20638
|
+
company: compatModule(underlying.company, {
|
|
20639
|
+
catchPhrase: () => underlying.company?.catchphrase?.(),
|
|
20640
|
+
buzzPhrase: () => underlying.company?.bs?.() ?? underlying.company?.buzzword?.()
|
|
20641
|
+
})
|
|
20642
|
+
};
|
|
20643
|
+
return new Proxy(underlying, {
|
|
20644
|
+
get(target, property) {
|
|
20645
|
+
if (property in modules)
|
|
20646
|
+
return modules[property];
|
|
20647
|
+
const direct = target[property];
|
|
20648
|
+
if (direct && typeof direct === "object")
|
|
20649
|
+
return compatModule(direct);
|
|
20650
|
+
return direct;
|
|
20651
|
+
}
|
|
20652
|
+
});
|
|
20653
|
+
}
|
|
20654
|
+
|
|
20527
20655
|
// src/relation-utils.ts
|
|
20528
20656
|
function normalizeRelationEntry(entry) {
|
|
20529
20657
|
if (typeof entry === "string")
|
|
@@ -26231,9 +26359,8 @@ class ModelQueryBuilder {
|
|
|
26231
26359
|
return this._withRelations;
|
|
26232
26360
|
}
|
|
26233
26361
|
buildWhereClauses(params) {
|
|
26234
|
-
const
|
|
26235
|
-
for (
|
|
26236
|
-
const w = this._wheres[i2];
|
|
26362
|
+
const terms = [];
|
|
26363
|
+
for (const w of this._wheres) {
|
|
26237
26364
|
let clause;
|
|
26238
26365
|
if (w.raw) {
|
|
26239
26366
|
clause = w.raw;
|
|
@@ -26244,15 +26371,15 @@ class ModelQueryBuilder {
|
|
|
26244
26371
|
clause = w.operator === "=" ? `${col} IS NULL` : `${col} IS NOT NULL`;
|
|
26245
26372
|
} else if (w.operator === "in" || w.operator === "not in") {
|
|
26246
26373
|
const arr = w.value;
|
|
26247
|
-
clause =
|
|
26374
|
+
clause = renderInPredicate(sqlColumn(w.column), arr, w.operator === "not in", arr.map(() => "?").join(", "));
|
|
26248
26375
|
params.push(...arr);
|
|
26249
26376
|
} else {
|
|
26250
26377
|
clause = `${sqlColumn(w.column)} ${w.operator} ?`;
|
|
26251
26378
|
params.push(w.value);
|
|
26252
26379
|
}
|
|
26253
|
-
|
|
26380
|
+
terms.push({ conn: w.boolean === "or" ? "OR" : "AND", sql: clause });
|
|
26254
26381
|
}
|
|
26255
|
-
return
|
|
26382
|
+
return renderWhereTerms(terms);
|
|
26256
26383
|
}
|
|
26257
26384
|
softDeleteClause() {
|
|
26258
26385
|
if (this._trashed === "include" || !softDeletesEnabled(this._definition))
|
|
@@ -26844,27 +26971,6 @@ async function createTableFromModel(definition) {
|
|
|
26844
26971
|
}
|
|
26845
26972
|
await exec.run(`CREATE TABLE IF NOT EXISTS ${definition.table} (${columns.join(", ")})`, []);
|
|
26846
26973
|
}
|
|
26847
|
-
function createFakerCompatLayer(underlying) {
|
|
26848
|
-
return new Proxy(underlying, {
|
|
26849
|
-
get(target, prop) {
|
|
26850
|
-
if (prop === "location")
|
|
26851
|
-
return target.address;
|
|
26852
|
-
if (prop === "datatype") {
|
|
26853
|
-
const rng = target.random;
|
|
26854
|
-
const num = target.number;
|
|
26855
|
-
const str = target.string;
|
|
26856
|
-
return {
|
|
26857
|
-
boolean: () => rng?.boolean?.(),
|
|
26858
|
-
number: (opts) => num?.int?.(opts),
|
|
26859
|
-
float: (opts) => num?.float?.(opts),
|
|
26860
|
-
uuid: () => crypto.randomUUID(),
|
|
26861
|
-
string: (length) => str?.alphanumeric?.(length ?? 10)
|
|
26862
|
-
};
|
|
26863
|
-
}
|
|
26864
|
-
return target[prop];
|
|
26865
|
-
}
|
|
26866
|
-
});
|
|
26867
|
-
}
|
|
26868
26974
|
async function seedModel(definition, count, faker) {
|
|
26869
26975
|
const exec = getExecutor();
|
|
26870
26976
|
const seeder = definition.traits?.useSeeder;
|
|
@@ -29912,6 +30018,7 @@ export {
|
|
|
29912
30018
|
createQueryBuilder,
|
|
29913
30019
|
createModel,
|
|
29914
30020
|
createMigrationDriver,
|
|
30021
|
+
createFakerCompatLayer,
|
|
29915
30022
|
createDynamoDBToolingAdapter,
|
|
29916
30023
|
createDynamoDBQueryBuilder,
|
|
29917
30024
|
createDynamoDBItemBuilder,
|