1 24 25 package org.continuent.sequoia.controller.requests; 26 27 import java.io.Serializable ; 28 import java.sql.SQLException ; 29 import java.util.ArrayList ; 30 import java.util.SortedSet ; 31 import java.util.StringTokenizer ; 32 import java.util.TreeSet ; 33 34 import org.continuent.sequoia.common.i18n.Translate; 35 import org.continuent.sequoia.controller.semantic.SemanticBehavior; 36 import org.continuent.sequoia.controller.sql.schema.AliasedDatabaseTable; 37 import org.continuent.sequoia.controller.sql.schema.DatabaseColumn; 38 import org.continuent.sequoia.controller.sql.schema.DatabaseSchema; 39 import org.continuent.sequoia.controller.sql.schema.DatabaseTable; 40 import org.continuent.sequoia.controller.sql.schema.TableColumn; 41 42 58 public class DeleteRequest extends AbstractWriteRequest implements Serializable 59 { 60 private static final long serialVersionUID = 2321073659092135758L; 61 62 63 protected transient boolean isUnique = false; 64 65 66 protected transient ArrayList from; 67 68 81 protected ArrayList whereValues; 82 83 98 public DeleteRequest(String sqlQuery, boolean escapeProcessing, int timeout, 99 String lineSeparator) 100 { 101 super(sqlQuery, escapeProcessing, timeout, lineSeparator, 102 RequestType.DELETE); 103 } 104 105 108 public boolean altersAggregateList() 109 { 110 return false; 111 } 112 113 116 public boolean altersDatabaseCatalog() 117 { 118 return false; 119 } 120 121 124 public boolean altersDatabaseSchema() 125 { 126 return false; 127 } 128 129 132 public boolean altersMetadataCache() 133 { 134 return false; 135 } 136 137 140 public boolean altersQueryResultCache() 141 { 142 return true; 143 } 144 145 148 public boolean altersSomething() 149 { 150 return true; 151 } 152 153 156 public boolean altersStoredProcedureList() 157 { 158 return false; 159 } 160 161 164 public boolean altersUserDefinedTypes() 165 { 166 return false; 167 } 168 169 172 public boolean altersUsers() 173 { 174 return false; 175 } 176 177 180 public void cloneParsing(AbstractRequest request) 181 { 182 if (!request.isParsed()) 183 return; 184 cloneParsingCommons(request); 185 cloneTableNameAndColumns((AbstractWriteRequest) request); 186 isParsed = true; 187 } 188 189 200 private ArrayList getFromTables(String fromClause, DatabaseSchema dbs) 201 throws SQLException 202 { 203 StringTokenizer tables = new StringTokenizer (fromClause, ","); 204 ArrayList result = new ArrayList (tables.countTokens()); 205 while (tables.hasMoreTokens()) 206 { 207 String dropTableName = tables.nextToken().trim(); 208 String alias = null; 211 int aliasIdx = dropTableName.indexOf(' '); 212 if (aliasIdx != -1) 213 { 214 alias = dropTableName.substring(aliasIdx); 215 dropTableName = dropTableName.substring(0, aliasIdx); 216 } 217 218 DatabaseTable table = dbs.getTable(dropTableName); 219 if (table == null) 220 throw new SQLException ("Unknown table '" + dropTableName 221 + "' in FROM clause of this DELETE statement: '" 222 + sqlQueryOrTemplate + "'"); 223 result.add(new AliasedDatabaseTable(table, alias)); 224 } 225 226 return result; 227 } 228 229 242 private ArrayList getWhereColumns(String whereClause, ArrayList aliasedFrom) 243 { 244 ArrayList result = new ArrayList (); ArrayList dbColumns = new ArrayList (); 247 DatabaseColumn col; 250 for (int i = 0; i < aliasedFrom.size(); i++) 251 { 252 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)).getTable(); 253 ArrayList cols = t.getColumns(); 254 int size = cols.size(); 255 for (int j = 0; j < size; j++) 256 { 257 col = (DatabaseColumn) cols.get(j); 258 int matchIdx = whereClause.indexOf(col.getName()); 261 while (matchIdx > 0) 262 { 263 char beforePattern = whereClause.charAt(matchIdx - 1); 265 if (((beforePattern >= 'a') && (beforePattern <= 'z')) || (beforePattern == '_')) 268 matchIdx = whereClause.indexOf(col.getName(), matchIdx + 1); 269 else 270 break; 271 } 272 if (matchIdx == -1) 273 continue; 274 result.add(new TableColumn(t.getName(), col.getName())); 275 if (col.isUnique()) 276 pkValue = col.getName(); 277 dbColumns.add(col); 278 } 279 } 280 281 return result; 282 } 283 284 291 public ArrayList getValues() 292 { 293 return whereValues; 294 } 295 296 301 public boolean isUnique() 302 { 303 return isUnique; 304 } 305 306 309 public boolean needsMacroProcessing() 310 { 311 return true; 312 } 313 314 329 public void parse(DatabaseSchema schema, int granularity, 330 boolean isCaseSensitive) throws SQLException 331 { 332 if (granularity == ParsingGranularities.NO_PARSING) 333 { 334 isParsed = true; 335 return; 336 } 337 338 try 339 { 340 String originalSQL = this.trimCarriageReturnAndTabs(); 341 String sql = originalSQL.toLowerCase(); 342 343 int fromIdx = sql.indexOf("from "); 344 if (fromIdx == -1) 345 { 346 fromIdx = 6; } 349 else 350 { 351 String tableBetweenDeleteAndFrom; 357 if (isCaseSensitive) 358 tableBetweenDeleteAndFrom = originalSQL.substring(6, fromIdx).trim(); 359 else 360 tableBetweenDeleteAndFrom = sql.substring(6, fromIdx).trim(); 361 if (tableBetweenDeleteAndFrom.length() == 0) 362 tableName = null; 363 else 364 tableName = tableBetweenDeleteAndFrom; 365 fromIdx += 5; } 367 368 sql = sql.substring(fromIdx).trim(); 369 370 int whereIdx = sql.indexOf("where "); 372 373 if (isCaseSensitive) 374 sql = originalSQL.substring(originalSQL.length() - sql.length()); 375 if (tableName == null) 376 { if (whereIdx == -1) 378 tableName = sql; 379 else 380 tableName = sql.substring(0, whereIdx).trim(); 381 } 382 383 if (schema == null) 384 { 385 writeLockedTables = new TreeSet (); 386 writeLockedTables.add(tableName); 387 isParsed = true; 388 return; 389 } 390 391 DatabaseTable t = schema.getTable(tableName, isCaseSensitive); 393 if (t == null) 394 throw new SQLException ("Unknown table '" + tableName 395 + "' in this DELETE statement: " + sqlQueryOrTemplate + "'"); 396 else 397 tableName = t.getName(); 399 400 writeLockedTables = new TreeSet (); 401 writeLockedTables.add(tableName); 402 addDependingTables(schema, writeLockedTables); 403 404 try 405 { 406 switch (granularity) 407 { 408 case ParsingGranularities.NO_PARSING : 409 return; 410 case ParsingGranularities.TABLE : 411 break; 412 case ParsingGranularities.COLUMN : 413 from = getFromTables(tableName, schema); 414 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from); 415 416 if (from != null) 417 { 418 int size = from.size(); 421 ArrayList unaliased = new ArrayList (size); 422 for (int i = 0; i < size; i++) 423 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable() 424 .getName()); 425 from = unaliased; 426 } 427 break; 428 case ParsingGranularities.COLUMN_UNIQUE : 429 from = getFromTables(tableName, schema); 430 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from); 431 432 if (from != null) 433 { 434 int size = from.size(); 437 ArrayList unaliased = new ArrayList (size); 438 for (int i = 0; i < size; i++) 439 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable() 440 .getName()); 441 from = unaliased; 442 } 443 break; 444 default : 445 throw new SQLException ("Unsupported parsing granularity: '" 446 + granularity + "'"); 447 } 448 } 449 catch (SQLException e) 450 { 451 from = null; 452 columns = null; 453 whereValues = null; 454 throw e; 455 } 456 457 isParsed = true; 458 } 459 finally 460 { 461 if (isParsed) 462 { 463 SortedSet readSet = null; 464 if (from != null) 465 readSet = new TreeSet (from); 466 setSemantic(new SemanticBehavior(readSet, writeLockedTables, null, 467 altersDatabaseSchema(), altersMetadataCache(), 468 altersQueryResultCache(), altersUsers(), isReadOnly, 469 needsMacroProcessing(), SemanticBehavior.SERIALIZABLE_ORDER, 470 requiresConnectionPoolFlush 471 ? SemanticBehavior.FLUSH_ALL_USERS 472 : SemanticBehavior.FLUSH_NONE)); 473 } 474 } 475 } 476 477 482 public boolean returnsResultSet() 483 { 484 return false; 485 } 486 487 490 public void debug() 491 { 492 super.debug(); 493 System.out.println("Is unique: " + isUnique); 494 if (tableName != null) 495 System.out.println("Deleted table: " + tableName); 496 else 497 System.out.println("No information about deleted table"); 498 499 if (columns != null) 500 { 501 System.out.println("Columns columns:"); 502 for (int i = 0; i < columns.size(); i++) 503 System.out.println(" " 504 + ((TableColumn) columns.get(i)).getColumnName()); 505 } 506 else 507 System.out.println("No information about updated columns"); 508 509 System.out.println(); 510 } 511 512 515 public String getParsingResultsAsString() 516 { 517 StringBuffer sb = new StringBuffer (super.getParsingResultsAsString()); 518 sb.append(Translate.get("request.delete.single.row", isUnique)); 519 if (from != null && from.size() > 0) 520 { 521 sb.append(Translate.get("request.from.tables")); 522 for (int i = 0; i < from.size(); i++) 523 { 524 sb.append(Translate.get("request.from.table", from.get(i))); 525 } 526 } 527 if (whereValues != null && whereValues.size() > 0) 528 { 529 sb.append(Translate.get("request.where.tables")); 530 for (int i = 0; i < whereValues.size(); i++) 531 { 532 sb.append(Translate.get("request.where.table", whereValues.get(i))); 533 } 534 } 535 return sb.toString(); 536 } 537 } | Popular Tags |