1 | const h54sError = require('../error.js');
|
2 | const logs = require('../logs.js');
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | module.exports.convertTableObject = function(inObject, chunkThreshold) {
|
11 | const self = this;
|
12 |
|
13 | if(chunkThreshold > 30000) {
|
14 | console.warn('You should not set threshold larger than 30kb because of the SAS limitations');
|
15 | }
|
16 |
|
17 |
|
18 | if (typeof (inObject) !== 'object') {
|
19 | throw new h54sError('argumentError', 'The parameter passed to checkAndGetTypeObject is not an object');
|
20 | }
|
21 |
|
22 | const arrayLength = inObject.length;
|
23 | if (typeof (arrayLength) !== 'number') {
|
24 | throw new h54sError('argumentError', 'The parameter passed to checkAndGetTypeObject does not have a valid length and is most likely not an array');
|
25 | }
|
26 |
|
27 | const existingCols = {};
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | function checkAndIncrement(colSpec) {
|
33 | if (typeof (existingCols[colSpec.colName]) === 'undefined') {
|
34 | existingCols[colSpec.colName] = {};
|
35 | existingCols[colSpec.colName].colName = colSpec.colName;
|
36 | existingCols[colSpec.colName].colType = colSpec.colType;
|
37 | existingCols[colSpec.colName].colLength = colSpec.colLength > 0 ? colSpec.colLength : 1;
|
38 | return 0;
|
39 | }
|
40 |
|
41 | if (existingCols[colSpec.colName].colType !== colSpec.colType) {
|
42 | return -1;
|
43 | }
|
44 | if (existingCols[colSpec.colName].colLength < colSpec.colLength) {
|
45 | existingCols[colSpec.colName].colLength = colSpec.colLength > 0 ? colSpec.colLength : 1;
|
46 | return 0;
|
47 | }
|
48 | }
|
49 | let chunkArrayCount = 0;
|
50 | const targetArray = [];
|
51 | let currentTarget = 0;
|
52 | targetArray[currentTarget] = [];
|
53 | let j = 0;
|
54 | for (let i = 0; i < inObject.length; i++) {
|
55 | targetArray[currentTarget][j] = {};
|
56 | let chunkRowCount = 0;
|
57 |
|
58 | for (let key in inObject[i]) {
|
59 | const thisSpec = {};
|
60 | const thisValue = inObject[i][key];
|
61 |
|
62 |
|
63 | if(thisValue === undefined || thisValue === null) {
|
64 | continue;
|
65 | }
|
66 |
|
67 |
|
68 | if(typeof thisValue === 'number' && isNaN(thisValue)) {
|
69 | throw new h54sError('typeError', 'NaN value in one of the values (columns) is not allowed');
|
70 | }
|
71 |
|
72 | if(thisValue === -Infinity || thisValue === Infinity) {
|
73 | throw new h54sError('typeError', thisValue.toString() + ' value in one of the values (columns) is not allowed');
|
74 | }
|
75 |
|
76 | if(thisValue === true || thisValue === false) {
|
77 | throw new h54sError('typeError', 'Boolean value in one of the values (columns) is not allowed');
|
78 | }
|
79 |
|
80 |
|
81 | const thisType = typeof (thisValue);
|
82 |
|
83 | if (thisType === 'number') {
|
84 | if(thisValue < Number.MIN_SAFE_INTEGER || thisValue > Number.MAX_SAFE_INTEGER) {
|
85 | logs.addApplicationLog('Object[' + i + '].' + key + ' - This value exceeds expected numeric precision.');
|
86 | }
|
87 | thisSpec.colName = key;
|
88 | thisSpec.colType = 'num';
|
89 | thisSpec.colLength = 8;
|
90 | thisSpec.encodedLength = thisValue.toString().length;
|
91 | targetArray[currentTarget][j][key] = thisValue;
|
92 | } else if (thisType === 'string') {
|
93 | thisSpec.colName = key;
|
94 | thisSpec.colType = 'string';
|
95 | thisSpec.colLength = thisValue.length;
|
96 |
|
97 | if (thisValue === "") {
|
98 | targetArray[currentTarget][j][key] = " ";
|
99 | } else {
|
100 | targetArray[currentTarget][j][key] = encodeURIComponent(thisValue).replace(/'/g, '%27');
|
101 | }
|
102 | thisSpec.encodedLength = targetArray[currentTarget][j][key].length;
|
103 | } else if(thisValue instanceof Date) {
|
104 | console.log("ERROR VALUE ", thisValue)
|
105 | console.log("TYPEOF VALUE ", typeof thisValue)
|
106 | throw new h54sError('typeError', 'Date type not supported. Please use h54s.toSasDateTime function to convert it');
|
107 | } else if (thisType == 'object') {
|
108 | thisSpec.colName = key;
|
109 | thisSpec.colType = 'json';
|
110 | thisSpec.colLength = JSON.stringify(thisValue).length;
|
111 | targetArray[currentTarget][j][key] = encodeURIComponent(JSON.stringify(thisValue)).replace(/'/g, '%27');
|
112 | thisSpec.encodedLength = targetArray[currentTarget][j][key].length;
|
113 | }
|
114 |
|
115 | chunkRowCount = chunkRowCount + 6 + key.length + thisSpec.encodedLength;
|
116 |
|
117 | if (checkAndIncrement(thisSpec) == -1) {
|
118 | throw new h54sError('typeError', 'There is a type mismatch in the array between values (columns) of the same name.');
|
119 | }
|
120 | }
|
121 |
|
122 |
|
123 | if(Object.keys(targetArray[currentTarget][j]).length === 0) {
|
124 | targetArray[currentTarget].splice(j, 1);
|
125 | continue;
|
126 | }
|
127 |
|
128 | if (chunkRowCount > chunkThreshold) {
|
129 | throw new h54sError('argumentError', 'Row ' + j + ' exceeds size limit of 32kb');
|
130 | } else if(chunkArrayCount + chunkRowCount > chunkThreshold) {
|
131 |
|
132 | const lastRow = targetArray[currentTarget].pop();
|
133 | currentTarget++;
|
134 | targetArray[currentTarget] = [lastRow];
|
135 | j = 0;
|
136 | chunkArrayCount = chunkRowCount;
|
137 | } else {
|
138 | chunkArrayCount = chunkArrayCount + chunkRowCount;
|
139 | }
|
140 | j++;
|
141 | }
|
142 |
|
143 |
|
144 | const specArray = [];
|
145 | for (let k in existingCols) {
|
146 | specArray.push(existingCols[k]);
|
147 | }
|
148 | return {
|
149 | spec: specArray,
|
150 | data: targetArray,
|
151 | jsonLength: chunkArrayCount
|
152 | };
|
153 |
|
154 | };
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | module.exports.toSasDateTime = function (jsDate) {
|
163 | const basedate = new Date("January 1, 1960 00:00:00");
|
164 | const currdate = jsDate;
|
165 |
|
166 |
|
167 | const baseOffset = basedate.getTimezoneOffset();
|
168 | const currOffset = currdate.getTimezoneOffset();
|
169 |
|
170 |
|
171 | const offsetSecs = (currOffset - baseOffset) * 60;
|
172 | const baseDateSecs = basedate.getTime() / 1000;
|
173 | const currdateSecs = currdate.getTime() / 1000;
|
174 | const sasDatetime = Math.round(currdateSecs - baseDateSecs - offsetSecs);
|
175 |
|
176 | return sasDatetime;
|
177 | };
|