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