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 org.netbeans.modules.dbschema.TableElement; 35 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 36 import com.sun.jdo.spi.persistence.support.sqlstore.ActionDesc; 37 import com.sun.jdo.spi.persistence.support.sqlstore.SQLStoreManager; 38 import com.sun.jdo.spi.persistence.support.sqlstore.Transaction; 39 import com.sun.jdo.spi.persistence.support.sqlstore.model.*; 40 import com.sun.jdo.spi.persistence.support.sqlstore.sql.UpdateJoinTableDesc; 41 import com.sun.jdo.spi.persistence.support.sqlstore.sql.UpdateObjectDescImpl; 42 import com.sun.jdo.spi.persistence.utility.I18NHelper; 43 44 import java.util.ArrayList ; 45 import java.util.Collection ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 49 50 53 public class UpdateQueryPlan extends QueryPlan { 54 55 56 private boolean batch = false; 57 58 private UpdateObjectDescImpl updateDesc; 59 60 public UpdateQueryPlan(ActionDesc desc, SQLStoreManager store) { 61 super(desc, store); 62 this.updateDesc = (UpdateObjectDescImpl) desc; 63 this.action = getAction(updateDesc.getUpdateAction()); 64 } 65 66 private static int getAction(int updateAction) { 67 if (updateAction == ActionDesc.LOG_CREATE) { 68 return ACT_INSERT; 69 } else if (updateAction == ActionDesc.LOG_DESTROY) { 70 return ACT_DELETE; 71 } else if (updateAction == ActionDesc.LOG_UPDATE) { 72 return ACT_UPDATE; 73 } else { 74 return ACT_NOOP; 75 } 76 } 77 78 88 private void addColumn(LocalFieldDesc fieldDesc, Object value) { 89 90 if ((fieldDesc.sqlProperties & FieldDesc.PROP_SECONDARY_TRACKED_FIELD) > 0) { 92 return; 93 } 94 95 for (Iterator iter = fieldDesc.getColumnElements(); iter.hasNext(); ) { 96 ColumnElement columnElement = (ColumnElement) iter.next(); 97 TableElement tableElement = columnElement.getDeclaringTable(); 98 99 if (tableElement == null) { 100 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 101 "core.configuration.fieldnotable", fieldDesc.getName())); 103 } 104 105 QueryTable t = findQueryTable(tableElement); 106 UpdateStatement s = null; 107 108 if (t == null) { 109 t = addQueryTable(tableElement, null); 110 s = (UpdateStatement) addStatement(t); 111 } else { 112 s = (UpdateStatement) getStatement(t); 113 } 114 115 if (fieldDesc.isVersion() && action == ACT_UPDATE) { 116 s.addVersionColumn(columnElement); 118 } else { 119 s.addColumn(columnElement, value); 120 } 121 122 } 123 } 124 125 public void build() { 126 build(false); 127 } 128 129 135 public void build(boolean batch) { 136 137 if ((status & ST_BUILT) > 0) return; 138 139 this.batch = batch; 140 141 generateStatements(); 142 143 addColumns(); 144 145 if (statements.size() > 0) { 146 processStatements(); 147 } 148 149 processJoinTables(); 150 151 status = status | ST_BUILT; 152 } 153 154 private void generateStatements() { 155 if ((action == ACT_DELETE) || (action == ACT_INSERT)) { 157 Iterator iter = config.getTables(); 158 while (iter.hasNext()) { 159 TableDesc t = (TableDesc) iter.next(); 160 161 if (!t.isJoinTable()) { 163 if (findQueryTable(t.getTableElement()) == null) 164 addStatement(addQueryTable(t)); 165 } 166 } 167 168 if (action == ACT_INSERT) { 170 int i = 0; 171 int j = statements.size() - 1; 172 173 while (i < j) { 174 Statement s = (Statement) statements.get(i); 175 statements.set(i, statements.get(j)); 176 statements.set(j, s); 177 i++; 178 j--; 179 } 180 } 181 } 182 } 183 184 189 private void addColumns() { 190 if ((action == ACT_UPDATE) || (action == ACT_INSERT)) { 191 List updatedFields = updateDesc.getUpdatedFields(); 192 int size = (updatedFields != null) ? updatedFields.size() : 0; 193 for (int i = 0; i < size; i++) { 194 LocalFieldDesc f = (LocalFieldDesc) updatedFields.get(i); 195 Object value = batch ? f : updateDesc.getAfterValue(f); 196 addColumn(f, value); 197 } 198 } 199 } 200 201 private void addConstraints(UpdateStatement statement, 202 ArrayList localFields, 203 ArrayList foreignFields, 204 ArrayList columns) { 205 206 boolean isBeforeImageRequired = updateDesc.isBeforeImageRequired(); 207 for (int i = 0; i < localFields.size(); i++) { 208 LocalFieldDesc lf = (LocalFieldDesc) localFields.get(i); 209 LocalFieldDesc ff = (LocalFieldDesc) foreignFields.get(i); 210 ColumnElement ce = (ColumnElement) columns.get(i); 211 212 addConstraint(statement, lf, ff, ce, isBeforeImageRequired); 213 } 214 215 if (getConfig().hasVersionConsistency() && action != ACT_INSERT) { 217 QueryTable table = (QueryTable) statement.getQueryTables().get(0); 218 LocalFieldDesc versionField = table.getTableDesc().getVersionField(); 219 ColumnElement ce = (ColumnElement) versionField.getColumnElements().next(); 220 221 addConstraint(statement, versionField, versionField, ce, false); 222 } 223 224 statement.markConstraintAdded(); 225 } 226 227 private void addConstraint(UpdateStatement statement, 228 LocalFieldDesc lf, 229 LocalFieldDesc ff, 230 ColumnElement ce, 231 boolean isBeforeImageRequired) { 232 233 if (action != ACT_INSERT) { 234 if (batch) { 235 statement.addConstraint(ce, lf, ff); 236 } 237 else { 238 Object value = isBeforeImageRequired ? 239 updateDesc.getBeforeValue(ff) : updateDesc.getAfterValue(ff); 240 statement.addConstraint(lf, value); 241 } 242 } else { 243 Object value = batch ? ff : updateDesc.getAfterValue(ff); 244 statement.addColumn(ce, value); 245 } 246 } 247 248 private void addSecondaryTableConstraint(UpdateStatement statement) { 249 QueryTable table = (QueryTable) statement.getQueryTables().get(0); 250 ReferenceKeyDesc key = table.getTableDesc().getPrimaryTableKey(); 251 252 ArrayList localFields = key.getReferencingKey().getFields(); 253 ArrayList foreignFields = key.getReferencedKey().getFields(); 254 ArrayList columns = key.getReferencingKey().getColumns(); 255 256 addConstraints(statement, localFields, foreignFields, columns); 257 } 258 259 private void addBasetableConstraint(UpdateStatement statement) { 260 QueryTable table = (QueryTable) statement.getQueryTables().get(0); 261 KeyDesc key = table.getTableDesc().getKey(); 262 263 ArrayList localFields = key.getFields(); 264 ArrayList columns = key.getColumns(); 265 266 addConstraints(statement, localFields, localFields, columns); 267 } 268 269 private void processRelatedStatements(UpdateStatement statement) { 270 ArrayList secondaryTableStatements = statement.getSecondaryTableStatements(); 271 272 if (secondaryTableStatements != null) { 273 for (int i = 0; i < secondaryTableStatements.size(); i++) { 274 UpdateStatement secondaryTableStatement = (UpdateStatement) secondaryTableStatements.get(i); 275 276 if (!secondaryTableStatement.isConstraintAdded()) { 277 processRelatedStatements(secondaryTableStatement); 278 279 addSecondaryTableConstraint(secondaryTableStatement); 280 } 281 } 282 } 283 } 284 285 protected void processStatements() { 286 int size = statements.size(); 287 288 if (size > 1) { 289 super.processStatements(); 290 291 for (int i = 0; i < size; i++) { 292 UpdateStatement statement = (UpdateStatement) statements.get(i); 293 294 if (!statement.isConstraintAdded()) 295 processRelatedStatements(statement); 296 } 297 } 298 299 UpdateStatement masterStatement = null; 300 301 if (size == 1) 302 masterStatement = (UpdateStatement) statements.get(0); 303 else { 304 for (int i = 0; i < size; i++) { 307 masterStatement = (UpdateStatement) statements.get(i); 308 309 if (!masterStatement.isConstraintAdded()) break; 310 } 311 } 312 313 if (action != ACT_INSERT) 314 addBasetableConstraint(masterStatement); 315 316 if ((action != ACT_INSERT) && (updateDesc.getConcurrency() != null)) 317 updateDesc.getConcurrency().update(this); 318 } 319 320 private void processJoinTables() { 321 Collection fields = updateDesc.getUpdatedJoinTableFields(); 322 323 if (fields == null) return; 324 325 Iterator fieldIter = fields.iterator(); 326 327 ArrayList deleteStatements = new ArrayList (); 328 ArrayList insertStatements = new ArrayList (); 329 330 while (fieldIter.hasNext()) { 331 ForeignFieldDesc f = (ForeignFieldDesc) fieldIter.next(); 332 Collection descs = updateDesc.getUpdateJoinTableDescs(f); 333 Iterator descIter = descs.iterator(); 334 335 ColumnElement c = (ColumnElement) f.assocLocalColumns.get(0); 336 QueryTable t = addQueryTable(config.findTableDesc(c.getDeclaringTable())); 337 338 while (descIter.hasNext()) { 339 UpdateJoinTableDesc desc = (UpdateJoinTableDesc) descIter.next(); 340 int action = getAction(desc.getAction()); 341 342 UpdateStatement s = (UpdateStatement) createStatement(t); 343 s.setAction(action); 344 345 if (action == ACT_INSERT) { 346 insertStatements.add(s); 347 } else if (action == ACT_DELETE) { 348 349 354 s.minAffectedRows = 0; 355 deleteStatements.add(s); 356 } 357 358 s.addLocalConstraints(action, f, desc.getParentStateManager()); 359 s.addForeignConstraints(action, f, desc.getForeignStateManager()); 360 } 361 } 362 363 366 ArrayList oldStatements = statements; 367 statements = deleteStatements; 368 statements.addAll(oldStatements); 369 statements.addAll(insertStatements); 370 } 371 372 protected Statement newStatement() { 373 return new UpdateStatement(store.getVendorType(), this, batch); 374 } 375 376 381 public boolean checkBatchThreshold(Transaction tran) 382 { 383 for (int i = 0, size = statements.size(); i < size; i++) { 384 UpdateStatement updateStatement = (UpdateStatement) statements.get(i); 385 if (updateStatement.exceedsBatchThreshold(tran)) 386 return true; 387 } 388 return false; 389 } 390 391 } 392 | Popular Tags |