00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 public class DeleteRequest extends AbstractWriteRequest implements Serializable
00055 {
00056
00057 private transient boolean isUnique;
00058
00059
00060 private transient ArrayList from;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 protected ArrayList whereValues;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 public DeleteRequest(String sqlQuery, boolean escapeProcessing, int timeout,
00096 String lineSeparator, DatabaseSchema schema, int granularity,
00097 boolean isCaseSensitive) throws SQLException
00098 {
00099 this(sqlQuery, escapeProcessing, timeout, lineSeparator);
00100 parse(schema, granularity, isCaseSensitive);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 public DeleteRequest(String sqlQuery, boolean escapeProcessing, int timeout,
00119 String lineSeparator)
00120 {
00121 super(sqlQuery, escapeProcessing, timeout, lineSeparator);
00122 cacheable = RequestType.UNCACHEABLE;
00123 isParsed = false;
00124 isUnique = false;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 public void parse(DatabaseSchema schema, int granularity,
00143 boolean isCaseSensitive) throws SQLException
00144 {
00145 if (granularity == ParsingGranularities.NO_PARSING)
00146 {
00147 isParsed = true;
00148 return;
00149 }
00150
00151
00152 if (schema == null)
00153 throw new SQLException(
00154 "Unable to parse request with an undefined database schema");
00155
00156 String originalSQL = this.trimCarriageReturn();
00157 String sql = originalSQL.toLowerCase();
00158
00159 int fromIdx = sql.indexOf("from ");
00160 if (fromIdx == -1)
00161 {
00162
00163 fromIdx = 6;
00164 }
00165 else
00166 {
00167
00168
00169
00170
00171 String tableBetweenDeleteAndFrom;
00172 if (isCaseSensitive)
00173 tableBetweenDeleteAndFrom = originalSQL.substring(6, fromIdx).trim();
00174 else
00175 tableBetweenDeleteAndFrom = sql.substring(6, fromIdx).trim();
00176 if (tableBetweenDeleteAndFrom.length() == 0)
00177 tableName = null;
00178 else
00179 tableName = tableBetweenDeleteAndFrom;
00180 fromIdx += 5;
00181 }
00182
00183 sql = sql.substring(fromIdx).trim();
00184
00185
00186 int whereIdx = sql.indexOf("where ");
00187
00188 if (isCaseSensitive)
00189 sql = originalSQL.substring(originalSQL.length() - sql.length());
00190 if (tableName == null)
00191 {
00192 if (whereIdx == -1)
00193 tableName = sql;
00194 else
00195 tableName = sql.substring(0, whereIdx).trim();
00196 }
00197
00198
00199 DatabaseTable t = schema.getTable(tableName, isCaseSensitive);
00200 if (t == null)
00201 throw new SQLException("Unknown table '" + tableName
00202 + "' in this DELETE statement: " + sqlQuery + "'");
00203
00204 try
00205 {
00206 switch (granularity)
00207 {
00208 case ParsingGranularities.NO_PARSING :
00209 return;
00210 case ParsingGranularities.TABLE :
00211 break;
00212 case ParsingGranularities.COLUMN :
00213 from = getFromTables(tableName, schema);
00214 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from);
00215
00216 if (from != null)
00217 {
00218
00219
00220 int size = from.size();
00221 ArrayList unaliased = new ArrayList(size);
00222 for (int i = 0; i < size; i++)
00223 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable()
00224 .getName());
00225 from = unaliased;
00226 }
00227 break;
00228 case ParsingGranularities.COLUMN_UNIQUE :
00229 from = getFromTables(tableName, schema);
00230 columns = getWhereColumns(sql.substring(whereIdx + 6).trim(), from);
00231
00232 if (from != null)
00233 {
00234
00235
00236 int size = from.size();
00237 ArrayList unaliased = new ArrayList(size);
00238 for (int i = 0; i < size; i++)
00239 unaliased.add(((AliasedDatabaseTable) from.get(i)).getTable()
00240 .getName());
00241 from = unaliased;
00242 }
00243 break;
00244 default :
00245 throw new SQLException("Unsupported parsing granularity: '"
00246 + granularity + "'");
00247 }
00248 }
00249 catch (SQLException e)
00250 {
00251 from = null;
00252 columns = null;
00253 whereValues = null;
00254 throw e;
00255 }
00256
00257 isParsed = true;
00258 }
00259
00260
00261
00262
00263 public void cloneParsing(AbstractRequest request)
00264 {
00265 if (!request.isParsed())
00266 return;
00267 cloneTableNameAndColumns((AbstractWriteRequest) request);
00268 isParsed = true;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 private ArrayList getFromTables(String fromClause, DatabaseSchema dbs)
00283 throws SQLException
00284 {
00285 StringTokenizer tables = new StringTokenizer(fromClause, ",");
00286 ArrayList result = new ArrayList(tables.countTokens());
00287 while (tables.hasMoreTokens())
00288 {
00289 String tableName = tables.nextToken().trim();
00290
00291
00292 String alias = null;
00293 int aliasIdx = tableName.indexOf(' ');
00294 if (aliasIdx != -1)
00295 {
00296 alias = tableName.substring(aliasIdx);
00297 tableName = tableName.substring(0, aliasIdx);
00298 }
00299
00300 DatabaseTable table = dbs.getTable(tableName);
00301 if (table == null)
00302 throw new SQLException("Unknown table '" + tableName
00303 + "' in FROM clause of this DELETE statement: '" + sqlQuery + "'");
00304 result.add(new AliasedDatabaseTable(table, alias));
00305 }
00306
00307 return result;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 private ArrayList getWhereColumns(String whereClause, ArrayList aliasedFrom)
00324 {
00325 ArrayList result = new ArrayList();
00326 ArrayList dbColumns = new ArrayList();
00327
00328
00329
00330 DatabaseColumn col;
00331 for (int i = 0; i < aliasedFrom.size(); i++)
00332 {
00333 DatabaseTable t = ((AliasedDatabaseTable) aliasedFrom.get(i)).getTable();
00334 ArrayList cols = t.getColumns();
00335 int size = cols.size();
00336 for (int j = 0; j < size; j++)
00337 {
00338 col = (DatabaseColumn) cols.get(j);
00339
00340
00341 int matchIdx = whereClause.indexOf(col.getName());
00342 while (matchIdx > 0)
00343 {
00344
00345 char beforePattern = whereClause.charAt(matchIdx - 1);
00346
00347 if (((beforePattern >= 'a') && (beforePattern <= 'z'))
00348 || (beforePattern == '_'))
00349 matchIdx = whereClause.indexOf(col.getName(), matchIdx + 1);
00350 else
00351 break;
00352 }
00353 if (matchIdx == -1)
00354 continue;
00355 result.add(new TableColumn(t.getName(), col.getName()));
00356 if (col.isUnique())
00357 pkValue = col.getName();
00358 dbColumns.add(col);
00359 }
00360 }
00361
00362 return result;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372 public ArrayList getValues()
00373 {
00374 return whereValues;
00375 }
00376
00377
00378
00379
00380
00381
00382 public boolean isUnique()
00383 {
00384 return isUnique;
00385 }
00386
00387
00388
00389
00390
00391 public boolean isInsert()
00392 {
00393 return false;
00394 }
00395
00396
00397
00398
00399
00400 public boolean isUpdate()
00401 {
00402 return false;
00403 }
00404
00405
00406
00407
00408
00409 public boolean isDelete()
00410 {
00411 return true;
00412 }
00413
00414
00415
00416
00417
00418 public boolean isCreate()
00419 {
00420 return false;
00421 }
00422
00423
00424
00425
00426
00427 public boolean isDrop()
00428 {
00429 return false;
00430 }
00431
00432
00433
00434
00435 public void debug()
00436 {
00437 super.debug();
00438 System.out.println("Is unique: " + isUnique);
00439 if (tableName != null)
00440 System.out.println("Deleted table: " + tableName);
00441 else
00442 System.out.println("No information about deleted table");
00443
00444 if (columns != null)
00445 {
00446 System.out.println("Columns columns:");
00447 for (int i = 0; i < columns.size(); i++)
00448 System.out.println(" "
00449 + ((TableColumn) columns.get(i)).getColumnName());
00450 }
00451 else
00452 System.out.println("No information about updated columns");
00453
00454 System.out.println();
00455 }
00456
00457
00458
00459
00460 public boolean isAlter()
00461 {
00462 return false;
00463 }
00464 }