1 23 24 30 31 package com.sun.jdo.spi.persistence.support.sqlstore.sql.generator; 32 33 import org.netbeans.modules.dbschema.ColumnElement; 34 import com.sun.jdo.spi.persistence.support.sqlstore.SQLStateManager; 35 import com.sun.jdo.spi.persistence.support.sqlstore.Transaction; 36 import com.sun.jdo.spi.persistence.support.sqlstore.database.DBVendorType; 37 import com.sun.jdo.spi.persistence.support.sqlstore.model.ForeignFieldDesc; 38 import com.sun.jdo.spi.persistence.support.sqlstore.model.LocalFieldDesc; 39 import com.sun.jdo.spi.persistence.support.sqlstore.sql.UpdateObjectDescImpl; 40 import com.sun.jdo.spi.persistence.support.sqlstore.sql.constraint.ConstraintValue; 41 42 import java.sql.Connection ; 43 import java.sql.SQLException ; 44 import java.util.*; 45 46 49 public class UpdateStatement extends Statement implements Cloneable { 50 51 public int minAffectedRows; 52 53 private Map dbStatementCache = new HashMap(); 54 55 56 UpdateQueryPlan plan; 57 58 59 private List columnRefsForWhereClause; 60 61 62 private List versionColumns; 63 64 65 private boolean batch = false; 66 67 68 private StringBuffer values; 69 70 71 private boolean isConstraintAdded; 72 73 74 public static final String UPDATE_VERSION_COL_PROPERTY = 75 "com.sun.jdo.spi.persistence.support.sqlstore.sql.generator.UPDATE_VERSION_COL"; 77 82 private static final boolean UPDATE_VERSION_COL = Boolean.valueOf( 83 System.getProperty(UPDATE_VERSION_COL_PROPERTY, "true")).booleanValue(); 85 86 public UpdateStatement(DBVendorType vendorType, UpdateQueryPlan plan, boolean batch) { 87 super(vendorType); 88 this.plan = plan; 89 columnRefsForWhereClause = new ArrayList(); 90 this.batch = batch; 91 minAffectedRows = 1; 92 } 93 94 public void addColumn(ColumnElement columnElement, Object value) { 95 addColumnRef(new ColumnRef(columnElement, value)); 96 } 97 98 102 protected void addConstraint(ColumnElement columnElement, 103 LocalFieldDesc lf, Object value) { 104 columnRefsForWhereClause.add(new ColumnRef(columnElement, value)); 105 addConstraint(lf, value); 106 } 107 108 109 private void calculateWhereClauseColumnRefIndexes() { 110 int nextIndex = columns.size() + columnRefsForWhereClause.size(); 114 for (Iterator i = columnRefsForWhereClause.iterator(); i.hasNext(); ) { 115 ColumnRef columnRef = (ColumnRef)i.next(); 116 columnRef.setIndex(nextIndex--); 117 } 118 } 119 120 public boolean isConstraintAdded() { 121 return isConstraintAdded; 122 } 123 124 public void markConstraintAdded() { 125 isConstraintAdded = true; 126 } 127 128 129 public QueryPlan getQueryPlan() { 130 return plan; 131 } 132 133 136 protected void generateStatementText() { 137 138 statementText = new StringBuffer (); 139 140 StringBuffer columnList = generateColumnText(); 141 StringBuffer constraint = processConstraints(); 142 String tableName = ((QueryTable) tableList.get(0)).getTableDesc().getName(); 143 144 switch (action) { 146 case QueryPlan.ACT_UPDATE: 147 statementText.append("update "); appendQuotedText(statementText, tableName); 149 statementText.append(" set ").append(columnList).append(" where ").append(constraint); break; 151 152 case QueryPlan.ACT_DELETE: 153 statementText.append("delete from "); appendQuotedText(statementText, tableName); 155 statementText.append(" where ").append(constraint); break; 157 158 case QueryPlan.ACT_INSERT: 159 statementText.append("insert into "); appendQuotedText(statementText, tableName); 161 statementText.append("(").append(columnList). append(") values ").append("(").append(values).append(")"); break; 164 } 165 166 calculateWhereClauseColumnRefIndexes(); 167 } 168 169 private StringBuffer generateColumnText() { 170 StringBuffer columnList = new StringBuffer (); 171 int numValues = -1; 172 173 for (int i = 0; i < columns.size(); i++) { 174 ColumnRef c = (ColumnRef) columns.get(i); 175 176 if (columnList.length() > 0) { 177 columnList.append(", "); } 179 switch (action) { 180 case QueryPlan.ACT_UPDATE: 181 appendQuotedText(columnList, c.getName()); 182 columnList.append("= ?"); break; 184 185 case QueryPlan.ACT_INSERT: 186 appendQuotedText(columnList, c.getName()); 187 if (i == 0) { 188 values = new StringBuffer ().append(" ?"); } else { 190 values.append(", ?"); } 192 break; 193 } 194 195 if (!batch && 198 ((action == QueryPlan.ACT_UPDATE) || 199 (action == QueryPlan.ACT_INSERT))) { 200 numValues = numValues + 1; 201 InputValue val = new InputValue(c.getValue(), c.getColumnElement()); 202 inputDesc.values.add(numValues, val); 203 } 204 } 205 206 appendVersionColumnUpdateClause(columnList); 207 208 return columnList; 209 } 210 211 217 private void appendVersionColumnUpdateClause(StringBuffer setClause) { 218 if(UPDATE_VERSION_COL) { 219 if (versionColumns != null) 220 { 221 for (int i = 0; i < versionColumns.size(); i++) { 222 ColumnElement columnElement = (ColumnElement) versionColumns.get(i); 223 String columnName = columnElement.getName().getName(); 224 setClause.append(", "); 225 appendQuotedText(setClause, columnName); 226 setClause.append(" = "); 227 appendQuotedText(setClause, columnName); 228 setClause.append(" + "); 229 setClause.append("1"); 230 } 231 } 232 } 233 } 234 235 236 public void addLocalConstraints(int action, ForeignFieldDesc f, SQLStateManager sm) { 237 for (int i = 0; i < f.localFields.size(); i++) { 238 LocalFieldDesc lf = (LocalFieldDesc) f.localFields.get(i); 239 240 if (action == QueryPlan.ACT_INSERT) { 241 ColumnElement lc = (ColumnElement) f.assocLocalColumns.get(i); 244 245 addColumn(lc, lf.getValue(sm)); 246 } else if (action == QueryPlan.ACT_DELETE) { 247 LocalFieldDesc alf = (LocalFieldDesc) f.assocLocalFields.get(i); 248 249 addConstraint(alf, lf.getValue(sm)); 252 } 253 } 254 } 255 256 public void addForeignConstraints(int action, ForeignFieldDesc f, SQLStateManager sm) { 257 for (int i = 0; i < f.foreignFields.size(); i++) { 258 LocalFieldDesc ff = (LocalFieldDesc) f.foreignFields.get(i); 259 260 if (action == QueryPlan.ACT_INSERT) { 261 ColumnElement fc = (ColumnElement) f.assocForeignColumns.get(i); 264 265 addColumn(fc, ff.getValue(sm)); 266 } else if (action == QueryPlan.ACT_DELETE) { 267 LocalFieldDesc aff = (LocalFieldDesc) f.assocForeignFields.get(i); 268 269 addConstraint(aff, ff.getValue(sm)); 272 } 273 } 274 } 275 276 280 protected void processConstraintValue(ConstraintValue node, StringBuffer result) { 281 result.append("?"); if (!batch) 283 generateInputValueForConstraintValueNode(node); 284 } 285 286 294 public DBStatement getDBStatement(Transaction tran, Connection conn) 295 throws SQLException 296 { 297 DBStatement dbStatement = null; 298 299 synchronized (dbStatementCache) 300 { 301 dbStatement = (DBStatement)dbStatementCache.get(tran); 303 304 if (dbStatement == null) { 305 dbStatement = new DBStatement(conn, getText(), 306 tran.getUpdateTimeout()); 307 dbStatementCache.put(tran, dbStatement); 309 } 310 } 311 312 return dbStatement; 313 } 314 315 316 public boolean exceedsBatchThreshold(Transaction tran) 317 { 318 synchronized (dbStatementCache) 319 { 320 DBStatement dbStatement = (DBStatement)dbStatementCache.get(tran); 321 return (dbStatement != null) && dbStatement.exceedsBatchThreshold(); 322 } 323 } 324 325 330 public DBStatement removeDBStatement(Transaction tran) 331 { 332 synchronized (dbStatementCache) 333 { 334 DBStatement s = (DBStatement)dbStatementCache.remove(tran); 335 return s; 336 } 337 } 338 339 public void bindInputColumns(DBStatement s, 340 UpdateObjectDescImpl updateDesc) 341 throws SQLException { 342 343 for (Iterator i = getColumnRefs().iterator(); i.hasNext(); ) { 345 bindInputColumn(s, (ColumnRef)i.next(), updateDesc, false ); 346 } 347 for (Iterator i = columnRefsForWhereClause.iterator(); i.hasNext(); ) { 349 bindInputColumn(s, (ColumnRef) i.next(), updateDesc, 350 updateDesc.isBeforeImageRequired()); 351 } 352 353 } 354 355 363 private void bindInputColumn(DBStatement stmt, 364 ColumnRef columnRef, 365 UpdateObjectDescImpl updateDesc, 366 boolean getBeforeValue) throws SQLException { 367 368 Object inputValue = getInputValue(updateDesc, columnRef, getBeforeValue); 369 stmt.bindInputColumn(columnRef.getIndex(), inputValue, 370 columnRef.getColumnElement(), vendorType); 371 } 372 373 378 private Object [] getInputValues(UpdateObjectDescImpl updateDesc) { 379 Object [] inputValues = 380 new Object [getColumnRefs().size() + columnRefsForWhereClause.size()]; 381 for (Iterator i = getColumnRefs().iterator(); i.hasNext(); ) { 382 ColumnRef columnRef = (ColumnRef)i.next(); 383 inputValues[columnRef.getIndex() - 1] = getInputValue(updateDesc, columnRef, false); 385 } 386 final boolean getBeforeValue = updateDesc.isBeforeImageRequired(); 387 for (Iterator i = columnRefsForWhereClause.iterator(); i.hasNext(); ) { 388 ColumnRef columnRef = (ColumnRef)i.next(); 389 inputValues[columnRef.getIndex() - 1] = getInputValue(updateDesc, columnRef, getBeforeValue); 390 } 391 return inputValues; 392 } 393 394 400 public String getFormattedSQLText(UpdateObjectDescImpl updateDesc) { 401 return formatSqlText(getText(), getInputValues(updateDesc)); 402 } 403 404 413 private static Object getInputValue(UpdateObjectDescImpl updateDesc, 414 ColumnRef columnRef, 415 boolean getBeforeValue) { 416 Object value; 417 LocalFieldDesc field = (LocalFieldDesc) columnRef.getValue(); 418 419 if (field.isVersion()) { 420 value = updateDesc.getAfterValue(field); 424 } else { 425 value = getBeforeValue ? updateDesc.getBeforeValue(field) : 426 updateDesc.getAfterValue(field); 427 } 428 429 return value; 430 } 431 432 public void addVersionColumn(ColumnElement versionColumn) { 433 if (versionColumns == null) { 434 versionColumns = new ArrayList(); 435 } 436 versionColumns.add(versionColumn); 437 } 438 } 439 | Popular Tags |