forked from hpcc-systems/Visualization
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDatasourceStore.ts
More file actions
127 lines (111 loc) · 4.08 KB
/
DatasourceStore.ts
File metadata and controls
127 lines (111 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import type { DDL2 } from "@hpcc-js/ddl-shim";
import { Deferred, QueryResults } from "./dgrid-shim.ts";
import { ColumnType, RowFormatter } from "./RowFormatter.ts";
export interface IDatasource {
id: () => string;
hash: () => string;
label: () => string;
outFields: () => DDL2.IField[];
total: () => number;
fetch: (from: number, count: number) => Promise<ReadonlyArray<object>>;
}
export class DatasourceCache implements IDatasource {
protected _datasource: IDatasource;
_prevHash: string;
_fetchCache: { [key: string]: Promise<ReadonlyArray<object>> } = {};
constructor(datasource: IDatasource) {
this._datasource = datasource;
}
validateCache() {
const hash = this.hash();
if (this._prevHash !== hash) {
this._prevHash = hash;
this._fetchCache = {};
}
}
id() { return this._datasource.id(); }
hash() { return this._datasource.hash(); }
label() { return this._datasource.label(); }
outFields() { return this._datasource.outFields(); }
total() { return this._datasource.total(); }
fetch(from: number, count: number): Promise<ReadonlyArray<object>> {
this.validateCache();
const cacheID = `${from}->${count}`;
let retVal = this._fetchCache[cacheID];
if (!retVal) {
retVal = this._datasource.fetch(from, count);
this._fetchCache[cacheID] = retVal;
}
return retVal;
}
}
export class DatasourceStore {
_datasource: DatasourceCache;
_columnsIdx: { [key: string]: number } = {};
_columns;
private rowFormatter: RowFormatter;
constructor(datasource: IDatasource, renderHtml: boolean) {
this._datasource = new DatasourceCache(datasource);
this._columnsIdx = {};
this._columns = this.db2Columns(this._datasource.outFields()).map((column, idx) => {
this._columnsIdx[column.field] = idx;
return column;
});
this.rowFormatter = new RowFormatter(this._columns, renderHtml);
}
columns() {
return this._columns;
}
db2Columns(fields: DDL2.IField[], prefix = ""): ColumnType[] {
if (!fields) return [];
return fields.map((field, idx) => {
const column: ColumnType = {
field: prefix + field.id,
leafID: field.id,
label: field.id,
idx,
className: "resultGridCell",
sortable: true,
hidden: false,
isSet: false
};
if (field.type === "dataset") {
column.children = this.db2Columns(field.children, prefix + field.id + "_");
} else {
column.formatter = (cell, row) => {
switch (typeof cell) {
case "string":
return cell.replace(/\t/g, " ");
}
return cell;
};
}
return column;
});
}
getIdentity(row) {
return row.__hpcc_id;
}
_request(start, end): Promise<{ totalLength: number, data: any[] }> {
if (!this._datasource) return Promise.resolve({ totalLength: 0, data: [] });
const retVal = this._datasource.fetch(start, end - start).then(response => {
return {
totalLength: this._datasource.total(),
data: response.map((row, idx) => {
const formattedRow: any = this.rowFormatter.format(row);
formattedRow.__hpcc_id = start + idx;
formattedRow.__origRow = row;
return formattedRow;
})
};
});
return retVal;
}
fetchRange(options): Promise<any[]> {
const retVal = new Deferred();
this._request(options.start, options.end).then(response => retVal.resolve(response));
return new QueryResults(retVal.then(response => response.data), {
totalLength: retVal.then(response => response.totalLength)
});
}
}