@abaplint/runtime 2.3.122 → 2.3.123
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
|
}
|
|
@@ -90,6 +111,7 @@ class Table {
|
|
|
90
111
|
return this.header;
|
|
91
112
|
}
|
|
92
113
|
insertIndex(item, index) {
|
|
114
|
+
this.secondaryIndexes = {};
|
|
93
115
|
const val = this.getValue(item);
|
|
94
116
|
this.value.splice(index, 0, val);
|
|
95
117
|
for (const l of this.loops.values()) {
|
|
@@ -100,6 +122,7 @@ class Table {
|
|
|
100
122
|
return val;
|
|
101
123
|
}
|
|
102
124
|
deleteIndex(index) {
|
|
125
|
+
this.secondaryIndexes = {};
|
|
103
126
|
if (index > this.value.length) {
|
|
104
127
|
return;
|
|
105
128
|
}
|
|
@@ -119,6 +142,7 @@ class Table {
|
|
|
119
142
|
}
|
|
120
143
|
}
|
|
121
144
|
append(item, cloneRow = true) {
|
|
145
|
+
this.secondaryIndexes = {};
|
|
122
146
|
if (item instanceof field_symbol_1.FieldSymbol) {
|
|
123
147
|
const p = item.getPointer();
|
|
124
148
|
if (p === undefined) {
|
|
@@ -142,6 +166,7 @@ class Table {
|
|
|
142
166
|
}
|
|
143
167
|
}
|
|
144
168
|
appendInitial() {
|
|
169
|
+
this.secondaryIndexes = {};
|
|
145
170
|
// note that this will clone the object
|
|
146
171
|
this.append(this.rowType);
|
|
147
172
|
// @ts-ignore
|