public IPentahoResultSet getResultSet(final ReportSpec reportSpec) throws Exception { String jndiName = reportSpec.getReportSpecChoice().getJndiSource(); IPentahoConnection connection = null; if (reportSpec.getIsMDX()) { // did this ever work?? String connectStr = ""; // $NON-NLS-1$ IDBDatasourceService datasourceService = PentahoSystem.getObjectFactory().get(IDBDatasourceService.class, null); String dsName = datasourceService.getDSBoundName(jndiName); if (dsName != null) { connectStr = "dataSource=" + dsName + "; Catalog=mondrian"; // $NON-NLS-1$ //$NON-NLS-2$ } else { error( Messages.getInstance() .getErrorString("MDXBaseComponent.ERROR_0005_INVALID_CONNECTION")); // $NON-NLS-1$ return null; } Properties props = new Properties(); props.setProperty(IPentahoConnection.CONNECTION, connectStr); props.setProperty(IPentahoConnection.PROVIDER, reportSpec.getMondrianCubeDefinitionPath()); connection = PentahoConnectionFactory.getConnection( IPentahoConnection.MDX_DATASOURCE, props, getSession(), this); } else { connection = PentahoConnectionFactory.getConnection( IPentahoConnection.SQL_DATASOURCE, jndiName, getSession(), this); } String query = ReportParameterUtility.setupParametersForActionSequence(reportSpec.getQuery()); query = setupQueryParameters(query); IPentahoResultSet res = connection.executeQuery(query); return res; }
/** * attempt to aquire a connection. if connection isn't available, wait a certain period of time * before trying again. * * @return connection */ public IPentahoConnection getDatasourceConnection() { IPentahoConnection con; int[] timeouts = {200, 500, 2000}; for (int element : timeouts) { try { con = getConnection(); try { con.clearWarnings(); } catch (Exception ex) { // ignore } return con; } catch (Exception ex) { // ignore } waitFor(element); } con = getConnection(); try { con.clearWarnings(); } catch (Exception ex) { // ignore } return con; }
public IPentahoResultSet doQuery( final SQLConnection sqlConnection, final String query, boolean forwardOnlyResultset) throws Exception { // // At this point, 'connection' and 'sqlConnection' should be pointers to // the same object iff the 'connection' is a subclass of pentaho's SQLConnection. // It is possible that the sqlConnection will be null, but the connection // won't be if someone is using their own implementation of the SQLConnection from // the factory. // IPentahoResultSet resultSet = null; if (ComponentBase.debug) { dumpQuery(query); } if (preparedParameters.size() > 0) { if (!forwardOnlyResultset) { resultSet = connection.prepareAndExecuteQuery(query, preparedParameters); } else { if (sqlConnection != null) { resultSet = sqlConnection.prepareAndExecuteQuery( query, preparedParameters, SQLConnection.RESULTSET_FORWARDONLY, SQLConnection.CONCUR_READONLY); } else { throw new IllegalStateException( Messages.getInstance() .getErrorString( "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$ } } } else { if (!forwardOnlyResultset) { resultSet = connection.executeQuery(query); } else { if (sqlConnection != null) { resultSet = sqlConnection.executeQuery( query, SQLConnection.RESULTSET_FORWARDONLY, SQLConnection.CONCUR_READONLY); } else { throw new IllegalStateException( Messages.getInstance() .getErrorString( "SQLBaseComponent.ERROR_0008_UNSUPPORTED_CURSOR_TYPE")); //$NON-NLS-1$ } } } return resultSet; }
/** * called when in prepared-component mode, this method populates the preparedQuery string and * preparedParameters object. * * @param rawQuery * @return */ protected boolean prepareQuery(final String rawQuery) { try { if (connection == null) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$ return false; } if (!connection.initialized()) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$ return false; } preparedQuery = rawQuery; return true; } catch (Exception e) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()), e); //$NON-NLS-1$ } return false; }
/** dispose of the resultset, and if the owner, dispose of the connection. */ public void dispose() { rSet = null; // close connection if owner if (connectionOwner) { if (connection != null) { connection.close(); } connection = null; } }
/** * executes the specified query template. The query template is first formatted and then executed. * If live, the original result set is made available as an output. If not live, the result set is * converted into memory and the connection and live result set are closed. * * @param rawQuery query template * @param live returns original result set if true, memory result set if false * @return true if successful */ protected boolean runQuery(final String rawQuery, boolean live) { try { if ((connection == null) || !connection.initialized()) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$ return false; } String query = applyInputsToFormat(rawQuery); SQLConnection sqlConnection = null; if ((connection instanceof SQLConnection)) { sqlConnection = (SQLConnection) connection; } // Some of the following Added by Arijit Chatterjee passing the timeout value to SQLConnection // class if (sqlConnection != null) { if (this.getQueryTimeout() >= 0) { sqlConnection.setQueryTimeout(this.getQueryTimeout()); } if (this.getMaxRows() >= 0) { sqlConnection.setMaxRows(this.getMaxRows()); } if (this.getReadOnly()) { sqlConnection.setReadOnly(true); } } AbstractRelationalDbAction relationalDbAction = (AbstractRelationalDbAction) getActionDefinition(); IPentahoResultSet resultSet = null; boolean isForwardOnly = relationalDbAction.getUseForwardOnlyResultSet().getBooleanValue(false); resultSet = doQuery(sqlConnection, query, isForwardOnly); if (sqlConnection.isForcedForwardOnly()) { isForwardOnly = true; live = false; warn( Messages.getInstance() .getString("SQLBaseComponent.WARN_FALL_BACK_TO_NONSCROLLABLE")); // $NON-NLS-1$ } if (live) { // set the result set as the output rSet = resultSet; // After preparation and execution, we need to clear out the // prepared parameters. preparedParameters.clear(); if (resultSet != null) { getMetadata(resultSet, true); IActionOutput actionOutput = relationalDbAction.getOutputResultSet(); if (actionOutput != null) { actionOutput.setValue(resultSet); } return true; } else { // close the connection if owner error( Messages.getInstance() .getErrorString( "SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName())); //$NON-NLS-1$ if (connectionOwner) { connection.close(); } return false; } } else { // execute the query, read the results and cache them try { // After preparation and execution, we need to clear out the // prepared parameters. preparedParameters.clear(); IPentahoResultSet cachedResultSet = resultSet.memoryCopy(); rSet = cachedResultSet; IActionOutput actionOutput = relationalDbAction.getOutputResultSet(); if (actionOutput != null) { actionOutput.setValue(cachedResultSet); } } finally { // close the connection if owner if (connectionOwner) { connection.close(); connection = null; } } } return true; } catch (Exception e) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()), e); //$NON-NLS-1$ } return false; }
/** * executes a prepared method that returns a result set executePrepared looks up any * "PREPARELATER" params in the preparedParams map. * * @param preparedParams a map of possible parameters. * @return result set */ public IPentahoResultSet executePrepared(final Map preparedParams) { try { if (connection == null) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$ return null; } if (!connection.initialized()) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0007_NO_CONNECTION")); // $NON-NLS-1$ return null; } if (preparedQuery == null) { error( Messages.getInstance() .getErrorString( "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED", getActionName())); //$NON-NLS-1$ return null; } // copy the preparedParams list, so it can be used multiple times. ArrayList copyOfPreparedParameters = new ArrayList(preparedParameters); // parse preparedQuery, replacing any {PREPARELATER:NAME} with appropriate values String query = TemplateUtil.applyTemplate( preparedQuery, getRuntimeContext(), new ParamResolver(copyOfPreparedParameters, preparedParams)); if (ComponentBase.debug) { dumpQuery(query); } // evaluate IPentahoResultSet resultSet = null; if (preparedParameters.size() > 0) { resultSet = connection.prepareAndExecuteQuery(query, copyOfPreparedParameters); } else { resultSet = connection.executeQuery(query); } if (connection instanceof SQLConnection) { if (((SQLConnection) connection).isForcedForwardOnly()) { warn( Messages.getInstance() .getString("SQLBaseComponent.WARN_FALL_BACK_TO_NONSCROLLABLE")); // $NON-NLS-1$ } } boolean live = true; IActionDefinition actionDefinition = getActionDefinition(); if (actionDefinition instanceof AbstractRelationalDbAction) { AbstractRelationalDbAction relationalDbAction = (AbstractRelationalDbAction) actionDefinition; live = relationalDbAction.getLive().getBooleanValue(false); } IPentahoResultSet rs = resultSet; // BISERVER-5915, BISERVER-5875 - if the live setting is false, return an in memory resultset. if (!live) { rs = resultSet.memoryCopy(); } rSet = rs; return rs; } catch (Exception e) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()), e); //$NON-NLS-1$ } return null; }
/** * determines state of component, and executes accordingly. * * <p>various inputs that impact the state include: * * <p>live - returns a live result set vs. an in memory copy transform - transform a result set * based on additional inputs prepared_component - if available, use existing connection from * prepared component max_rows - sets the number of rows that should be returned in result sets * * <p>The specified output also impacts the state of the execution. If prepared_component is * defined as an output, setup the query but delay execution. */ @Override protected boolean executeAction() { IActionDefinition actionDefinition = getActionDefinition(); try { if (actionDefinition instanceof AbstractRelationalDbAction) { AbstractRelationalDbAction relationalDbAction = (AbstractRelationalDbAction) actionDefinition; // Added by Arijit Chatterjee IActionInput queryTimeoutInput = relationalDbAction.getQueryTimeout(); IActionInput maxRowsInput = relationalDbAction.getMaxRows(); IActionInput readOnlyInput = relationalDbAction.getReadOnly(); String baseQuery = getQuery(); if (baseQuery == null) { error( Messages.getInstance() .getErrorString( "SQLBaseComponent.ERROR_0001_QUERY_NOT_SPECIFIED", actionDefinition.getDescription())); // $NON-NLS-1$ return false; } IPreparedComponent sharedConnection = (IPreparedComponent) relationalDbAction.getSharedConnection().getValue(); if (readOnlyInput != ActionInputConstant.NULL_INPUT) { this.setReadOnly(readOnlyInput.getBooleanValue()); } if (sharedConnection != null) { connectionOwner = false; IPentahoConnection conn = sharedConnection.shareConnection(); if (conn == null) { error( Messages.getInstance() .getErrorString( "IPreparedComponent.ERROR_0002_CONNECTION_NOT_AVAILABLE", getActionName())); //$NON-NLS-1$ return false; } else if (conn.getDatasourceType() == IPentahoConnection.SQL_DATASOURCE) { connection = conn; } else { error( Messages.getInstance() .getErrorString( "IPreparedComponent.ERROR_0001_INVALID_CONNECTION_TYPE", getActionName())); //$NON-NLS-1$ return false; } } else { dispose(); connection = getDatasourceConnection(); } if (connection == null) { return false; } // Check if this is a prepared query that will be executed later. If so cache the // query and set this component as the output. This query will be run later from a // subreport. if (relationalDbAction.getOutputPreparedStatement() != null) { prepareQuery(baseQuery); IActionOutput actionOutput = relationalDbAction.getOutputPreparedStatement(); if (actionOutput != null) { actionOutput.setValue(this); } return true; } // TODO not sure if this should be allowed without connection ownership? // int maxRows = relationalDbAction.getMaxRows().getIntValue(-1); if (maxRowsInput != ActionInputConstant.NULL_INPUT) { this.setMaxRows(maxRowsInput.getIntValue()); } // Added by Arijit Chatterjee.Sets the value of timeout. Default is -1, if parameter not // found. if (queryTimeoutInput != ActionInputConstant.NULL_INPUT) { this.setQueryTimeout(queryTimeoutInput.getIntValue()); } if (relationalDbAction.getPerformTransform().getBooleanValue(false)) { runQuery(baseQuery, false); // The side effect of // transform rSet here rSet = PentahoDataTransmuter.crossTab( rSet, relationalDbAction.getTransformPivotColumn().getIntValue(-1) - 1, relationalDbAction.getTransformMeasuresColumn().getIntValue(-1) - 1, relationalDbAction.getTransformSortColumn().getIntValue(0) - 1, (Format) relationalDbAction.getTransformPivotDataFormat().getValue(), (Format) relationalDbAction.getTransformSortDataFormat().getValue(), relationalDbAction.getTransformOrderOutputColumns().getBooleanValue(false)); IActionOutput actionOutput = relationalDbAction.getOutputResultSet(); if (actionOutput != null) { actionOutput.setValue(rSet); } return true; } else { return runQuery(baseQuery, relationalDbAction.getLive().getBooleanValue(false)); } } else if (actionDefinition instanceof SqlConnectionAction) { SqlConnectionAction sqlConnectionAction = (SqlConnectionAction) actionDefinition; dispose(); connection = getDatasourceConnection(); if (connection == null) { return false; } else { IActionOutput actionOutput = sqlConnectionAction.getOutputConnection(); if (actionOutput != null) { actionOutput.setValue(this); return true; } else { return false; } } } } catch (Exception e) { error( Messages.getInstance() .getErrorString("SQLBaseComponent.ERROR_0006_EXECUTE_FAILED", getActionName()), e); //$NON-NLS-1$ } return false; }