Skip to content

Commit dd22da2

Browse files
authored
Merge pull request #1849 from dhensby/fix/ps-execute-stream
fix: prevent TypeError in PreparedStatement.execute() when streaming without callback
2 parents 0e9c326 + 7934ff1 commit dd22da2

5 files changed

Lines changed: 46 additions & 5 deletions

File tree

lib/base/prepared-statement.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,10 @@ class PreparedStatement extends EventEmitter {
356356
}
357357
}
358358

359-
req.execute('sp_execute', (err, result) => {
360-
if (err) return callback(err)
361-
362-
callback(null, result)
363-
})
359+
req.execute('sp_execute', typeof callback === 'function'
360+
? callback
361+
: () => {}
362+
)
364363

365364
return req
366365
}

test/common/tests.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,26 @@ module.exports = (sql, driver) => {
922922
}).catch(done)
923923
},
924924

925+
'prepared statement with streaming and no callback' (done) {
926+
const ps = new TestPreparedStatement()
927+
ps.stream = true
928+
ps.input('num', sql.Int)
929+
ps.prepare('select @num as number').then(() => {
930+
const req = ps.execute({ num: 123 })
931+
const rows = []
932+
933+
req.on('row', row => rows.push(row))
934+
req.on('error', err => {
935+
ps.unprepare(() => done(err))
936+
})
937+
req.on('done', () => {
938+
assert.strictEqual(rows.length, 1)
939+
assert.strictEqual(rows[0].number, 123)
940+
ps.unprepare(done)
941+
})
942+
}).catch(done)
943+
},
944+
925945
'transaction with rollback' (done) {
926946
let tbegin = false
927947
let tcommit = false

test/common/unit.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,4 +1402,24 @@ describe('connection string auth - tedious', () => {
14021402
})
14031403
})
14041404
})
1405+
1406+
describe('PreparedStatement streaming', () => {
1407+
const BasePreparedStatement = require('../../lib/base/prepared-statement')
1408+
const ConnectionPool = require('../../lib/tedious/connection-pool')
1409+
1410+
it('execute does not throw when stream=true and no callback provided', (done) => {
1411+
const pool = new ConnectionPool({ server: 'localhost' })
1412+
const ps = new BasePreparedStatement(pool)
1413+
ps.stream = true
1414+
ps.prepared = true
1415+
ps._handle = 1
1416+
1417+
// Should not throw TypeError — returns the inner Request
1418+
const req = ps.execute({})
1419+
assert.ok(req, 'execute() should return the inner Request')
1420+
// The request will error (no connection) — that's fine,
1421+
// the point is it doesn't throw TypeError
1422+
req.on('error', () => done())
1423+
})
1424+
})
14051425
})

test/msnodesqlv8/msnodesqlv8.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ describe('msnodesqlv8', function () {
8282
it('prepared statement with affected rows', done => TESTS['prepared statement with affected rows'](done))
8383
it('prepared statement in transaction', done => TESTS['prepared statement in transaction'](done))
8484
it('prepared statement with duplicate output column names', done => TESTS['prepared statement with duplicate output column names'](done))
85+
it('prepared statement with streaming and no callback', done => TESTS['prepared statement with streaming and no callback'](done))
8586
it('transaction with rollback', done => TESTS['transaction with rollback'](done))
8687
it('transaction with commit', done => TESTS['transaction with commit'](done))
8788
it('transaction throws on bad isolation level', done => TESTS['transaction throws on bad isolation level'](done))

test/tedious/tedious.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ describe('tedious', () => {
8989
it('prepared statement with affected rows', done => TESTS['prepared statement with affected rows'](done))
9090
it('prepared statement in transaction', done => TESTS['prepared statement in transaction'](done))
9191
it('prepared statement with duplicate output column names', done => TESTS['prepared statement with duplicate output column names'](done))
92+
it('prepared statement with streaming and no callback', done => TESTS['prepared statement with streaming and no callback'](done))
9293
it('transaction with rollback', done => TESTS['transaction with rollback'](done))
9394
it('transaction with commit', done => TESTS['transaction with commit'](done))
9495
it('transaction throws on bad isolation level', done => TESTS['transaction throws on bad isolation level'](done))

0 commit comments

Comments
 (0)