Skip to content
This repository was archived by the owner on Jul 15, 2021. It is now read-only.

Commit 1de03af

Browse files
committed
Add --stream option to CLI. Refs #26
Automatically switch to streaming mode when the input file is over 150kB or manually enable with --stream or -x. Not made the default mode since it is actually slower for files that can be parsed using the default method without running out of available memory. The hard limit for that is around 200kB on my machine. Refs #27
1 parent bf038c9 commit 1de03af

File tree

5 files changed

+77
-56
lines changed

5 files changed

+77
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ var readStream = require('fs').createReadStream('./large-input-file.sql');
7575
readStream.pipe(parserTransform);
7676
parserTransform.pipe(process.stdout);
7777

78-
parser.on('error', function (err) {
78+
parserTransform.on('error', function (err) {
7979
console.log(err);
8080
process.exit(1);
8181
});
8282

83-
parser.on('finish', function () {
83+
parserTransform.on('finish', function () {
8484
process.exit(0);
8585
});
8686
```

bin/sqlite-parser

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
* @copyright 2015-2016 Code School (http://codeschool.com)
55
* @author Nick Wronski <[email protected]>
66
*/
7-
'use strict';var _index=require('../lib/index');var _index2=_interopRequireDefault(_index);var _fs=require('fs');var _path=require('path');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var args=resolveArgs(process.argv.slice(2));if(args['version']){console.log('sqlite-parser v1.0.0-beta2');process.exit(0);}if(args['help']||args._.length===0){console.log('Usage: sqlite-parser infile [--output outfile]');process.exit(0);}var input=(0,_path.normalize)(args._[0]);var output=args['o']||args['output'];if(output){output=(0,_path.normalize)(output);}(0,_fs.stat)(input,function startCallback(err){if(err){return error(err);}(0,_fs.readFile)(input,'utf8',readCallback);});function resolveArgs(argv){var args={_:[]};var last=null;var isNewArg=function isNewArg(arg){return!arg||arg.indexOf('-')===0;};var aliases={o:'output',v:'version',h:'help'};for(var i=0;i<argv.length;i+=1){var arg=argv[i];if(isNewArg(arg)){var cur=arg.indexOf('--')!==-1?arg.slice(2):aliases[arg.slice(1)];var peek=argv.length-1!==i?argv[i+1]:null;var peekNew=isNewArg(peek);args[cur]=peekNew?true:peek;if(!peekNew){i+=1;}}else{args._.push(arg);}}return args;}function error(err){console.error(err.message);process.exit(1);}function writeOut(result,outPath){var outDir=(0,_path.dirname)(outPath);function writeCallback(err){if(err){return error(err);}process.exit(0);}function mkdirCallback(err){if(err){return error(err);}(0,_fs.writeFile)(outPath,result,writeCallback);}function statCallback(err){if(err){return(0,_fs.mkdir)(outDir,mkdirCallback);}mkdirCallback();}(0,_fs.stat)(outDir,statCallback);}function parserCallback(err,ast){if(err){return error(err);}var result=void 0;try{result=JSON.stringify(ast,null,2);}catch(e){return error(e);}if(output){writeOut(result,output);}else{process.stdout.write(result);process.exit(0);}}function readCallback(err,data){if(err){return error(err);}(0,_index2.default)(data,parserCallback);}
7+
'use strict';var _index=require('../lib/index');var _index2=_interopRequireDefault(_index);var _fs=require('fs');var _path=require('path');function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var aliases={o:'output',v:'version',h:'help',x:'stream'};var args=resolveArgs(process.argv.slice(2));var error=function error(err){console.error(err);process.exit(1);};var done=checkThen(function(){process.exit(0);});if(args['version']){console.log('sqlite-parser v1.0.0-beta2');process.exit(0);}if(args['help']||args._.length===0){console.log('Usage:\tsqlite-parser [infile]\n');console.log('Option\t\t\tAlias\tDescription');console.log('--output [outfile]\t-o\tWrite output to a file instead of stdout');console.log('--stream\t\t-x\tEnable streaming mode (default: infile >150kB)');console.log('--version\t\t-v\tGet current parser version');process.exit(0);}var streaming=args['stream'];var input=(0,_path.normalize)(args._[0]);var output=args['output'];if(output){output=(0,_path.normalize)(output);}(0,_fs.stat)(input,checkThen(function(_ref){var size=_ref.size;if(size/1000>=150){streaming=true;}var startStream=streaming?streamParser:standardParser;if(output){(function(){var outDir=(0,_path.dirname)(output);(0,_fs.stat)(outDir,checkThen(startStream,function(){(0,_fs.mkdir)(outDir,startStream);}));})();}else{startStream();}}));function resolveArgs(argv){var args={_:[]};var last=null;var isNewArg=function isNewArg(arg){return!arg||arg.indexOf('-')===0;};for(var i=0;i<argv.length;i+=1){var arg=argv[i];if(isNewArg(arg)){var cur=arg.indexOf('--')!==-1?arg.slice(2):aliases[arg.slice(1)];var peek=argv.length-1!==i?argv[i+1]:null;var peekNew=isNewArg(peek);args[cur]=peekNew?true:peek;if(!peekNew){i+=1;}}else{args._.push(arg);}}return args;}function checkThen(){var resCallback=arguments.length>0&&arguments[0]!==undefined?arguments[0]:done;var errCallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:error;return function(err,result){if(err){return errCallback(err);}resCallback(result);};}function streamParser(){var parserTransform=_index2.default.createParser();var singleNodeTransform=_index2.default.createStitcher();var readStream=(0,_fs.createReadStream)(input);var writeStream=output?(0,_fs.createWriteStream)(output):process.stdout;readStream.pipe(parserTransform);parserTransform.pipe(singleNodeTransform);singleNodeTransform.pipe(writeStream);parserTransform.on('error',error);singleNodeTransform.on('error',error);writeStream.on('finish',done);}function standardParser(){(0,_fs.readFile)(input,'utf8',checkThen(function(data){(0,_index2.default)(data,checkThen(function(ast){var result=void 0;try{result=JSON.stringify(ast,null,2);}catch(e){return error(e);}if(output){(0,_fs.writeFile)(output,result,checkThen(done));}else{process.stdout.write(result+'\n');done();}}));}));};

lib/streaming.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/sqlite-parser.js

Lines changed: 72 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,31 @@ import {
33
stat,
44
writeFile,
55
mkdir,
6-
readFile
6+
readFile,
7+
createReadStream,
8+
createWriteStream
79
} from 'fs';
810
import {
911
normalize,
1012
dirname
1113
} from 'path';
1214

15+
const aliases = {
16+
o: 'output',
17+
v: 'version',
18+
h: 'help',
19+
x: 'stream'
20+
};
1321
const args = resolveArgs(process.argv.slice(2));
1422

23+
const error = function (err) {
24+
console.error(err);
25+
process.exit(1);
26+
}
27+
const done = checkThen(function () {
28+
process.exit(0);
29+
});
30+
1531
if (args['version']) {
1632
console.log(`sqlite-parser v@@VERSION`);
1733
process.exit(0);
@@ -21,27 +37,38 @@ if (args['help'] || args._.length === 0) {
2137
console.log(`Usage:\tsqlite-parser [infile]\n`);
2238
console.log(`Option\t\t\tAlias\tDescription`);
2339
console.log(`--output [outfile]\t-o\tWrite output to a file instead of stdout`);
40+
console.log(`--stream\t\t-x\tEnable streaming mode (default: infile >150kB)`);
2441
console.log(`--version\t\t-v\tGet current parser version`);
2542
process.exit(0);
2643
}
2744

45+
let streaming = args['stream'];
2846
const input = normalize(args._[0]);
29-
let output = args['o'] || args['output'];
30-
47+
let output = args['output'];
3148
if (output) {
3249
output = normalize(output);
3350
}
3451

35-
stat(input, function startCallback(err) {
36-
if (err) { return error(err); }
37-
readFile(input, 'utf8', readCallback);
38-
});
52+
stat(input, checkThen(function ({ size }) {
53+
// If the file size is above a 150kB limit, switch to streaming mode
54+
if (size / 1000 >= 150) {
55+
streaming = true;
56+
}
57+
const startStream = streaming ? streamParser : standardParser;
58+
if (output) {
59+
const outDir = dirname(output);
60+
stat(outDir, checkThen(startStream, function () {
61+
mkdir(outDir, startStream);
62+
}));
63+
} else {
64+
startStream();
65+
}
66+
}));
3967

4068
function resolveArgs(argv) {
4169
const args = { _: [] };
4270
let last = null;
4371
const isNewArg = (arg) => !arg || arg.indexOf('-') === 0;
44-
const aliases = { o: 'output', v: 'version', h: 'help' };
4572
for (let i = 0; i < argv.length; i += 1) {
4673
const arg = argv[i];
4774
if (isNewArg(arg)) {
@@ -57,53 +84,47 @@ function resolveArgs(argv) {
5784
return args;
5885
}
5986

60-
function error(err) {
61-
console.error(err.message);
62-
process.exit(1);
87+
function checkThen(
88+
resCallback = done,
89+
errCallback = error
90+
) {
91+
return function (err, result) {
92+
if (err) { return errCallback(err); }
93+
resCallback(result);
94+
};
6395
}
6496

65-
function writeOut(result, outPath) {
66-
const outDir = dirname(outPath);
67-
68-
function writeCallback(err) {
69-
if (err) { return error(err) }
70-
process.exit(0);
71-
}
97+
function streamParser() {
98+
const parserTransform = parser.createParser();
99+
const singleNodeTransform = parser.createStitcher();
100+
const readStream = createReadStream(input);
101+
const writeStream = output ? createWriteStream(output) : process.stdout;
72102

73-
function mkdirCallback(err) {
74-
if (err) { return error(err) }
75-
writeFile(outPath, result, writeCallback);
76-
}
103+
readStream.pipe(parserTransform);
104+
parserTransform.pipe(singleNodeTransform);
105+
singleNodeTransform.pipe(writeStream);
77106

78-
function statCallback(err) {
79-
if (err) {
80-
return mkdir(outDir, mkdirCallback);
81-
}
82-
mkdirCallback();
83-
}
107+
parserTransform.on('error', error);
108+
singleNodeTransform.on('error', error);
84109

85-
stat(outDir, statCallback);
110+
writeStream.on('finish', done);
86111
}
87112

88-
function parserCallback(err, ast) {
89-
if (err) { return error(err) }
90-
let result;
91-
92-
try {
93-
result = JSON.stringify(ast, null, 2);
94-
} catch (e) {
95-
return error(e);
96-
}
97-
98-
if (output) {
99-
writeOut(result, output);
100-
} else {
101-
process.stdout.write(result);
102-
process.exit(0);
103-
}
104-
}
105-
106-
function readCallback(err, data) {
107-
if (err) { return error(err) }
108-
parser(data, parserCallback);
109-
}
113+
function standardParser() {
114+
readFile(input, 'utf8', checkThen(function (data) {
115+
parser(data, checkThen(function (ast) {
116+
let result;
117+
try {
118+
result = JSON.stringify(ast, null, 2);
119+
} catch (e) {
120+
return error(e);
121+
}
122+
if (output) {
123+
writeFile(output, result, checkThen(done));
124+
} else {
125+
process.stdout.write(`${result}\n`);
126+
done();
127+
}
128+
}));
129+
}));
130+
};

src/streaming.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export class SingleNodeTransform extends Transform {
7575
}
7676

7777
_flush(callback) {
78-
this.push(`\n ]\n}`);
78+
this.push(`\n ]\n}\n`);
7979
callback();
8080
}
8181
}

0 commit comments

Comments
 (0)