sqlite-zod-orm 3.4.0 → 3.4.1
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/index.js +27 -3
- package/package.json +1 -1
- package/src/database.ts +34 -1
- package/src/query-builder.ts +7 -2
package/dist/index.js
CHANGED
|
@@ -112,6 +112,8 @@ function compileIQO(tableName, iqo) {
|
|
|
112
112
|
sql += ` WHERE ${compiled.sql}`;
|
|
113
113
|
params.push(...compiled.params);
|
|
114
114
|
} else if (iqo.wheres.length > 0) {
|
|
115
|
+
const hasJoins = iqo.joins.length > 0;
|
|
116
|
+
const qualify = (field) => hasJoins && !field.includes(".") ? `${tableName}.${field}` : field;
|
|
115
117
|
const whereParts = [];
|
|
116
118
|
for (const w of iqo.wheres) {
|
|
117
119
|
if (w.operator === "IN") {
|
|
@@ -120,11 +122,11 @@ function compileIQO(tableName, iqo) {
|
|
|
120
122
|
whereParts.push("1 = 0");
|
|
121
123
|
} else {
|
|
122
124
|
const placeholders = arr.map(() => "?").join(", ");
|
|
123
|
-
whereParts.push(`${w.field} IN (${placeholders})`);
|
|
125
|
+
whereParts.push(`${qualify(w.field)} IN (${placeholders})`);
|
|
124
126
|
params.push(...arr.map(transformValueForStorage));
|
|
125
127
|
}
|
|
126
128
|
} else {
|
|
127
|
-
whereParts.push(`${w.field} ${w.operator} ?`);
|
|
129
|
+
whereParts.push(`${qualify(w.field)} ${w.operator} ?`);
|
|
128
130
|
params.push(transformValueForStorage(w.value));
|
|
129
131
|
}
|
|
130
132
|
}
|
|
@@ -4955,7 +4957,29 @@ class _Database {
|
|
|
4955
4957
|
return null;
|
|
4956
4958
|
};
|
|
4957
4959
|
const revisionGetter = () => this._getRevision(entityName);
|
|
4958
|
-
const
|
|
4960
|
+
const conditionResolver = (conditions) => {
|
|
4961
|
+
const resolved = {};
|
|
4962
|
+
for (const [key, value] of Object.entries(conditions)) {
|
|
4963
|
+
if (value && typeof value === "object" && typeof value.id === "number" && typeof value.delete === "function") {
|
|
4964
|
+
const fkCol = key + "_id";
|
|
4965
|
+
const rel = this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.foreignKey === fkCol);
|
|
4966
|
+
if (rel) {
|
|
4967
|
+
resolved[fkCol] = value.id;
|
|
4968
|
+
} else {
|
|
4969
|
+
const relByNav = this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.to === key + "s") || this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.to === key);
|
|
4970
|
+
if (relByNav) {
|
|
4971
|
+
resolved[relByNav.foreignKey] = value.id;
|
|
4972
|
+
} else {
|
|
4973
|
+
resolved[key] = value;
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
} else {
|
|
4977
|
+
resolved[key] = value;
|
|
4978
|
+
}
|
|
4979
|
+
}
|
|
4980
|
+
return resolved;
|
|
4981
|
+
};
|
|
4982
|
+
const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, conditionResolver, revisionGetter);
|
|
4959
4983
|
if (initialCols.length > 0)
|
|
4960
4984
|
builder.select(...initialCols);
|
|
4961
4985
|
return builder;
|
package/package.json
CHANGED
package/src/database.ts
CHANGED
|
@@ -453,7 +453,40 @@ class _Database<Schemas extends SchemaMap> {
|
|
|
453
453
|
// Pass revision getter — allows .subscribe() to detect ALL changes
|
|
454
454
|
const revisionGetter = () => this._getRevision(entityName);
|
|
455
455
|
|
|
456
|
-
|
|
456
|
+
// Condition resolver: { author: aliceEntity } → { author_id: 1 }
|
|
457
|
+
const conditionResolver = (conditions: Record<string, any>): Record<string, any> => {
|
|
458
|
+
const resolved: Record<string, any> = {};
|
|
459
|
+
for (const [key, value] of Object.entries(conditions)) {
|
|
460
|
+
// Detect entity references: objects with `id` and `delete` (augmented entities)
|
|
461
|
+
if (value && typeof value === 'object' && typeof value.id === 'number' && typeof value.delete === 'function') {
|
|
462
|
+
// Find a belongs-to relationship: entityName has a FK named `key_id` pointing to another table
|
|
463
|
+
const fkCol = key + '_id';
|
|
464
|
+
const rel = this.relationships.find(
|
|
465
|
+
r => r.type === 'belongs-to' && r.from === entityName && r.foreignKey === fkCol
|
|
466
|
+
);
|
|
467
|
+
if (rel) {
|
|
468
|
+
resolved[fkCol] = value.id;
|
|
469
|
+
} else {
|
|
470
|
+
// Fallback: try any relationship that matches the key as the nav name
|
|
471
|
+
const relByNav = this.relationships.find(
|
|
472
|
+
r => r.type === 'belongs-to' && r.from === entityName && r.to === key + 's'
|
|
473
|
+
) || this.relationships.find(
|
|
474
|
+
r => r.type === 'belongs-to' && r.from === entityName && r.to === key
|
|
475
|
+
);
|
|
476
|
+
if (relByNav) {
|
|
477
|
+
resolved[relByNav.foreignKey] = value.id;
|
|
478
|
+
} else {
|
|
479
|
+
resolved[key] = value; // pass through
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
} else {
|
|
483
|
+
resolved[key] = value;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return resolved;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, conditionResolver, revisionGetter);
|
|
457
490
|
if (initialCols.length > 0) builder.select(...initialCols);
|
|
458
491
|
return builder;
|
|
459
492
|
}
|
package/src/query-builder.ts
CHANGED
|
@@ -86,6 +86,11 @@ export function compileIQO(tableName: string, iqo: IQO): { sql: string; params:
|
|
|
86
86
|
sql += ` WHERE ${compiled.sql}`;
|
|
87
87
|
params.push(...compiled.params);
|
|
88
88
|
} else if (iqo.wheres.length > 0) {
|
|
89
|
+
const hasJoins = iqo.joins.length > 0;
|
|
90
|
+
// When joins exist, qualify bare column names with the main table
|
|
91
|
+
const qualify = (field: string) =>
|
|
92
|
+
hasJoins && !field.includes('.') ? `${tableName}.${field}` : field;
|
|
93
|
+
|
|
89
94
|
const whereParts: string[] = [];
|
|
90
95
|
for (const w of iqo.wheres) {
|
|
91
96
|
if (w.operator === 'IN') {
|
|
@@ -94,11 +99,11 @@ export function compileIQO(tableName: string, iqo: IQO): { sql: string; params:
|
|
|
94
99
|
whereParts.push('1 = 0');
|
|
95
100
|
} else {
|
|
96
101
|
const placeholders = arr.map(() => '?').join(', ');
|
|
97
|
-
whereParts.push(`${w.field} IN (${placeholders})`);
|
|
102
|
+
whereParts.push(`${qualify(w.field)} IN (${placeholders})`);
|
|
98
103
|
params.push(...arr.map(transformValueForStorage));
|
|
99
104
|
}
|
|
100
105
|
} else {
|
|
101
|
-
whereParts.push(`${w.field} ${w.operator} ?`);
|
|
106
|
+
whereParts.push(`${qualify(w.field)} ${w.operator} ?`);
|
|
102
107
|
params.push(transformValueForStorage(w.value));
|
|
103
108
|
}
|
|
104
109
|
}
|