@bkmj/node-red-contrib-odbcmj 2.1.3 → 2.1.4

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.
Files changed (2) hide show
  1. package/odbc.js +54 -47
  2. package/package.json +1 -1
package/odbc.js CHANGED
@@ -122,7 +122,7 @@ module.exports = function (RED) {
122
122
  // ... (Pas de changement dans cette section)
123
123
  });
124
124
 
125
-
125
+
126
126
  // --- ODBC Query Node ---
127
127
  function odbc(config) {
128
128
  RED.nodes.createNode(this, config);
@@ -203,60 +203,67 @@ module.exports = function (RED) {
203
203
  // NOUVELLE IMPLEMENTATION DU STREAMING
204
204
  // =================================================================
205
205
  this.executeStreamQuery = async (dbConnection, queryString, queryParams, msg, send) => {
206
- const chunkSize = parseInt(this.config.streamChunkSize) || 1;
207
- const fetchSize = chunkSize > 50 ? 50 : chunkSize; // Optimisation : ne pas fetcher plus que nécessaire à la fois
208
- let cursor;
209
-
210
- try {
211
- // LA BONNE METHODE !
212
- cursor = await dbConnection.query(queryString, queryParams, { cursor: true, fetchSize: fetchSize });
206
+ const chunkSize = parseInt(this.config.streamChunkSize) || 1;
207
+ // La taille du fetch peut être optimisée, mais restons simple pour la clarté.
208
+ const fetchSize = chunkSize > 50 ? 50 : chunkSize;
209
+ let cursor;
213
210
 
214
- this.status({ fill: "blue", shape: "dot", text: "streaming rows..." });
211
+ try {
212
+ cursor = await dbConnection.query(queryString, queryParams, { cursor: true, fetchSize: fetchSize });
213
+ this.status({ fill: "blue", shape: "dot", text: "streaming rows..." });
215
214
 
216
- let rowCount = 0;
217
- let chunk = [];
218
- let rows;
219
-
220
- // .fetch() peut retourner plusieurs lignes à la fois, on boucle dessus
221
- while ((rows = await cursor.fetch())) {
222
- // Si fetch retourne un tableau vide, c'est la fin.
223
- if (rows.length === 0) break;
215
+ let rowCount = 0;
216
+ let chunk = [];
224
217
 
225
- for (const row of rows) {
226
- rowCount++;
227
- chunk.push(row);
228
- if (chunk.length >= chunkSize) {
229
- const newMsg = RED.util.cloneMessage(msg);
230
- objPath.set(newMsg, this.config.outputObj, chunk);
231
- newMsg.odbc_stream = { index: rowCount - chunk.length, count: chunk.length, complete: false };
232
- send(newMsg);
233
- chunk = [];
234
- }
218
+ // Boucle infinie qui sera rompue de l'intérieur
219
+ while (true) {
220
+ const rows = await cursor.fetch();
221
+
222
+ // 1. VÉRIFIER D'ABORD LA FIN DU FLUX
223
+ if (!rows || rows.length === 0) {
224
+ // Le flux de la base de données est terminé.
225
+ // Le contenu actuel de `chunk` est le tout dernier lot.
226
+ if (chunk.length > 0) {
227
+ const newMsg = RED.util.cloneMessage(msg);
228
+ objPath.set(newMsg, this.config.outputObj, chunk);
229
+ // C'est le message final, donc `complete` est TRUE.
230
+ newMsg.odbc_stream = { index: rowCount - chunk.length, count: chunk.length, complete: true };
231
+ send(newMsg);
232
+ } else if (rowCount === 0) {
233
+ // Gérer le cas où la requête ne retourne aucune ligne.
234
+ const newMsg = RED.util.cloneMessage(msg);
235
+ objPath.set(newMsg, this.config.outputObj, []);
236
+ newMsg.odbc_stream = { index: 0, count: 0, complete: true };
237
+ send(newMsg);
235
238
  }
239
+ // Quitter la boucle car il n'y a plus rien à faire.
240
+ break;
236
241
  }
237
-
238
- if (chunk.length > 0) {
239
- const newMsg = RED.util.cloneMessage(msg);
240
- objPath.set(newMsg, this.config.outputObj, chunk);
241
- newMsg.odbc_stream = { index: rowCount - chunk.length, count: chunk.length, complete: true };
242
- send(newMsg);
243
- }
244
-
245
- if (rowCount === 0) {
246
- const newMsg = RED.util.cloneMessage(msg);
247
- objPath.set(newMsg, this.config.outputObj, []);
248
- newMsg.odbc_stream = { index: 0, count: 0, complete: true };
249
- send(newMsg);
250
- }
251
-
252
- this.status({ fill: "green", shape: "dot", text: `success (${rowCount} rows)` });
253
242
 
254
- } finally {
255
- if (cursor) {
256
- await cursor.close();
243
+ // 2. S'IL Y A DES LIGNES, LES TRAITER
244
+ for (const row of rows) {
245
+ rowCount++;
246
+ chunk.push(row);
247
+ if (chunk.length >= chunkSize) {
248
+ const newMsg = RED.util.cloneMessage(msg);
249
+ objPath.set(newMsg, this.config.outputObj, chunk);
250
+ // Ce lot n'est pas le dernier, donc `complete` est FALSE.
251
+ newMsg.odbc_stream = { index: rowCount - chunk.length, count: chunk.length, complete: false };
252
+ send(newMsg);
253
+ // Vider le lot pour le prochain remplissage.
254
+ chunk = [];
255
+ }
257
256
  }
257
+ } // Fin de la boucle while
258
+
259
+ this.status({ fill: "green", shape: "dot", text: `success (${rowCount} rows)` });
260
+
261
+ } finally {
262
+ if (cursor) {
263
+ await cursor.close();
258
264
  }
259
- };
265
+ }
266
+ };
260
267
 
261
268
  // =================================================================
262
269
  // NOUVELLE LOGIQUE D'ENTREE UNIFIEE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bkmj/node-red-contrib-odbcmj",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "A powerful Node-RED node to connect to any ODBC data source, with connection pooling, advanced retry logic, and result streaming.",
5
5
  "keywords": [
6
6
  "node-red",