1 23 24 package org.continuent.sequoia.controller.requests; 25 26 import java.io.Serializable ; 27 import java.sql.SQLException ; 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.SortedSet ; 31 import java.util.StringTokenizer ; 32 import java.util.TreeSet ; 33 import java.util.regex.Matcher ; 34 import java.util.regex.Pattern ; 35 36 import org.continuent.sequoia.common.i18n.Translate; 37 import org.continuent.sequoia.controller.semantic.SemanticBehavior; 38 import org.continuent.sequoia.controller.sql.schema.DatabaseColumn; 39 import org.continuent.sequoia.controller.sql.schema.DatabaseSchema; 40 import org.continuent.sequoia.controller.sql.schema.DatabaseTable; 41 import org.continuent.sequoia.controller.sql.schema.TableColumn; 42 43 57 public class CreateRequest extends AbstractWriteRequest implements Serializable 58 { 59 private static final long serialVersionUID = -8810498358284503952L; 60 61 62 protected transient DatabaseTable table = null; 63 64 68 protected transient Collection fromTables = null; 69 70 protected boolean altersDatabaseCatalog = true; 73 protected boolean altersDatabaseSchema = true; 74 protected boolean altersSomething = true; 75 protected boolean altersStoredProcedureList = true; 76 protected boolean altersUserDefinedTypes = true; 77 protected boolean altersUsers = true; 78 79 protected boolean altersAggregateList = false; 80 protected boolean altersMetadataCache = false; 81 protected boolean altersQueryResultCache = false; 82 83 98 public CreateRequest(String sqlQuery, boolean escapeProcessing, int timeout, 99 String lineSeparator) 100 { 101 super(sqlQuery, escapeProcessing, timeout, lineSeparator, 102 RequestType.CREATE); 103 setMacrosAreProcessed(true); } 105 106 109 public boolean altersAggregateList() 110 { 111 return altersAggregateList; 112 } 113 114 117 public boolean altersDatabaseCatalog() 118 { 119 return altersDatabaseCatalog; 120 } 121 122 130 public boolean altersDatabaseSchema() 131 { 132 return altersDatabaseSchema; 133 } 134 135 138 public boolean altersMetadataCache() 139 { 140 return altersMetadataCache; 141 } 142 143 146 public boolean altersQueryResultCache() 147 { 148 return altersQueryResultCache; 149 } 150 151 154 public boolean altersSomething() 155 { 156 return altersSomething; 157 } 158 159 162 public boolean altersStoredProcedureList() 163 { 164 return altersStoredProcedureList; 165 } 166 167 170 public boolean altersUserDefinedTypes() 171 { 172 return altersUserDefinedTypes; 173 } 174 175 178 public boolean altersUsers() 179 { 180 return altersUsers; 181 } 182 183 186 public void cloneParsing(AbstractRequest request) 187 { 188 if (!request.isParsed()) 189 return; 190 cloneParsingCommons(request); 191 CreateRequest createRequest = (CreateRequest) request; 192 cloneTableNameAndColumns(createRequest); 193 table = createRequest.getDatabaseTable(); 194 fromTables = createRequest.getFromTables(); 195 isParsed = true; 196 } 197 198 204 public DatabaseTable getDatabaseTable() 205 { 206 return table; 207 } 208 209 215 public Collection getFromTables() 216 { 217 return fromTables; 218 } 219 220 223 public boolean needsMacroProcessing() 224 { 225 return false; 226 } 227 228 232 private static final String CREATE_TABLE_SELECT_INTO = "^select.*into\\s+((temporary|temp)\\s+)?(table\\s+)?([^(\\s|\\()]+)(.*)?"; 233 private static final Pattern CREATE_TABLE_SELECT_INTO_STATEMENT_PATTERN = Pattern 234 .compile( 235 CREATE_TABLE_SELECT_INTO, 236 Pattern.CASE_INSENSITIVE 237 | Pattern.DOTALL); 238 239 243 public void parse(DatabaseSchema schema, int granularity, 244 boolean isCaseSensitive) throws SQLException 245 { 246 if (granularity == ParsingGranularities.NO_PARSING) 247 { 248 isParsed = true; 249 return; 250 } 251 252 try 253 { 254 String originalSQL = this.trimCarriageReturnAndTabs(); 255 String sql = originalSQL.toLowerCase(); 256 257 Matcher matcher = CREATE_TABLE_SELECT_INTO_STATEMENT_PATTERN.matcher(sql); 258 if (matcher.matches()) 259 { 260 table = new DatabaseTable(matcher.group(4)); 262 263 altersDatabaseCatalog = false; 264 altersDatabaseSchema = true; 265 altersStoredProcedureList = false; 266 altersUserDefinedTypes = false; 267 altersUsers = false; 268 isParsed = true; 269 return; 270 } 271 272 sql = sql.substring("create".length()).trim(); 274 275 if (sql.startsWith("database")) 277 { altersDatabaseCatalog = true; 279 altersDatabaseSchema = false; 280 altersStoredProcedureList = false; 281 altersUserDefinedTypes = false; 282 altersUsers = false; 283 return; 284 } 285 if (sql.startsWith("index") || sql.startsWith("unique") 286 || sql.startsWith("role") || sql.startsWith("sequence")) 287 { altersSomething = false; 292 return; 293 } 294 if (sql.startsWith("function") || sql.startsWith("method") 295 || sql.startsWith("procedure") || sql.startsWith("trigger") 296 || sql.startsWith("type")) 297 { altersDatabaseCatalog = false; 300 altersDatabaseSchema = false; 301 altersStoredProcedureList = true; 302 altersUserDefinedTypes = true; 303 altersUsers = false; 304 return; 305 } 306 307 altersDatabaseCatalog = false; 309 altersDatabaseSchema = true; 310 altersStoredProcedureList = false; 311 altersUserDefinedTypes = false; 312 altersUsers = false; 313 if (sql.startsWith("schema") || sql.startsWith("view")) 314 return; 316 317 int tableIdx = sql.indexOf("table"); 319 if (tableIdx < 0) 320 throw new SQLException ("Unsupported CREATE statement: '" 321 + sqlQueryOrTemplate + "'"); 322 323 328 sql = sql.substring(tableIdx + 5).trim(); 330 331 int selectIdx = sql.indexOf("select"); 333 if (selectIdx != -1 && sql.charAt(selectIdx + 6) != ' ') 334 selectIdx = -1; 335 336 if (isCaseSensitive) sql = originalSQL.substring(originalSQL.length() - sql.length()); 338 339 if (selectIdx != -1) 340 { 341 int nextSpaceIdx = sql.indexOf(" "); 343 tableName = sql.substring(0, nextSpaceIdx).trim(); 344 table = new DatabaseTable(tableName); 345 sql = sql.substring(selectIdx).trim(); 347 SelectRequest select = new SelectRequest(sql, false, 60, 348 getLineSeparator()); 349 select.parse(schema, granularity, isCaseSensitive); 350 fromTables = select.getFrom(); 351 if (granularity > ParsingGranularities.TABLE) 352 { columns = select.getSelect(); 354 int size = columns.size(); 355 for (int i = 0; i < size; i++) 356 { 357 TableColumn tc = (TableColumn) columns.get(i); 358 table.addColumn(new DatabaseColumn(tc.getColumnName(), false)); 359 } 360 } 361 } 362 else 363 { 364 int openParenthesisIdx = sql.indexOf("("); 367 int closeParenthesisIdx = sql.lastIndexOf(")"); 368 if ((openParenthesisIdx == -1) && (closeParenthesisIdx == -1)) 369 { 370 table = new DatabaseTable(sql.trim()); 372 if (granularity > ParsingGranularities.TABLE) 373 columns = new ArrayList (); 374 isParsed = true; 375 return; 376 } 377 else if ((openParenthesisIdx == -1) || (closeParenthesisIdx == -1) 378 || (openParenthesisIdx > closeParenthesisIdx)) 379 { 380 throw new SQLException ("Syntax error in this CREATE statement: '" 381 + sqlQueryOrTemplate + "'"); 382 } 383 else 384 { 385 tableName = sql.substring(0, openParenthesisIdx).trim(); 386 } 387 table = new DatabaseTable(tableName); 388 389 if (granularity > ParsingGranularities.TABLE) 391 { 392 columns = new ArrayList (); 393 sql = sql.substring(openParenthesisIdx + 1, closeParenthesisIdx) 394 .trim(); 395 StringTokenizer columnTokens = new StringTokenizer (sql, ","); 396 String word; 397 String lowercaseWord; 398 StringTokenizer wordTokens = null; 399 String token; 400 DatabaseColumn col = null; 401 402 while (columnTokens.hasMoreTokens()) 403 { 404 token = columnTokens.nextToken().trim(); 405 406 if ((token.indexOf("(") != -1) && (token.indexOf(")") == -1)) 410 { 411 if (columnTokens.hasMoreTokens()) 412 token = token + "," + columnTokens.nextToken().trim(); 413 else 414 { 415 tableName = null; 416 columns = null; 417 throw new SQLException ( 418 "Syntax error in this CREATE statement: '" 419 + sqlQueryOrTemplate + "'"); 420 } 421 } 422 423 wordTokens = new StringTokenizer (token, " "); 426 word = wordTokens.nextToken().trim(); 427 lowercaseWord = word.toLowerCase(); 428 429 if (!lowercaseWord.equals("constraint") 432 && !lowercaseWord.equals("index") 433 && !lowercaseWord.equals("check")) 434 { 435 String columnName; 436 boolean isUnique = false; 437 if (lowercaseWord.equals("primary") 439 || lowercaseWord.startsWith("unique")) 440 { 441 442 openParenthesisIdx = token.indexOf("("); 444 closeParenthesisIdx = token.indexOf(")"); 445 if ((openParenthesisIdx == -1) || (closeParenthesisIdx == -1) 446 || (openParenthesisIdx > closeParenthesisIdx)) 447 { 448 tableName = null; 449 columns = null; 450 throw new SQLException ( 451 "Syntax error in this CREATE statement: '" 452 + sqlQueryOrTemplate + "'"); 453 } 454 455 columnName = token.substring(openParenthesisIdx + 1, 456 closeParenthesisIdx).trim(); 457 458 int comma; 459 while ((comma = columnName.indexOf(',')) != -1) 460 { 461 String col1 = columnName.substring(0, comma).trim(); 462 col = table.getColumn(col1); 463 if (col == null) 464 { 465 tableName = null; 466 columns = null; 467 throw new SQLException ( 468 "Syntax error in this CREATE statement: '" 469 + sqlQueryOrTemplate + "'"); 470 } 471 else 472 col.setIsUnique(true); 473 columnName = columnName.substring(comma + 1); 474 } 475 476 col = table.getColumn(columnName); 478 479 if (col == null) 484 { 485 tableName = null; 486 columns = null; 487 throw new SQLException ( 488 "Syntax error in this CREATE statement: '" 489 + sqlQueryOrTemplate + "'"); 490 } 491 else 492 col.setIsUnique(true); 493 } 494 else 495 { 496 columnName = word; 498 499 if (!wordTokens.hasMoreTokens()) 500 { 501 tableName = null; 503 columns = null; 504 throw new SQLException ( 505 "Syntax error in this CREATE statement: '" 506 + sqlQueryOrTemplate + "'"); 507 } 508 509 do 511 { 512 word = wordTokens.nextToken().trim().toLowerCase(); 513 if (word.equals("primary") || word.startsWith("unique")) 514 { 515 isUnique = true; 517 break; 518 } 519 } 520 while (wordTokens.hasMoreTokens()); 521 522 columns.add(new TableColumn(tableName, columnName)); 525 table.addColumn(new DatabaseColumn(columnName, isUnique)); 526 } 527 } 528 } 529 } 530 } 531 isParsed = true; 532 } 533 finally 534 { 535 if (isParsed) 536 { 537 SortedSet readSet = null; 538 if (fromTables != null) 539 readSet = new TreeSet (fromTables); 540 setSemantic(new SemanticBehavior(readSet, writeLockedTables, null, 541 altersDatabaseSchema, altersMetadataCache, altersQueryResultCache, 542 altersUsers, isReadOnly, needsMacroProcessing(), 543 SemanticBehavior.SERIALIZABLE_ORDER, requiresConnectionPoolFlush 544 ? SemanticBehavior.FLUSH_ALL_USERS 545 : SemanticBehavior.FLUSH_NONE)); 546 } 547 } 548 } 549 550 555 public boolean returnsResultSet() 556 { 557 return false; 558 } 559 560 563 public String getParsingResultsAsString() 564 { 565 StringBuffer sb = new StringBuffer (super.getParsingResultsAsString()); 566 sb.append(Translate.get("request.create.table", table)); 567 if (fromTables != null) 568 { 569 sb.append(Translate.get("request.create.from.tables")); 570 for (int i = 0; i < fromTables.size(); i++) 571 sb.append(Translate.get("request.create.from.table", fromTables 572 .toArray()[i])); 573 } 574 sb.append(Translate.get("request.alters", 575 new String []{String.valueOf(altersAggregateList()), 576 String.valueOf(altersDatabaseCatalog()), 577 String.valueOf(altersDatabaseSchema()), 578 String.valueOf(altersMetadataCache()), 579 String.valueOf(altersQueryResultCache()), 580 String.valueOf(altersSomething()), 581 String.valueOf(altersStoredProcedureList()), 582 String.valueOf(altersUserDefinedTypes()), 583 String.valueOf(altersUsers())})); 584 return sb.toString(); 585 } 586 587 590 public void debug() 591 { 592 super.debug(); 593 if (tableName != null) 594 System.out.println("Created table: " + tableName); 595 else 596 System.out.println("No information about created table"); 597 598 if (columns != null) 599 { 600 System.out.println("Created columns:"); 601 for (int i = 0; i < columns.size(); i++) 602 System.out.println(" " 603 + ((TableColumn) columns.get(i)).getColumnName()); 604 } 605 else 606 System.out.println("No information about created columns"); 607 608 System.out.println(); 609 } 610 611 } | Popular Tags |