Description
Hello,
I want to turn a resultSet into a readableStream (like node-mssql and node-mysql provide through their pipe
methods), so I can pipe it to whatever I want to do with the results (millions of lines).
Here is my function to execute a query and then returns a readable stream :
async function executeQuery(connectionParameters, query, queryParameters) {
const getConnection = promisify(oracle.getConnection.bind(oracle))
const connection = await getConnection(connectionParameters)
const executeQuery = promisify(connection.execute.bind(connection))
const result = await executeQuery(query, queryParameters, { resultSet: true })
const getRow = promisify(result.resultSet.getRow.bind(result.resultSet))
const rs = Readable({ objectMode: true })
rs._read = async function() {
const row = await getRow()
if (!row) {
result.resultSet.close((e) => { if (e) throw e })
connection.release((e) => { if (e) throw e })
return rs.push(null)
}
rs.push(row)
}
return rs
}
Here is how I use it :
const query$ = await executeQuery(connectionParameters, query, queryParameters)
return new Promise((resolve, reject) => {
query$.on("error", reject)
const csvStringifier$ = csvStringify({ delimiter: argv.delimiter })
csvStringifier$.on("error", reject)
const file$ = fs.createWriteStream("./extraction.csv")
file$.on("finish", resolve).on("error", reject)
query$.pipe(csvStringifier$).pipe(file$)
})
My issue is as a certain point, the fetching stops without errors.
For the same query, sometimes they're 10K rows written to the file, then only 2K, then 14K...
I'm pretty sure it's due to my _read
implementation, but I can't figure out what's wrong with it.
In node.js doc (https://nodejs.org/api/stream.html#stream_readable_read_size_1) this part is unclear to me :
When _read is called, if data is available from the resource, _read should start pushing that data into the read queue by calling this.push(dataChunk). _read should continue reading from the resource and pushing data until push returns false, at which point it should stop reading from the resource. Only when _read is called again after it has stopped should it start reading more data from the resource and pushing that data onto the queue.
Thanks in advance.
EDIT : Here is an example of an implementation : https://github.com/felixge/node-mysql/blob/de5913227dbbaacbbdf22ee38689d090e1451be9/lib/protocol/sequences/Query.js#L188