Skip to content

Commit

Permalink
Add support for per per-query types (#1825)
Browse files Browse the repository at this point in the history
The documentation states that you can pass custom type processors to
query objects. See:

https://node-postgres.com/features/queries#types

This didn't actually work. This commit adds an initial implementation
of per-query type-parsing. Caveats:

* It does not work with pg-native. That would require a separate pull
  request to pg-native, and a rather significant change to how that
  library handles query results.

* Per-query types do not "inherit" from types assigned to the Client,
  ala TypeOverrides.
  • Loading branch information
twooster authored and brianc committed Apr 16, 2019
1 parent 43ebcfb commit 566058d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
5 changes: 3 additions & 2 deletions lib/client.js
Expand Up @@ -478,8 +478,9 @@ Client.prototype.query = function (config, values, callback) {
if (this.binary && !query.binary) {
query.binary = true
}
if (query._result) {
query._result._getTypeParser = this._types.getTypeParser.bind(this._types)

if (query._result && !query._result._types) {
query._result._types = this._types
}

if (!this._queryable) {
Expand Down
7 changes: 3 additions & 4 deletions lib/result.js
Expand Up @@ -12,13 +12,14 @@ var types = require('pg-types')
// result object returned from query
// in the 'end' event and also
// passed as second argument to provided callback
var Result = function (rowMode) {
var Result = function (rowMode, types) {
this.command = null
this.rowCount = null
this.oid = null
this.rows = []
this.fields = []
this._parsers = []
this._types = types
this.RowCtor = null
this.rowAsArray = rowMode === 'array'
if (this.rowAsArray) {
Expand Down Expand Up @@ -94,11 +95,9 @@ Result.prototype.addFields = function (fieldDescriptions) {
for (var i = 0; i < fieldDescriptions.length; i++) {
var desc = fieldDescriptions[i]
this.fields.push(desc)
var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text')
var parser = (this._types || types).getTypeParser(desc.dataTypeID, desc.format || 'text')
this._parsers.push(parser)
}
}

Result.prototype._getTypeParser = types.getTypeParser

module.exports = Result
28 changes: 23 additions & 5 deletions test/integration/client/custom-types-tests.js
Expand Up @@ -3,13 +3,13 @@ const helper = require('./test-helper')
const Client = helper.pg.Client
const suite = new helper.Suite()

const client = new Client({
types: {
getTypeParser: () => () => 'okay!'
}
})
const customTypes = {
getTypeParser: () => () => 'okay!'
}

suite.test('custom type parser in client config', (done) => {
const client = new Client({ types: customTypes })

client.connect()
.then(() => {
client.query('SELECT NOW() as val', assert.success(function (res) {
Expand All @@ -18,3 +18,21 @@ suite.test('custom type parser in client config', (done) => {
}))
})
})

// Custom type-parsers per query are not supported in native
if (!helper.args.native) {
suite.test('custom type parser in query', (done) => {
const client = new Client()

client.connect()
.then(() => {
client.query({
text: 'SELECT NOW() as val',
types: customTypes
}, assert.success(function (res) {
assert.equal(res.rows[0].val, 'okay!')
client.end().then(done)
}))
})
})
}

1 comment on commit 566058d

@yocontra
Copy link
Contributor

@yocontra yocontra commented on 566058d Apr 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@twooster @brianc This breaks using types in pg-cursor btw - https://github.com/brianc/node-pg-cursor/blob/master/index.js#L53-L55

It seems like this was an undocumented attribute, but if other libraries were relying on it this should have been published as a breaking change.

Please sign in to comment.