// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.dq.analysis; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.emf.common.util.EList; import org.talend.cwm.exception.AnalysisExecutionException; import org.talend.cwm.helper.ColumnHelper; import org.talend.cwm.helper.ColumnSetHelper; import org.talend.cwm.helper.SwitchHelpers; import org.talend.cwm.management.i18n.Messages; import org.talend.cwm.relational.TdColumn; import org.talend.dataquality.PluginConstant; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.indicators.Indicator; import org.talend.dataquality.indicators.columnset.ColumnDependencyIndicator; import org.talend.dataquality.indicators.columnset.ColumnsetPackage; import org.talend.dataquality.indicators.definition.IndicatorDefinition; import org.talend.dq.dbms.DbmsLanguage; import org.talend.dq.dbms.DbmsLanguageFactory; import org.talend.dq.helper.AnalysisExecutorHelper; import org.talend.dq.helper.ContextHelper; import org.talend.dq.indicators.definitions.DefinitionHandler; import org.talend.utils.sugars.ReturnCode; import org.talend.utils.sugars.TypedReturnCode; import orgomg.cwm.objectmodel.core.CoreFactory; import orgomg.cwm.objectmodel.core.Expression; import orgomg.cwm.objectmodel.core.Package; import orgomg.cwm.resource.relational.ColumnSet; /** * DOC jet class global comment. Detailled comment */ public class FunctionalDependencyExecutor extends ColumnAnalysisSqlExecutor { private static Logger log = Logger.getLogger(FunctionalDependencyExecutor.class); private String catalogName = null; private String schemaName = null; @Override protected boolean check(Analysis analysis) { return true; } @Override protected boolean runAnalysis(Analysis analysis, String sqlStatement) { Boolean runStatus = Boolean.TRUE; TypedReturnCode<java.sql.Connection> trc = this.getConnectionBeforeRun(analysis); if (!trc.isOk()) { log.error(trc.getMessage()); setError(trc.getMessage()); traceError(Messages.getString( "FunctionalDependencyExecutor.CANNOTEXECUTEANALYSIS", analysis.getName(), trc.getMessage()));//$NON-NLS-1$ return Boolean.FALSE; } Connection connection = trc.getObject(); try { // execute the sql statement for each indicator EList<Indicator> indicators = analysis.getResults().getIndicators(); EList<Indicator> deactivatedIndicators = analysis.getParameters().getDeactivatedIndicators(); for (Indicator indicator : indicators) { if (deactivatedIndicators.contains(indicator)) { continue; // do not evaluate this indicator } Expression query = dbms().getInstantiatedExpression(indicator); if (query == null) { // TODO internationalize the string. traceError("Query not executed for indicator: \"" + AnalysisExecutorHelper.getIndicatorName(indicator) + "\" "//$NON-NLS-1$//$NON-NLS-2$ + "query is null");//$NON-NLS-1$ runStatus = Boolean.FALSE; continue; } try { boolean exeStatus = executeQuery(indicator, connection, query); if (!exeStatus) { // TODO internationalize the string. traceError("Query not executed for indicator: \"" + AnalysisExecutorHelper.getIndicatorName(indicator) + "\" "//$NON-NLS-1$//$NON-NLS-2$ + "SQL query: " + query.getBody());//$NON-NLS-1$ runStatus = Boolean.FALSE; continue; } } catch (AnalysisExecutionException e) { traceError(e.getMessage()); runStatus = Boolean.FALSE; continue; } indicator.setComputed(true); } } finally { ReturnCode rc = closeConnection(analysis, connection); if (!rc.isOk()) { runStatus = Boolean.FALSE; } } return runStatus; } private boolean executeQuery(Indicator indicator, Connection connection, Expression query) throws AnalysisExecutionException { try { List<Object[]> myResultSet = executeQuery(catalogName, connection, query.getBody()); indicator.storeSqlResults(myResultSet); } catch (SQLException e) { log.error(e, e); // MOD TDQ-8388 return the exact error message throw new AnalysisExecutionException(e.getMessage()); } return true; } @Override public String createSqlStatement(Analysis analysis) { this.cachedAnalysis = analysis; DbmsLanguage dbmsLanguage = DbmsLanguageFactory.createDbmsLanguage(analysis); EList<Indicator> indicators = analysis.getResults().getIndicators(); for (Indicator indicator : indicators) { instantiateQuery(indicator, dbmsLanguage); } // no query to return, here we only instantiate several SQL queries return PluginConstant.EMPTY_STRING; } private boolean instantiateQuery(Indicator indicator, DbmsLanguage dbmsLanguage) { // (but is not need, hence we keep it commented) if (ColumnsetPackage.eINSTANCE.getColumnDependencyIndicator().equals(indicator.eClass())) { ColumnDependencyIndicator rowMatchingIndicator = (ColumnDependencyIndicator) indicator; TdColumn columnA = rowMatchingIndicator.getColumnA(); TdColumn columnB = rowMatchingIndicator.getColumnB(); IndicatorDefinition indicatorDefinition = indicator.getIndicatorDefinition(); // MOD qiongli 2012-3-14 TDQ-4433 in this case(import by "button" from low veresion and no import // SystemIndicator),the IndicatorDefinition maybe a proxy,should reset it. if (indicatorDefinition == null || indicatorDefinition.eIsProxy()) { indicatorDefinition = DefinitionHandler.getInstance().getIndicatorDefinition("Functional Dependency"); //$NON-NLS-1$ indicator.setIndicatorDefinition(indicatorDefinition); } Expression sqlGenericExpression = dbms().getSqlExpression(indicatorDefinition); Expression instantiatedSqlExpression = createInstantiatedSqlExpression(sqlGenericExpression, columnA, columnB, dbmsLanguage); indicator.setInstantiatedExpression(instantiatedSqlExpression); return true; } traceError(Messages.getString( "FunctionalDependencyExecutor.UNHANDLEDGIVENINDICATOR", AnalysisExecutorHelper.getIndicatorName(indicator)));//$NON-NLS-1$ return Boolean.FALSE; } /** * DOC jet Comment method "createInstantiatedSqlExpression". * * @param sqlGenericExpression * @param columnA * @param columnB * @param dbmsLanguage * @param useNulls * @return */ private Expression createInstantiatedSqlExpression(Expression sqlGenericExpression, TdColumn columnA, TdColumn columnB, DbmsLanguage dbmsLanguage) { assert columnA != null; assert columnB != null; String genericSQL = sqlGenericExpression.getBody(); // MOD zshen 11005: SQL syntax error for all analysis on Informix databases in Talend Open Profiler String table = getTableNameFromColumn(columnA); String instantiatedSQL = dbms().fillGenericQueryWithColumnsABAndTable(genericSQL, dbmsLanguage.quote(columnA.getName()), dbmsLanguage.quote(columnB.getName()), table); // ~11005 List<String> whereClauses = new ArrayList<String>(); String dataFilter = ContextHelper.getDataFilterWithoutContext(cachedAnalysis); if (!StringUtils.isEmpty(dataFilter)) { whereClauses.add(dataFilter); } instantiatedSQL = dbms().addWhereToSqlStringStatement(instantiatedSQL, whereClauses); Expression instantiatedExpression = CoreFactory.eINSTANCE.createExpression(); instantiatedExpression.setLanguage(sqlGenericExpression.getLanguage()); instantiatedExpression.setBody(instantiatedSQL); return instantiatedExpression; } private String getTableNameFromColumn(TdColumn column) { ColumnSet columnSetOwner = ColumnHelper.getColumnOwnerAsColumnSet(column); if (columnSetOwner == null) { log.error(Messages.getString("FunctionalDependencyExecutor.COLUMNSETOWNERISNULL", column.getName()));//$NON-NLS-1$ } else { // this is so bad code Package pack = ColumnSetHelper.getParentCatalogOrSchema(columnSetOwner); if (SwitchHelpers.SCHEMA_SWITCH.doSwitch(pack) != null) { schemaName = pack.getName(); Package catalog = ColumnSetHelper.getParentCatalogOrSchema(pack); // MOD mzhao 2010-02-10 Fix a NEP. if (catalog != null && SwitchHelpers.CATALOG_SWITCH.doSwitch(catalog) != null) { catalogName = catalog.getName(); } } if (SwitchHelpers.CATALOG_SWITCH.doSwitch(pack) != null) { catalogName = pack.getName(); } return dbms().toQualifiedName(catalogName, schemaName, columnSetOwner.getName()); } return null; } }