@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 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
  }
@@ -77,10 +98,11 @@ class Table {
77
98
  throw "Table, set error";
78
99
  }
79
100
  this.clear();
80
- for (const a of tab.array()) {
81
- // this clones the values, and add sorting if required
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/runtime",
3
- "version": "2.3.122",
3
+ "version": "2.3.124",
4
4
  "description": "Transpiler - Runtime",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",