values.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright (c) 2015-present, Vitaly Tomilov
  3. *
  4. * See the LICENSE file at the top-level directory of this distribution
  5. * for licensing information.
  6. *
  7. * Removal or modification of this copyright notice is prohibited.
  8. */
  9. const {ColumnSet} = require('../column-set');
  10. const npm = {
  11. formatting: require('../../formatting'),
  12. utils: require('../../utils')
  13. };
  14. /**
  15. * @method helpers.values
  16. * @description
  17. * Generates a string of comma-separated value groups from either one object or an array of objects,
  18. * to be used as part of a query:
  19. *
  20. * - from a single object: `(val_1, val_2, ...)`
  21. * - from an array of objects: `(val_11, val_12, ...), (val_21, val_22, ...)`
  22. *
  23. * @param {object|object[]} data
  24. * A source object with properties as values, or an array of such objects.
  25. *
  26. * If it is anything else, the method will throw {@link external:TypeError TypeError} = `Invalid parameter 'data' specified.`
  27. *
  28. * When `data` is an array that contains a non-object value, the method will throw {@link external:Error Error} =
  29. * `Invalid object at index N.`
  30. *
  31. * When `data` is an empty array, an empty string is returned.
  32. *
  33. * @param {array|helpers.Column|helpers.ColumnSet} [columns]
  34. * Columns for which to return values.
  35. *
  36. * It is optional when `data` is a single object, and required when `data` is an array of objects. If not specified for an array
  37. * of objects, the method will throw {@link external:TypeError TypeError} = `Parameter 'columns' is required when generating multi-row values.`
  38. *
  39. * When the final {@link helpers.ColumnSet ColumnSet} is empty (no columns in it), the method will throw
  40. * {@link external:Error Error} = `Cannot generate values without any columns.`
  41. *
  42. * @returns {string}
  43. * - comma-separated value groups, according to `data`
  44. * - an empty string, if `data` is an empty array
  45. *
  46. * @see
  47. * {@link helpers.Column Column},
  48. * {@link helpers.ColumnSet ColumnSet}
  49. *
  50. * @example
  51. *
  52. * const pgp = require('pg-promise')();
  53. *
  54. * const dataSingle = {val: 123, msg: 'hello'};
  55. * const dataMulti = [{val: 123, msg: 'hello'}, {val: 456, msg: 'world!'}];
  56. *
  57. * // Properties can be pulled automatically from a single object:
  58. *
  59. * pgp.helpers.values(dataSingle);
  60. * //=> (123,'hello')
  61. *
  62. * @example
  63. *
  64. * // Column details are required when using an array of objects:
  65. *
  66. * pgp.helpers.values(dataMulti, ['val', 'msg']);
  67. * //=> (123,'hello'),(456,'world!')
  68. *
  69. * @example
  70. *
  71. * // Column details from a reusable ColumnSet (recommended for performance):
  72. *
  73. * const cs = new pgp.helpers.ColumnSet(['val', 'msg']);
  74. *
  75. * pgp.helpers.values(dataMulti, cs);
  76. * //=> (123,'hello'),(456,'world!')
  77. *
  78. */
  79. function values(data, columns, capSQL) {
  80. if (!data || typeof data !== 'object') {
  81. throw new TypeError('Invalid parameter \'data\' specified.');
  82. }
  83. const isArray = Array.isArray(data);
  84. if (!(columns instanceof ColumnSet)) {
  85. if (isArray && npm.utils.isNull(columns)) {
  86. throw new TypeError('Parameter \'columns\' is required when generating multi-row values.');
  87. }
  88. columns = new ColumnSet(columns || data);
  89. }
  90. if (!columns.columns.length) {
  91. throw new Error('Cannot generate values without any columns.');
  92. }
  93. const format = npm.formatting.as.format,
  94. fmOptions = {capSQL};
  95. if (isArray) {
  96. return data.map((d, index) => {
  97. if (!d || typeof d !== 'object') {
  98. throw new Error(`Invalid object at index ${index}.`);
  99. }
  100. return '(' + format(columns.variables, columns.prepare(d), fmOptions) + ')';
  101. }).join();
  102. }
  103. return '(' + format(columns.variables, columns.prepare(data), fmOptions) + ')';
  104. }
  105. module.exports = {values};