@abaplint/runtime 2.3.122 → 2.3.124
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.
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { FieldSymbol, Integer, Table } from "../types";
|
|
2
|
+
import { ICharacter } from "../types/_character";
|
|
3
|
+
import { INumeric } from "../types/_numeric";
|
|
4
|
+
declare type topType = {
|
|
5
|
+
[name: string]: INumeric | ICharacter;
|
|
6
|
+
};
|
|
2
7
|
export interface ILoopOptions {
|
|
3
8
|
where?: (i: any) => Promise<boolean>;
|
|
4
9
|
usingKey?: string;
|
|
5
10
|
from?: Integer;
|
|
6
11
|
to?: Integer;
|
|
12
|
+
topEquals?: topType;
|
|
7
13
|
}
|
|
8
14
|
export declare function loop(table: Table | FieldSymbol | undefined, options?: ILoopOptions): AsyncGenerator<any, void, unknown>;
|
|
15
|
+
export {};
|
|
@@ -25,12 +25,53 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
|
|
|
25
25
|
};
|
|
26
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
27
|
exports.loop = void 0;
|
|
28
|
-
const
|
|
28
|
+
const compare_1 = require("../compare");
|
|
29
29
|
const types_1 = require("../types");
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
function binarySearchFrom(array, left, right, keyField, keyValue) {
|
|
31
|
+
while (right - left > 1) {
|
|
32
|
+
const middle = Math.floor(((right - left) / 2) + left);
|
|
33
|
+
if ((0, compare_1.ge)(array[middle].get()[keyField], keyValue)) {
|
|
34
|
+
right = middle;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
left = middle;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return right;
|
|
41
|
+
}
|
|
42
|
+
function binarySearchTo(array, left, right, keyField, keyValue) {
|
|
43
|
+
while (right - left > 1) {
|
|
44
|
+
const middle = Math.floor(((right - left) / 2) + left);
|
|
45
|
+
if ((0, compare_1.le)(array[middle].get()[keyField], keyValue)) {
|
|
46
|
+
left = middle;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
right = middle;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return right;
|
|
53
|
+
}
|
|
54
|
+
function determineFromTo(array, topEquals, key) {
|
|
55
|
+
if (topEquals === undefined) {
|
|
56
|
+
// if there is no WHERE supplied, its using the sorting of the secondary key
|
|
57
|
+
return { from: 1, to: array.length };
|
|
58
|
+
}
|
|
59
|
+
let from = 0;
|
|
60
|
+
let to = array.length;
|
|
61
|
+
// todo: multi field
|
|
62
|
+
const keyField = key.keyFields[0].toLowerCase();
|
|
63
|
+
const keyValue = topEquals[keyField];
|
|
64
|
+
if (keyField && keyValue) {
|
|
65
|
+
from = binarySearchFrom(array, from, to, keyField, keyValue);
|
|
66
|
+
to = binarySearchTo(array, from, to, keyField, keyValue);
|
|
67
|
+
// console.dir("from: " + from + ", to: " + to);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
from: from,
|
|
71
|
+
to: to,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
32
74
|
function loop(table, options) {
|
|
33
|
-
var _a, _b;
|
|
34
75
|
return __asyncGenerator(this, arguments, function* loop_1() {
|
|
35
76
|
if (table === undefined) {
|
|
36
77
|
throw new Error("LOOP at undefined");
|
|
@@ -46,25 +87,20 @@ function loop(table, options) {
|
|
|
46
87
|
abap.builtin.sy.get().subrc.set(4);
|
|
47
88
|
return yield __await(void 0);
|
|
48
89
|
}
|
|
49
|
-
|
|
90
|
+
let loopFrom = (options === null || options === void 0 ? void 0 : options.from) && (options === null || options === void 0 ? void 0 : options.from.get()) > 0 ? options.from.get() - 1 : 0;
|
|
50
91
|
let loopTo = (options === null || options === void 0 ? void 0 : options.to) && options.to.get() < length ? options.to.get() : length;
|
|
51
|
-
|
|
52
|
-
let entered = false;
|
|
53
|
-
let array = table.array();
|
|
92
|
+
let array = [];
|
|
54
93
|
if ((options === null || options === void 0 ? void 0 : options.usingKey) && options.usingKey !== undefined && options.usingKey !== "primary_key") {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (secondary?.isUnique === true) {
|
|
63
|
-
deleteInternal(copy, {adjacent: true, comparing: secondary.keyFields});
|
|
64
|
-
}
|
|
65
|
-
*/
|
|
66
|
-
array = copy.array();
|
|
94
|
+
array = table.getSecondaryIndex(options.usingKey);
|
|
95
|
+
const { from, to } = determineFromTo(array, options.topEquals, table.getKeyByName(options.usingKey));
|
|
96
|
+
loopFrom = Math.max(loopFrom, from) - 1;
|
|
97
|
+
loopTo = Math.min(loopTo, to);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
array = table.array();
|
|
67
101
|
}
|
|
102
|
+
const loopIndex = table.startLoop(loopFrom);
|
|
103
|
+
let entered = false;
|
|
68
104
|
try {
|
|
69
105
|
const isStructured = array[0] instanceof types_1.Structure;
|
|
70
106
|
while (loopIndex.index < loopTo) {
|
|
@@ -84,7 +120,10 @@ function loop(table, options) {
|
|
|
84
120
|
entered = true;
|
|
85
121
|
yield yield __await(current);
|
|
86
122
|
loopIndex.index++;
|
|
87
|
-
|
|
123
|
+
if ((options === null || options === void 0 ? void 0 : options.to) === undefined && (options === null || options === void 0 ? void 0 : options.usingKey) === undefined) {
|
|
124
|
+
// extra rows might have been inserted inside the loop
|
|
125
|
+
loopTo = array.length;
|
|
126
|
+
}
|
|
88
127
|
}
|
|
89
128
|
}
|
|
90
129
|
finally {
|
|
@@ -34,7 +34,10 @@ export declare class Table {
|
|
|
34
34
|
private readonly loops;
|
|
35
35
|
private readonly options;
|
|
36
36
|
private readonly qualifiedName;
|
|
37
|
+
private secondaryIndexes;
|
|
37
38
|
constructor(rowType: TableRowType, options?: ITableOptions, qualifiedName?: string);
|
|
39
|
+
getKeyByName(name: string): ITableKey | undefined;
|
|
40
|
+
getSecondaryIndex(name: string): TableRowType[];
|
|
38
41
|
getQualifiedName(): string | undefined;
|
|
39
42
|
getOptions(): ITableOptions | undefined;
|
|
40
43
|
startLoop(start?: number): LoopIndex;
|
package/build/src/types/table.js
CHANGED
|
@@ -7,6 +7,7 @@ const clone_1 = require("../clone");
|
|
|
7
7
|
const field_symbol_1 = require("./field_symbol");
|
|
8
8
|
const data_reference_1 = require("./data_reference");
|
|
9
9
|
const insert_internal_1 = require("../statements/insert_internal");
|
|
10
|
+
const sort_1 = require("../statements/sort");
|
|
10
11
|
var TableAccessType;
|
|
11
12
|
(function (TableAccessType) {
|
|
12
13
|
TableAccessType["standard"] = "STANDARD";
|
|
@@ -24,6 +25,7 @@ exports.LoopIndex = LoopIndex;
|
|
|
24
25
|
class Table {
|
|
25
26
|
constructor(rowType, options, qualifiedName) {
|
|
26
27
|
this.value = [];
|
|
28
|
+
this.secondaryIndexes = {};
|
|
27
29
|
this.loops = new Set();
|
|
28
30
|
this.rowType = rowType;
|
|
29
31
|
this.options = options;
|
|
@@ -43,6 +45,23 @@ class Table {
|
|
|
43
45
|
}
|
|
44
46
|
this.qualifiedName = qualifiedName === null || qualifiedName === void 0 ? void 0 : qualifiedName.toUpperCase();
|
|
45
47
|
}
|
|
48
|
+
getKeyByName(name) {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
return (_b = (_a = this.getOptions()) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b.find(s => s.name.toUpperCase() === name.toUpperCase());
|
|
51
|
+
}
|
|
52
|
+
getSecondaryIndex(name) {
|
|
53
|
+
if (this.secondaryIndexes[name.toUpperCase()]) {
|
|
54
|
+
return this.secondaryIndexes[name.toUpperCase()];
|
|
55
|
+
}
|
|
56
|
+
const secondary = this.getKeyByName(name);
|
|
57
|
+
if (secondary === undefined) {
|
|
58
|
+
throw `Table, secondary key "${name}" not found`;
|
|
59
|
+
}
|
|
60
|
+
const copy = (0, clone_1.clone)(this.value);
|
|
61
|
+
(0, sort_1.sort)(copy, { by: secondary.keyFields.map(k => { return { component: k.toLowerCase() }; }) });
|
|
62
|
+
this.secondaryIndexes[name.toUpperCase()] = copy;
|
|
63
|
+
return copy;
|
|
64
|
+
}
|
|
46
65
|
getQualifiedName() {
|
|
47
66
|
return this.qualifiedName;
|
|
48
67
|
}
|
|
@@ -66,9 +85,11 @@ class Table {
|
|
|
66
85
|
}
|
|
67
86
|
clear() {
|
|
68
87
|
this.value = [];
|
|
88
|
+
this.secondaryIndexes = {};
|
|
69
89
|
}
|
|
70
90
|
set(tab) {
|
|
71
91
|
var _a, _b;
|
|
92
|
+
this.secondaryIndexes = {};
|
|
72
93
|
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.withHeader) === true) {
|
|
73
94
|
(_b = this.header) === null || _b === void 0 ? void 0 : _b.set(tab);
|
|
74
95
|
}
|
|
@@ -77,10 +98,11 @@ class Table {
|
|
|
77
98
|
throw "Table, set error";
|
|
78
99
|
}
|
|
79
100
|
this.clear();
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(0, insert_internal_1.insertInternal)({ table: this, data: a });
|
|
101
|
+
if (tab instanceof field_symbol_1.FieldSymbol) {
|
|
102
|
+
tab = tab.getPointer();
|
|
83
103
|
}
|
|
104
|
+
// this clones the values, and add sorting if required
|
|
105
|
+
(0, insert_internal_1.insertInternal)({ table: this, data: tab, lines: true });
|
|
84
106
|
}
|
|
85
107
|
}
|
|
86
108
|
getHeader() {
|
|
@@ -90,6 +112,7 @@ class Table {
|
|
|
90
112
|
return this.header;
|
|
91
113
|
}
|
|
92
114
|
insertIndex(item, index) {
|
|
115
|
+
this.secondaryIndexes = {};
|
|
93
116
|
const val = this.getValue(item);
|
|
94
117
|
this.value.splice(index, 0, val);
|
|
95
118
|
for (const l of this.loops.values()) {
|
|
@@ -100,6 +123,7 @@ class Table {
|
|
|
100
123
|
return val;
|
|
101
124
|
}
|
|
102
125
|
deleteIndex(index) {
|
|
126
|
+
this.secondaryIndexes = {};
|
|
103
127
|
if (index > this.value.length) {
|
|
104
128
|
return;
|
|
105
129
|
}
|
|
@@ -119,6 +143,7 @@ class Table {
|
|
|
119
143
|
}
|
|
120
144
|
}
|
|
121
145
|
append(item, cloneRow = true) {
|
|
146
|
+
this.secondaryIndexes = {};
|
|
122
147
|
if (item instanceof field_symbol_1.FieldSymbol) {
|
|
123
148
|
const p = item.getPointer();
|
|
124
149
|
if (p === undefined) {
|
|
@@ -142,6 +167,7 @@ class Table {
|
|
|
142
167
|
}
|
|
143
168
|
}
|
|
144
169
|
appendInitial() {
|
|
170
|
+
this.secondaryIndexes = {};
|
|
145
171
|
// note that this will clone the object
|
|
146
172
|
this.append(this.rowType);
|
|
147
173
|
// @ts-ignore
|