-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathlehd_handler.js
More file actions
executable file
·89 lines (73 loc) · 3.1 KB
/
Copy pathlehd_handler.js
File metadata and controls
executable file
·89 lines (73 loc) · 3.1 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
#!/usr/bin/env node
// run like this: $./lehd_handler.js ./lehd/pa_od_file.csv
//
// This is a special handler for LEHD dataset. It reads LEHD csv files
// and converts them into binary arrays.
var fs = require('fs');
var path = require('path');
var lineReader = require('line-reader');
var processData = function(sourceFile) {
var basename = path.basename(sourceFile, path.extname(sourceFile));
var destFile = path.dirname(sourceFile) + '/' + basename + '.txt'; // save destination file as txt in order to force node.js to gzip the file and cache it
if (fs.existsSync(destFile)) {
console.log('Destination file ' + destFile + ' already exists. Doing nothing ...');
} else if (!fs.existsSync(sourceFile)) {
console.log('Source file ' + sourceFile + ' doesn\'t exist. Doing nothing ...');
} else {
console.log('Processing ' + sourceFile + ' and writing to ' + destFile + ' ...');
CSVToBin(sourceFile, destFile);
}
}
function CSVToBin(sourceFile, destFile, strDelimiter) {
// var outStream = fs.createWriteStream(destFile);
var outStream = fs.openSync(destFile, 'w');
var firstLine = true;
var lineCounter = 0;
strDelimiter = (strDelimiter || ",");
var objPattern = new RegExp(("(\\" + strDelimiter + "|\\r?\\n|\\r|^)" + "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" + "([^\"\\" + strDelimiter + "\\r\\n]*))"), "gi");
lineReader.eachLine(sourceFile, function(line, last) {
// loop through everyline of CSV and convert it to binary data
line += '\n';
var arrMatches = null;
var tempData = [];
while (arrMatches = objPattern.exec(line)) {
var strMatchedDelimiter = arrMatches[1];
if (strMatchedDelimiter.length && (strMatchedDelimiter != strDelimiter)) {
if (tempData.length > 0) {
// the first line of CSV file is column names. add it to metadata (JSON file) and continue to the next line of CSV
// TODO reading and managing metadata
if (firstLine) {
firstLine = false;
} else {
// TODO handle each type of data differently. right now I'm using doubles for everything, even strings
var buf = new Buffer(8 * tempData.length);
for (var i = 0; i < tempData.length; i++) {
buf.writeDoubleLE(parseFloat(tempData[i]), i*8);
}
lineCounter++;
if (lineCounter % 1000 == 0)
console.log('wrote ' + lineCounter + ' lines ...');
//outStream.writeSync(buf);
fs.writeSync(outStream, buf, 0, buf.length);
}
}
tempData = [];
}
if (arrMatches[2]) {
var strMatchedValue = arrMatches[2].replace(new RegExp("\"\"", "g"),"\"");
} else {
var strMatchedValue = arrMatches[3];
}
tempData.push(strMatchedValue);
}
// TODO write size of each row and number of rows to metadata JSON in order to make it easier for the client to load the data
if (last) {
//outStream.end();
fs.closeSync(outStream);
console.log('Wrote ' + lineCounter + ' lines. All done.');
return false;
}
return true;
});
}
processData(process.argv[2]);