12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // ██████╗ ███████╗████████╗███████╗ ██████╗████████╗ ██████╗██╗ ██╗██╗██╗ ██████╗ ██████╗ ███████╗███╗ ██╗
- // ██╔══██╗██╔════╝╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝ ██╔════╝██║ ██║██║██║ ██╔══██╗██╔══██╗██╔════╝████╗ ██║
- // ██║ ██║█████╗ ██║ █████╗ ██║ ██║ ██║ ███████║██║██║ ██║ ██║██████╔╝█████╗ ██╔██╗ ██║
- // ██║ ██║██╔══╝ ██║ ██╔══╝ ██║ ██║ ██║ ██╔══██║██║██║ ██║ ██║██╔══██╗██╔══╝ ██║╚██╗██║
- // ██████╔╝███████╗ ██║ ███████╗╚██████╗ ██║ ╚██████╗██║ ██║██║███████╗██████╔╝██║ ██║███████╗██║ ╚████║
- // ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝
- //
- // ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗
- // ██╔══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗██╔════╝
- // ██████╔╝█████╗ ██║ ██║ ██║██████╔╝██║ ██║███████╗
- // ██╔══██╗██╔══╝ ██║ ██║ ██║██╔══██╗██║ ██║╚════██║
- // ██║ ██║███████╗╚██████╗╚██████╔╝██║ ██║██████╔╝███████║
- // ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝
- //
- // Given a set of records from a join query, pull out any children records that
- // have been added. These are found by checking the namespace used in the SELECT
- // statement. For children they are selected using an alias similar to:
- //
- // SELECT childTable.childColumn as childTable__childColumn
- //
- // This prevents collisions between column names on the parent and child record.
- // It also allows the children to easily be grabbed from the flat record and
- // nested. This functions takes a result set from a query that looks like the one
- // above and pulls out the children.
- //
- var util = require('util');
- var _ = require('@sailshq/lodash');
- module.exports = function detectChildrenRecords(primaryKeyAttr, records) {
- // Hold children records from all the records
- var children = {};
- // Go through each record and pull out any children.
- _.each(records, function searchForChildren(record) {
- // Build a local cache to use for the children of this record
- var cache = {};
- // Find the Primary Key of the record
- var recordPk = record[primaryKeyAttr];
- if (!recordPk) {
- throw new Error('Could not find a primary key for a record. Perhaps it wasn\'t selected in the query. The primary key was set to: ' + primaryKeyAttr + ' and the record returned was: ' + util.inspect(record, false, null));
- }
- // Process each key in the record and build up a child record that can
- // then be nested into the parent.
- _.forIn(record, function checkForChildren(val, key) {
- // Check if the key can be split this on the special alias identifier '__' (two underscores).
- var split = key.split('__');
- if (split.length < 2) {
- return;
- }
- var alias = _.first(split);
- var attribute = _.last(split);
- // Make sure the local cache knows about this child (i.e. the populated alias name - pets).
- if (!_.has(cache, alias)) {
- cache[alias] = {};
- }
- // Add the child value to the cache
- cache[alias][attribute] = val;
- // Remove the child attribute from the parent
- delete record[key];
- });
- // Combine the local cache into the children cache which holds values
- // for all the records.
- _.each(cache, function cacheChild(val, key) {
- if (!_.has(children, key)) {
- children[key] = [];
- }
- // Store the local cache on the top level cache
- children[key] = children[key].concat(cache[key]);
- });
- });
- return {
- parents: _.uniq(records, primaryKeyAttr),
- children: children
- };
- };
|