define.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // ██████╗ ███████╗███████╗██╗███╗ ██╗███████╗
  2. // ██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝
  3. // ██║ ██║█████╗ █████╗ ██║██╔██╗ ██║█████╗
  4. // ██║ ██║██╔══╝ ██╔══╝ ██║██║╚██╗██║██╔══╝
  5. // ██████╔╝███████╗██║ ██║██║ ╚████║███████╗
  6. // ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝
  7. //
  8. module.exports = require('machine').build({
  9. friendlyName: 'Define',
  10. description: 'Create a new table in the database based on a given schema.',
  11. inputs: {
  12. datastore: {
  13. description: 'The datastore to use for connections.',
  14. extendedDescription: 'Datastores represent the config and manager required to obtain an active database connection.',
  15. required: true,
  16. example: '==='
  17. },
  18. tableName: {
  19. description: 'The name of the table to describe.',
  20. required: true,
  21. example: 'users'
  22. },
  23. definition: {
  24. description: 'The definition of the schema to build.',
  25. required: true,
  26. example: {}
  27. },
  28. meta: {
  29. friendlyName: 'Meta (custom)',
  30. description: 'Additional stuff to pass to the driver.',
  31. extendedDescription: 'This is reserved for custom driver-specific extensions.',
  32. example: '==='
  33. }
  34. },
  35. exits: {
  36. success: {
  37. description: 'The table was created successfully.'
  38. },
  39. badConnection: {
  40. friendlyName: 'Bad connection',
  41. description: 'A connection either could not be obtained or there was an error using the connection.'
  42. }
  43. },
  44. fn: function define(inputs, exits) {
  45. // Dependencies
  46. var _ = require('@sailshq/lodash');
  47. var Helpers = require('./private');
  48. // Set a flag if a leased connection from outside the adapter was used or not.
  49. var leased = _.has(inputs.meta, 'leasedConnection');
  50. // ╔═╗╔═╗╔═╗╦ ╦╔╗╔ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌
  51. // ╚═╗╠═╝╠═╣║║║║║║ │ │ │││││││├┤ │ │ ││ ││││
  52. // ╚═╝╩ ╩ ╩╚╩╝╝╚╝ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘
  53. // Spawn a new connection for running queries on.
  54. Helpers.connection.spawnOrLeaseConnection(inputs.datastore, inputs.meta, function spawnConnectionCb(err, connection) {
  55. if (err) {
  56. return exits.badConnection(err);
  57. }
  58. // Escape Table Name
  59. var tableName;
  60. try {
  61. tableName = Helpers.schema.escapeTableName(inputs.tableName);
  62. } catch (e) {
  63. // If there was an issue, release the connection
  64. Helpers.connection.releaseConnection(connection, leased, function releaseConnectionCb() {
  65. return exits.error(e);
  66. });
  67. return;
  68. }
  69. // ╔╗ ╦ ╦╦╦ ╔╦╗ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬ ┌─┐┌┬┐┬─┐┬┌┐┌┌─┐
  70. // ╠╩╗║ ║║║ ║║ │─┼┐│ │├┤ ├┬┘└┬┘ └─┐ │ ├┬┘│││││ ┬
  71. // ╚═╝╚═╝╩╩═╝═╩╝ └─┘└└─┘└─┘┴└─ ┴ └─┘ ┴ ┴└─┴┘└┘└─┘
  72. // Iterate through each attribute, building a query string
  73. var schema;
  74. try {
  75. schema = Helpers.schema.buildSchema(inputs.definition);
  76. } catch (e) {
  77. // If there was an issue, release the connection
  78. Helpers.connection.releaseConnection(connection, leased, function releaseConnectionCb() {
  79. return exits.error(e);
  80. });
  81. return;
  82. }
  83. // Build Query
  84. var query = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + schema + ')';
  85. // ╦═╗╦ ╦╔╗╔ ┌─┐┬─┐┌─┐┌─┐┌┬┐┌─┐ ┌┬┐┌─┐┌┐ ┬ ┌─┐
  86. // ╠╦╝║ ║║║║ │ ├┬┘├┤ ├─┤ │ ├┤ │ ├─┤├┴┐│ ├┤
  87. // ╩╚═╚═╝╝╚╝ └─┘┴└─└─┘┴ ┴ ┴ └─┘ ┴ ┴ ┴└─┘┴─┘└─┘
  88. // ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
  89. // │─┼┐│ │├┤ ├┬┘└┬┘
  90. // └─┘└└─┘└─┘┴└─ ┴
  91. Helpers.query.runNativeQuery(connection, query, [], undefined, function runNativeQueryCb(err) {
  92. if (err) {
  93. // If there was an issue, release the connection
  94. Helpers.connection.releaseConnection(connection, leased, function releaseConnectionCb() {
  95. return exits.error(err);
  96. });
  97. return;
  98. }
  99. // ╔╗ ╦ ╦╦╦ ╔╦╗ ┬┌┐┌┌┬┐┌─┐─┐ ┬┌─┐┌─┐
  100. // ╠╩╗║ ║║║ ║║ ││││ ││├┤ ┌┴┬┘├┤ └─┐
  101. // ╚═╝╚═╝╩╩═╝═╩╝ ┴┘└┘─┴┘└─┘┴ └─└─┘└─┘
  102. // Build any indexes
  103. Helpers.schema.buildIndexes({
  104. connection: connection,
  105. definition: inputs.definition,
  106. tableName: inputs.tableName
  107. },
  108. function buildIndexesCb(err) {
  109. Helpers.connection.releaseConnection(connection, leased, function releaseConnectionCb() {
  110. if (err) {
  111. return exits.error(err);
  112. }
  113. return exits.success();
  114. });
  115. return;
  116. }); // </ buildIndexes() >
  117. }); // </ runNativeQuery >
  118. }); // </ spawnConnection >
  119. }
  120. });