create.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // ██████╗██████╗ ███████╗ █████╗ ████████╗███████╗
  2. // ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝
  3. // ██║ ██████╔╝█████╗ ███████║ ██║ █████╗
  4. // ██║ ██╔══██╗██╔══╝ ██╔══██║ ██║ ██╔══╝
  5. // ╚██████╗██║ ██║███████╗██║ ██║ ██║ ███████╗
  6. // ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝
  7. //
  8. // Perform a create query and fetch the record if needed.
  9. var _ = require('@sailshq/lodash');
  10. var compileStatement = require('./compile-statement');
  11. var runQuery = require('./run-query');
  12. module.exports = function createEach(options, cb) {
  13. // ╦ ╦╔═╗╦ ╦╔╦╗╔═╗╔╦╗╔═╗ ┌─┐┌─┐┌┬┐┬┌─┐┌┐┌┌─┐
  14. // ╚╗╔╝╠═╣║ ║ ║║╠═╣ ║ ║╣ │ │├─┘ │ ││ ││││└─┐
  15. // ╚╝ ╩ ╩╩═╝╩═╩╝╩ ╩ ╩ ╚═╝ └─┘┴ ┴ ┴└─┘┘└┘└─┘
  16. if (_.isUndefined(options) || !_.isPlainObject(options)) {
  17. throw new Error('Invalid options argument. Options must contain: connection, statement, fetch, and primaryKey.');
  18. }
  19. if (!_.has(options, 'connection') || !_.isObject(options.connection)) {
  20. throw new Error('Invalid option used in options argument. Missing or invalid connection.');
  21. }
  22. if (!_.has(options, 'statement') || !_.isPlainObject(options.statement)) {
  23. throw new Error('Invalid option used in options argument. Missing or invalid statement.');
  24. }
  25. if (!_.has(options, 'fetch') || !_.isBoolean(options.fetch)) {
  26. throw new Error('Invalid option used in options argument. Missing or invalid fetch flag.');
  27. }
  28. if (!_.has(options, 'primaryKey') || !_.isString(options.primaryKey)) {
  29. throw new Error('Invalid option used in options argument. Missing or invalid primaryKey flag.');
  30. }
  31. // ╔═╗╔═╗╔╦╗╔═╗╦╦ ╔═╗ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
  32. // ║ ║ ║║║║╠═╝║║ ║╣ │─┼┐│ │├┤ ├┬┘└┬┘
  33. // ╚═╝╚═╝╩ ╩╩ ╩╩═╝╚═╝ └─┘└└─┘└─┘┴└─ ┴
  34. // Compile the statement into a native query.
  35. var compiledQuery;
  36. try {
  37. compiledQuery = compileStatement(options.statement);
  38. } catch (e) {
  39. // If the statement could not be compiled, return an error.
  40. return cb(e);
  41. }
  42. // ╦═╗╦ ╦╔╗╔ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
  43. // ╠╦╝║ ║║║║ │─┼┐│ │├┤ ├┬┘└┬┘
  44. // ╩╚═╚═╝╝╚╝ └─┘└└─┘└─┘┴└─ ┴
  45. // Run the initial query (bulk insert)
  46. var insertOptions = {
  47. connection: options.connection,
  48. nativeQuery: compiledQuery.nativeQuery,
  49. valuesToEscape: compiledQuery.valuesToEscape,
  50. meta: compiledQuery.meta,
  51. disconnectOnError: false,
  52. queryType: 'insert'
  53. };
  54. // Determine if a custom primary key value was used. If so pass it down so that
  55. // the report can be used correctly. MySQL doesn't return these values.
  56. if (options.statement.insert[options.primaryKey]) {
  57. insertOptions.customPrimaryKey = options.statement.insert[options.primaryKey];
  58. }
  59. runQuery(insertOptions, function runQueryCb(err, report) {
  60. if (err) {
  61. return cb(err);
  62. }
  63. // If no fetch was used, then nothing else needs to be done.
  64. if (!options.fetch) {
  65. return cb(undefined, report.result);
  66. }
  67. // ╔═╗╔═╗╦═╗╔═╗╔═╗╦═╗╔╦╗ ┌┬┐┬ ┬┌─┐ ┌─┐┌─┐┌┬┐┌─┐┬ ┬
  68. // ╠═╝║╣ ╠╦╝╠╣ ║ ║╠╦╝║║║ │ ├─┤├┤ ├┤ ├┤ │ │ ├─┤
  69. // ╩ ╚═╝╩╚═╚ ╚═╝╩╚═╩ ╩ ┴ ┴ ┴└─┘ └ └─┘ ┴ └─┘┴ ┴
  70. // Otherwise, fetch the newly inserted record
  71. var fetchStatement = {
  72. select: '*',
  73. from: options.statement.into,
  74. where: {}
  75. };
  76. // Build up the WHERE clause for the statement to get the newly inserted
  77. // records.
  78. fetchStatement.where[options.primaryKey] = report.result.inserted;
  79. // ╔═╗╔═╗╔╦╗╔═╗╦╦ ╔═╗ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
  80. // ║ ║ ║║║║╠═╝║║ ║╣ │─┼┐│ │├┤ ├┬┘└┬┘
  81. // ╚═╝╚═╝╩ ╩╩ ╩╩═╝╚═╝ └─┘└└─┘└─┘┴└─ ┴
  82. // Compile the statement into a native query.
  83. var compiledQuery;
  84. try {
  85. compiledQuery = compileStatement(fetchStatement);
  86. } catch (err) {
  87. // If the statement could not be compiled, return an error.
  88. return cb(err);
  89. }
  90. // ╦═╗╦ ╦╔╗╔ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
  91. // ╠╦╝║ ║║║║ │─┼┐│ │├┤ ├┬┘└┬┘
  92. // ╩╚═╚═╝╝╚╝ └─┘└└─┘└─┘┴└─ ┴
  93. // Run the fetch query.
  94. runQuery({
  95. connection: options.connection,
  96. nativeQuery: compiledQuery.nativeQuery,
  97. valuesToEscape: compiledQuery.valuesToEscape,
  98. meta: compiledQuery.meta,
  99. disconnectOnError: false,
  100. queryType: 'select'
  101. }, function runQueryCb(err, report) {
  102. if (err) {
  103. return cb(err);
  104. }
  105. return cb(undefined, report.result);
  106. });
  107. });
  108. };