feat: now search callback response will emit SearchRequest after every search request is sent

This commit is contained in:
zhaoyunfeng 2021-05-24 12:34:32 +08:00
parent 010b472dd8
commit e74ba91238
4 changed files with 30 additions and 12 deletions

View File

@ -276,15 +276,15 @@ containing the following fields:
|timeLimit |the maximum amount of time the server should take in responding, in seconds. Defaults to 10. Lots of servers will ignore this.|
|paged |enable and/or configure automatic result paging|
Responses from the `search` method are an `EventEmitter` where you will get a
notification for each `searchEntry` that comes back from the server. You will
additionally be able to listen for a `searchReference`, `error` and `end` event.
Note that the `error` event will only be for client/TCP errors, not LDAP error
codes like the other APIs. You'll want to check the LDAP status code
(likely for `0`) on the `end` event to assert success. LDAP search results
can give you a lot of status codes, such as time or size exceeded, busy,
inappropriate matching, etc., which is why this method doesn't try to wrap up
the code matching.
Responses inside callback of the `search` method are an `EventEmitter` where you will get a notification for
each `searchEntry` that comes back from the server. You will additionally be able to listen for a `searchRequest`
, `searchReference`, `error` and `end` event.
`searchRequest` is emitted immediately after every `SearchRequest` is sent with a `SearchRequest` param. You can do op
like `client.abandon` with `searchRequest.messageID` to abandon this search request. Note that the `error` event will
only be for client/TCP errors, not LDAP error codes like the other APIs. You'll want to check the LDAP status code
(likely for `0`) on the `end` event to assert success. LDAP search results can give you a lot of status codes, such as
time or size exceeded, busy, inappropriate matching, etc., which is why this method doesn't try to wrap up the code
matching.
Example:
@ -298,6 +298,9 @@ const opts = {
client.search('o=example', opts, (err, res) => {
assert.ifError(err);
res.on('searchRequest', (searchRequest) => {
console.log('searchRequest: ', searchRequest.messageID);
});
res.on('searchEntry', (entry) => {
console.log('entry: ' + JSON.stringify(entry.object));
});

View File

@ -1251,7 +1251,9 @@ Client.prototype._sendSocket = function _sendSocket (message,
conn.end()
} else if (emitter) {
sentEmitter = true
return callback(null, emitter)
callback(null, emitter)
emitter.emit('searchRequest', message)
return
}
return false
}

View File

@ -55,6 +55,7 @@ function SearchPager (opts) {
this.started = false
const emitter = new EventEmitter()
emitter.on('searchRequest', this.emit.bind(this, 'searchRequest'))
emitter.on('searchEntry', this.emit.bind(this, 'searchEntry'))
emitter.on('end', this._onEnd.bind(this))
emitter.on('error', this._onError.bind(this))

View File

@ -777,14 +777,23 @@ tap.test('search paged', { timeout: 10000 }, function (t) {
t.test('paged - no pauses', function (t2) {
let countEntries = 0
let countPages = 0
let currentSearchRequest = null
t.context.client.search('cn=paged', { paged: { pageSize: 100 } }, function (err, res) {
t2.error(err)
res.on('searchEntry', entryListener)
res.on('searchRequest', (searchRequest) => {
t2.ok(searchRequest instanceof ldap.SearchRequest)
if (currentSearchRequest === null) {
t2.equal(countPages, 0)
}
currentSearchRequest = searchRequest
})
res.on('page', pageListener)
res.on('error', (err) => t2.error(err))
res.on('end', function () {
res.on('end', function (result) {
t2.equal(countEntries, 1000)
t2.equal(countPages, 10)
t2.equal(result.messageID, currentSearchRequest.messageID)
t2.end()
})
@ -797,8 +806,11 @@ tap.test('search paged', { timeout: 10000 }, function (t) {
countEntries += 1
}
function pageListener () {
function pageListener(result) {
countPages += 1
if (countPages < 10) {
t2.equal(result.messageID, currentSearchRequest.messageID)
}
}
})
})