-
Notifications
You must be signed in to change notification settings - Fork 0
/
dataRestore.js
203 lines (180 loc) · 5.8 KB
/
dataRestore.js
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
const electron = require("electron");
const protobuf = require('protobufjs')
const fileSystem = require('fs')
const zlib = require('zlib');
var exports = module.exports = {}
const DBCreationManager = require('./js/db-creation-manager')
var dbManager
/**
* Init function. Open connection to database
*
* @param {Boolean} shouldCreate flag that indicates should database be
* created, or only to open connection to existing database
*/
exports.init = function(shouldCreate) {
dbManager = new DBCreationManager(shouldCreate);
}
/**
* Restore serialized and compressed file and puts data
* in database.
*
* @param {String} _filePath Absoulte path of the file which should be restored
* @param {String} _fileType File type of the file which should be restored
*/
exports.restore = function(_filePath, _fileType) {
const filePath = _filePath;
const fileType = _fileType
if (dbManager.isNotDatabaseOpen())
{
return new Promise((resolve, reject) => {
resolve({
code : 200,
message : "Data recovery database not open. Success."
})
})
}
if (fileType === 0) {
return new Promise((resolve, reject) => {
try {
const data = fileSystem.readFileSync(filePath, "utf8");
var dailyActivitiesJSON = JSON.parse(data);
dbManager.insertJSONarray(dailyActivitiesJSON);
resolve({
code : 200,
message : "Decompression success"
})
}
catch(exception) {
reject("Error while using json file")
}
})
}
else {
return decompress(filePath, fileType)
}
}
/**
* Finish data restoring. Close database connection.
*/
exports.finish = function() {
if (dbManager != undefined) {
dbManager.close()
}
}
/**
* Decompress file. On success it starts deserialization of
* decompressed data.
*
* @param {*} filePath Absoulte path of the file which should be decompressed
* @param {*} fileType File type of the file which should be decompressed
*/
function decompress(filePath, fileType) {
return new Promise( (resolve, reject) => {
const fileContents = fileSystem.createReadStream(filePath);
const unzip = zlib.createInflate();
var writeStream = new WMStrm();
fileContents.pipe(unzip).pipe(writeStream).on('finish', (err) => {
deserialize(writeStream.memStore, fileType).then(() => {
resolve({
code : 200,
message : "Decompression success"
})
}).catch((err) => {
reject("Error while deserializing")
})
})
.on('error', (err) => {
reject("Error while decompressing")
})
})
}
var stream = require('stream');
var util = require('util');
// use Node.js Writable, otherwise load polyfill
var Writable = stream.Writable ||
require('readable-stream').Writable;
function WMStrm(options) {
// allow use without new operator
if (!(this instanceof WMStrm)) {
return new WMStrm(options);
}
Writable.call(this, options); // init super
this.memStore = Buffer.from(''); // empty
}
util.inherits(WMStrm, Writable);
WMStrm.prototype._write = function (chunk, enc, cb) {
// our memory store stores things in buffers
var buffer = (Buffer.isBuffer(chunk)) ?
chunk : // already is Buffer use it
Buffer.from(chunk, enc); // string, convert
// concat to the buffer already there
this.memStore = Buffer.concat([this.memStore, buffer]);
cb();
};
/**
* Deserialize data using proto schema. When deserialization is done
* it inserts data in database.
*
* @param {*} _fileData Absoulte path of the file which should be deserialized
* @param {*} _fileType File type of the file which should be deserialized
*/
function deserialize(_fileData, _fileType) {
const fileData = _fileData
const fileType = _fileType
return new Promise( (resolve, reject) => {
try {
var reader = protobuf.Reader.create(fileData);
var sensorDataBuffer = []
while(reader.pos < reader.len) {
var sensorData;
if (fileType === 1) {
sensorData = require('./sensordata.js').LocationData.decodeDelimited(reader)
}
else if (fileType === 2) {
sensorData = require('./sensordata.js').SensorData.decodeDelimited(reader)
}
sensorData = fixInt64(sensorData)
sensorDataBuffer.push(sensorData)
}
if (fileType === 1) {
dbManager.insertLocationData(sensorDataBuffer)
}
else if (fileType === 2) {
dbManager.insertDeviceData(sensorDataBuffer)
}
resolve({
code : 200,
message : "Decompression success"
})
}
catch (exception) {
console.log(exception)
if (dbManager.isNotDatabaseOpen())
{
resolve({
code : 200,
message : "Decompression: database not open. Success."
})
}
reject("Error while deserializing")
}
})
}
/**
* Recursive function that find all long fields of the object and
* converts them to number. JavaScript doesn't have support for
* 64-bit integers and all long fields has to be converted to Number.
*
* @param {Object} obj
*/
var fixInt64 = function(obj) {
for(var key in obj) {
if(typeof obj[key] === 'object'){
fixInt64(obj[key]);
}
if(obj[key] instanceof protobuf.util.Long){
obj[key] = obj[key].toNumber();
}
}
return obj;
}