@abaplint/runtime 2.13.49 → 2.13.51
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/build/src/statements/concatenate.js +11 -8
- package/build/src/statements/insert_internal.js +34 -49
- package/build/src/statements/loop.js +11 -3
- package/build/src/statements/select.js +6 -0
- package/build/src/statements/sort.d.ts +2 -1
- package/build/src/statements/sort.js +29 -0
- package/build/src/types/float.js +8 -0
- package/build/src/types/integer.js +5 -5
- package/build/src/types/table.d.ts +4 -0
- package/build/src/types/table.js +36 -0
- package/package.json +5 -5
|
@@ -17,19 +17,22 @@ function concatenate(input) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
if (input.lines === true) {
|
|
20
|
-
|
|
20
|
+
let result = "";
|
|
21
21
|
const tab = input.source[0];
|
|
22
22
|
if (tab instanceof types_1.Table) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
const array = tab.array();
|
|
24
|
+
const length = array.length;
|
|
25
|
+
const respectingBlanks = input.respectingBlanks === true;
|
|
26
|
+
const hasSeparator = sep.length > 0;
|
|
27
|
+
for (let i = 0; i < length; i++) {
|
|
28
|
+
if (hasSeparator === true && i > 0) {
|
|
29
|
+
result += sep;
|
|
29
30
|
}
|
|
31
|
+
const value = array[i].get();
|
|
32
|
+
result += respectingBlanks === true ? value : value.trimEnd();
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
|
-
input.target.set(
|
|
35
|
+
input.target.set(result);
|
|
33
36
|
}
|
|
34
37
|
else {
|
|
35
38
|
let result = "";
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.insertInternal = insertInternal;
|
|
4
|
-
const compare_1 = require("../compare");
|
|
5
4
|
const types_1 = require("../types");
|
|
6
|
-
const read_table_1 = require("./read_table");
|
|
7
5
|
const sort_1 = require("./sort");
|
|
8
6
|
function insertInternal(options) {
|
|
9
7
|
if (options.table instanceof types_1.FieldSymbol) {
|
|
@@ -18,60 +16,34 @@ function insertInternal(options) {
|
|
|
18
16
|
}
|
|
19
17
|
options.data = options.data.getPointer();
|
|
20
18
|
}
|
|
19
|
+
let data = options.data;
|
|
20
|
+
if (typeof data === "string") {
|
|
21
|
+
const tmp = options.table.getRowType().clone();
|
|
22
|
+
tmp.set(data);
|
|
23
|
+
data = tmp;
|
|
24
|
+
}
|
|
21
25
|
const tableOptions = options.table.getOptions();
|
|
22
|
-
|
|
26
|
+
const isSorted = tableOptions?.primaryKey?.type === types_1.TableAccessType.sorted
|
|
23
27
|
|| tableOptions?.primaryKey?.type === types_1.TableAccessType.hashed;
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const insert = options.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
if ((0, compare_1.ne)(row[key.toLowerCase()], insert[key.toLowerCase()])) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
28
|
+
if (isSorted === true
|
|
29
|
+
&& !(options.table instanceof types_1.HashedTable)
|
|
30
|
+
&& options.index === undefined
|
|
31
|
+
&& options.lines !== true) {
|
|
32
|
+
const insert = options.initial === true ? options.table.getRowType() : data;
|
|
33
|
+
if (insert !== undefined) {
|
|
34
|
+
const result = options.table.insertSorted(insert, (a, b) => (0, sort_1.compareRows)(a, b, tableOptions?.primaryKey?.keyFields || []), tableOptions?.primaryKey?.isUnique === true, options.noClone);
|
|
35
|
+
if (result.subrc === 0) {
|
|
36
|
+
if (options.assigning) {
|
|
37
|
+
options.assigning.assign(result.value);
|
|
41
38
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
if (tableOptions.primaryKey?.isUnique === true) {
|
|
46
|
-
const withKeyValue = [];
|
|
47
|
-
let binary = false;
|
|
48
|
-
const data = options?.data;
|
|
49
|
-
if (data instanceof types_1.Structure) {
|
|
50
|
-
const fieldName = tableOptions.primaryKey.keyFields[0].toLowerCase();
|
|
51
|
-
if (fieldName !== "table_line" && fieldName.includes("-") === false) {
|
|
52
|
-
withKeyValue.push({ key: (i) => { return i[fieldName]; }, value: data.get()[fieldName] });
|
|
53
|
-
binary = true;
|
|
39
|
+
if (options.referenceInto) {
|
|
40
|
+
options.referenceInto.assign(result.value);
|
|
54
41
|
}
|
|
55
42
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// @ts-ignore
|
|
59
|
-
return (0, compare_1.eq)(row.table_line, options.data);
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
(0, read_table_1.readTable)(options.table, { withKey: compare, withKeyValue: withKeyValue, binarySearch: binary });
|
|
63
|
-
if (abap.builtin.sy.get().subrc.get() === 0) {
|
|
64
|
-
abap.builtin.sy.get().subrc.set(4);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
43
|
+
abap.builtin.sy.get().subrc.set(result.subrc);
|
|
44
|
+
return;
|
|
67
45
|
}
|
|
68
46
|
}
|
|
69
|
-
let data = options.data;
|
|
70
|
-
if (typeof data === "string") {
|
|
71
|
-
const tmp = options.table.getRowType().clone();
|
|
72
|
-
tmp.set(data);
|
|
73
|
-
data = tmp;
|
|
74
|
-
}
|
|
75
47
|
if (data && options.index) {
|
|
76
48
|
const index = options.index.get() - 1;
|
|
77
49
|
const val = options.table.insertIndex(data, index);
|
|
@@ -97,6 +69,19 @@ function insertInternal(options) {
|
|
|
97
69
|
}
|
|
98
70
|
}
|
|
99
71
|
else if (options.initial === true) {
|
|
72
|
+
if (options.table instanceof types_1.HashedTable) {
|
|
73
|
+
const { value: val, subrc: subrc } = options.table.insert(options.table.getRowType());
|
|
74
|
+
if (subrc === 0) {
|
|
75
|
+
if (options.assigning) {
|
|
76
|
+
options.assigning.assign(val);
|
|
77
|
+
}
|
|
78
|
+
if (options.referenceInto) {
|
|
79
|
+
options.referenceInto.assign(val);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
abap.builtin.sy.get().subrc.set(subrc);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
100
85
|
let index = options.table.getArrayLength();
|
|
101
86
|
if (options.index) {
|
|
102
87
|
index = options.index.get() - 1;
|
|
@@ -31,10 +31,10 @@ function dynamicToWhere(condition, evaluate) {
|
|
|
31
31
|
if (evaluate === undefined) {
|
|
32
32
|
throw new Error("Dynamic WHERE evaluation function is not defined");
|
|
33
33
|
}
|
|
34
|
-
const matches = text.matchAll(/([\w-]+)\s+(\w+)\s+([<>\w-]+)/gi);
|
|
34
|
+
const matches = text.matchAll(/([\w-]+)\s+(NOT\s+IN|\w+)\s+([<>\w-]+)/gi);
|
|
35
35
|
for (const match of matches) {
|
|
36
36
|
const left = match[1];
|
|
37
|
-
const comparator = match[2].toLowerCase();
|
|
37
|
+
const comparator = match[2].toLowerCase().replace(/\s+/g, " ");
|
|
38
38
|
let right = "";
|
|
39
39
|
// console.dir({left, right});
|
|
40
40
|
const cleft = "i." + left.toLowerCase().replace(/-/g, ".get().");
|
|
@@ -43,13 +43,21 @@ function dynamicToWhere(condition, evaluate) {
|
|
|
43
43
|
const name = "fs_" + rightMatch[1].toLowerCase() + "_";
|
|
44
44
|
right = `evaluate("${name}").get()["${rightMatch[2].toLowerCase()}"]`;
|
|
45
45
|
}
|
|
46
|
+
const fieldSymbol = match[3].match(/^<(\w+)>$/);
|
|
47
|
+
if (right === "" && fieldSymbol) {
|
|
48
|
+
right = `evaluate("fs_${fieldSymbol[1].toLowerCase()}_").getPointer()`;
|
|
49
|
+
}
|
|
46
50
|
if (right === "") {
|
|
47
|
-
right = `evaluate("${match[3]}")`;
|
|
51
|
+
right = `evaluate("${match[3].toLowerCase()}")`;
|
|
48
52
|
}
|
|
49
53
|
if (comparator === "in") {
|
|
50
54
|
const cnew = `abap.compare.in(${cleft}, ${right})`;
|
|
51
55
|
text = text.replace(match[0], cnew);
|
|
52
56
|
}
|
|
57
|
+
else if (comparator === "not in") {
|
|
58
|
+
const cnew = `!abap.compare.in(${cleft}, ${right})`;
|
|
59
|
+
text = text.replace(match[0], cnew);
|
|
60
|
+
}
|
|
53
61
|
else {
|
|
54
62
|
const cnew = `abap.compare.${comparator}(${cleft}, ${right})`;
|
|
55
63
|
text = text.replace(match[0], cnew);
|
|
@@ -12,6 +12,12 @@ async function select(target, input, runtimeOptions, context) {
|
|
|
12
12
|
target = target.getPointer();
|
|
13
13
|
}
|
|
14
14
|
if (rows.length === 0) {
|
|
15
|
+
// INTO TABLE always initializes the target, also when nothing is found;
|
|
16
|
+
// a work area is left untouched instead
|
|
17
|
+
if (runtimeOptions?.appending !== true
|
|
18
|
+
&& (target instanceof types_1.Table || target instanceof types_1.HashedTable)) {
|
|
19
|
+
target.clear();
|
|
20
|
+
}
|
|
15
21
|
abap.builtin.sy.get().dbcnt.set(0);
|
|
16
22
|
abap.builtin.sy.get().subrc.set(4);
|
|
17
23
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FieldSymbol, Table } from "../types";
|
|
1
|
+
import { FieldSymbol, Table, TableRowType } from "../types";
|
|
2
2
|
export interface ISortOptions {
|
|
3
3
|
descending?: boolean;
|
|
4
4
|
skipSortedCheck?: boolean;
|
|
@@ -7,4 +7,5 @@ export interface ISortOptions {
|
|
|
7
7
|
descending?: boolean;
|
|
8
8
|
}[];
|
|
9
9
|
}
|
|
10
|
+
export declare function compareRows(a: TableRowType, b: TableRowType, keyFields: readonly string[]): number;
|
|
10
11
|
export declare function sort(input: Table | FieldSymbol | any[], options?: ISortOptions): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compareRows = compareRows;
|
|
3
4
|
exports.sort = sort;
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const compare_1 = require("../compare");
|
|
@@ -63,6 +64,34 @@ function compare(a, b, input) {
|
|
|
63
64
|
return 1;
|
|
64
65
|
}
|
|
65
66
|
}
|
|
67
|
+
function compareWholeRows(a, b) {
|
|
68
|
+
if ((0, compare_1.eq)(a, b)) {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
else if ((0, compare_1.lt)(a, b)) {
|
|
72
|
+
return -1;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function compareRows(a, b, keyFields) {
|
|
79
|
+
if (keyFields.length > 0) {
|
|
80
|
+
for (const keyField of keyFields) {
|
|
81
|
+
const component = keyField.toLowerCase();
|
|
82
|
+
const result = component === "table_line"
|
|
83
|
+
? compareWholeRows(a, b)
|
|
84
|
+
: compare(a, b, { component });
|
|
85
|
+
if (result !== 0) {
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return compareWholeRows(a, b);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
66
95
|
function sort(input, options) {
|
|
67
96
|
// console.dir(input);
|
|
68
97
|
if (input instanceof types_1.FieldSymbol) {
|
package/build/src/types/float.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Float = void 0;
|
|
4
|
+
const throw_error_1 = require("../throw_error");
|
|
4
5
|
const hex_1 = require("./hex");
|
|
5
6
|
const xstring_1 = require("./xstring");
|
|
6
7
|
const integer8_1 = require("./integer8");
|
|
7
8
|
const decfloat34_1 = require("./decfloat34");
|
|
9
|
+
const FLOAT_DIGITS = /^\s*[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)? *$/;
|
|
8
10
|
/*
|
|
9
11
|
function getNumberParts(x: number) {
|
|
10
12
|
if(isNaN(x)) {
|
|
@@ -59,6 +61,12 @@ class Float {
|
|
|
59
61
|
this.value = 0;
|
|
60
62
|
}
|
|
61
63
|
else if (typeof value === "string") {
|
|
64
|
+
if (value.endsWith("-")) {
|
|
65
|
+
value = "-" + value.substring(0, value.length - 1);
|
|
66
|
+
}
|
|
67
|
+
if (FLOAT_DIGITS.test(value) === false) {
|
|
68
|
+
(0, throw_error_1.throwError)("CX_SY_CONVERSION_NO_NUMBER");
|
|
69
|
+
}
|
|
62
70
|
this.value = parseFloat(value);
|
|
63
71
|
}
|
|
64
72
|
else if (value instanceof integer8_1.Integer8) {
|
|
@@ -85,11 +85,11 @@ class Integer {
|
|
|
85
85
|
this.set(Math.round(value.getRaw()));
|
|
86
86
|
}
|
|
87
87
|
else if (value instanceof hex_1.Hex || value instanceof xstring_1.XString || value instanceof hex_uint8_1.HexUInt8) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const maxVal = Math.pow(2,
|
|
88
|
+
const hex = value.get();
|
|
89
|
+
let num = parseInt(hex, 16);
|
|
90
|
+
// handle two complement, the first bit is the sign
|
|
91
|
+
if (hex.length >= 8) {
|
|
92
|
+
const maxVal = Math.pow(2, hex.length / 2 * 8);
|
|
93
93
|
if (num > maxVal / 2 - 1) {
|
|
94
94
|
num = num - maxVal;
|
|
95
95
|
}
|
|
@@ -110,6 +110,10 @@ export declare class Table implements ITable {
|
|
|
110
110
|
getHeader(): TableRowType;
|
|
111
111
|
get(): TableRowType;
|
|
112
112
|
insertIndex(item: TableRowType, index: number, noClone?: boolean): any;
|
|
113
|
+
insertSorted(item: TableRowType, compare: (a: TableRowType, b: TableRowType) => number, unique: boolean, noClone?: boolean): {
|
|
114
|
+
value: TableRowType | undefined;
|
|
115
|
+
subrc: number;
|
|
116
|
+
};
|
|
113
117
|
/** index = javascript indexed */
|
|
114
118
|
deleteIndex(index: number): void;
|
|
115
119
|
append(item: TableRowType): any;
|
package/build/src/types/table.js
CHANGED
|
@@ -463,6 +463,42 @@ class Table {
|
|
|
463
463
|
}
|
|
464
464
|
return val;
|
|
465
465
|
}
|
|
466
|
+
insertSorted(item, compare, unique, noClone = false) {
|
|
467
|
+
if (item instanceof field_symbol_1.FieldSymbol) {
|
|
468
|
+
const pointer = item.getPointer();
|
|
469
|
+
if (pointer === undefined) {
|
|
470
|
+
throw new Error("insertSorted, fs not assigned");
|
|
471
|
+
}
|
|
472
|
+
return this.insertSorted(pointer, compare, unique, noClone);
|
|
473
|
+
}
|
|
474
|
+
const val = noClone === true ? item : this.cloneRow(item);
|
|
475
|
+
const lastIndex = this.value.length - 1;
|
|
476
|
+
if (lastIndex < 0) {
|
|
477
|
+
return { value: this.insertIndex(val, 0, true), subrc: 0 };
|
|
478
|
+
}
|
|
479
|
+
const lastComparison = compare(this.value[lastIndex], val);
|
|
480
|
+
if (lastComparison < 0 || (lastComparison === 0 && unique === false)) {
|
|
481
|
+
return { value: this.insertIndex(val, this.value.length, true), subrc: 0 };
|
|
482
|
+
}
|
|
483
|
+
else if (lastComparison === 0) {
|
|
484
|
+
return { value: undefined, subrc: 4 };
|
|
485
|
+
}
|
|
486
|
+
let low = 0;
|
|
487
|
+
let high = this.value.length;
|
|
488
|
+
while (low < high) {
|
|
489
|
+
const middle = Math.floor((low + high) / 2);
|
|
490
|
+
if (compare(this.value[middle], val) <= 0) {
|
|
491
|
+
low = middle + 1;
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
high = middle;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (unique === true && low > 0 && compare(this.value[low - 1], val) === 0) {
|
|
498
|
+
return { value: undefined, subrc: 4 };
|
|
499
|
+
}
|
|
500
|
+
return { value: this.insertIndex(val, low, true), subrc: 0 };
|
|
501
|
+
}
|
|
466
502
|
/** index = javascript indexed */
|
|
467
503
|
deleteIndex(index) {
|
|
468
504
|
this.secondaryIndexes = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/runtime",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.51",
|
|
4
4
|
"description": "Transpiler - Runtime",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/src/index.d.ts",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"compile": "tsc",
|
|
14
|
-
"publish:major": "npm --no-git-tag-version version major &&
|
|
15
|
-
"publish:minor": "npm --no-git-tag-version version minor &&
|
|
16
|
-
"publish:patch": "npm --no-git-tag-version version patch &&
|
|
14
|
+
"publish:major": "npm --no-git-tag-version version major && rimraf build && npm install && npm run test && npm publish --access public",
|
|
15
|
+
"publish:minor": "npm --no-git-tag-version version minor && rimraf build && npm install && npm run test && npm publish --access public",
|
|
16
|
+
"publish:patch": "npm --no-git-tag-version version patch && rimraf build && npm install && npm run test && npm publish --access public",
|
|
17
17
|
"test": "npm run compile && mocha"
|
|
18
18
|
},
|
|
19
19
|
"mocha": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/mocha": "^10.0.10",
|
|
34
34
|
"@types/node": "^24.13.3",
|
|
35
35
|
"chai": "^4.5.0",
|
|
36
|
-
"mocha": "^11.
|
|
36
|
+
"mocha": "^11.8.0",
|
|
37
37
|
"source-map-support": "^0.5.21",
|
|
38
38
|
"typescript": "^6.0.3"
|
|
39
39
|
},
|