@abaplint/runtime 2.3.121 → 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 clone_1 = require("../clone");
28
+ const compare_1 = require("../compare");
29
29
  const types_1 = require("../types");
30
- // import {deleteInternal} from "./delete_internal";
31
- const sort_1 = require("./sort");
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
- const 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;
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
- const loopIndex = table.startLoop(loopFrom);
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
- const secondary = (_b = (_a = table.getOptions()) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b.find(s => { var _a; return s.name.toUpperCase() === ((_a = options.usingKey) === null || _a === void 0 ? void 0 : _a.toUpperCase()); });
56
- if (secondary === undefined) {
57
- throw `LOOP, secondary key "${options.usingKey}" not found`;
58
- }
59
- const copy = (0, clone_1.clone)(table);
60
- (0, sort_1.sort)(copy, { by: secondary.keyFields.map(k => { return { component: k.toLowerCase() }; }) });
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
- loopTo = (options === null || options === void 0 ? void 0 : options.to) && options.to.get() < array.length ? options.to.get() : array.length;
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;
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/runtime",
3
- "version": "2.3.121",
3
+ "version": "2.3.123",
4
4
  "description": "Transpiler - Runtime",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",