'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* * +------------------------------------------------------------------------+ * | Licensed Materials - Property of IBM * | IBM Cognos Products: Dashboard * | (C) Copyright IBM Corp. 2018, 2020 * | * | US Government Users Restricted Rights - Use, duplication or disclosure * | restricted by GSA ADP Schedule Contract with IBM Corp. * +------------------------------------------------------------------------+ */ define(['underscore', 'bi/moser/moser.min', '../../apiHelpers/SlotAPIHelper'], function (_, MoserJS, SlotAPIHelper) { var _class, _temp; var SOURCE_TYPES_TO_VERIFY_JOIN = [MoserJS.default.UseSpecType.FILE.value(), MoserJS.default.UseSpecType.DATASET.value()]; var DatasourceUtil = (_temp = _class = function () { function DatasourceUtil() { _classCallCheck(this, DatasourceUtil); } /** * We agreed only do client level join for uploaded files and data sets (dataset2), * or a module created from uploaded files or data sets (dataset2). * @returns true if items are from source types in SOURCE_TYPES_TO_VERIFY_JOIN */ DatasourceUtil._shouldVerifyJoin = function _shouldVerifyJoin(module) { var items = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var moserDataSources = arguments[2]; var newAPI = !!(module.getInterfaceType && module.getImplType); if (newAPI) { var dataSourceId = module.getId(); var verifyJoin = true; for (var i = 0; i < items.length && verifyJoin; i++) { var columnId = items[i]; var metadataColumn = module.getMetadataColumn(columnId); var table = metadataColumn ? metadataColumn.getTableName() : null; if (!metadataColumn || !table) { // Skip if not a metadata column or metadata column is not from a table, e.g. stand alone model calculations. verifyJoin = false; break; } var originalType = moserDataSources.getOriginalSourceType(dataSourceId, columnId); if (originalType && SOURCE_TYPES_TO_VERIFY_JOIN.indexOf(originalType) === -1) { verifyJoin = false; break; } } return verifyJoin; } else { var theMoserJS = DatasourceUtil.MoserJS_Inst || MoserJS; var tables = []; return _.find(items, function (columnId) { if (!DatasourceUtil.isMultiMeasuresSeriesOrValue(columnId)) { var _metadataColumn = module.getMetadataColumn(columnId); var _table = _metadataColumn ? _metadataColumn.getTable() : null; if (!_metadataColumn || !_table) { return true; } // Do not check again if already checked if (tables.indexOf(_table.idForExpression) === -1) { tables.push(_table.idForExpression); var useSpec = theMoserJS.default.ModuleUtils.getObjectUseSpec(_table); if (useSpec) { // Return if there is a source type not belongs to the local join return SOURCE_TYPES_TO_VERIFY_JOIN.indexOf(useSpec.getType().value()) === -1; } } } }) === undefined; } }; DatasourceUtil.isMultiMeasuresSeriesOrValue = function isMultiMeasuresSeriesOrValue(itemId) { return itemId.indexOf(SlotAPIHelper.MULTI_MEASURES_SERIES) === 0 || itemId.indexOf(SlotAPIHelper.MULTI_MEASURES_VALUE) === 0; }; DatasourceUtil.getTableRef = function getTableRef(dataSource, itemIds) { var names = []; if (dataSource) { itemIds.forEach(function (item) { var metadataColumn = dataSource.getMetadataColumn(item); var tableName = metadataColumn && metadataColumn.getTableName(); if (tableName && names.indexOf(tableName) === -1) { names.push(tableName); } }); } return names; }; /** * * @param {object} module - the data source module, either an uploaded file, a dataset, a package, a module, or a model built from an uploaded file, a dataset, a package, or a module * @param {object[]} projectedItems - An array of projected items ids * @param return true if metadata columns referenced by pageContextItemSpec and dataSlots are from: * 1) uploaded files * 2) data sets * 3) the combination of 1) and 2). */ DatasourceUtil.isSupportedNonJoinTableDatascourceType = function isSupportedNonJoinTableDatascourceType(module) { var itemIds = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; if (!module || module.getSourceType() === 'package' || itemIds.length === 0) { return false; } return DatasourceUtil._shouldVerifyJoin(module, itemIds); }; /** * A dashboard works against one MUI module created on the fly each time a dashboard is created. * A package is a metadata model that have not the necessary table joins applied at the database level. * Therefore dashboards need not worry about these joins. * A dashboard only handle join relationships at the data module level. * MUI creates a module which can be one of: * 1) contain one single package, this is the simplest case * 2) uploaded file containing more than one table where there are no joins between tables. In Endor, all tables within an uploaded xlsx are not joined * 3) a data module containing any combination of packgages, other modules, uploaded files and data sets. This is the complex case. * * For Endor release, decision is made to only verify table joins for uploaded files and data sets since currently there is no API to get accurate * join relationships for case3). * * @param return true if metadata columns referenced by pageContextItemSpec and dataSlots are from: * 1) uploaded files * 2) data sets * 3) the combination of 1) and 2). */ DatasourceUtil.mustVerifyJoinTablesInSameDataSource = function mustVerifyJoinTablesInSameDataSource(dataSource, pageContextItemSpec) { var itemIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var moserDataSources = arguments[3]; //A module can be a package in which case return false (this is the simples case) OR when pageContextItem has no hierarchy context to work on var dataSourceType = dataSource.getType && dataSource.getType() || dataSource.getSourceType && dataSource.getSourceType(); if (dataSourceType === 'package') { return false; } var pageContextColumnIds = pageContextItemSpec && pageContextItemSpec.hierarchies && pageContextItemSpec.hierarchies.map(function (h) { return h.hierarchyUniqueName; }) || pageContextItemSpec && pageContextItemSpec.getItemIds && pageContextItemSpec.getItemIds(); if (!_.isArray(pageContextColumnIds) || !pageContextColumnIds.length) { return false; } itemIds.push.apply(itemIds, pageContextColumnIds); return DatasourceUtil._shouldVerifyJoin(dataSource, itemIds, moserDataSources); }; DatasourceUtil.haveTableJoinsInSameDataSource = function haveTableJoinsInSameDataSource(module, tableNames, otherTableNames) { // TODO Clean internal function names in other classes. var tablesHaveJoinRelationship = module.hasJoinedTables ? module.hasJoinedTables.bind(module) : module.tablesHaveJointRelationship.bind(module); var result = _.find(otherTableNames, function (otherTableName) { return _.find(tableNames, function (tableName) { return tablesHaveJoinRelationship(tableName, otherTableName); }); }); return result ? true : false; }; /** * Returns a boolean indicating whether there is a least the same table referenced in both tables * * @param {array} tableRef1 - table 1 to check * @param {array} tableRef2 - the table to check against tableRef1 * * @return {boolean} return true if there is at least one table name matched in both tables, else return false */ DatasourceUtil.haveATableReference = function haveATableReference() { var tableRef1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var tableRef2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var exactMatch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (exactMatch && tableRef1.length !== tableRef2.length || tableRef1.length === 0 && tableRef2.length === 0) { return false; } return _.find(tableRef1, function (ref1) { return tableRef2.indexOf(ref1) !== -1; }) ? true : false; }; /** * Dynamically calculates and returns the list of table references for the specified page context entry * * @param {object} module - the module to retrieve the table names * @param {object} pageContextEntry - the page context entry * * @return {array} List of retrieved table names */ /** * Determine whether the slot and dataItem are ordinal and attribute * * @param {object} slot - The slot item that the function will compare * @param {object} dataItem - The dataItem that the function will compare to the slot * * @return {boolean} A boolean to represent whether or not it is Ordinal vs. Attribute **/ /** * Process and return a merged filter page context * * @param {array} netFilterPageContext - array filter net page context * @param {array} synchronizedFilters - array of synchronized filters * * @return {array} merged synchronized and filter net page context array */ DatasourceUtil.mergeSynchronizePageContextFilter = function mergeSynchronizePageContextFilter(netFilterPageContext, synchronizedFilters) { if (!synchronizedFilters || synchronizedFilters.length === 0) { return netFilterPageContext; } var hasFilterByName = function hasFilterByName(filtersToCheck, filterName) { var exist = _.find(filtersToCheck, function (filter) { return filter.getItemName().toLowerCase() === filterName; }); return exist ? true : false; }; //Populate this vis Filters var thisVisFilters = {}; var getFiltersByScope = function getFiltersByScope(scope) { var array = thisVisFilters[scope] = thisVisFilters[scope] || []; return array; }; netFilterPageContext.forEach(function (entry) { var filters = getFiltersByScope(entry.getScope()); filters.push(entry); }); //Process synch local filters first because they have precedence over global filters var localSynchFilters = synchronizedFilters.filter(function (entry) { return entry.scope !== 'global'; }); localSynchFilters.forEach(function (entry) { var nameToCheck = entry.filterName.toLowerCase(); var thisTableFilters = getFiltersByScope(entry.scope); if (!hasFilterByName(thisTableFilters, nameToCheck)) { thisTableFilters.push(entry.getAPI()); } //Remove the same one in the global if it exists since the thisTab one takes precedence since these ones may have been already defined in this vis so remove them thisVisFilters.global = _.filter(thisVisFilters.global, function (filter) { return filter.getItemName().toLowerCase() !== nameToCheck; }); }); //Now process synch global filters var globalSynchFilters = synchronizedFilters.filter(function (entry) { return entry.scope === 'global'; }); globalSynchFilters.forEach(function (entry) { var nameToCheck = entry.filterName.toLowerCase(); var toAdd = true; //Loop through set of thisTab filters and only add the global filter if it is not defined in the thisTab scope for (var property in thisVisFilters) { if (property !== 'global' && hasFilterByName(thisVisFilters[property], nameToCheck)) { toAdd = false; break; } } if (toAdd) { var globalFilters = getFiltersByScope('global'); globalFilters.push(entry.getAPI()); } }); //Now concat all results and return as a single array var result = void 0; for (var prop in thisVisFilters) { if (thisVisFilters[prop] && thisVisFilters[prop].length > 0) { if (!result) { result = thisVisFilters[prop]; } else { result = result.concat(thisVisFilters[prop]); } } } return result || []; }; DatasourceUtil.metadataColumnSupportsFiltering = function metadataColumnSupportsFiltering(column) { if (!column) { return false; } // getAggregateMode is from the old object MetadaColumn // getAggregationMode is the new API function // the column passed in can be either the old MetadaColumn or the new API Column var getAggregationMode = (column.getAggregateMode || column.getAggregationMode).bind(column); return !(column.getType() === 'fact' && (getAggregationMode() === 'static' || column.getDefaultAggregation() === 'calculated')); }; return DatasourceUtil; }(), _class.getPageContextItemTableRef = function (dataSource, pageContextEntry) { var tableRef = []; var itemIds = pageContextEntry.getItemIds ? pageContextEntry.getItemIds() : _.pluck(pageContextEntry.hierarchies, 'hierarchyUniqueName'); itemIds.forEach(function (itemId) { var column = dataSource.getMetadataColumn(itemId); if (column) { var name = column.getTableName(); if (tableRef.indexOf(name) === -1) { tableRef.push(name); } } }); return tableRef; }, _class.isOrdinalAttribute = function (slot, dataItem) { var slotType = slot.getDefinition().getType(); var dataType = dataItem.getMetadataColumn().getType(); return slotType === 'ordinal' && dataType === 'attribute'; }, _temp); return DatasourceUtil; }); //# sourceMappingURL=DatasourceUtil.js.map