@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.
- package/odbc.js +54 -47
- 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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
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
|
-
|
|
217
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
+
"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",
|