Skip to content

Instantly share code, notes, and snippets.

@rmela
Last active December 22, 2023 17:51
Show Gist options
  • Save rmela/a3bed669ad6194fb2d9670789541b0c7 to your computer and use it in GitHub Desktop.
Save rmela/a3bed669ad6194fb2d9670789541b0c7 to your computer and use it in GitHub Desktop.
SQLite query results as nodejs readable stream
echo 'create table foo ( name string, value int )' | sqlite3 foo.db
for idx in {0..1000}
do
echo "insert into foo( name, value ) values( $idx, 'abc${idx}' );"
done | sqlite3 foo.db
/*
*
* Return SQLite3 query results as a Nodejs stream, sensitive to backpressure.
*
* Assumes a foo.db file with a lot of rows - I used 1000 with a number & a string
*/
const stream = require('stream');
const sqlite = require('sqlite3');
class DBStream extends stream.Readable {
constructor( opts ) {
super( { objectMode: true } );
this.sql = opts.sql;
this.db = new sqlite.Database( opts.db );
this.stmt = this.db.prepare( this.sql );
this.on( 'end', () => this.stmt.finalize( () => this.db.close() ));
}
_read() {
let strm = this;
this.stmt.get( function(err,result) {
// If result is undefined, push null, which will end the stream.
/*
* Should have no backpressure problems,
* since _read is only called when the downstream is
* ready to fetch data
*/
err ?
strm.emit('error', err ) :
strm.push( result || null);
})
}
}
/*
* simple test
*/
stream.pipeline(
[
new DBStream( { sql:'select * from foo' } ),
new stream.Transform( { objectMode: true, transform:( data, enc, cb ) => cb( null, JSON.stringify( data ) ) } ),
process.stdout
],
err => { err && console.error(err); process.exit(0) }
)
@wil92
Copy link

wil92 commented Apr 14, 2022

good stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment