1 24 25 package org.objectweb.cjdbc.common.sql; 26 27 import java.io.IOException ; 28 import java.io.Serializable ; 29 import java.sql.SQLException ; 30 import java.util.ArrayList ; 31 import java.util.HashMap ; 32 import java.util.StringTokenizer ; 33 34 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn; 35 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema; 36 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable; 37 import org.objectweb.cjdbc.common.sql.schema.TableColumn; 38 import org.objectweb.cjdbc.common.stream.CJDBCInputStream; 39 40 51 public class UpdateRequest extends AbstractWriteRequest implements Serializable 52 { 53 private static final long serialVersionUID = 1943340529813559587L; 54 55 56 private transient boolean isUnique; 57 58 private transient HashMap updatedValues = null; 59 60 78 public UpdateRequest(String sqlQuery, boolean escapeProcessing, int timeout, 79 String lineSeparator, DatabaseSchema schema, int granularity, 80 boolean isCaseSensitive) throws SQLException 81 { 82 this(sqlQuery, escapeProcessing, timeout, lineSeparator); 83 parse(schema, granularity, isCaseSensitive); 84 } 85 86 101 public UpdateRequest(String sqlQuery, boolean escapeProcessing, int timeout, 102 String lineSeparator) 103 { 104 super(sqlQuery, escapeProcessing, timeout, lineSeparator, 105 RequestType.UPDATE); 106 } 107 108 111 public UpdateRequest(CJDBCInputStream in) throws IOException 112 { 113 super(in, RequestType.UPDATE); 114 } 115 116 133 public void parse(DatabaseSchema schema, int granularity, 134 boolean isCaseSensitive) throws SQLException 135 { 136 if (granularity == ParsingGranularities.NO_PARSING) 137 { 138 isParsed = true; 139 return; 140 } 141 142 if (schema == null) 144 throw new SQLException ( 145 "Unable to parse request with an undefined database schema"); 146 147 String whereClause = null; 148 isUnique = true; 149 150 String originalSQL = this.trimCarriageReturnAndTabs(); 151 String sql = originalSQL.toLowerCase(); 152 153 sql = sql.substring(7).trim(); 155 156 int setIdx = sql.indexOf("set "); 158 int whereIdx = sql.indexOf("where "); 159 if (setIdx == -1) 160 throw new SQLException ( 161 "Unable to find the SET keyword in this UPDATE statement: '" 162 + sqlQuery + "'"); 163 164 if (isCaseSensitive) 165 sql = originalSQL.substring(7).trim(); 166 167 if (whereIdx == -1) 168 { 169 whereIdx = sql.length(); 170 isUnique = false; 171 } 172 else 173 { 174 whereClause = sql.substring(whereIdx + 5); 175 sql = sql.substring(0, whereIdx + 1).trim(); 178 } 179 180 DatabaseTable t = schema.getTable(sql.substring(0, setIdx).trim(), 182 isCaseSensitive); 183 if (t == null) 184 throw new SQLException ("Unknown table '" + tableName 185 + "' in this UPDATE statement: '" + sqlQuery + "'"); 186 else 187 tableName = t.getName(); 189 190 if (granularity > ParsingGranularities.TABLE) 191 { 192 StringTokenizer columnTokens = new StringTokenizer (sql.substring( 195 setIdx + 4, whereIdx), ","); 196 columns = new ArrayList (); 198 DatabaseColumn col = null; 199 while (columnTokens.hasMoreTokens()) 200 { 201 String token = columnTokens.nextToken(); 202 int eq = token.indexOf("="); 203 if (eq == -1) 204 continue; 205 token = token.substring(0, eq).trim(); 206 col = t.getColumn(token, isCaseSensitive); 207 if (col == null) 208 { 209 tableName = null; 210 columns = null; 211 throw new SQLException ("Unknown column name '" + token 212 + "' in this UPDATE statement: '" + sqlQuery + "'"); 213 } 214 else 215 columns.add(new TableColumn(tableName, col.getName())); 216 } 217 } 218 219 isParsed = true; 220 if (!isUnique) 221 return; 222 else 223 isUnique = false; 224 225 if (granularity < ParsingGranularities.COLUMN_UNIQUE) 226 return; 227 228 updatedValues = new HashMap (columns.size()); 230 231 DatabaseColumn col = null; 235 ArrayList cols = t.getColumns(); 236 int size = cols.size(); 237 for (int j = 0; j < size; j++) 238 { 239 col = (DatabaseColumn) cols.get(j); 240 String colName = col.getName(); 241 int matchIdx = whereClause.indexOf(colName); 243 while (matchIdx > 0) 244 { 245 char beforePattern = whereClause.charAt(matchIdx - 1); 247 if (((beforePattern >= 'a') && (beforePattern <= 'z')) 248 || ((beforePattern >= 'A') && (beforePattern <= 'Z')) 249 || (beforePattern == '_')) 250 matchIdx = whereClause.indexOf(colName, matchIdx + 1); 251 else 252 { isUnique = col.isUnique(); 254 if (!isUnique) 255 return; 256 int eq = whereClause.indexOf("=", matchIdx); 259 if ((eq == -1) 260 || (whereClause.substring(matchIdx + colName.length(), eq).trim() 261 .length() > 0)) 262 { 263 isUnique = false; 264 return; 265 } 266 do 267 { 268 eq++; } 270 while (whereClause.charAt(eq) == ' '); 271 272 char startChar = whereClause.charAt(eq); 274 int end; 275 if ((startChar == '\'') || (startChar == '"')) 276 { 277 eq++; 278 do 279 { end = whereClause.indexOf(startChar, eq); 281 } 282 while (whereClause.charAt(end - 1) == '\\'); 283 } 284 else 285 { 286 end = whereClause.indexOf(",", eq); 288 if (end == -1) 289 end = whereClause.length(); 290 } 291 pkValue = whereClause.substring(eq, end); 292 293 matchIdx = whereClause.indexOf(colName, matchIdx + 1); 294 } 295 } 296 } 297 298 cacheable = RequestType.UNIQUE_CACHEABLE; 299 300 sql = originalSQL.substring(7).substring(0, whereIdx).trim(); 302 if (!isCaseSensitive) 303 sql.toLowerCase(); 304 int set = sql.toLowerCase().indexOf("set"); 305 sql = sql.substring(set + 3).trim(); 306 307 for (int j = 0; j < cols.size(); j++) 308 { 309 col = (DatabaseColumn) cols.get(j); 310 String colName = (isCaseSensitive) ? col.getName() : col.getName() 312 .toLowerCase(); 313 int matchIdx = sql.indexOf(colName); 314 315 while (matchIdx >= 0) 316 { 317 char afterPattern = sql.charAt(matchIdx + colName.length()); 318 if ((afterPattern != '=') && (afterPattern != ' ')) 319 { 320 matchIdx = sql.indexOf(colName, matchIdx + colName.length()); 321 continue; 322 } 323 324 char beforePattern = Character.CONTROL; 326 try 327 { 328 beforePattern = sql.charAt(matchIdx - 1); 329 } 330 catch (RuntimeException e) 331 { 332 } 334 if (((beforePattern >= 'a') && (beforePattern <= 'z')) || (beforePattern == '_')) 338 matchIdx = sql.indexOf(colName, matchIdx + 1); 339 else 340 { int eq = sql.indexOf("=", matchIdx); 342 do 343 { 344 eq++; } 346 while (sql.charAt(eq) == ' '); 347 348 char startChar = sql.charAt(eq); 350 int end; 351 if ((startChar == '\'') || (startChar == '"')) 352 { 353 eq++; 354 do 355 { end = sql.indexOf(startChar, eq); 357 } 358 while (sql.charAt(end - 1) == '\\'); 359 } 360 else 361 { 362 end = sql.indexOf(",", eq); 364 if (end == -1) 365 end = sql.length(); 366 } 367 updatedValues.put(col.getName(), sql.substring(eq, end).trim()); 368 break; 369 } 370 } 371 } 372 } 373 374 380 public HashMap getUpdatedValues() 381 { 382 return updatedValues; 383 } 384 385 388 public void cloneParsing(AbstractRequest request) 389 { 390 if (!request.isParsed()) 391 return; 392 cloneTableNameAndColumns((AbstractWriteRequest) request); 393 updatedValues = ((UpdateRequest) request).getUpdatedValues(); 394 isParsed = true; 395 } 396 397 403 public boolean isUnique() 404 { 405 return isUnique; 406 } 407 408 411 public boolean needsMacroProcessing() 412 { 413 return true; 414 } 415 416 419 public boolean returnsResultSet() 420 { 421 return false; 422 } 423 424 427 public void debug() 428 { 429 super.debug(); 430 if (tableName != null) 431 System.out.println("Updated table: " + tableName); 432 else 433 System.out.println("No information about updated table"); 434 435 if (columns != null) 436 { 437 System.out.println("Updated columns:"); 438 for (int i = 0; i < columns.size(); i++) 439 System.out.println(" " 440 + ((TableColumn) columns.get(i)).getColumnName()); 441 } 442 else 443 System.out.println("No information about updated columns"); 444 445 System.out.println("Unique update: " + isUnique); 446 447 System.out.println(""); 448 } 449 } | Popular Tags |