retold-data-service 2.0.28 → 2.0.29

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": "retold-data-service",
3
- "version": "2.0.28",
3
+ "version": "2.0.29",
4
4
  "description": "Serve up a whole model!",
5
5
  "main": "source/Retold-Data-Service.js",
6
6
  "bin": {
@@ -509,43 +509,69 @@ module.exports = (pDataClonerService, pOratorServiceServer) =>
509
509
  }
510
510
 
511
511
  // MySQL / MSSQL / PostgreSQL: async execution via connection pool
512
- // MySQL pool.query uses callbacks; MSSQL/PostgreSQL pool.query returns a promise.
513
512
  if (tmpActiveProvider.pool)
514
513
  {
515
- let tmpQueryResult = tmpActiveProvider.pool.query(tmpSQL,
516
- (pQueryError) =>
517
- {
518
- // Callback-style (MySQL) only fires if pool.query
519
- // accepted the callback parameter
520
- if (pQueryError)
521
- {
522
- tmpFable.log.warn(`Data Cloner: Migration failed: ${tmpSQL} — ${pQueryError}`);
523
- }
524
- else
525
- {
526
- tmpFable.log.info(`Data Cloner: Migration applied: ${tmpSQL}`);
527
- tmpExecutedStatements.push(tmpSQL);
528
- }
529
- return fExecNext(pIndex + 1);
530
- });
531
-
532
- // Promise-style (MSSQL / PostgreSQL) — if query returned a thenable,
533
- // handle it; the callback above will not fire in this case.
534
- if (tmpQueryResult && typeof(tmpQueryResult.then) === 'function')
514
+ // For MSSQL multi-statement batches (containing DECLARE,
515
+ // cursors, dynamic SQL with QUOTENAME, etc.), pool.query()
516
+ // wraps SQL in sp_executesql which cannot handle these
517
+ // constructs. Use request.batch() instead, which sends
518
+ // raw T-SQL without wrapping.
519
+ let tmpIsBatch = (tmpProviderName === 'MSSQL') && tmpSQL.indexOf('DECLARE') >= 0
520
+ && typeof(tmpActiveProvider.pool.request) === 'function';
521
+
522
+ if (tmpIsBatch)
535
523
  {
536
- tmpQueryResult
524
+ tmpActiveProvider.pool.request().batch(tmpSQL)
537
525
  .then(() =>
538
526
  {
539
527
  tmpFable.log.info(`Data Cloner: Migration applied: ${tmpSQL}`);
540
528
  tmpExecutedStatements.push(tmpSQL);
541
529
  return fExecNext(pIndex + 1);
542
530
  })
543
- .catch((pPromiseError) =>
531
+ .catch((pBatchError) =>
544
532
  {
545
- tmpFable.log.warn(`Data Cloner: Migration failed: ${tmpSQL} — ${pPromiseError}`);
533
+ tmpFable.log.warn(`Data Cloner: Migration failed: ${tmpSQL} — ${pBatchError}`);
546
534
  return fExecNext(pIndex + 1);
547
535
  });
548
536
  }
537
+ else
538
+ {
539
+ // MySQL uses callbacks; MSSQL/PostgreSQL pool.query returns a promise.
540
+ let tmpQueryResult = tmpActiveProvider.pool.query(tmpSQL,
541
+ (pQueryError) =>
542
+ {
543
+ // Callback-style (MySQL) — only fires if pool.query
544
+ // accepted the callback parameter
545
+ if (pQueryError)
546
+ {
547
+ tmpFable.log.warn(`Data Cloner: Migration failed: ${tmpSQL} — ${pQueryError}`);
548
+ }
549
+ else
550
+ {
551
+ tmpFable.log.info(`Data Cloner: Migration applied: ${tmpSQL}`);
552
+ tmpExecutedStatements.push(tmpSQL);
553
+ }
554
+ return fExecNext(pIndex + 1);
555
+ });
556
+
557
+ // Promise-style (MSSQL / PostgreSQL) — if query returned a thenable,
558
+ // handle it; the callback above will not fire in this case.
559
+ if (tmpQueryResult && typeof(tmpQueryResult.then) === 'function')
560
+ {
561
+ tmpQueryResult
562
+ .then(() =>
563
+ {
564
+ tmpFable.log.info(`Data Cloner: Migration applied: ${tmpSQL}`);
565
+ tmpExecutedStatements.push(tmpSQL);
566
+ return fExecNext(pIndex + 1);
567
+ })
568
+ .catch((pPromiseError) =>
569
+ {
570
+ tmpFable.log.warn(`Data Cloner: Migration failed: ${tmpSQL} — ${pPromiseError}`);
571
+ return fExecNext(pIndex + 1);
572
+ });
573
+ }
574
+ }
549
575
  }
550
576
  else
551
577
  {