result.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. 'use strict'
  2. const types = require('pg-types')
  3. const matchRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/
  4. // result object returned from query
  5. // in the 'end' event and also
  6. // passed as second argument to provided callback
  7. class Result {
  8. constructor(rowMode, types) {
  9. this.command = null
  10. this.rowCount = null
  11. this.oid = null
  12. this.rows = []
  13. this.fields = []
  14. this._parsers = undefined
  15. this._types = types
  16. this.RowCtor = null
  17. this.rowAsArray = rowMode === 'array'
  18. if (this.rowAsArray) {
  19. this.parseRow = this._parseRowAsArray
  20. }
  21. this._prebuiltEmptyResultObject = null
  22. }
  23. // adds a command complete message
  24. addCommandComplete(msg) {
  25. let match
  26. if (msg.text) {
  27. // pure javascript
  28. match = matchRegexp.exec(msg.text)
  29. } else {
  30. // native bindings
  31. match = matchRegexp.exec(msg.command)
  32. }
  33. if (match) {
  34. this.command = match[1]
  35. if (match[3]) {
  36. // COMMAND OID ROWS
  37. this.oid = parseInt(match[2], 10)
  38. this.rowCount = parseInt(match[3], 10)
  39. } else if (match[2]) {
  40. // COMMAND ROWS
  41. this.rowCount = parseInt(match[2], 10)
  42. }
  43. }
  44. }
  45. _parseRowAsArray(rowData) {
  46. const row = new Array(rowData.length)
  47. for (let i = 0, len = rowData.length; i < len; i++) {
  48. const rawValue = rowData[i]
  49. if (rawValue !== null) {
  50. row[i] = this._parsers[i](rawValue)
  51. } else {
  52. row[i] = null
  53. }
  54. }
  55. return row
  56. }
  57. parseRow(rowData) {
  58. const row = { ...this._prebuiltEmptyResultObject }
  59. for (let i = 0, len = rowData.length; i < len; i++) {
  60. const rawValue = rowData[i]
  61. const field = this.fields[i].name
  62. if (rawValue !== null) {
  63. const v = this.fields[i].format === 'binary' ? Buffer.from(rawValue) : rawValue
  64. row[field] = this._parsers[i](v)
  65. } else {
  66. row[field] = null
  67. }
  68. }
  69. return row
  70. }
  71. addRow(row) {
  72. this.rows.push(row)
  73. }
  74. addFields(fieldDescriptions) {
  75. // clears field definitions
  76. // multiple query statements in 1 action can result in multiple sets
  77. // of rowDescriptions...eg: 'select NOW(); select 1::int;'
  78. // you need to reset the fields
  79. this.fields = fieldDescriptions
  80. if (this.fields.length) {
  81. this._parsers = new Array(fieldDescriptions.length)
  82. }
  83. const row = {}
  84. for (let i = 0; i < fieldDescriptions.length; i++) {
  85. const desc = fieldDescriptions[i]
  86. row[desc.name] = null
  87. if (this._types) {
  88. this._parsers[i] = this._types.getTypeParser(desc.dataTypeID, desc.format || 'text')
  89. } else {
  90. this._parsers[i] = types.getTypeParser(desc.dataTypeID, desc.format || 'text')
  91. }
  92. }
  93. this._prebuiltEmptyResultObject = { ...row }
  94. }
  95. }
  96. module.exports = Result