1 22 23 package org.xquark.extractor.runtime; 24 25 import java.io.InputStream ; 26 import java.math.BigDecimal ; 27 import java.sql.PreparedStatement ; 28 import java.sql.ResultSet ; 29 import java.sql.SQLException ; 30 import java.util.*; 31 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.xquark.extractor.ExtractorConnection; 35 import org.xquark.extractor.algebra.ExternalVariable; 36 import org.xquark.extractor.common.MessageLibrary; 37 import org.xquark.extractor.metadata.MetaDataManager; 38 import org.xquark.extractor.sql.PlaceHolderInfo; 39 import org.xquark.extractor.sql.RuntimeVarInfo; 40 import org.xquark.extractor.sql.StatementInfo; 41 import org.xquark.schema.Type; 42 import org.xquark.xml.xdbc.PreparedXMLStatement; 43 import org.xquark.xml.xdbc.XMLDBCException; 44 import org.xquark.xml.xdbc.XMLResultSet; 45 import org.xquark.xquery.parser.*; 46 47 51 public class PreparedExtractorStatement extends ExtractorStatement implements PreparedXMLStatement { 52 53 private static Log log = LogFactory.getLog(PreparedExtractorStatement.class); 54 55 private static final byte PARAM_OBJECT = 0; 56 private static final byte PARAM_XML = 1; 57 private static final byte PARAM_DECIMAL = 2; 58 private static final byte PARAM_INPUTSTREAM = 3; 59 private static final byte PARAM_BYTES = 4; 60 private static final byte PARAM_BOOLEAN = 5; 61 private static final byte PARAM_DATE = 6; 62 private static final byte PARAM_DOUBLE = 7; 63 private static final byte PARAM_FLOAT = 8; 64 private static final byte PARAM_LONG = 9; 65 private static final byte PARAM_STRING = 10; 66 private static final byte PARAM_SEQUENCE = 11; 67 68 69 protected Query _query = null; 70 71 72 76 protected Map _externalVarMap = new HashMap(); 77 78 82 protected Map _queryMap = new HashMap(); 83 84 85 92 public PreparedExtractorStatement(ExtractorConnection connection, int stmtId, QueryFactory queryFactory, MetaDataManager metadataManager, String query, Map cachedStatements) throws XMLDBCException { 93 super(connection, stmtId, queryFactory, metadataManager); 94 if (cachedStatements != null) { 95 _query = (Query) cachedStatements.get(query); 96 } 97 if (_query == null) { 98 _query = queryFactory.createCompiledQuery(query); 99 if (cachedStatements != null) { 100 cachedStatements.put(query, _query); 101 } 102 } 103 try { 105 prepareJDBCStatements(); 106 } catch (SQLException e) { 107 throw new XMLDBCException(MessageLibrary.getMessage("E_ERR_SQL", e.getMessage())); 108 } 109 } 110 111 public void close() throws XMLDBCException { 112 if (!_isClosed) { 113 CompiledQueryTreeExecutor executor = new CompiledQueryTreeExecutor() { 115 116 public void execute(Query.SQLExecutionInfo sInfo) throws SQLException { 117 if (_stmt == null) 119 _stmt = createJdbcStatement(); 120 121 if (sInfo.sql != null) 122 sInfo.sql.cleanAll(_stmt); 123 124 NodeStatementInfo nsi = getPreparedStatements(sInfo); 126 nsi.mainQueryStmt.close(); 127 Iterator it = null; 128 if (nsi.firstExecStmts != null) { 129 it = nsi.firstExecStmts.iterator(); 130 while (it.hasNext()) 131 ((PreparedStatement ) it.next()).close(); 132 } 133 if (nsi.nextExecStmts != null) { 134 it = nsi.nextExecStmts.iterator(); 135 while (it.hasNext()) 136 ((PreparedStatement ) it.next()).close(); 137 } 138 } 139 }; 140 try { 141 browseCompiledQuery(executor); 142 } catch (SQLException e) { 143 } 144 145 _externalVarMap.clear(); 146 _queryMap.clear(); 147 148 super.close(); 149 } 150 } 151 152 private NodeStatementInfo getPreparedStatements(Query.SQLExecutionInfo sInfo) { 153 return (NodeStatementInfo) _queryMap.get(sInfo); 154 } 155 156 public PreparedStatement createPreparedJdbcStatement(String query) throws SQLException { 157 PreparedStatement retVal = null; 158 if (_connection.getExtractor().useScrollableResultSets()) 159 retVal = _connection.getJdbcConnection().prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); 160 else 161 retVal = _connection.getJdbcConnection().prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 162 163 return retVal; 164 } 165 166 167 168 169 private void setVariable(String ns, String varName, Object value, byte valueType) throws XMLDBCException { 170 HashMap varMap = _query.getModule().getVariables(); 171 if (varMap == null) 172 throw new XMLDBCException("Variable $" + ((ns==null)?"":"{" + ns + "}") + varName + " is not defined."); 173 varMap = (HashMap)varMap.get(ns); 174 if (varMap == null) 175 throw new XMLDBCException("Variable $" + ((ns==null)?"":"{" + ns + "}") + varName + " is not defined."); 176 Variable var = (Variable)varMap.get(varName); 177 if (var == null) 178 throw new XMLDBCException("Variable $" + ((ns==null)?"":"{" + ns + "}") + varName + " is not defined."); 179 180 List placeHolders = (List) _externalVarMap.get(ExternalVariable.getExpandedName(ns, varName)); 181 if (placeHolders == null) 182 return; 183 184 RuntimeVarInfo varInfo = null; 185 for (int i = 0; i < placeHolders.size(); i++) { 186 varInfo = (RuntimeVarInfo) placeHolders.get(i); 187 try { 188 switch (valueType) { 189 case PARAM_OBJECT : 190 varInfo.setObject(value); 191 break; 192 case PARAM_XML : 193 varInfo.setParameter((String ) value); 194 break; 195 case PARAM_DECIMAL : 196 varInfo.setBigDecimal((BigDecimal ) value); 197 break; 198 case PARAM_INPUTSTREAM : 199 StreamInfo sInfo = (StreamInfo) value; 200 varInfo.setInputStream(sInfo.stream, sInfo.length); 201 break; 202 case PARAM_BYTES : 203 varInfo.setBytes((byte[]) value); 204 break; 205 case PARAM_BOOLEAN : 206 varInfo.setBoolean(((Boolean ) value).booleanValue()); 207 break; 208 case PARAM_DATE : 209 varInfo.setDate((Date) value); 210 break; 211 case PARAM_DOUBLE : 212 varInfo.setDouble(((Double ) value).doubleValue()); 213 break; 214 case PARAM_FLOAT : 215 varInfo.setFloat(((Float ) value).floatValue()); 216 break; 217 case PARAM_LONG : 218 varInfo.setLong(((Long ) value).longValue()); 219 break; 220 case PARAM_STRING : 221 varInfo.setString((String ) value); 222 break; 223 default : 227 } 228 229 } catch (Exception e) { 230 throw new XMLDBCException(MessageLibrary.getMessage("ST_VAR_SETTING"), e); 231 } 232 } 233 } 234 235 public void setExternalVariable(String ns, String varName, String value) throws XMLDBCException { 236 setVariable(ns, varName, value, PARAM_XML); 237 } 238 239 public void setExternalVariable(String varName, String value) throws XMLDBCException { 240 setExternalVariable(null, varName, value); 241 } 242 243 public void setObject(String ns, String varName, Object value) throws XMLDBCException { 244 setVariable(ns, varName, value, PARAM_OBJECT); 245 } 246 247 public void setObject(String varName, Object value) throws XMLDBCException { 248 setObject(null, varName, value); 249 } 250 251 public void setBigDecimal(String ns, String varName, BigDecimal value) throws XMLDBCException { 252 setVariable(ns, varName, value, PARAM_DECIMAL); 253 } 254 255 public void setBigDecimal(String varName, BigDecimal value) throws XMLDBCException { 256 setBigDecimal(null, varName, value); 257 } 258 259 protected class StreamInfo { 260 InputStream stream; 261 int length; 262 263 public StreamInfo(InputStream stream, int length) { 264 this.stream = stream; 265 this.length = length; 266 } 267 } 268 269 public void setInputStream(String ns, String varName, InputStream value, int length) throws XMLDBCException { 270 setVariable(ns, varName, new StreamInfo(value, length), PARAM_INPUTSTREAM); 271 } 272 273 public void setInputStream(String varName, InputStream value, int length) throws XMLDBCException { 274 setInputStream(null, varName, value, length); 275 } 276 277 public void setBytes(String ns, String varName, byte[] value) throws XMLDBCException { 278 setVariable(ns, varName, value, PARAM_BYTES); 279 } 280 281 public void setBytes(String varName, byte[] value) throws XMLDBCException { 282 setBytes(null, varName, value); 283 } 284 285 public void setBoolean(String ns, String varName, boolean value) throws XMLDBCException { 286 setVariable(ns, varName, new Boolean (value), PARAM_BOOLEAN); 287 } 288 289 public void setBoolean(String varName, boolean value) throws XMLDBCException { 290 setBoolean(null, varName, value); 291 } 292 293 public void setDate(String ns, String varName, Date value) throws XMLDBCException { 294 setVariable(ns, varName, value, PARAM_DATE); 295 } 296 297 public void setDate(String varName, Date value) throws XMLDBCException { 298 setDate(null, varName, value); 299 } 300 301 public void setDouble(String ns, String varName, double value) throws XMLDBCException { 302 setVariable(ns, varName, new Double (value), PARAM_DOUBLE); 303 } 304 305 public void setDouble(String varName, double value) throws XMLDBCException { 306 setDouble(null, varName, value); 307 } 308 309 public void setFloat(String ns, String varName, float value) throws XMLDBCException { 310 setVariable(ns, varName, new Float (value), PARAM_FLOAT); 311 } 312 313 public void setFloat(String varName, float value) throws XMLDBCException { 314 setFloat(null, varName, value); 315 } 316 317 public void setLong(String ns, String varName, long value) throws XMLDBCException { 318 setVariable(ns, varName, new Long (value), PARAM_LONG); 319 } 320 321 public void setLong(String varName, long value) throws XMLDBCException { 322 setLong(null, varName, value); 323 324 } 325 326 public void setString(String ns, String varName, String value) throws XMLDBCException { 327 setVariable(ns, varName, value, PARAM_STRING); 328 } 329 330 public void setString(String varName, String value) throws XMLDBCException { 331 setString(null, varName, value); 332 } 333 334 public void setSequence(String ns, String varName, List value) throws XMLDBCException { 335 setVariable(ns, varName, value, PARAM_SEQUENCE); 336 } 337 338 public void setSequence(String varName, List value) throws XMLDBCException { 339 setSequence(null, varName, value); 340 } 341 342 public void clearVariables() throws XMLDBCException { 343 _externalVarMap.clear(); 344 } 345 346 347 348 349 public boolean execute() throws XMLDBCException { 350 if (_currentResultSet != null) 351 _currentResultSet.close(); 352 _currentResultSet = runQuery(_query.getCompiledQuery()); 353 return true; 354 } 355 356 public XMLResultSet executeQuery() throws XMLDBCException { 357 execute(); 358 return _currentResultSet; 359 } 360 361 protected SynchronizedResultSet executeSQL(Query.SQLExecutionInfo sqlInfo) throws XQueryException, XMLDBCException { 362 SynchronizedResultSet retVal = null; 363 NodeStatementInfo pStmts = (NodeStatementInfo) _queryMap.get(sqlInfo); 364 365 try { 366 368 if (pStmts.firstExecStmts != null) { 370 if (pStmts.firstPerformed) { for (int i = 0; i < pStmts.nextExecStmts.size(); i++) { 372 ((PreparedStatement ) pStmts.nextExecStmts.get(i)).executeUpdate(); 373 } 374 } else { for (int i = 0; i < pStmts.firstExecStmts.size(); i++) { 376 ((PreparedStatement ) pStmts.firstExecStmts.get(i)).executeUpdate(); 377 } 378 pStmts.firstPerformed = true; 379 } 380 } 381 382 retVal = new SynchronizedResultSet(pStmts.mainQueryStmt, sqlInfo.mapper, _metadataManager.getDbmsInfo()); 384 } catch (XMLDBCException ex) { 385 throw ex; 386 } catch (SQLException ex) { 387 throw new XMLDBCException(ex.getMessage(), ex); 388 } 389 390 return retVal; 391 } 392 393 private void prepareJDBCStatements() throws SQLException { 394 CompiledQueryTreeExecutor executor = new CompiledQueryTreeExecutor() { 395 396 public void execute(Query.SQLExecutionInfo sInfo) throws SQLException { 397 List requestList = sInfo.sql.getRequestList(); 398 399 if (log.isDebugEnabled()) { 400 log.debug("=================< SQL >================="); 401 for (int i = 0; i < requestList.size(); i++) 402 log.debug(((StatementInfo) requestList.get(i)).sStmt); 403 } 404 405 408 NodeStatementInfo pStmts = new NodeStatementInfo(); 410 _queryMap.put(sInfo, pStmts); 411 412 StatementInfo stmtInfo = null; 414 PreparedStatement pStmt = null; 415 if (requestList.size() > 1) 416 pStmts.firstExecStmts = new ArrayList(); 417 for (int i = 0; i < requestList.size() - 1; i++) { 418 stmtInfo = (StatementInfo) requestList.get(i); 419 pStmt = createPreparedJdbcStatement(stmtInfo.sStmt); 420 pStmts.firstExecStmts.add(pStmt); 421 registerPlaceHolders(stmtInfo.parameterList, pStmt); 422 } 423 424 stmtInfo = (StatementInfo) requestList.get(requestList.size() - 1); 426 pStmt = createPreparedJdbcStatement(stmtInfo.sStmt); 427 pStmts.mainQueryStmt = pStmt; 428 registerPlaceHolders(stmtInfo.parameterList, pStmt); 429 430 requestList = sInfo.sql.getResetStatementList(); 432 433 if (log.isDebugEnabled()) { 434 log.debug("==============< SQL Reset >=============="); 435 for (int i = 0; i < requestList.size(); i++) 436 log.debug(((StatementInfo) requestList.get(i)).sStmt); 437 } 438 439 if (!requestList.isEmpty()) 440 pStmts.nextExecStmts = new ArrayList(); 441 for (int i = 0; i < requestList.size(); i++) { 442 stmtInfo = (StatementInfo) requestList.get(i); 443 pStmt = createPreparedJdbcStatement(stmtInfo.sStmt); 444 pStmts.nextExecStmts.add(pStmt); 445 registerPlaceHolders(stmtInfo.parameterList, pStmt); 446 } 447 } 448 }; 449 browseCompiledQuery(executor); 450 } 451 452 private void registerPlaceHolders(List placeholders, PreparedStatement pStmt) { 453 for (int i = 0; i < placeholders.size(); i++) { 454 registerPlaceHolder((PlaceHolderInfo) placeholders.get(i), pStmt); 455 } 456 } 457 458 private void registerPlaceHolder(PlaceHolderInfo placeholder, PreparedStatement pStmt) { 459 List runTimeVarInfos = (List) _externalVarMap.get(placeholder.varId); 460 if (runTimeVarInfos == null) { 461 runTimeVarInfos = new ArrayList(); 462 _externalVarMap.put(placeholder.varId, runTimeVarInfos); 463 } 464 runTimeVarInfos.add(new RuntimeVarInfo(placeholder, pStmt)); 465 } 466 467 468 469 470 protected class NodeStatementInfo { 471 boolean firstPerformed = false; 472 List firstExecStmts = null; 473 List nextExecStmts = null; 474 PreparedStatement mainQueryStmt = null; 475 } 476 477 protected void browseCompiledQuery(CompiledQueryTreeExecutor executor) throws SQLException { 478 Iterator it = _query.getCompiledQuery().iterator(); 479 while (it.hasNext()) 480 browseQueryTree(executor, ((Query.CompiledExpression) it.next()).sqlInfoTree); 481 } 482 483 protected void browseQueryTree(CompiledQueryTreeExecutor executor, Query.SQLExecutionInfo sInfo) throws SQLException { 484 if (sInfo == null) 486 return; 487 488 if (sInfo.sql != null) 489 executor.execute(sInfo); 490 491 if (sInfo.childrenQueries != null) { 493 Iterator it = sInfo.childrenQueries.iterator(); 494 while (it.hasNext()) 495 browseQueryTree(executor, (Query.SQLExecutionInfo) it.next()); 496 } 497 } 498 499 protected interface CompiledQueryTreeExecutor { 500 void execute(Query.SQLExecutionInfo sInfo) throws SQLException ; 501 } 502 503 507 public javax.xml.namespace.QName [] getParameterNames() { 508 ArrayList names = new ArrayList(); 509 XQueryModule module = _query.getModule(); 510 if (module.getDeclList() != null) { 511 for (int i = 0; i < module.getDeclList().size(); i++) { 512 QName name = (QName) module.getDeclList().get(i); 513 HashMap map = null; 514 if (module.getVariables() != null) { 515 map = (HashMap) module.getVariables().get(name.getNameSpace()); 516 if (map != null) { 517 Variable vari = (Variable) map.get(name.getLocalName()); 518 if (vari != null && vari.getExpression() == null) { 519 names.add(new javax.xml.namespace.QName (vari.getVarName().getNameSpace(),vari.getVarName().getLocalName())); 520 } 521 } 522 } 523 } 524 } 525 javax.xml.namespace.QName qnames[] = new javax.xml.namespace.QName [names.size()]; 526 return (javax.xml.namespace.QName []) names.toArray(qnames); 527 } 528 531 public javax.xml.namespace.QName getParameterType(javax.xml.namespace.QName varName) { 532 XQueryModule module = _query.getModule(); 533 org.xquark.xquery.parser.ExternalVariable extVar = (org.xquark.xquery.parser.ExternalVariable) module.getExternalVariables().get(varName); 534 Type type = extVar.getQType().getSimpleType().getBaseType(); 535 return new javax.xml.namespace.QName (type.getNamespace(), type.getName()); 536 } 537 538 } 539 | Popular Tags |