process-each-record.js 4.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // ██████╗ ██████╗ ██████╗ ██████╗███████╗███████╗███████╗ ███████╗ █████╗ ██████╗██╗ ██╗
  2. // ██╔══██╗██╔══██╗██╔═══██╗██╔════╝██╔════╝██╔════╝██╔════╝ ██╔════╝██╔══██╗██╔════╝██║ ██║
  3. // ██████╔╝██████╔╝██║ ██║██║ █████╗ ███████╗███████╗ █████╗ ███████║██║ ███████║
  4. // ██╔═══╝ ██╔══██╗██║ ██║██║ ██╔══╝ ╚════██║╚════██║ ██╔══╝ ██╔══██║██║ ██╔══██║
  5. // ██║ ██║ ██║╚██████╔╝╚██████╗███████╗███████║███████║ ███████╗██║ ██║╚██████╗██║ ██║
  6. // ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝╚══════╝╚══════╝╚══════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
  7. //
  8. // ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██████╗
  9. // ██╔══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗
  10. // ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██║ ██║
  11. // ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║ ██║
  12. // ██║ ██║███████╗╚██████╗╚██████╔╝██║ ██║██████╔╝
  13. // ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝
  14. //
  15. var _ = require('@sailshq/lodash');
  16. var utils = require('waterline-utils');
  17. var eachRecordDeep = utils.eachRecordDeep;
  18. module.exports = function processEachRecord(options) {
  19. // ╦ ╦╔═╗╦ ╦╔╦╗╔═╗╔╦╗╔═╗ ┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐
  20. // ╚╗╔╝╠═╣║ ║ ║║╠═╣ ║ ║╣ │ │├─┘ │ ││ ││││└─┐
  21. // ╚╝ ╩ ╩╩═╝╩═╩╝╩ ╩ ╩ ╚═╝ └─┘┴ ┴ ┴└─┘┘└┘└─┘
  22. if (_.isUndefined(options) || !_.isPlainObject(options)) {
  23. throw new Error('Invalid options argument. Options must contain: records, identity, and orm.');
  24. }
  25. if (!_.has(options, 'records') || !_.isArray(options.records)) {
  26. throw new Error('Invalid option used in options argument. Missing or invalid records.');
  27. }
  28. if (!_.has(options, 'identity') || !_.isString(options.identity)) {
  29. throw new Error('Invalid option used in options argument. Missing or invalid identity.');
  30. }
  31. if (!_.has(options, 'orm') || !_.isPlainObject(options.orm)) {
  32. throw new Error('Invalid option used in options argument. Missing or invalid orm.');
  33. }
  34. // Key the collections by identity instead of column name
  35. var collections = _.reduce(options.orm.collections, function(memo, val) {
  36. memo[val.identity] = val;
  37. return memo;
  38. }, {});
  39. options.orm.collections = collections;
  40. // Run all the records through the iterator so that they can be normalized.
  41. eachRecordDeep(options.records, function iterator(record, WLModel) {
  42. // Check if the record and the model contain any boolean types.
  43. // Because MySQL returns these as binary (0, 1) they must be
  44. // transformed into true/false values.
  45. _.each(WLModel.definition, function checkAttributes(attrDef) {
  46. var columnName = attrDef.columnName;
  47. if (attrDef.type === 'boolean' && _.has(record, columnName)) {
  48. if (!_.isBoolean(record[columnName])) {
  49. if (record[columnName] === 0) {
  50. record[columnName] = false;
  51. }
  52. if (record[columnName] === 1) {
  53. record[columnName] = true;
  54. }
  55. }
  56. }
  57. // JSON parse any type of JSON column type
  58. if (attrDef.type === 'json' && _.has(record, columnName)) {
  59. // Special case: If it came back as the `null` literal, leave it alone
  60. if (_.isNull(record[columnName])) {
  61. return;
  62. }
  63. // But otherwise, assume it's a JSON string and try to parse it
  64. record[columnName] = JSON.parse(record[columnName]);
  65. }
  66. });
  67. }, true, options.identity, options.orm);
  68. };