UNPKG

12.8 kBPlain TextView Raw
1import { Column } from "./column";
2import { Record } from "./record";
3import { ResponseTemplate } from "./responsetemplate";
4
5/**
6 * Response Class inheriting from ResponseTemplate Class
7 */
8export class Response extends ResponseTemplate {
9
10 /**
11 * The API Command used within this request
12 */
13 private command: any;
14 /**
15 * Column names available in this responsse
16 * NOTE: this includes also FIRST, LAST, LIMIT, COUNT, TOTAL
17 * and maybe further specific columns in case of a list query
18 */
19 private columnkeys: string[];
20 /**
21 * Container of Column Instances
22 */
23 private columns: Column[];
24 /**
25 * Record Index we currently point to in record list
26 */
27 private recordIndex: number;
28 /**
29 * Record List (List of rows)
30 */
31 private records: Record[];
32
33 /**
34 * Constructor
35 * @param raw API plain response
36 * @param cmd API command used within this request
37 * @param $ph placeholder array to get vars in response description dynamically replaced
38 */
39 public constructor(raw: string, cmd: any, ph: any = {}) {
40
41 super(raw);
42
43 const keys = Object.keys(ph);
44 keys.forEach((varName: string) => {
45 this.raw = this.raw.replace(new RegExp(`{${varName}}`, "g"), ph[varName]);
46 });
47 this.raw = this.raw.replace(/\{[A-Z_]+\}/g, "");
48 /* eslint-disable constructor-super */
49 super(this.raw);
50 /* eslint-enable constructor-super */
51
52 this.command = cmd;
53 if (
54 this.command &&
55 Object.prototype.hasOwnProperty.call(this.command, "PASSWORD")
56 ) { // make password no longer accessible
57 this.command.PASSWORD = "***";
58 }
59 this.columnkeys = [];
60 this.columns = [];
61 this.recordIndex = 0;
62 this.records = [];
63
64 if (Object.prototype.hasOwnProperty.call(this.hash, "PROPERTY")) {
65 const colKeys = Object.keys(this.hash.PROPERTY);
66 let count = 0;
67 colKeys.forEach((c: string) => {
68 const d = this.hash.PROPERTY[c];
69 this.addColumn(c, d);
70 if (d.length > count) {
71 count = d.length;
72 }
73 });
74 for (let i = 0; i < count; i++) {
75 const d: any = {};
76 colKeys.forEach((k: string) => {
77 const col = this.getColumn(k);
78 if (col) {
79 const v = col.getDataByIndex(i);
80 if (v !== null) {
81 d[k] = v;
82 }
83 }
84 });
85 this.addRecord(d);
86 }
87 }
88 }
89
90 /**
91 * Add a column to the column list
92 * @param key column name
93 * @param data array of column data
94 * @returns Current Response Instance for method chaining
95 */
96 public addColumn(key: string, data: string[]): Response {
97 const col = new Column(key, data);
98 this.columns.push(col);
99 this.columnkeys.push(key);
100 return this;
101 }
102
103 /**
104 * Add a record to the record list
105 * @param h row hash data
106 * @returns Current Response Instance for method chaining
107 */
108 public addRecord(h: any): Response {
109 this.records.push(new Record(h));
110 return this;
111 }
112
113 /**
114 * Get column by column name
115 * @param key column name
116 * @returns column instance or null if column does not exist
117 */
118 public getColumn(key: string): Column | null {
119 return (this.hasColumn(key) ? this.columns[this.columnkeys.indexOf(key)] : null);
120 }
121
122 /**
123 * Get Data by Column Name and Index
124 * @param colkey column name
125 * @param index column data index
126 * @returns column data at index or null if not found
127 */
128 public getColumnIndex(colkey: string, index: number): string | null {
129 const col = this.getColumn(colkey);
130 return col ? col.getDataByIndex(index) : null;
131 }
132
133 /**
134 * Get Column Names
135 * @returns Array of Column Names
136 */
137 public getColumnKeys(): string[] {
138 return this.columnkeys;
139 }
140
141 /**
142 * Get List of Columns
143 * @returns Array of Columns
144 */
145 public getColumns(): Column[] {
146 return this.columns;
147 }
148
149 /**
150 * Get Command used in this request
151 * @returns command
152 */
153 public getCommand(): any {
154 return this.command;
155 }
156
157 /**
158 * Get Command used in this request in plain text format
159 * @return command as plain text
160 */
161 public getCommandPlain(): string {
162 let tmp = "";
163 Object.keys(this.command).forEach((key: string) => {
164 tmp += `${key} = ${this.command[key]}\n`;
165 });
166 return tmp;
167 }
168
169 /**
170 * Get Page Number of current List Query
171 * @returns page number or null in case of a non-list response
172 */
173 public getCurrentPageNumber(): number | null {
174 const first = this.getFirstRecordIndex();
175 const limit = this.getRecordsLimitation();
176 if (first !== null && limit) {
177 return Math.floor(first / limit) + 1;
178 }
179 return null;
180 }
181
182 /**
183 * Get Record of current record index
184 * @returns Record or null in case of a non-list response
185 */
186 public getCurrentRecord(): Record | null {
187 return this.hasCurrentRecord() ? this.records[this.recordIndex] : null;
188 }
189
190 /**
191 * Get Index of first row in this response
192 * @returns first row index
193 */
194 public getFirstRecordIndex(): number | null {
195 const col = this.getColumn("FIRST");
196 if (col) {
197 const f = col.getDataByIndex(0);
198 if (f !== null) {
199 return parseInt(f, 10);
200 }
201 }
202 if (this.records.length) {
203 return 0;
204 }
205 return null;
206 }
207
208 /**
209 * Get last record index of the current list query
210 * @returns record index or null for a non-list response
211 */
212 public getLastRecordIndex(): number | null {
213 const col = this.getColumn("LAST");
214 if (col) {
215 const l = col.getDataByIndex(0);
216 if (l !== null) {
217 return parseInt(l, 10);
218 }
219 }
220 const len = this.getRecordsCount();
221 if (len) {
222 return (len - 1);
223 }
224 return null;
225 }
226
227 /**
228 * Get Response as List Hash including useful meta data for tables
229 * @returns hash including list meta data and array of rows in hash notation
230 */
231 public getListHash(): any {
232 const lh: any[] = [];
233 this.getRecords().forEach((rec) => {
234 lh.push(rec.getData());
235 });
236 return {
237 LIST: lh,
238 meta: {
239 columns: this.getColumnKeys(),
240 pg: this.getPagination(),
241 },
242 };
243 }
244
245 /**
246 * Get next record in record list
247 * @returns Record or null in case there's no further record
248 */
249 public getNextRecord(): Record | null {
250 if (this.hasNextRecord()) {
251 return this.records[++this.recordIndex];
252 }
253 return null;
254 }
255
256 /**
257 * Get Page Number of next list query
258 * @returns page number or null if there's no next page
259 */
260 public getNextPageNumber(): number | null {
261 const cp = this.getCurrentPageNumber();
262 if (cp === null) {
263 return null;
264 }
265 const page = cp + 1;
266 const pages = this.getNumberOfPages();
267 return (page <= pages ? page : pages);
268 }
269
270 /**
271 * Get the number of pages available for this list query
272 * @returns number of pages
273 */
274 public getNumberOfPages(): number {
275 const t = this.getRecordsTotalCount();
276 const limit = this.getRecordsLimitation();
277 if (t && limit) {
278 return Math.ceil(t / this.getRecordsLimitation());
279 }
280 return 0;
281 }
282
283 /**
284 * Get object containing all paging data
285 * @returns paginator data
286 */
287 public getPagination(): any {
288 return {
289 COUNT: this.getRecordsCount(),
290 CURRENTPAGE: this.getCurrentPageNumber(),
291 FIRST: this.getFirstRecordIndex(),
292 LAST: this.getLastRecordIndex(),
293 LIMIT: this.getRecordsLimitation(),
294 NEXTPAGE: this.getNextPageNumber(),
295 PAGES: this.getNumberOfPages(),
296 PREVIOUSPAGE: this.getPreviousPageNumber(),
297 TOTAL: this.getRecordsTotalCount(),
298 };
299 }
300
301 /**
302 * Get Page Number of previous list query
303 * @returns page number or null if there's no previous page
304 */
305 public getPreviousPageNumber(): number | null {
306 const cp = this.getCurrentPageNumber();
307 if (cp === null) {
308 return null;
309 }
310 return (cp - 1) || null;
311 }
312
313 /**
314 * Get previous record in record list
315 * @returns Record or null if there's no previous record
316 */
317 public getPreviousRecord(): Record | null {
318 if (this.hasPreviousRecord()) {
319 return this.records[--this.recordIndex];
320 }
321 return null;
322 }
323
324 /**
325 * Get Record at given index
326 * @param idx record index
327 * @returns Record or null if index does not exist
328 */
329 public getRecord(idx: number): Record | null {
330 if (idx >= 0 && this.records.length > idx) {
331 return this.records[idx];
332 }
333 return null;
334 }
335
336 /**
337 * Get all Records
338 * @returns array of records
339 */
340 public getRecords(): Record[] {
341 return this.records;
342 }
343
344 /**
345 * Get count of rows in this response
346 * @returns count of rows
347 */
348 public getRecordsCount(): number {
349 return this.records.length;
350 }
351
352 /**
353 * Get total count of records available for the list query
354 * @returns total count of records or count of records for a non-list response
355 */
356 public getRecordsTotalCount(): number {
357 const col = this.getColumn("TOTAL");
358 if (col) {
359 const t = col.getDataByIndex(0);
360 if (t !== null) {
361 return parseInt(t, 10);
362 }
363 }
364 return this.getRecordsCount();
365 }
366
367 /**
368 * Get limit(ation) setting of the current list query
369 * This is the count of requested rows
370 * @returns limit setting or count requested rows
371 */
372 public getRecordsLimitation(): number {
373 const col = this.getColumn("LIMIT");
374 if (col) {
375 const l = col.getDataByIndex(0);
376 if (l !== null) {
377 return parseInt(l, 10);
378 }
379 }
380 return this.getRecordsCount();
381 }
382
383 /**
384 * Check if this list query has a next page
385 * @returns boolean result
386 */
387 public hasNextPage(): boolean {
388 const cp = this.getCurrentPageNumber();
389 if (cp === null) {
390 return false;
391 }
392 return (cp + 1 <= this.getNumberOfPages());
393 }
394
395 /**
396 * Check if this list query has a previous page
397 * @returns boolean result
398 */
399 public hasPreviousPage(): boolean {
400 const cp = this.getCurrentPageNumber();
401 if (cp === null) {
402 return false;
403 }
404 return ((cp - 1) > 0);
405 }
406
407 /**
408 * Reset index in record list back to zero
409 * @returns Current Response Instance for method chaining
410 */
411 public rewindRecordList(): Response {
412 this.recordIndex = 0;
413 return this;
414 }
415
416 /**
417 * Check if column exists in response
418 * @param key column name
419 * @returns boolean result
420 */
421 private hasColumn(key: string): boolean {
422 return (this.columnkeys.indexOf(key) !== -1);
423 }
424
425 /**
426 * Check if the record list contains a record for the
427 * current record index in use
428 * @returns boolean result
429 */
430 private hasCurrentRecord(): boolean {
431 const len = this.records.length;
432 return (
433 len > 0 &&
434 this.recordIndex >= 0 &&
435 this.recordIndex < len
436 );
437 }
438
439 /**
440 * Check if the record list contains a next record for the
441 * current record index in use
442 * @returns boolean result
443 */
444 private hasNextRecord(): boolean {
445 const next = this.recordIndex + 1;
446 return (this.hasCurrentRecord() && (next < this.records.length));
447 }
448
449 /**
450 * Check if the record list contains a previous record for the
451 * current record index in use
452 * @returns boolean result
453 */
454 private hasPreviousRecord(): boolean {
455 return (this.recordIndex > 0 && this.hasCurrentRecord());
456 }
457}