Skip to content

Commit

Permalink
feat(rest): extend wrapped results
Browse files Browse the repository at this point in the history
whenever a wrapped result is returned from a request
to eXist-db's REST-API (for both GET and POST) the
response will be extended with metadata derived
from the <exist:result> elements attributes.

- hits
- start
- count
- session
- compilationTime
- executionTime

If any of the above attributes is not set the property is set
to -1.
  • Loading branch information
line-o committed Aug 8, 2022
1 parent 390a6a2 commit 048327a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
58 changes: 38 additions & 20 deletions components/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ const postAttributeNames = [
'cache'
]

const existResultRegex = /^<exist:result/
/**
* Tests if body is a wrapped result from exist=db
*
* @param {String} body server response body
* @returns {Boolean}
*/
function isExistResult (body) {
return existResultRegex.test(body)
}

const sessionRegex = /exist:session="(\d+)"/
const hitsRegex = /exist:hits="(\d+)"/
const startRegex = /exist:start="(\d+)"/
Expand All @@ -91,6 +102,29 @@ function getAttributeValueByRegex (existResult, regex) {
return regex.test(existResult) ? parseInt(regex.exec(existResult)[1], 10) : -1
}

function extendIfWrapped (response) {
const { body } = response
if (!isExistResult(body)) {
return response
}

const session = getAttributeValueByRegex(body, sessionRegex)
const hits = getAttributeValueByRegex(body, hitsRegex)
const start = getAttributeValueByRegex(body, startRegex)
const count = getAttributeValueByRegex(body, countRegex)
const compilationTime = getAttributeValueByRegex(body, compilationTimeRegex)
const executionTime = getAttributeValueByRegex(body, executionTimeRegex)

return Object.assign(response, {
session,
hits,
start,
count,
compilationTime,
executionTime
})
}

/**
* create resource in DB
* @param {Object} restClient Got-instance
Expand Down Expand Up @@ -136,25 +170,8 @@ async function post (restClient, query, path, options) {
},
body
})
const existResult = response.body

const session = getAttributeValueByRegex(existResult, sessionRegex)
const hits = getAttributeValueByRegex(existResult, hitsRegex)
const start = getAttributeValueByRegex(existResult, startRegex)
const count = getAttributeValueByRegex(existResult, countRegex)
const compilationTime = getAttributeValueByRegex(existResult, compilationTimeRegex)
const executionTime = getAttributeValueByRegex(existResult, executionTimeRegex)

return {
session,
hits,
start,
count,
compilationTime,
executionTime,
body: existResult,
statusCode: response.statusCode
}
return extendIfWrapped(response)
}

/**
Expand All @@ -179,10 +196,11 @@ async function get (restClient, path, searchParams, writableStream) {
readStream,
writableStream
)
return _response
return extendIfWrapped(_response)
}

return restClient.get({ url, searchParams })
const response = await restClient.get({ url, searchParams })
return extendIfWrapped(response)
}

/**
Expand Down
6 changes: 3 additions & 3 deletions spec/tests/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ test('with rest client', async function (t) {
try {
const res = await rc.get('db/rest-test', { _wrap: 'yes', _indent: 'yes', _query })
st.equal(res.statusCode, 200, 'server responded with status ' + res.statusCode)
const lines = res.body.split('\n')
st.equal(res.hits, 1, 'result returned ' + res.hits + ' hit(s)')
st.equal(res.start, 1, 'start is ' + res.start)
st.equal(res.count, 1, 'count is ' + res.count)

const lines = res.body.split('\n')
st.ok(lines[0].startsWith('<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist"'))
st.equal(lines[1], ' <c name="/db/rest-test">')
st.equal(lines[2], ' <r name="from-buffer.xml"/>')
Expand Down Expand Up @@ -292,7 +292,7 @@ test('with rest client', async function (t) {
const lines = res.body.split('\n')
st.equal(lines.length, 1, 'body consists of a single line')
st.ok(lines[0].startsWith('<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist"'))
st.ok(lines[0].contains('<c name="/db/rest-test">'), 'contains result')
st.ok(lines[0].includes('<c name="/db/rest-test">'), 'contains result')
st.end()
} catch (e) {
st.fail(e)
Expand Down Expand Up @@ -341,7 +341,7 @@ test('with rest client', async function (t) {
try {
const res = await rc.post('xmldb:get-child-resources("/db/rest-test")', 'db/rest-test', { cache: 'yes', start: 1, max: 1 })
st.equal(res.statusCode, 200, 'server responded with status ' + res.statusCode)
st.ok(res.session, 'Got session ' + res.session)
st.isNot(res.session, -1, 'Got session ' + res.session)
st.equal(res.hits, 7, 'result returned ' + res.hits + ' hit(s)')
st.equal(res.start, 1, 'start is ' + res.start)
st.equal(res.count, 1, 'count is ' + res.count)
Expand Down

0 comments on commit 048327a

Please sign in to comment.