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
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
00159 fromIdx = 6;
00160 }
00161
else
00162 {
00163 fromIdx += 5;
00164 }
00165
00166
00167
00168
00169
00170
00171 sql = sql.substring(fromIdx).trim();
00172
00173
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
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
00204
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
00220
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
00276
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();
00311 ArrayList dbColumns =
new ArrayList();
00312
00313
00314
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
00325
00326
int matchIdx = whereClause.indexOf(col.
getName());
00327
while (matchIdx > 0)
00328 {
00329
00330
char beforePattern = whereClause.charAt(matchIdx - 1);
00331
00332
if (((beforePattern >=
'a') && (beforePattern <=
'z'))
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 }