1 19 20 package org.apache.cayenne.access.jdbc; 21 22 import java.sql.CallableStatement ; 23 import java.sql.Connection ; 24 import java.sql.ResultSet ; 25 import java.sql.SQLException ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.List ; 29 import java.util.Map ; 30 31 import org.apache.cayenne.CayenneRuntimeException; 32 import org.apache.cayenne.access.OperationObserver; 33 import org.apache.cayenne.access.QueryLogger; 34 import org.apache.cayenne.access.trans.ProcedureTranslator; 35 import org.apache.cayenne.access.types.ExtendedType; 36 import org.apache.cayenne.dba.DbAdapter; 37 import org.apache.cayenne.map.EntityResolver; 38 import org.apache.cayenne.map.Procedure; 39 import org.apache.cayenne.map.ProcedureParameter; 40 import org.apache.cayenne.query.ProcedureQuery; 41 42 49 public class ProcedureAction extends BaseSQLAction { 50 51 protected ProcedureQuery query; 52 53 57 protected int processedResultSets; 58 59 public ProcedureAction(ProcedureQuery query, DbAdapter adapter, 60 EntityResolver entityResolver) { 61 super(adapter, entityResolver); 62 this.query = query; 63 } 64 65 public void performAction(Connection connection, OperationObserver observer) 66 throws SQLException , Exception { 67 68 processedResultSets = 0; 69 70 ProcedureTranslator transl = createTranslator(connection); 71 72 CallableStatement statement = (CallableStatement ) transl.createStatement(); 73 74 try { 75 79 statement.execute(); 83 84 readProcedureOutParameters(statement, observer); 86 87 while (true) { 89 if (statement.getMoreResults()) { 90 ResultSet rs = statement.getResultSet(); 91 92 try { 93 RowDescriptor descriptor = describeResultSet( 94 rs, 95 processedResultSets++); 96 readResultSet(rs, descriptor, query, observer); 97 } 98 finally { 99 try { 100 rs.close(); 101 } 102 catch (SQLException ex) { 103 } 104 } 105 } 106 else { 107 int updateCount = statement.getUpdateCount(); 108 if (updateCount == -1) { 109 break; 110 } 111 QueryLogger.logUpdateCount(updateCount); 112 observer.nextCount(query, updateCount); 113 } 114 } 115 } 116 finally { 117 try { 118 statement.close(); 119 } 120 catch (SQLException ex) { 121 122 } 123 } 124 } 125 126 131 protected ProcedureTranslator createTranslator(Connection connection) { 132 ProcedureTranslator translator = new ProcedureTranslator(); 133 translator.setAdapter(getAdapter()); 134 translator.setQuery(query); 135 translator.setEntityResolver(getEntityResolver()); 136 translator.setConnection(connection); 137 return translator; 138 } 139 140 146 protected RowDescriptor describeResultSet(ResultSet resultSet, int setIndex) { 147 if (setIndex < 0) { 148 throw new IllegalArgumentException ( 149 "Expected a non-negative result set index. Got: " + setIndex); 150 } 151 152 List descriptors = query.getResultDescriptors(); 153 154 if (descriptors.isEmpty()) { 155 return new RowDescriptor(resultSet, getAdapter().getExtendedTypes()); 157 } 158 159 if (setIndex >= descriptors.size() || descriptors.get(setIndex) == null) { 161 throw new CayenneRuntimeException("No descriptor for result set at index '" 162 + setIndex 163 + "' configured."); 164 } 165 166 ColumnDescriptor[] columns = (ColumnDescriptor[]) descriptors.get(setIndex); 167 return new RowDescriptor(columns, getAdapter().getExtendedTypes()); 168 } 169 170 173 protected Procedure getProcedure() { 174 return getEntityResolver().lookupProcedure(query); 175 } 176 177 180 protected void readProcedureOutParameters( 181 CallableStatement statement, 182 OperationObserver delegate) throws SQLException , Exception { 183 184 long t1 = System.currentTimeMillis(); 185 186 Map result = null; 188 List parameters = getProcedure().getCallParameters(); 189 for (int i = 0; i < parameters.size(); i++) { 190 ProcedureParameter parameter = (ProcedureParameter) parameters.get(i); 191 192 if (!parameter.isOutParam()) { 193 continue; 194 } 195 196 if (result == null) { 197 result = new HashMap (); 198 } 199 200 ColumnDescriptor descriptor = new ColumnDescriptor(parameter); 201 ExtendedType type = getAdapter().getExtendedTypes().getRegisteredType( 202 descriptor.getJavaClass()); 203 Object val = type.materializeObject(statement, i + 1, descriptor 204 .getJdbcType()); 205 206 result.put(descriptor.getLabel(), val); 207 } 208 209 if (result != null && !result.isEmpty()) { 210 QueryLogger.logSelectCount(1, System.currentTimeMillis() - t1); 212 delegate.nextDataRows(query, Collections.singletonList(result)); 213 } 214 } 215 } 216 | Popular Tags |