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