@mlagie/sql-connector 3.0.2 → 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.2",
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,7 +106,7 @@ 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((_, i) => getDialect().getPlaceholder(values.length + i))
109
+ .map((_, i) => getDialect().getPlaceholder(offset + values.length + i))
110
110
  .join(",");
111
111
 
112
112
  conditions.push(
@@ -116,7 +116,7 @@ function buildWhere(where, values) {
116
116
  } else if (operatorValue === null && (operator === "=" || operator === "!=")) {
117
117
  conditions.push(`${getDialect().escape(key)} IS ${operator === "!=" ? "NOT " : ""}NULL`);
118
118
  } else {
119
- conditions.push(`${getDialect().escape(key)} ${operator} ${getDialect().getPlaceholder(values.length)}`);
119
+ conditions.push(`${getDialect().escape(key)} ${operator} ${getDialect().getPlaceholder(offset + values.length)}`);
120
120
  values.push(operatorValue);
121
121
  }
122
122
  }
@@ -129,7 +129,7 @@ function buildWhere(where, values) {
129
129
  continue;
130
130
  }
131
131
 
132
- conditions.push(`${getDialect().escape(key)} = ${getDialect().getPlaceholder(values.length)}`);
132
+ conditions.push(`${getDialect().escape(key)} = ${getDialect().getPlaceholder(offset + values.length)}`);
133
133
  values.push(value);
134
134
  }
135
135
 
@@ -139,9 +139,10 @@ function buildWhere(where, values) {
139
139
  /**
140
140
  * Construit les parties de la requête et extrait les valeurs sécurisées
141
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)
142
143
  * @returns {Object} Un objet contenant la chaîne SQL générée et le tableau des valeurs { sql, values }
143
144
  */
144
- function buildQueryParts(options) {
145
+ function buildQueryParts(options, valueOffset = 0) {
145
146
  const parts = [];
146
147
  const values = [];
147
148
 
@@ -152,7 +153,7 @@ function buildQueryParts(options) {
152
153
  if (typeof options.where !== 'object' || Array.isArray(options.where)) {
153
154
  throw new Error("Raw string WHERE clauses are not allowed. Use a structured filter instead.");
154
155
  }
155
- parts.push(`WHERE ${buildWhere(options.where, values)}`);
156
+ parts.push(`WHERE ${buildWhere(options.where, values, valueOffset)}`);
156
157
  }
157
158
 
158
159
  if (options.groupBy) {
@@ -177,7 +178,7 @@ function buildQueryParts(options) {
177
178
  throw new Error("Invalid LIMIT value");
178
179
  }
179
180
 
180
- parts.push(`LIMIT ?`);
181
+ parts.push(`LIMIT ${getDialect().getPlaceholder(valueOffset + values.length)}`);
181
182
  values.push(options.limit);
182
183
  }
183
184