@mlagie/sql-connector 3.0.1 → 3.0.3
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mlagie/sql-connector",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "The sql-connector module allows you to manage connections to a MySQL database, define table schemas, and interact with data in a simple and efficient way.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
@@ -88,8 +88,8 @@ class ModelInstance {
|
|
|
88
88
|
const dialect = getDialect();
|
|
89
89
|
const values = Object.values(model);
|
|
90
90
|
|
|
91
|
-
const setClause = setKeys.map(key => {
|
|
92
|
-
return `${dialect.escape(key)} =
|
|
91
|
+
const setClause = setKeys.map((key, i) => {
|
|
92
|
+
return `${dialect.escape(key)} = ${dialect.getPlaceholder(i)}`;
|
|
93
93
|
}).join(', ');
|
|
94
94
|
|
|
95
95
|
let targetCriteria;
|
|
@@ -126,7 +126,7 @@ class ModelInstance {
|
|
|
126
126
|
targetCriteria = fallbackRec;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
const { sql: whereClause, values: whereValues } = buildQueryParts({ where: targetCriteria });
|
|
129
|
+
const { sql: whereClause, values: whereValues } = buildQueryParts({ where: targetCriteria }, setKeys.length);
|
|
130
130
|
values.push(...whereValues);
|
|
131
131
|
|
|
132
132
|
const sql_request = `UPDATE ${dialect.escape(this._name)} SET ${setClause} ${whereClause}`;
|
|
@@ -61,7 +61,7 @@ function buildSelect(select = []) {
|
|
|
61
61
|
.join(',\n');
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function buildWhere(where, values) {
|
|
64
|
+
function buildWhere(where, values, offset = 0) {
|
|
65
65
|
const conditions = [];
|
|
66
66
|
|
|
67
67
|
for (const [key, value] of Object.entries(where)) {
|
|
@@ -70,7 +70,7 @@ function buildWhere(where, values) {
|
|
|
70
70
|
throw new Error("OR conditions cannot be empty");
|
|
71
71
|
}
|
|
72
72
|
const clauses = value
|
|
73
|
-
.map((item) => buildWhere(item, values))
|
|
73
|
+
.map((item) => buildWhere(item, values, offset))
|
|
74
74
|
.filter(Boolean);
|
|
75
75
|
|
|
76
76
|
if (clauses.length) {
|
|
@@ -85,7 +85,7 @@ function buildWhere(where, values) {
|
|
|
85
85
|
throw new Error("AND conditions cannot be empty");
|
|
86
86
|
}
|
|
87
87
|
const clauses = value
|
|
88
|
-
.map((item) => buildWhere(item, values))
|
|
88
|
+
.map((item) => buildWhere(item, values, offset))
|
|
89
89
|
.filter(Boolean);
|
|
90
90
|
|
|
91
91
|
if (clauses.length) {
|
|
@@ -106,15 +106,17 @@ function buildWhere(where, values) {
|
|
|
106
106
|
for (const [operator, operatorValue] of Object.entries(value)) {
|
|
107
107
|
if (operator === "IN" || operator === "NOT IN") {
|
|
108
108
|
const placeholders = operatorValue
|
|
109
|
-
.map(() =>
|
|
109
|
+
.map((_, i) => getDialect().getPlaceholder(offset + values.length + i))
|
|
110
110
|
.join(",");
|
|
111
111
|
|
|
112
112
|
conditions.push(
|
|
113
113
|
`${getDialect().escape(key)} ${operator} (${placeholders})`
|
|
114
114
|
);
|
|
115
115
|
values.push(...operatorValue);
|
|
116
|
+
} else if (operatorValue === null && (operator === "=" || operator === "!=")) {
|
|
117
|
+
conditions.push(`${getDialect().escape(key)} IS ${operator === "!=" ? "NOT " : ""}NULL`);
|
|
116
118
|
} else {
|
|
117
|
-
conditions.push(`${getDialect().escape(key)} ${operator}
|
|
119
|
+
conditions.push(`${getDialect().escape(key)} ${operator} ${getDialect().getPlaceholder(offset + values.length)}`);
|
|
118
120
|
values.push(operatorValue);
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -122,7 +124,12 @@ function buildWhere(where, values) {
|
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
|
|
127
|
+
if (value === null) {
|
|
128
|
+
conditions.push(`${getDialect().escape(key)} IS NULL`);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
conditions.push(`${getDialect().escape(key)} = ${getDialect().getPlaceholder(offset + values.length)}`);
|
|
126
133
|
values.push(value);
|
|
127
134
|
}
|
|
128
135
|
|
|
@@ -132,9 +139,10 @@ function buildWhere(where, values) {
|
|
|
132
139
|
/**
|
|
133
140
|
* Construit les parties de la requête et extrait les valeurs sécurisées
|
|
134
141
|
* @param {Object} options Options de filtrage, tri et pagination
|
|
142
|
+
* @param {number} [valueOffset=0] Décalage d'index pour les placeholders (utile quand des valeurs ont déjà été liées avant le WHERE, ex: SET d'un UPDATE)
|
|
135
143
|
* @returns {Object} Un objet contenant la chaîne SQL générée et le tableau des valeurs { sql, values }
|
|
136
144
|
*/
|
|
137
|
-
function buildQueryParts(options) {
|
|
145
|
+
function buildQueryParts(options, valueOffset = 0) {
|
|
138
146
|
const parts = [];
|
|
139
147
|
const values = [];
|
|
140
148
|
|
|
@@ -145,7 +153,7 @@ function buildQueryParts(options) {
|
|
|
145
153
|
if (typeof options.where !== 'object' || Array.isArray(options.where)) {
|
|
146
154
|
throw new Error("Raw string WHERE clauses are not allowed. Use a structured filter instead.");
|
|
147
155
|
}
|
|
148
|
-
parts.push(`WHERE ${buildWhere(options.where, values)}`);
|
|
156
|
+
parts.push(`WHERE ${buildWhere(options.where, values, valueOffset)}`);
|
|
149
157
|
}
|
|
150
158
|
|
|
151
159
|
if (options.groupBy) {
|
|
@@ -169,8 +177,8 @@ function buildQueryParts(options) {
|
|
|
169
177
|
if (!Number.isInteger(options.limit) || options.limit < 0) {
|
|
170
178
|
throw new Error("Invalid LIMIT value");
|
|
171
179
|
}
|
|
172
|
-
|
|
173
|
-
parts.push(`LIMIT
|
|
180
|
+
|
|
181
|
+
parts.push(`LIMIT ${getDialect().getPlaceholder(valueOffset + values.length)}`);
|
|
174
182
|
values.push(options.limit);
|
|
175
183
|
}
|
|
176
184
|
|