123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // ██████╗██████╗ ███████╗ █████╗ ████████╗███████╗ █████╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗
- // ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝ ██╔══██╗██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║
- // ██║ ██████╔╝█████╗ ███████║ ██║ █████╗ ███████║██║ ██║ ██║██║ ██║██╔██╗ ██║
- // ██║ ██╔══██╗██╔══╝ ██╔══██║ ██║ ██╔══╝ ██╔══██║██║ ██║ ██║██║ ██║██║╚██╗██║
- // ╚██████╗██║ ██║███████╗██║ ██║ ██║ ███████╗ ██║ ██║╚██████╗ ██║ ██║╚██████╔╝██║ ╚████║
- // ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
- //
- module.exports = require('machine').build({
- friendlyName: 'Create',
- description: 'Insert a record into a table in the database.',
- inputs: {
- datastore: {
- description: 'The datastore to use for connections.',
- extendedDescription: 'Datastores represent the config and manager required to obtain an active database connection.',
- required: true,
- readOnly: true,
- example: '==='
- },
- models: {
- description: 'An object containing all of the model definitions that have been registered.',
- required: true,
- example: '==='
- },
- query: {
- description: 'A valid stage three Waterline query.',
- required: true,
- example: '==='
- }
- },
- exits: {
- success: {
- description: 'The record was successfully inserted.',
- outputVariableName: 'record',
- outputType: 'ref'
- },
- invalidDatastore: {
- description: 'The datastore used is invalid. It is missing key pieces.'
- },
- badConnection: {
- friendlyName: 'Bad connection',
- description: 'A connection either could not be obtained or there was an error using the connection.'
- },
- notUnique: {
- friendlyName: 'Not Unique',
- outputType: 'ref'
- }
- },
- fn: function create(inputs, exits) {
- // Dependencies
- var _ = require('@sailshq/lodash');
- var utils = require('waterline-utils');
- var Helpers = require('./private');
- // Store the Query input for easier access
- var query = inputs.query;
- query.meta = query.meta || {};
- // Find the model definition
- var model = inputs.models[query.using];
- if (!model) {
- return exits.invalidDatastore();
- }
- // Set a flag if a leased connection from outside the adapter was used or not.
- var leased = _.has(query.meta, 'leasedConnection');
- // Set a flag to determine if records are being returned
- var fetchRecords = false;
- // Build a faux ORM for use in processEachRecords
- var fauxOrm = {
- collections: inputs.models
- };
- // ╔═╗╦═╗╔═╗ ╔═╗╦═╗╔═╗╔═╗╔═╗╔═╗╔═╗ ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐┌─┐
- // ╠═╝╠╦╝║╣───╠═╝╠╦╝║ ║║ ║╣ ╚═╗╚═╗ ├┬┘├┤ │ │ │├┬┘ ││└─┐
- // ╩ ╩╚═╚═╝ ╩ ╩╚═╚═╝╚═╝╚═╝╚═╝╚═╝ ┴└─└─┘└─┘└─┘┴└──┴┘└─┘
- // Process each record to normalize output
- try {
- Helpers.query.preProcessRecord({
- records: [query.newRecord],
- identity: model.identity,
- orm: fauxOrm
- });
- } catch (e) {
- return exits.error(e);
- }
- // ╔═╗╔═╗╔╗╔╦ ╦╔═╗╦═╗╔╦╗ ┌┬┐┌─┐ ┌─┐┌┬┐┌─┐┌┬┐┌─┐┌┬┐┌─┐┌┐┌┌┬┐
- // ║ ║ ║║║║╚╗╔╝║╣ ╠╦╝ ║ │ │ │ └─┐ │ ├─┤ │ ├┤ │││├┤ │││ │
- // ╚═╝╚═╝╝╚╝ ╚╝ ╚═╝╩╚═ ╩ ┴ └─┘ └─┘ ┴ ┴ ┴ ┴ └─┘┴ ┴└─┘┘└┘ ┴
- // Convert the Waterline criteria into a Waterline Query Statement. This
- // turns it into something that is declarative and can be easily used to
- // build a SQL query.
- // See: https://github.com/treelinehq/waterline-query-docs for more info
- // on Waterline Query Statements.
- var statement;
- try {
- statement = utils.query.converter({
- model: query.using,
- method: 'create',
- values: query.newRecord
- });
- } catch (e) {
- return exits.error(e);
- }
- // ╔╦╗╔═╗╔╦╗╔═╗╦═╗╔╦╗╦╔╗╔╔═╗ ┬ ┬┬ ┬┬┌─┐┬ ┬ ┬ ┬┌─┐┬ ┬ ┬┌─┐┌─┐
- // ║║║╣ ║ ║╣ ╠╦╝║║║║║║║║╣ │││├─┤││ ├─┤ └┐┌┘├─┤│ │ │├┤ └─┐
- // ═╩╝╚═╝ ╩ ╚═╝╩╚═╩ ╩╩╝╚╝╚═╝ └┴┘┴ ┴┴└─┘┴ ┴ └┘ ┴ ┴┴─┘└─┘└─┘└─┘
- // ┌┬┐┌─┐ ┬─┐┌─┐┌┬┐┬ ┬┬─┐┌┐┌
- // │ │ │ ├┬┘├┤ │ │ │├┬┘│││
- // ┴ └─┘ ┴└─└─┘ ┴ └─┘┴└─┘└┘
- if (_.has(query.meta, 'fetch') && query.meta.fetch) {
- fetchRecords = true;
- }
- // Find the Primary Key
- var primaryKeyField = model.primaryKey;
- var primaryKeyColumnName = model.definition[primaryKeyField].columnName;
- // Remove primary key if the value is NULL. This allows the auto-increment
- // to work properly if set.
- if (_.isNull(statement.insert[primaryKeyColumnName])) {
- delete statement.insert[primaryKeyColumnName];
- }
- // ╔═╗╔═╗╔═╗╦ ╦╔╗╔ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌
- // ╚═╗╠═╝╠═╣║║║║║║ │ │ │││││││├┤ │ │ ││ ││││
- // ╚═╝╩ ╩ ╩╚╩╝╝╚╝ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘
- // ┌─┐┬─┐ ┬ ┬┌─┐┌─┐ ┬ ┌─┐┌─┐┌─┐┌─┐┌┬┐ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌
- // │ │├┬┘ │ │└─┐├┤ │ ├┤ ├─┤└─┐├┤ ││ │ │ │││││││├┤ │ │ ││ ││││
- // └─┘┴└─ └─┘└─┘└─┘ ┴─┘└─┘┴ ┴└─┘└─┘─┴┘ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘
- // Spawn a new connection for running queries on.
- Helpers.connection.spawnOrLeaseConnection(inputs.datastore, query.meta, function spawnOrLeaseConnectionCb(err, connection) {
- if (err) {
- return exits.badConnection(err);
- }
- // ╦╔╗╔╔═╗╔═╗╦═╗╔╦╗ ┬─┐┌─┐┌─┐┌─┐┬─┐┌┬┐
- // ║║║║╚═╗║╣ ╠╦╝ ║ ├┬┘├┤ │ │ │├┬┘ ││
- // ╩╝╚╝╚═╝╚═╝╩╚═ ╩ ┴└─└─┘└─┘└─┘┴└──┴┘
- // Insert the record and return the new values
- Helpers.query.create({
- connection: connection,
- statement: statement,
- fetch: fetchRecords,
- primaryKey: primaryKeyColumnName
- },
- function createRecordCb(err, insertedRecords) {
- // Release the connection if needed.
- Helpers.connection.releaseConnection(connection, leased, function releaseCb() {
- // If there was an error return it.
- if (err) {
- if (err.footprint && err.footprint.identity === 'notUnique') {
- return exits.notUnique(err);
- }
- return exits.error(err);
- }
- if (fetchRecords) {
- // Process each record to normalize output
- try {
- Helpers.query.processEachRecord({
- records: insertedRecords,
- identity: model.identity,
- orm: fauxOrm
- });
- } catch (e) {
- return exits.error(e);
- }
- // Only return the first record (there should only ever be one)
- var insertedRecord = _.first(insertedRecords);
- return exits.success({ record: insertedRecord });
- }
- return exits.success();
- }); // </ .releaseConnection(); >
- }); // </ .insertRecord(); >
- }); // </ .spawnOrLeaseConnection(); >
- }
- });
|