123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // ███████╗███████╗██╗ ███████╗ ██████╗████████╗ █████╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗
- // ██╔════╝██╔════╝██║ ██╔════╝██╔════╝╚══██╔══╝ ██╔══██╗██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║
- // ███████╗█████╗ ██║ █████╗ ██║ ██║ ███████║██║ ██║ ██║██║ ██║██╔██╗ ██║
- // ╚════██║██╔══╝ ██║ ██╔══╝ ██║ ██║ ██╔══██║██║ ██║ ██║██║ ██║██║╚██╗██║
- // ███████║███████╗███████╗███████╗╚██████╗ ██║ ██║ ██║╚██████╗ ██║ ██║╚██████╔╝██║ ╚████║
- // ╚══════╝╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
- //
- module.exports = require('machine').build({
- friendlyName: 'Select',
- description: 'Find record(s) 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 results of the select query.',
- outputVariableName: 'records',
- 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.'
- }
- },
- fn: function select(inputs, exits) {
- // Dependencies
- var _ = require('@sailshq/lodash');
- var WLUtils = require('waterline-utils');
- var Converter = WLUtils.query.converter;
- 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');
- // ╔═╗╔═╗╔╗╔╦ ╦╔═╗╦═╗╔╦╗ ┌┬┐┌─┐ ┌─┐┌┬┐┌─┐┌┬┐┌─┐┌┬┐┌─┐┌┐┌┌┬┐
- // ║ ║ ║║║║╚╗╔╝║╣ ╠╦╝ ║ │ │ │ └─┐ │ ├─┤ │ ├┤ │││├┤ │││ │
- // ╚═╝╚═╝╝╚╝ ╚╝ ╚═╝╩╚═ ╩ ┴ └─┘ └─┘ ┴ ┴ ┴ ┴ └─┘┴ ┴└─┘┘└┘ ┴
- // 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 = Converter({
- model: query.using,
- method: 'find',
- criteria: query.criteria
- });
- } catch (e) {
- return exits.error(e);
- }
- // Compile the original Waterline Query
- var compiledQuery;
- try {
- compiledQuery = Helpers.query.compileStatement(statement);
- } catch (e) {
- return exits.error(e);
- }
- // ╔═╗╔═╗╔═╗╦ ╦╔╗╔ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌
- // ╚═╗╠═╝╠═╣║║║║║║ │ │ │││││││├┤ │ │ ││ ││││
- // ╚═╝╩ ╩ ╩╚╩╝╝╚╝ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘
- // ┌─┐┬─┐ ┬ ┬┌─┐┌─┐ ┬ ┌─┐┌─┐┌─┐┌─┐┌┬┐ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌
- // │ │├┬┘ │ │└─┐├┤ │ ├┤ ├─┤└─┐├┤ ││ │ │ │││││││├┤ │ │ ││ ││││
- // └─┘┴└─ └─┘└─┘└─┘ ┴─┘└─┘┴ ┴└─┘└─┘─┴┘ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘
- // Spawn a new connection for running queries on.
- Helpers.connection.spawnOrLeaseConnection(inputs.datastore, query.meta, function spawnConnectionCb(err, connection) {
- if (err) {
- return exits.badConnection(err);
- }
- // ╦═╗╦ ╦╔╗╔ ┌─┐┌─┐┬ ┌─┐┌─┐┌┬┐ ┌─┐ ┬ ┬┌─┐┬─┐┬ ┬
- // ╠╦╝║ ║║║║ └─┐├┤ │ ├┤ │ │ │─┼┐│ │├┤ ├┬┘└┬┘
- // ╩╚═╚═╝╝╚╝ └─┘└─┘┴─┘└─┘└─┘ ┴ └─┘└└─┘└─┘┴└─ ┴
- var queryType = 'select';
- Helpers.query.runQuery({
- connection: connection,
- nativeQuery: compiledQuery.nativeQuery,
- valuesToEscape: compiledQuery.valuesToEscape,
- meta: compiledQuery.meta,
- queryType: queryType,
- disconnectOnError: leased ? false : true
- },
- function runQueryCb(err, report) {
- // The runQuery helper will automatically release the connection on error
- // if needed.
- if (err) {
- return exits.error(err);
- }
- // Always release the connection unless a leased connection from outside
- // the adapter was used.
- Helpers.connection.releaseConnection(connection, leased, function releaseConnectionCb() {
- var selectRecords = report.result;
- var orm = {
- collections: inputs.models
- };
- // Process each record to normalize output
- try {
- Helpers.query.processEachRecord({
- records: selectRecords,
- identity: model.identity,
- orm: orm
- });
- } catch (e) {
- return exits.error(e);
- }
- return exits.success({ records: selectRecords });
- }); // </ releaseConnection >
- }); // </ runQuery >
- }); // </ spawnConnection >
- }
- });
|