1 56 package org.objectstyle.cayenne.access.trans; 57 58 import java.sql.CallableStatement ; 59 import java.sql.PreparedStatement ; 60 import java.util.ArrayList ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 import java.util.Map ; 64 65 import org.apache.log4j.Level; 66 import org.objectstyle.cayenne.access.QueryLogger; 67 import org.objectstyle.cayenne.access.QueryTranslator; 68 import org.objectstyle.cayenne.map.Procedure; 69 import org.objectstyle.cayenne.map.ProcedureParameter; 70 import org.objectstyle.cayenne.query.ProcedureQuery; 71 72 77 public class ProcedureTranslator extends QueryTranslator { 78 79 82 static class NotInParam { 83 84 protected String type; 85 86 public NotInParam(String type) { 87 this.type = type; 88 } 89 90 public String toString() { 91 return type; 92 } 93 } 94 95 private static NotInParam OUT_PARAM = new NotInParam("[OUT]"); 96 97 protected List callParams; 98 protected List values; 99 100 103 protected String createSqlString() { 104 Procedure procedure = getProcedure(); 105 106 StringBuffer buf = new StringBuffer (); 107 108 int totalParams = callParams.size(); 109 110 if (procedure.isReturningValue()) { 112 totalParams--; 113 buf.append("{? = call "); 114 } 115 else { 116 buf.append("{call "); 117 } 118 119 buf.append(procedure.getFullyQualifiedName()); 120 121 if (totalParams > 0) { 122 buf.append("(?"); 124 125 for (int i = 1; i < totalParams; i++) { 126 buf.append(", ?"); 127 } 128 129 buf.append(")"); 130 } 131 132 buf.append("}"); 133 return buf.toString(); 134 } 135 136 public PreparedStatement createStatement(Level logLevel) throws Exception { 137 long t1 = System.currentTimeMillis(); 138 139 this.callParams = getProcedure().getCallParameters(); 140 this.values = new ArrayList (callParams.size()); 141 142 initValues(); 143 String sqlStr = createSqlString(); 144 145 if (QueryLogger.isLoggable(logLevel)) { 146 long time = System.currentTimeMillis() - t1; 148 149 List loggableParameters = new ArrayList (values.size()); 150 Iterator it = values.iterator(); 151 while (it.hasNext()) { 152 Object val = it.next(); 153 if (val instanceof NotInParam) { 154 val = val.toString(); 155 } 156 loggableParameters.add(val); 157 } 158 159 QueryLogger.logQuery(logLevel, sqlStr, loggableParameters, time); 160 } 161 CallableStatement stmt = connection.prepareCall(sqlStr); 162 initStatement(stmt); 163 return stmt; 164 } 165 166 public Procedure getProcedure() { 167 return getEntityResolver().lookupProcedure(query); 168 } 169 170 public ProcedureQuery getProcedureQuery() { 171 return (ProcedureQuery) query; 172 } 173 174 180 public org.objectstyle.cayenne.access.util.ResultDescriptor getProcedureResultDescriptor() { 181 return org.objectstyle.cayenne.access.util.ResultDescriptor.createDescriptor( 182 getProcedure(), 183 getAdapter().getExtendedTypes()); 184 } 185 186 189 protected void initStatement(CallableStatement stmt) throws Exception { 190 if (values != null && values.size() > 0) { 191 List params = getProcedure().getCallParameters(); 192 193 int len = values.size(); 194 for (int i = 0; i < len; i++) { 195 ProcedureParameter param = (ProcedureParameter) params.get(i); 196 197 if (param.isOutParam()) { 200 setOutParam(stmt, param, i + 1); 201 } 202 203 if (param.isInParameter()) { 204 setInParam(stmt, param, values.get(i), i + 1); 205 } 206 } 207 } 208 } 209 210 protected void initValues() { 211 Map queryValues = getProcedureQuery().getParameters(); 212 213 217 Iterator it = callParams.iterator(); 218 while (it.hasNext()) { 219 ProcedureParameter param = (ProcedureParameter) it.next(); 220 221 if (param.getDirection() == ProcedureParameter.OUT_PARAMETER) { 222 values.add(OUT_PARAM); 223 } 224 else { 225 values.add(queryValues.get(param.getName())); 226 } 227 } 228 } 229 230 233 protected void setInParam( 234 CallableStatement stmt, 235 ProcedureParameter param, 236 Object val, 237 int pos) throws Exception { 238 239 int type = param.getType(); 240 adapter.bindParameter(stmt, val, pos, type, param.getPrecision()); 241 } 242 243 246 protected void setOutParam(CallableStatement stmt, ProcedureParameter param, int pos) 247 throws Exception { 248 249 int precision = param.getPrecision(); 250 if (precision >= 0) { 251 stmt.registerOutParameter(pos, param.getType(), precision); 252 } 253 else { 254 stmt.registerOutParameter(pos, param.getType()); 255 } 256 } 257 } | Popular Tags |