001 package railo.runtime.tag; 002 003 import java.sql.DatabaseMetaData; 004 import java.sql.ResultSet; 005 import java.sql.SQLException; 006 import java.util.HashMap; 007 import java.util.HashSet; 008 import java.util.Map; 009 import java.util.Set; 010 import java.util.regex.Pattern; 011 012 import railo.commons.lang.StringUtil; 013 import railo.commons.sql.SQLUtil; 014 import railo.runtime.PageContext; 015 import railo.runtime.db.DataSourceManager; 016 import railo.runtime.db.DatasourceConnection; 017 import railo.runtime.exp.ApplicationException; 018 import railo.runtime.exp.DatabaseException; 019 import railo.runtime.exp.PageException; 020 import railo.runtime.ext.tag.TagImpl; 021 import railo.runtime.listener.ApplicationContextPro; 022 import railo.runtime.op.Caster; 023 import railo.runtime.op.Constants; 024 import railo.runtime.timer.Stopwatch; 025 import railo.runtime.type.Array; 026 import railo.runtime.type.ArrayImpl; 027 import railo.runtime.type.Collection; 028 import railo.runtime.type.Collection.Key; 029 import railo.runtime.type.KeyImpl; 030 import railo.runtime.type.QueryColumn; 031 import railo.runtime.type.QueryImpl; 032 import railo.runtime.type.QueryPro; 033 import railo.runtime.type.SVArray; 034 import railo.runtime.type.Struct; 035 import railo.runtime.type.StructImpl; 036 037 /** 038 * Handles all interactions with files. The attributes you use with cffile depend on the value of the action attribute. 039 * For example, if the action = "write", use the attributes associated with writing a text file. 040 * 041 * 042 * 043 **/ 044 public final class DBInfo extends TagImpl { 045 046 private static final Key TABLE_NAME = KeyImpl.intern("TABLE_NAME"); 047 private static final Key COLUMN_NAME = KeyImpl.intern("COLUMN_NAME"); 048 private static final Key IS_PRIMARYKEY = KeyImpl.intern("IS_PRIMARYKEY"); 049 private static final Key IS_FOREIGNKEY = KeyImpl.intern("IS_FOREIGNKEY"); 050 private static final Key COLUMN_DEF = KeyImpl.intern("COLUMN_DEF"); 051 private static final Key COLUMN_DEFAULT_VALUE = KeyImpl.intern("COLUMN_DEFAULT_VALUE"); 052 private static final Key REFERENCED_PRIMARYKEY = KeyImpl.intern("REFERENCED_PRIMARYKEY"); 053 private static final Key REFERENCED_PRIMARYKEY_TABLE = KeyImpl.intern("REFERENCED_PRIMARYKEY_TABLE"); 054 private static final Key USER = KeyImpl.intern("USER"); 055 private static final Key TABLE_SCHEM = KeyImpl.intern("TABLE_SCHEM"); 056 private static final Key DECIMAL_DIGITS = KeyImpl.intern("DECIMAL_DIGITS"); 057 058 private static final Key DATABASE_NAME = KeyImpl.intern("database_name"); 059 private static final Key TABLE_CAT = KeyImpl.intern("TABLE_CAT"); 060 private static final Key PROCEDURE = KeyImpl.intern("procedure"); 061 private static final Key CATALOG = KeyImpl.intern("catalog"); 062 private static final Key SCHEMA = KeyImpl.intern("schema"); 063 private static final Key DATABASE_PRODUCTNAME = KeyImpl.intern("DATABASE_PRODUCTNAME"); 064 private static final Key DATABASE_VERSION = KeyImpl.intern("DATABASE_VERSION"); 065 private static final Key DRIVER_NAME = KeyImpl.intern("DRIVER_NAME"); 066 private static final Key DRIVER_VERSION = KeyImpl.intern("DRIVER_VERSION"); 067 private static final Key JDBC_MAJOR_VERSION = KeyImpl.intern("JDBC_MAJOR_VERSION"); 068 private static final Key JDBC_MINOR_VERSION = KeyImpl.intern("JDBC_MINOR_VERSION"); 069 070 private static final int TYPE_NONE=0; 071 private static final int TYPE_DBNAMES=1; 072 private static final int TYPE_TABLES=2; 073 private static final int TYPE_TABLE_COLUMNS = 3; 074 private static final int TYPE_VERSION = 4; 075 private static final int TYPE_PROCEDURES = 5; 076 private static final int TYPE_PROCEDURE_COLUMNS = 6; 077 private static final int TYPE_FOREIGNKEYS = 7; 078 private static final int TYPE_INDEX = 8; 079 private static final int TYPE_USERS = 9; 080 private static final int TYPE_TERMS = 10; 081 private static final Collection.Key CARDINALITY = KeyImpl.init("CARDINALITY"); 082 083 084 //private static final String[] ALL_TABLE_TYPES = {"TABLE", "VIEW", "SYSTEM TABLE", "SYNONYM"}; 085 086 private String datasource; 087 private String name; 088 private int type; 089 090 091 private String dbname; 092 private String password; 093 private String pattern; 094 private String table; 095 private String procedure; 096 private String username; 097 private String strType; 098 099 100 /** 101 * @see javax.servlet.jsp.tagext.Tag#release() 102 */ 103 public void release() { 104 super.release(); 105 datasource=null; 106 name=null; 107 type=TYPE_NONE; 108 dbname=null; 109 password=null; 110 pattern=null; 111 table=null; 112 procedure=null; 113 username=null; 114 115 116 117 } 118 119 /** 120 * @param procedure the procedure to set 121 */ 122 public void setProcedure(String procedure) { 123 this.procedure = procedure; 124 } 125 126 /** 127 * @param datasource the datasource to set 128 */ 129 public void setDatasource(String datasource) { 130 this.datasource = datasource; 131 } 132 133 /** 134 * @param name the name to set 135 */ 136 public void setName(String name) { 137 this.name = name; 138 } 139 140 /** 141 * @param type the type to set 142 * @throws ApplicationException 143 */ 144 public void setType(String strType) throws ApplicationException { 145 this.strType=strType; 146 strType=strType.toLowerCase().trim(); 147 148 if("dbnames".equals(strType)) this.type=TYPE_DBNAMES; 149 else if("dbname".equals(strType)) this.type=TYPE_DBNAMES; 150 else if("tables".equals(strType)) this.type=TYPE_TABLES; 151 else if("table".equals(strType)) this.type=TYPE_TABLES; 152 else if("columns".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 153 else if("column".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 154 else if("version".equals(strType)) this.type=TYPE_VERSION; 155 else if("procedures".equals(strType)) this.type=TYPE_PROCEDURES; 156 else if("procedure".equals(strType)) this.type=TYPE_PROCEDURES; 157 158 159 else if("table_columns".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 160 else if("table_column".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 161 else if("column_table".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 162 else if("column_tables".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 163 164 else if("tablecolumns".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 165 else if("tablecolumn".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 166 else if("columntable".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 167 else if("columntables".equals(strType)) this.type=TYPE_TABLE_COLUMNS; 168 169 else if("procedure_columns".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 170 else if("procedure_column".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 171 else if("column_procedure".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 172 else if("column_procedures".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 173 174 else if("procedurecolumns".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 175 else if("procedurecolumn".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 176 else if("columnprocedure".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 177 else if("columnprocedures".equals(strType)) this.type=TYPE_PROCEDURE_COLUMNS; 178 179 else if("foreignkeys".equals(strType)) this.type=TYPE_FOREIGNKEYS; 180 else if("foreignkey".equals(strType)) this.type=TYPE_FOREIGNKEYS; 181 else if("index".equals(strType)) this.type=TYPE_INDEX; 182 else if("users".equals(strType)) this.type=TYPE_USERS; 183 else if("user".equals(strType)) this.type=TYPE_USERS; 184 185 else if("term".equals(strType)) this.type=TYPE_TERMS; 186 else if("terms".equals(strType)) this.type=TYPE_TERMS; 187 188 else throw new ApplicationException("invalid value for attribute type ["+strType+"]", 189 "valid values are [dbname,tables,columns,version,procedures,foreignkeys,index,users]"); 190 191 } 192 193 /** 194 * @param dbname the dbname to set 195 */ 196 public void setDbname(String dbname) { 197 this.dbname = dbname; 198 } 199 public void setDbnames(String dbname) { 200 this.dbname = dbname; 201 } 202 203 /** 204 * @param password the password to set 205 */ 206 public void setPassword(String password) { 207 this.password = password; 208 } 209 210 /** 211 * @param pattern the pattern to set 212 */ 213 public void setPattern(String pattern) { 214 this.pattern = pattern; 215 } 216 217 /** 218 * @param table the table to set 219 */ 220 public void setTable(String table) { 221 this.table = table; 222 } 223 224 /** 225 * @param username the username to set 226 */ 227 public void setUsername(String username) { 228 this.username = username; 229 } 230 231 232 /** 233 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 234 */ 235 public int doStartTag() throws PageException { 236 datasource=getDatasource(pageContext, datasource); 237 DataSourceManager manager = pageContext.getDataSourceManager(); 238 DatasourceConnection dc=manager.getConnection(pageContext,datasource, username, password); 239 try { 240 241 if(type==TYPE_TABLE_COLUMNS) typeColumns(dc.getConnection().getMetaData()); 242 else if(type==TYPE_DBNAMES) typeDBNames(dc.getConnection().getMetaData()); 243 else if(type==TYPE_FOREIGNKEYS) typeForeignKeys(dc.getConnection().getMetaData()); 244 else if(type==TYPE_INDEX) typeIndex(dc.getConnection().getMetaData()); 245 else if(type==TYPE_PROCEDURES) typeProcedures(dc.getConnection().getMetaData()); 246 else if(type==TYPE_PROCEDURE_COLUMNS)typeProcedureColumns(dc.getConnection().getMetaData()); 247 else if(type==TYPE_TERMS) typeTerms(dc.getConnection().getMetaData()); 248 else if(type==TYPE_TABLES) typeTables(dc.getConnection().getMetaData()); 249 else if(type==TYPE_VERSION) typeVersion(dc.getConnection().getMetaData()); 250 else if(type==TYPE_USERS) typeUsers(dc.getConnection().getMetaData()); 251 252 } 253 catch(SQLException sqle) { 254 throw new DatabaseException(sqle,dc); 255 } 256 finally { 257 manager.releaseConnection(pageContext,dc); 258 } 259 260 261 262 263 return SKIP_BODY; 264 } 265 266 267 268 private void typeColumns(DatabaseMetaData metaData) throws PageException, SQLException { 269 required("table",table); 270 271 Stopwatch stopwatch=new Stopwatch(); 272 stopwatch.start(); 273 274 table=setCase(metaData, table); 275 pattern=setCase(metaData, pattern); 276 if(StringUtil.isEmpty(pattern,true)) pattern=null; 277 String schema=null; 278 int index=table.indexOf('.'); 279 if(index>0) { 280 schema=table.substring(0,index); 281 table=table.substring(index+1); 282 } 283 checkTable(metaData); 284 285 ResultSet columns = metaData.getColumns(dbname, schema, table, pattern); 286 QueryPro qry = new QueryImpl(columns,"query"); 287 288 int len=qry.getRecordcount(); 289 290 qry.rename(COLUMN_DEF,COLUMN_DEFAULT_VALUE); 291 292 // make sure decimal digits exists 293 QueryColumn col = qry.getColumn(DECIMAL_DIGITS,null); 294 if(col==null){ 295 Array arr=new ArrayImpl(); 296 for(int i=1;i<=len;i++) { 297 arr.append(Constants.DOUBLE_ZERO); 298 } 299 qry.addColumn(DECIMAL_DIGITS, arr); 300 } 301 302 303 // add is primary 304 Map primaries = new HashMap(); 305 String tblName; 306 Array isPrimary=new ArrayImpl(); 307 Set set; 308 Object o; 309 for(int i=1;i<=len;i++) { 310 311 // decimal digits 312 o=qry.getAt(DECIMAL_DIGITS, i,null); 313 if(o==null)qry.setAtEL(DECIMAL_DIGITS, i,Constants.DOUBLE_ZERO); 314 315 set=(Set) primaries.get(tblName=(String) qry.getAt(TABLE_NAME, i)); 316 if(set==null) { 317 set=toSet(metaData.getPrimaryKeys(dbname, null, tblName),"COLUMN_NAME"); 318 primaries.put(tblName,set); 319 } 320 isPrimary.append(set.contains(qry.getAt(COLUMN_NAME, i))?"YES":"NO"); 321 } 322 qry.addColumn(IS_PRIMARYKEY, isPrimary); 323 324 // add is foreignkey 325 Map foreigns = new HashMap(); 326 Array isForeign=new ArrayImpl(); 327 Array refPrim=new ArrayImpl(); 328 Array refPrimTbl=new ArrayImpl(); 329 //Map map,inner; 330 Map<String, Map<String, SVArray>> map; 331 Map<String, SVArray> inner; 332 for(int i=1;i<=len;i++) { 333 map=(Map) foreigns.get(tblName=(String) qry.getAt(TABLE_NAME, i)); 334 if(map==null) { 335 map=toMap(metaData.getImportedKeys(dbname, schema, table),"FKCOLUMN_NAME",new String[]{"PKCOLUMN_NAME","PKTABLE_NAME"}); 336 foreigns.put(tblName, map); 337 } 338 inner = map.get(qry.getAt(COLUMN_NAME, i)); 339 if(inner!=null) { 340 isForeign.append("YES"); 341 refPrim.append(inner.get("PKCOLUMN_NAME")); 342 refPrimTbl.append(inner.get("PKTABLE_NAME")); 343 } 344 else { 345 isForeign.append("NO"); 346 refPrim.append("N/A"); 347 refPrimTbl.append("N/A"); 348 } 349 } 350 qry.addColumn(IS_FOREIGNKEY, isForeign); 351 qry.addColumn(REFERENCED_PRIMARYKEY, refPrim); 352 qry.addColumn(REFERENCED_PRIMARYKEY_TABLE, refPrimTbl); 353 354 355 qry.setExecutionTime(stopwatch.time()); 356 357 358 pageContext.setVariable(name, qry); 359 } 360 361 private Map<String,Map<String, SVArray>> toMap(ResultSet result,String columnName,String[] additional) throws SQLException { 362 Map<String,Map<String, SVArray>> map=new HashMap<String,Map<String, SVArray>>(); 363 Map<String, SVArray> inner; 364 String col; 365 SVArray item; 366 while(result.next()){ 367 col=result.getString(columnName); 368 inner=map.get(col); 369 if(inner!=null) { 370 for(int i=0;i<additional.length;i++) { 371 item=(SVArray) inner.get(additional[i]); 372 item.add(result.getString(additional[i])); 373 item.setPosition(item.size()); 374 } 375 } 376 else { 377 inner=new HashMap<String, SVArray>(); 378 map.put(col, inner); 379 for(int i=0;i<additional.length;i++) { 380 item=new SVArray(); 381 item.add(result.getString(additional[i])); 382 inner.put(additional[i], item); 383 } 384 } 385 } 386 return map; 387 } 388 389 private Set<String> toSet(ResultSet result,String columnName) throws SQLException { 390 Set<String> set = new HashSet<String>(); 391 while(result.next()){ 392 set.add(result.getString(columnName)); 393 } 394 return set; 395 } 396 397 private void typeDBNames(DatabaseMetaData metaData) throws PageException, SQLException { 398 399 Stopwatch stopwatch=new Stopwatch(); 400 stopwatch.start(); 401 402 railo.runtime.type.Query catalogs = new QueryImpl(metaData.getCatalogs(),"query"); 403 railo.runtime.type.Query scheme = new QueryImpl(metaData.getSchemas(),"query"); 404 405 Pattern p=null; 406 if(pattern!=null && !"%".equals(pattern)) 407 p=SQLUtil.pattern(pattern, true); 408 409 410 411 String[] columns=new String[]{"database_name","type"}; 412 String[] types=new String[]{"VARCHAR","VARCHAR"}; 413 railo.runtime.type.Query qry=new QueryImpl(columns,types,0,"query"); 414 int row=1,len=catalogs.getRecordcount(); 415 String value; 416 // catalog 417 for(int i=1;i<=len;i++) { 418 value=(String) catalogs.getAt(TABLE_CAT, i); 419 if(!matchPattern(value,p)) continue; 420 qry.addRow(); 421 qry.setAt(DATABASE_NAME, row, value); 422 qry.setAt(KeyImpl.TYPE, row, "CATALOG"); 423 row++; 424 } 425 // scheme 426 len=scheme.getRecordcount(); 427 for(int i=1;i<=len;i++) { 428 value=(String) scheme.getAt(TABLE_SCHEM, i); 429 if(!matchPattern(value,p)) continue; 430 qry.addRow(); 431 qry.setAt(DATABASE_NAME, row, value); 432 qry.setAt(KeyImpl.TYPE, row, "SCHEMA"); 433 row++; 434 } 435 436 qry.setExecutionTime(stopwatch.time()); 437 438 439 pageContext.setVariable(name, qry); 440 } 441 442 private void typeForeignKeys(DatabaseMetaData metaData) throws PageException, SQLException { 443 required("table",table); 444 445 Stopwatch stopwatch=new Stopwatch(); 446 stopwatch.start(); 447 table=setCase(metaData, table); 448 int index=table.indexOf('.'); 449 String schema=null; 450 if(index>0) { 451 schema=table.substring(0,index); 452 table=table.substring(index+1); 453 } 454 455 checkTable(metaData); 456 457 ResultSet columns = metaData.getCrossReference(dbname, schema, table, null, null, null);// TODO ist das ok 458 railo.runtime.type.Query qry = new QueryImpl(columns,"query"); 459 460 461 qry.setExecutionTime(stopwatch.time()); 462 463 464 pageContext.setVariable(name, qry); 465 } 466 467 private void checkTable(DatabaseMetaData metaData) throws SQLException, ApplicationException { 468 ResultSet tables =null; 469 470 try { 471 tables = metaData.getTables(null, null, setCase(metaData,table), null); 472 if(!tables.next()) throw new ApplicationException("there is no table that match the following pattern ["+table+"]"); 473 } 474 finally { 475 if(tables!=null) tables.close(); 476 } 477 } 478 479 private String setCase(DatabaseMetaData metaData, String id) throws SQLException { 480 if(id==null) return null; 481 482 if(metaData.storesLowerCaseIdentifiers()) return id.toLowerCase(); 483 if(metaData.storesUpperCaseIdentifiers()) return id.toUpperCase(); 484 return id; 485 } 486 487 private void typeIndex(DatabaseMetaData metaData) throws PageException, SQLException { 488 required("table",table); 489 490 Stopwatch stopwatch=new Stopwatch(); 491 stopwatch.start(); 492 493 table=setCase(metaData, table); 494 int index=table.indexOf('.'); 495 String schema=null; 496 if(index>0) { 497 schema=table.substring(0,index); 498 table=table.substring(index+1); 499 } 500 501 checkTable(metaData); 502 503 ResultSet tables = metaData.getIndexInfo(dbname, schema, table, false, true); 504 railo.runtime.type.Query qry = new QueryImpl(tables,"query"); 505 506 // type int 2 string 507 int rows = qry.getRecordcount(); 508 String strType; 509 int type,card; 510 for(int row=1;row<=rows;row++){ 511 512 // type 513 switch(type=Caster.toIntValue(qry.getAt(KeyImpl.TYPE,row))){ 514 case 0: 515 strType="Table Statistic"; 516 break; 517 case 1: 518 strType="Clustered Index"; 519 break; 520 case 2: 521 strType="Hashed Index"; 522 break; 523 case 3: 524 strType="Other Index"; 525 break; 526 default: 527 strType=Caster.toString(type); 528 } 529 qry.setAt(KeyImpl.TYPE, row, strType); 530 531 // CARDINALITY 532 card=Caster.toIntValue(qry.getAt(CARDINALITY,row),0); 533 qry.setAt(CARDINALITY, row, Caster.toDouble(card)); 534 535 } 536 qry.setExecutionTime(stopwatch.time()); 537 538 539 pageContext.setVariable(name, qry); 540 } 541 542 private void typeProcedures(DatabaseMetaData metaData) throws SQLException, PageException { 543 Stopwatch stopwatch=new Stopwatch(); 544 stopwatch.start(); 545 546 String schema=null; 547 pattern=setCase(metaData, pattern); 548 if(StringUtil.isEmpty(pattern,true)) { 549 pattern=null; 550 } 551 552 ResultSet tables = metaData.getProcedures(dbname, schema, pattern); 553 railo.runtime.type.Query qry = new QueryImpl(tables,"query"); 554 qry.setExecutionTime(stopwatch.time()); 555 556 557 pageContext.setVariable(name, qry); 558 } 559 560 private void typeProcedureColumns(DatabaseMetaData metaData) throws SQLException, PageException { 561 required("procedure",procedure); 562 563 Stopwatch stopwatch=new Stopwatch(); 564 stopwatch.start(); 565 566 procedure=setCase(metaData, procedure); 567 pattern=setCase(metaData, pattern); 568 if(StringUtil.isEmpty(pattern,true)) pattern=null; 569 String schema=null; 570 int index=procedure.indexOf('.'); 571 if(index>0) { 572 schema=procedure.substring(0,index); 573 procedure=procedure.substring(index+1); 574 } 575 576 577 ResultSet tables = metaData.getProcedureColumns(dbname, schema, procedure, pattern); 578 579 railo.runtime.type.Query qry = new QueryImpl(tables,"query"); 580 qry.setExecutionTime(stopwatch.time()); 581 582 583 pageContext.setVariable(name, qry); 584 } 585 586 private void typeTerms(DatabaseMetaData metaData) throws SQLException, PageException { 587 Struct sct=new StructImpl(); 588 sct.setEL(PROCEDURE, metaData.getProcedureTerm()); 589 sct.setEL(CATALOG, metaData.getCatalogTerm()); 590 sct.setEL(SCHEMA, metaData.getSchemaTerm()); 591 592 pageContext.setVariable(name, sct); 593 } 594 595 private void typeTables(DatabaseMetaData metaData) throws PageException, SQLException { 596 597 598 599 Stopwatch stopwatch=new Stopwatch(); 600 stopwatch.start(); 601 602 pattern=setCase(metaData, pattern); 603 604 ResultSet tables = metaData.getTables(dbname, null, pattern, null); 605 railo.runtime.type.Query qry = new QueryImpl(tables,"query"); 606 607 qry.setExecutionTime(stopwatch.time()); 608 609 610 pageContext.setVariable(name, qry); 611 } 612 613 private void typeVersion(DatabaseMetaData metaData) throws PageException, SQLException { 614 615 Stopwatch stopwatch=new Stopwatch(); 616 stopwatch.start(); 617 618 Key[] columns=new Key[]{DATABASE_PRODUCTNAME,DATABASE_VERSION,DRIVER_NAME,DRIVER_VERSION,JDBC_MAJOR_VERSION,JDBC_MINOR_VERSION}; 619 String[] types=new String[]{"VARCHAR","VARCHAR","VARCHAR","VARCHAR","DOUBLE","DOUBLE"}; 620 621 railo.runtime.type.Query qry=new QueryImpl(columns,types,1,"query"); 622 623 qry.setAt(DATABASE_PRODUCTNAME,1,metaData.getDatabaseProductName()); 624 qry.setAt(DATABASE_VERSION,1,metaData.getDatabaseProductVersion()); 625 qry.setAt(DRIVER_NAME,1,metaData.getDriverName()); 626 qry.setAt(DRIVER_VERSION,1,metaData.getDriverVersion()); 627 qry.setAt(JDBC_MAJOR_VERSION,1,new Double(metaData.getJDBCMajorVersion())); 628 qry.setAt(JDBC_MINOR_VERSION,1,new Double(metaData.getJDBCMinorVersion())); 629 630 631 qry.setExecutionTime(stopwatch.time()); 632 633 634 pageContext.setVariable(name, qry); 635 } 636 637 private void typeUsers(DatabaseMetaData metaData) throws PageException, SQLException { 638 639 Stopwatch stopwatch=new Stopwatch(); 640 stopwatch.start(); 641 642 checkTable(metaData); 643 ResultSet result = metaData.getSchemas(); 644 QueryPro qry = new QueryImpl(result,"query"); 645 646 647 qry.rename(TABLE_SCHEM,USER); 648 649 qry.setExecutionTime(stopwatch.time()); 650 651 652 pageContext.setVariable(name, qry); 653 } 654 655 private void required(String name, String value) throws ApplicationException { 656 if(value==null) 657 throw new ApplicationException("Missing attribute ["+name+"]. The type ["+strType+"] requires the attribute [" + name + "]."); 658 } 659 660 private static boolean matchPattern(String value, Pattern pattern) { 661 if(pattern==null) return true; 662 return SQLUtil.match(pattern, value); 663 } 664 665 /** 666 * @see javax.servlet.jsp.tagext.Tag#doEndTag() 667 */ 668 public int doEndTag() { 669 return EVAL_PAGE; 670 } 671 672 673 public static String getDatasource(PageContext pageContext, String datasource) throws ApplicationException { 674 if(StringUtil.isEmpty(datasource)){ 675 datasource=((ApplicationContextPro)pageContext.getApplicationContext()).getDefaultDataSource(); 676 677 if(StringUtil.isEmpty(datasource)) 678 throw new ApplicationException( 679 "attribute [datasource] is required, when no default datasource is defined", 680 "you can define a default datasource as attribute [defaultdatasource] of the tag cfapplication or as data member of the application.cfc (this.defaultdatasource=\"mydatasource\";)"); 681 } 682 return datasource; 683 } 684 }