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.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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 public class UpdateRequest extends AbstractWriteRequest implements Serializable
00050 {
00051
00052 private transient boolean isUnique;
00053
00054 private transient HashMap updatedValues = null;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
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
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
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
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
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
00363
00364
00365
00366
00367
00368
00369 public HashMap getUpdatedValues()
00370 {
00371 return updatedValues;
00372 }
00373
00374
00375
00376
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
00386
00387
00388
00389
00390 public boolean isInsert()
00391 {
00392 return false;
00393 }
00394
00395
00396
00397
00398
00399 public boolean isUpdate()
00400 {
00401 return true;
00402 }
00403
00404
00405
00406
00407
00408 public boolean isDelete()
00409 {
00410 return false;
00411 }
00412
00413
00414
00415
00416
00417 public boolean isCreate()
00418 {
00419 return false;
00420 }
00421
00422
00423
00424
00425
00426 public boolean isDrop()
00427 {
00428 return false;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437 public boolean isUnique()
00438 {
00439 return isUnique;
00440 }
00441
00442
00443
00444
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 }
00467
00468
00469
00470 public boolean isAlter()
00471 {
00472 return false;
00473 }
00474 }