orange-orm 4.7.5-beta.0 → 4.7.5

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/dist/index.mjs CHANGED
@@ -17444,59 +17444,100 @@ function requireWrapQuery$2 () {
17444
17444
  function runQuery(query, onCompleted) {
17445
17445
  var params = query.parameters;
17446
17446
  var sql = query.sql();
17447
- log.emitQuery({ sql, parameters: params });
17448
-
17449
- // Helper function to check for non-ASCII UTF-8 characters
17450
- function hasNonAsciiCharacters(str) {
17451
- // Check if string contains any character with code point > 127 (non-ASCII)
17452
- return /[\u0080-\uFFFF]/.test(str);
17453
- }
17454
-
17455
- function stringToHex(str) {
17456
- return Buffer.from(str, 'utf8').toString('hex');
17457
- }
17458
17447
 
17459
17448
  const replacements = [];
17460
17449
  const parametersToRemove = [];
17461
17450
  const engine = getSessionSingleton(_context, 'engine');
17462
17451
 
17463
17452
  if (engine === 'sap') {
17464
- //non-ASCII UTF-8 characters workaround
17465
- for (let i = 0; i < params.length; i++) {
17466
- const parameter = params[i];
17453
+ const sap = connection.msnodesqlv8;
17467
17454
 
17468
- if (typeof parameter === 'string' && hasNonAsciiCharacters(parameter)) {
17469
- const hexValue = stringToHex(parameter);
17470
- const convertClause = `CONVERT(VARCHAR(255), CONVERT(VARBINARY(127), 0x${hexValue}))`;
17455
+ // Check if this is a stored procedure call
17456
+ const isStoredProcCall = /EXECUTE\s+/i.test(sql) || /EXEC\s+/i.test(sql);
17457
+ let hexVariables = [];
17471
17458
 
17472
- replacements.push({
17473
- index: i,
17474
- replacement: convertClause
17475
- });
17459
+ // Non-ASCII UTF-8 characters workaround
17460
+ for (let i = 0; i < params.length; i++) {
17461
+ const parameter = params[i];
17476
17462
 
17477
- parametersToRemove.push(i);
17463
+ if (typeof parameter === 'string') {
17464
+ const paramLength = parameter.length;
17465
+ const byteLength = Buffer.from(parameter, 'utf8').length;
17466
+
17467
+ if (hasNonAsciiCharacters(parameter)) {
17468
+ const hexValue = stringToHex(parameter);
17469
+
17470
+ if (isStoredProcCall) {
17471
+ // For stored procedures, create a variable with exact lengths
17472
+ const varName = `@hex_param_${i}`;
17473
+ const convertClause = `CONVERT(VARCHAR(${paramLength}), CONVERT(VARBINARY(${byteLength}), 0x${hexValue}))`;
17474
+
17475
+ hexVariables.push({
17476
+ declaration: `DECLARE ${varName} VARCHAR(${paramLength})`,
17477
+ assignment: `SET ${varName} = ${convertClause}`
17478
+ });
17479
+
17480
+ replacements.push({
17481
+ index: i,
17482
+ replacement: varName
17483
+ });
17484
+ } else {
17485
+ // For regular queries, use inline conversion with exact lengths
17486
+ const convertClause = `CONVERT(VARCHAR(${paramLength}), CONVERT(VARBINARY(${byteLength}), 0x${hexValue}))`;
17487
+ replacements.push({
17488
+ index: i,
17489
+ replacement: convertClause
17490
+ });
17491
+ }
17492
+ parametersToRemove.push(i);
17493
+ } else {
17494
+ // For ASCII strings, use VarChar with exact byte length
17495
+ params[i] = sap.VarChar(parameter, byteLength);
17496
+ }
17478
17497
  }
17479
17498
  }
17480
- }
17481
17499
 
17482
- // Second pass: replace the ? placeholders at specific positions
17483
- if (replacements.length > 0) {
17484
- let questionMarkIndex = 0;
17485
- sql = sql.replace(/\?/g, (match) => {
17486
- const replacement = replacements.find(r => r.index === questionMarkIndex);
17487
- questionMarkIndex++;
17500
+ // Apply replacements
17501
+ if (replacements.length > 0) {
17502
+ let questionMarkIndex = 0;
17503
+ sql = sql.replace(/\?/g, (match) => {
17504
+ const replacement = replacements.find(r => r.index === questionMarkIndex);
17505
+ questionMarkIndex++;
17488
17506
 
17489
- if (replacement) {
17490
- return replacement.replacement;
17507
+ if (replacement) {
17508
+ return replacement.replacement;
17509
+ }
17510
+ return match;
17511
+ });
17512
+
17513
+ // For stored procedures, inject hex variable declarations
17514
+ if (isStoredProcCall && hexVariables.length > 0) {
17515
+ const lines = sql.split('\n');
17516
+ let insertIndex = 0;
17517
+
17518
+ // Find the last DECLARE statement
17519
+ for (let i = 0; i < lines.length; i++) {
17520
+ if (/^\s*DECLARE\s+/i.test(lines[i])) {
17521
+ insertIndex = i + 1;
17522
+ }
17523
+ }
17524
+
17525
+ // Insert hex variable declarations and assignments
17526
+ const hexDeclarations = hexVariables.map(v => v.declaration);
17527
+ const hexAssignments = hexVariables.map(v => v.assignment);
17528
+
17529
+ lines.splice(insertIndex, 0, ...hexDeclarations, ...hexAssignments);
17530
+ sql = lines.join('\n');
17491
17531
  }
17492
- return match;
17532
+ }
17533
+
17534
+ // Remove parameters in reverse order to maintain correct indices
17535
+ parametersToRemove.reverse().forEach(index => {
17536
+ params.splice(index, 1);
17493
17537
  });
17494
17538
  }
17495
17539
 
17496
- // Remove parameters in reverse order to maintain correct indices
17497
- parametersToRemove.reverse().forEach(index => {
17498
- params.splice(index, 1);
17499
- });
17540
+ log.emitQuery({ sql, parameters: params });
17500
17541
 
17501
17542
  runOriginalQuery.call(connection, sql, params, onInnerCompleted);
17502
17543
  let result = [];
@@ -17511,7 +17552,6 @@ function requireWrapQuery$2 () {
17511
17552
  }
17512
17553
  result.push(rows);
17513
17554
  if (!hasMore) {
17514
-
17515
17555
  if (result.length === 1)
17516
17556
  onCompleted(null, result[0]);
17517
17557
  else
@@ -17519,7 +17559,15 @@ function requireWrapQuery$2 () {
17519
17559
  }
17520
17560
  }
17521
17561
  }
17562
+ }
17563
+
17564
+ function hasNonAsciiCharacters(str) {
17565
+ // Check if string contains any character with code point > 127 (non-ASCII)
17566
+ return /[\u0080-\uFFFF]/.test(str);
17567
+ }
17522
17568
 
17569
+ function stringToHex(str) {
17570
+ return Buffer.from(str, 'utf8').toString('hex');
17523
17571
  }
17524
17572
 
17525
17573
  wrapQuery_1$2 = wrapQuery;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orange-orm",
3
- "version": "4.7.5-beta.0",
3
+ "version": "4.7.5",
4
4
  "main": "./src/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "browser": "./dist/index.browser.mjs",
@@ -8,59 +8,100 @@ function wrapQuery(_context, connection) {
8
8
  function runQuery(query, onCompleted) {
9
9
  var params = query.parameters;
10
10
  var sql = query.sql();
11
- log.emitQuery({ sql, parameters: params });
12
-
13
- // Helper function to check for non-ASCII UTF-8 characters
14
- function hasNonAsciiCharacters(str) {
15
- // Check if string contains any character with code point > 127 (non-ASCII)
16
- return /[\u0080-\uFFFF]/.test(str);
17
- }
18
-
19
- function stringToHex(str) {
20
- return Buffer.from(str, 'utf8').toString('hex');
21
- }
22
11
 
23
12
  const replacements = [];
24
13
  const parametersToRemove = [];
25
14
  const engine = getSessionSingleton(_context, 'engine');
26
15
 
27
16
  if (engine === 'sap') {
28
- //non-ASCII UTF-8 characters workaround
29
- for (let i = 0; i < params.length; i++) {
30
- const parameter = params[i];
17
+ const sap = connection.msnodesqlv8;
31
18
 
32
- if (typeof parameter === 'string' && hasNonAsciiCharacters(parameter)) {
33
- const hexValue = stringToHex(parameter);
34
- const convertClause = `CONVERT(VARCHAR(255), CONVERT(VARBINARY(127), 0x${hexValue}))`;
19
+ // Check if this is a stored procedure call
20
+ const isStoredProcCall = /EXECUTE\s+/i.test(sql) || /EXEC\s+/i.test(sql);
21
+ let hexVariables = [];
35
22
 
36
- replacements.push({
37
- index: i,
38
- replacement: convertClause
39
- });
23
+ // Non-ASCII UTF-8 characters workaround
24
+ for (let i = 0; i < params.length; i++) {
25
+ const parameter = params[i];
40
26
 
41
- parametersToRemove.push(i);
27
+ if (typeof parameter === 'string') {
28
+ const paramLength = parameter.length;
29
+ const byteLength = Buffer.from(parameter, 'utf8').length;
30
+
31
+ if (hasNonAsciiCharacters(parameter)) {
32
+ const hexValue = stringToHex(parameter);
33
+
34
+ if (isStoredProcCall) {
35
+ // For stored procedures, create a variable with exact lengths
36
+ const varName = `@hex_param_${i}`;
37
+ const convertClause = `CONVERT(VARCHAR(${paramLength}), CONVERT(VARBINARY(${byteLength}), 0x${hexValue}))`;
38
+
39
+ hexVariables.push({
40
+ declaration: `DECLARE ${varName} VARCHAR(${paramLength})`,
41
+ assignment: `SET ${varName} = ${convertClause}`
42
+ });
43
+
44
+ replacements.push({
45
+ index: i,
46
+ replacement: varName
47
+ });
48
+ } else {
49
+ // For regular queries, use inline conversion with exact lengths
50
+ const convertClause = `CONVERT(VARCHAR(${paramLength}), CONVERT(VARBINARY(${byteLength}), 0x${hexValue}))`;
51
+ replacements.push({
52
+ index: i,
53
+ replacement: convertClause
54
+ });
55
+ }
56
+ parametersToRemove.push(i);
57
+ } else {
58
+ // For ASCII strings, use VarChar with exact byte length
59
+ params[i] = sap.VarChar(parameter, byteLength);
60
+ }
42
61
  }
43
62
  }
44
- }
45
-
46
- // Second pass: replace the ? placeholders at specific positions
47
- if (replacements.length > 0) {
48
- let questionMarkIndex = 0;
49
- sql = sql.replace(/\?/g, (match) => {
50
- const replacement = replacements.find(r => r.index === questionMarkIndex);
51
- questionMarkIndex++;
52
63
 
53
- if (replacement) {
54
- return replacement.replacement;
64
+ // Apply replacements
65
+ if (replacements.length > 0) {
66
+ let questionMarkIndex = 0;
67
+ sql = sql.replace(/\?/g, (match) => {
68
+ const replacement = replacements.find(r => r.index === questionMarkIndex);
69
+ questionMarkIndex++;
70
+
71
+ if (replacement) {
72
+ return replacement.replacement;
73
+ }
74
+ return match;
75
+ });
76
+
77
+ // For stored procedures, inject hex variable declarations
78
+ if (isStoredProcCall && hexVariables.length > 0) {
79
+ const lines = sql.split('\n');
80
+ let insertIndex = 0;
81
+
82
+ // Find the last DECLARE statement
83
+ for (let i = 0; i < lines.length; i++) {
84
+ if (/^\s*DECLARE\s+/i.test(lines[i])) {
85
+ insertIndex = i + 1;
86
+ }
87
+ }
88
+
89
+ // Insert hex variable declarations and assignments
90
+ const hexDeclarations = hexVariables.map(v => v.declaration);
91
+ const hexAssignments = hexVariables.map(v => v.assignment);
92
+
93
+ lines.splice(insertIndex, 0, ...hexDeclarations, ...hexAssignments);
94
+ sql = lines.join('\n');
55
95
  }
56
- return match;
96
+ }
97
+
98
+ // Remove parameters in reverse order to maintain correct indices
99
+ parametersToRemove.reverse().forEach(index => {
100
+ params.splice(index, 1);
57
101
  });
58
102
  }
59
103
 
60
- // Remove parameters in reverse order to maintain correct indices
61
- parametersToRemove.reverse().forEach(index => {
62
- params.splice(index, 1);
63
- });
104
+ log.emitQuery({ sql, parameters: params });
64
105
 
65
106
  runOriginalQuery.call(connection, sql, params, onInnerCompleted);
66
107
  let result = [];
@@ -75,7 +116,6 @@ function wrapQuery(_context, connection) {
75
116
  }
76
117
  result.push(rows);
77
118
  if (!hasMore) {
78
-
79
119
  if (result.length === 1)
80
120
  onCompleted(null, result[0]);
81
121
  else
@@ -83,7 +123,15 @@ function wrapQuery(_context, connection) {
83
123
  }
84
124
  }
85
125
  }
126
+ }
127
+
128
+ function hasNonAsciiCharacters(str) {
129
+ // Check if string contains any character with code point > 127 (non-ASCII)
130
+ return /[\u0080-\uFFFF]/.test(str);
131
+ }
86
132
 
133
+ function stringToHex(str) {
134
+ return Buffer.from(str, 'utf8').toString('hex');
87
135
  }
88
136
 
89
137
  module.exports = wrapQuery;