src/org/objectweb/cjdbc/common/sql/DeleteRequest.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.common.sql; 00026 00027 import java.io.Serializable; 00028 import java.sql.SQLException; 00029 import java.util.ArrayList; 00030 import java.util.StringTokenizer; 00031 00032 import org.objectweb.cjdbc.common.sql.schema.AliasedDatabaseTable; 00033 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn; 00034 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 00035 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 00036 import org.objectweb.cjdbc.common.sql.schema.TableColumn; 00037 00050 public class DeleteRequest extends AbstractWriteRequest implements Serializable 00051 { 00053 private transient boolean isUnique; 00054 00056 private transient ArrayList from; 00057 00071 protected ArrayList whereValues; 00072 00091 public DeleteRequest(String sqlQuery, boolean escapeProcessing, int timeout, 00092 String lineSeparator, DatabaseSchema schema, int granularity, 00093 boolean isCaseSensitive) throws SQLException 00094 { 00095 this(sqlQuery, escapeProcessing, timeout, lineSeparator); 00096 parse(schema, granularity, isCaseSensitive); 00097 } 00098 00114 public DeleteRequest(String sqlQuery, boolean escapeProcessing, int timeout, 00115 String lineSeparator) 00116 { 00117 super(sqlQuery, escapeProcessing, timeout, lineSeparator); 00118 cacheable = RequestType.UNCACHEABLE; 00119 isParsed = false; 00120 isUnique = false; 00121 } 00122 00138 public void parse(DatabaseSchema schema, int granularity, 00139 boolean isCaseSensitive) throws SQLException 00140 { 00141 if (granularity == ParsingGranularities.NO_PARSING) 00142 { 00143 isParsed = true; 00144 return; 00145 } 00146 00147 // Sanity check 00148 if (schema == null) 00149 throw new SQLException( 00150 "Unable to parse request with an undefined database schema"); 00151 00152 String originalSQL = this.trimCarriageReturn(); 00153 String sql = originalSQL.toLowerCase(); 00154 00155 int fromIdx = sql.indexOf("from "); 00156 if (fromIdx == -1) 00157 { 00158 // For queries like: DELETE t WHERE ... used by Oracle 00159 fromIdx = 6; // 6 = "delete".length() 00160 } 00161 else 00162 { 00163 fromIdx += 5; // 5 = "from".length() 00164 } 00165 00166 // Syntax is usually DELETE FROM t WHERE ... but it can be 00167 // DELETE t1,t2,... FROM t1,t2,.... WHERE ... 00168 // Let's ignore everything between DELETE and FROM, and suppose that we 00169 // delete from all tables (will just have a wider invalidation impact on the 00170 // cache). 00171 sql = sql.substring(fromIdx).trim(); 00172 00173 // Look for the WHERE clause 00174 int whereIdx = sql.indexOf("where "); 00175 00176 if (isCaseSensitive) 00177 sql = originalSQL.substring(originalSQL.length() - sql.length()); 00178 if (whereIdx == -1) 00179 tableName = sql; 00180 else 00181 tableName = sql.substring(0, whereIdx).trim(); 00182 00183 // Get the table on which DELETE occurs 00184 DatabaseTable t = schema.getTable(tableName, isCaseSensitive); 00185 if (t == null) 00186 throw new SQLException("Unknown table '" + tableName 00187 + "' in this DELETE statement: " + sqlQuery + "'"); 00188 00189 try 00190 { 00191 switch (granularity) 00192 { 00193 case ParsingGranularities.NO_PARSING : 00194 return; 00195 case ParsingGranularities.TABLE : 00196 break; 00197 case ParsingGranularities.COLUMN : 00198 from = getFromTables(tableName, schema); 00199 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from); 00200 00201 if (from != null) 00202 { 00203 // Convert 'from' to an ArrayList of String objects instead of 00204 // AliasedTables objects 00205 int size = from.size(); 00206 ArrayList unaliased = new ArrayList(size); 00207 for (int i = 0; i < size; i++) 00208 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable() 00209 .getName()); 00210 from = unaliased; 00211 } 00212 break; 00213 case ParsingGranularities.COLUMN_UNIQUE : 00214 from = getFromTables(tableName, schema); 00215 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from); 00216 00217 if (from != null) 00218 { 00219 // Convert 'from' to an ArrayList of String objects instead of 00220 // AliasedTables objects 00221 int size = from.size(); 00222 ArrayList unaliased = new ArrayList(size); 00223 for (int i = 0; i < size; i++) 00224 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable() 00225 .getName()); 00226 from = unaliased; 00227 } 00228 break; 00229 default : 00230 throw new SQLException("Unsupported parsing granularity: '" 00231 + granularity + "'"); 00232 } 00233 } 00234 catch (SQLException e) 00235 { 00236 from = null; 00237 columns = null; 00238 whereValues = null; 00239 throw e; 00240 } 00241 00242 isParsed = true; 00243 } 00244 00248 public void cloneParsing(AbstractRequest request) 00249 { 00250 if (!request.isParsed()) 00251 return; 00252 cloneTableNameAndColumns((AbstractWriteRequest) request); 00253 isParsed = true; 00254 } 00255 00267 private ArrayList getFromTables(String fromClause, DatabaseSchema dbs) 00268 throws SQLException 00269 { 00270 StringTokenizer tables = new StringTokenizer(fromClause, ","); 00271 ArrayList result = new ArrayList(tables.countTokens()); 00272 while (tables.hasMoreTokens()) 00273 { 00274 String tableName = tables.nextToken().trim(); 00275 // Check if the table has an alias 00276 // Example: SELECT x.price FROM item x 00277 String alias = null; 00278 int aliasIdx = tableName.indexOf(' '); 00279 if (aliasIdx != -1) 00280 { 00281 alias = tableName.substring(aliasIdx); 00282 tableName = tableName.substring(0, aliasIdx); 00283 } 00284 00285 DatabaseTable table = dbs.getTable(tableName); 00286 if (table == null) 00287 throw new SQLException("Unknown table '" + tableName 00288 + "' in FROM clause of this DELETE statement: '" + sqlQuery + "'"); 00289 result.add(new AliasedDatabaseTable(table, alias)); 00290 } 00291 00292 return result; 00293 } 00294 00308 private ArrayList getWhereColumns(String whereClause, ArrayList aliasedFrom) 00309 { 00310 ArrayList result = new ArrayList(); // TableColumn objects 00311 ArrayList dbColumns = new ArrayList(); // DatabaseColumn objects 00312 00313 // Instead of parsing the clause, we use a brutal force technique 00314 // and we try to directly identify every column name of each table. 00315 DatabaseColumn col; 00316 for (int i = 0; i < aliasedFrom.size(); i++) 00317 { 00318 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)).getTable(); 00319 ArrayList cols = t.getColumns(); 00320 int size = cols.size(); 00321 for (int j = 0; j < size; j++) 00322 { 00323 col = (DatabaseColumn) cols.get(j); 00324 // if pattern found and column not already in result, it's a dependency 00325 // ! 00326 int matchIdx = whereClause.indexOf(col.getName()); 00327 while (matchIdx > 0) 00328 { 00329 // Try to check that we got the full pattern and not a sub-pattern 00330 char beforePattern = whereClause.charAt(matchIdx - 1); 00331 // Everything should be lowercase here 00332 if (((beforePattern >= 'a') && (beforePattern <= 'z')) // Everything 00333 || (beforePattern == '_')) 00334 matchIdx = whereClause.indexOf(col.getName(), matchIdx + 1); 00335 else 00336 break; 00337 } 00338 if (matchIdx == -1) 00339 continue; 00340 result.add(new TableColumn(t.getName(), col.getName())); 00341 if (col.isUnique()) 00342 pkValue = col.getName(); 00343 dbColumns.add(col); 00344 } 00345 } 00346 00347 return result; 00348 } 00349 00357 public ArrayList getValues() 00358 { 00359 return whereValues; 00360 } 00361 00367 public boolean isUnique() 00368 { 00369 return isUnique; 00370 } 00371 00376 public boolean isInsert() 00377 { 00378 return false; 00379 } 00380 00385 public boolean isUpdate() 00386 { 00387 return false; 00388 } 00389 00394 public boolean isDelete() 00395 { 00396 return true; 00397 } 00398 00403 public boolean isCreate() 00404 { 00405 return false; 00406 } 00407 00412 public boolean isDrop() 00413 { 00414 return false; 00415 } 00416 00420 public void debug() 00421 { 00422 super.debug(); 00423 System.out.println("Is unique: " + isUnique); 00424 if (tableName != null) 00425 System.out.println("Deleted table: " + tableName); 00426 else 00427 System.out.println("No information about deleted table"); 00428 00429 if (columns != null) 00430 { 00431 System.out.println("Columns columns:"); 00432 for (int i = 0; i < columns.size(); i++) 00433 System.out.println(" " 00434 + ((TableColumn) columns.get(i)).getColumnName()); 00435 } 00436 else 00437 System.out.println("No information about updated columns"); 00438 00439 System.out.println(); 00440 } 00441 00445 public boolean isAlter() 00446 { 00447 return false; 00448 } 00449 }

CJDBCversion1.0.4に対してTue Oct 12 15:15:57 2004に生成されました。 doxygen 1.3.8