123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- // ██████╗ ██████╗ ██╗ ██╗███╗ ██╗████████╗ █████╗ ██████╗████████╗██╗ ██████╗ ███╗ ██╗
- // ██╔════╝██╔═══██╗██║ ██║████╗ ██║╚══██╔══╝ ██╔══██╗██╔════╝╚══██╔══╝██║██╔═══██╗████╗ ██║
- // ██║ ██║ ██║██║ ██║██╔██╗ ██║ ██║ ███████║██║ ██║ ██║██║ ██║██╔██╗ ██║
- // ██║ ██║ ██║██║ ██║██║╚██╗██║ ██║ ██╔══██║██║ ██║ ██║██║ ██║██║╚██╗██║
- // ╚██████╗╚██████╔╝╚██████╔╝██║ ╚████║ ██║ ██║ ██║╚██████╗ ██║ ██║╚██████╔╝██║ ╚████║
- // ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
- //
- module.exports = require('machine').build({
- friendlyName: 'Count',
- description: 'Return the count of the records matched by the query.',
- 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 count query.',
- outputExample: '==='
- },
- 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 count(inputs, exits) {
- // Dependencies
- var _ = require('@sailshq/lodash');
- var Converter = require('waterline-utils').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: 'count',
- 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 = 'count';
- 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() {
- return exits.success(report.result);
- }); // </ releaseConnection >
- }); // </ runQuery >
- }); // </ spawnConnection >
- }
- });
|