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.HashMap;
00031
import java.util.StringTokenizer;
00032
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
00049 public class UpdateRequest extends AbstractWriteRequest implements Serializable
00050 {
00052 private transient boolean isUnique;
00053
00054 private transient HashMap
updatedValues = null;
00055
00074 public UpdateRequest(String sqlQuery,
boolean escapeProcessing,
int timeout,
00075 String lineSeparator,
DatabaseSchema schema,
int granularity,
00076
boolean isCaseSensitive)
throws SQLException
00077 {
00078
this(sqlQuery, escapeProcessing, timeout, lineSeparator);
00079
parse(schema, granularity, isCaseSensitive);
00080 }
00081
00097 public UpdateRequest(String sqlQuery,
boolean escapeProcessing,
int timeout,
00098 String lineSeparator)
00099 {
00100 super(sqlQuery, escapeProcessing, timeout, lineSeparator);
00101 cacheable =
RequestType.UNCACHEABLE;
00102 isParsed =
false;
00103
isUnique =
false;
00104 }
00105
00123 public void parse(
DatabaseSchema schema,
int granularity,
00124
boolean isCaseSensitive)
throws SQLException
00125 {
00126
if (granularity ==
ParsingGranularities.NO_PARSING)
00127 {
00128 isParsed =
true;
00129
return;
00130 }
00131
00132
00133
if (schema == null)
00134
throw new SQLException(
00135
"Unable to parse request with an undefined database schema");
00136
00137 String whereClause = null;
00138
isUnique =
true;
00139
00140 String originalSQL =
this.trimCarriageReturn();
00141 String sql = originalSQL.toLowerCase();
00142
00143
00144 sql = sql.substring(7).trim();
00145
00146
00147
int setIdx = sql.indexOf(
"set ");
00148
int whereIdx = sql.indexOf(
"where ");
00149
if (setIdx == -1)
00150
throw new SQLException(
00151
"Unable to find the SET keyword in this UPDATE statement: '"
00152 + sqlQuery +
"'");
00153
00154
if (isCaseSensitive)
00155 sql = originalSQL.substring(7).trim();
00156
00157
if (whereIdx == -1)
00158 {
00159 whereIdx = sql.length();
00160
isUnique =
false;
00161 }
00162
else
00163 {
00164 whereClause = sql.substring(whereIdx + 5);
00165
00166
00167 sql = sql.substring(0, whereIdx + 1).trim();
00168 }
00169
00170
00171
DatabaseTable t = schema.getTable(sql.substring(0, setIdx).trim(),
00172 isCaseSensitive);
00173
if (t == null)
00174
throw new SQLException(
"Unknown table '" + tableName
00175 +
"' in this UPDATE statement: '" + sqlQuery +
"'");
00176
else
00177
00178 tableName = t.
getName();
00179
00180
if (granularity >
ParsingGranularities.TABLE)
00181 {
00182
00183
00184 StringTokenizer columnTokens =
new StringTokenizer(sql.substring(
00185 setIdx + 4, whereIdx),
",");
00186
00187 columns =
new ArrayList();
00188
DatabaseColumn col = null;
00189
while (columnTokens.hasMoreTokens())
00190 {
00191 String token = columnTokens.nextToken();
00192
int eq = token.indexOf(
"=");
00193
if (eq == -1)
00194
continue;
00195 token = token.substring(0, eq).trim();
00196 col = t.
getColumn(token, isCaseSensitive);
00197
if (col == null)
00198 {
00199 tableName = null;
00200 columns = null;
00201
throw new SQLException(
"Unknown column name '" + token
00202 +
"' in this UPDATE statement: '" + sqlQuery +
"'");
00203 }
00204
else
00205 columns.add(
new TableColumn(tableName, col.
getName()));
00206 }
00207 }
00208
00209 isParsed =
true;
00210
if (!
isUnique)
00211
return;
00212
else
00213
isUnique =
false;
00214
00215
if (granularity <
ParsingGranularities.COLUMN_UNIQUE)
00216
return;
00217
00218
00219
updatedValues =
new HashMap(columns.size());
00220
00221
00222
00223
00224
DatabaseColumn col = null;
00225 ArrayList cols = t.
getColumns();
00226
int size = cols.size();
00227
for (
int j = 0; j < size; j++)
00228 {
00229 col = (
DatabaseColumn) cols.get(j);
00230 String colName = col.
getName();
00231
00232
int matchIdx = whereClause.indexOf(colName);
00233
while (matchIdx > 0)
00234 {
00235
00236
char beforePattern = whereClause.charAt(matchIdx - 1);
00237
if (((beforePattern >=
'a') && (beforePattern <=
'z'))
00238 || ((beforePattern >=
'A') && (beforePattern <=
'Z'))
00239 || (beforePattern ==
'_'))
00240 matchIdx = whereClause.indexOf(colName, matchIdx + 1);
00241
else
00242 {
00243
isUnique = col.
isUnique();
00244
if (!
isUnique)
00245
return;
00246
00247
00248
int eq = whereClause.indexOf(
"=", matchIdx);
00249
if ((eq == -1)
00250 || (whereClause.substring(matchIdx + colName.length(), eq).trim()
00251 .length() > 0))
00252 {
00253
isUnique =
false;
00254
return;
00255 }
00256
do
00257 {
00258 eq++;
00259 }
00260
while (whereClause.charAt(eq) ==
' ');
00261
00262
00263
char startChar = whereClause.charAt(eq);
00264
int end;
00265
if ((startChar ==
'\'') || (startChar ==
'"'))
00266 {
00267 eq++;
00268
do
00269 {
00270 end = whereClause.indexOf(startChar, eq);
00271 }
00272
while (whereClause.charAt(end - 1) ==
'\\');
00273 }
00274
else
00275 {
00276
00277 end = whereClause.indexOf(
",", eq);
00278
if (end == -1)
00279 end = whereClause.length();
00280 }
00281 pkValue = whereClause.substring(eq, end);
00282
00283 matchIdx = whereClause.indexOf(colName, matchIdx + 1);
00284 }
00285 }
00286 }
00287
00288 cacheable =
RequestType.UNIQUE_CACHEABLE;
00289
00290
00291 sql = originalSQL.substring(7).substring(0, whereIdx).trim();
00292
if(!isCaseSensitive)
00293 sql.toLowerCase();
00294
int set = sql.toLowerCase().indexOf(
"set");
00295 sql = sql.substring(set+3).trim();
00296
00297
for (
int j = 0; j < cols.size(); j++)
00298 {
00299 col = (
DatabaseColumn) cols.get(j);
00300
00301 String colName = (isCaseSensitive) ? col.
getName() : col.
getName().toLowerCase();
00302
int matchIdx = sql.indexOf(colName);
00303
00304
while (matchIdx >= 0)
00305 {
00306
char afterPattern = sql.charAt(matchIdx + colName.length());
00307
if ((afterPattern !=
'=') && (afterPattern !=
' '))
00308 {
00309 matchIdx = sql.indexOf(colName, matchIdx + colName.length());
00310
continue;
00311 }
00312
00313
00314
char beforePattern = Character.CONTROL;
00315
try
00316 {
00317 beforePattern = sql.charAt(matchIdx - 1);
00318 }
00319
catch (RuntimeException e)
00320 {
00321
00322 }
00323
if (((beforePattern >=
'a') && (beforePattern <=
'z'))
00324
00325
00326 || (beforePattern ==
'_'))
00327 matchIdx = sql.indexOf(colName, matchIdx + 1);
00328
else
00329 {
00330
int eq = sql.indexOf(
"=", matchIdx);
00331
do
00332 {
00333 eq++;
00334 }
00335
while (sql.charAt(eq) ==
' ');
00336
00337
00338
char startChar = sql.charAt(eq);
00339
int end;
00340
if ((startChar ==
'\'') || (startChar ==
'"'))
00341 {
00342 eq++;
00343
do
00344 {
00345 end = sql.indexOf(startChar, eq);
00346 }
00347
while (sql.charAt(end - 1) ==
'\\');
00348 }
00349
else
00350 {
00351
00352 end = sql.indexOf(
",", eq);
00353
if (end == -1)
00354 end = sql.length();
00355 }
00356
updatedValues.put(col.
getName(), sql.substring(eq, end).trim());
00357
break;
00358 }
00359 }
00360 }
00361 }
00362
00369 public HashMap
getUpdatedValues()
00370 {
00371
return updatedValues;
00372 }
00373
00377 public void cloneParsing(
AbstractRequest request)
00378 {
00379
if (!request.
isParsed())
00380
return;
00381
cloneTableNameAndColumns((
AbstractWriteRequest) request);
00382
updatedValues = ((
UpdateRequest) request).getUpdatedValues();
00383 isParsed =
true;
00384 }
00385
00390 public boolean isInsert()
00391 {
00392
return false;
00393 }
00394
00399 public boolean isUpdate()
00400 {
00401
return true;
00402 }
00403
00408 public boolean isDelete()
00409 {
00410
return false;
00411 }
00412
00417 public boolean isCreate()
00418 {
00419
return false;
00420 }
00421
00426 public boolean isDrop()
00427 {
00428
return false;
00429 }
00430
00437 public boolean isUnique()
00438 {
00439
return isUnique;
00440 }
00441
00445 public void debug()
00446 {
00447 super.debug();
00448
if (tableName != null)
00449 System.out.println(
"Updated table: " + tableName);
00450
else
00451 System.out.println(
"No information about updated table");
00452
00453
if (columns != null)
00454 {
00455 System.out.println(
"Updated columns:");
00456
for (
int i = 0; i < columns.size(); i++)
00457 System.out.println(
" "
00458 + ((
TableColumn) columns.get(i)).getColumnName());
00459 }
00460
else
00461 System.out.println(
"No information about updated columns");
00462
00463 System.out.println(
"Unique update: " +
isUnique);
00464
00465 System.out.println(
"");
00466 }
00470 public boolean isAlter()
00471 {
00472
return false;
00473 }
00474 }