001 package railo.runtime.db; 002 003 import java.io.ByteArrayInputStream; 004 import java.util.Enumeration; 005 import java.util.HashSet; 006 import java.util.Set; 007 import java.util.Vector; 008 009 import railo.runtime.sql.old.ParseException; 010 import railo.runtime.sql.old.ZExp; 011 import railo.runtime.sql.old.ZExpression; 012 import railo.runtime.sql.old.ZFromItem; 013 import railo.runtime.sql.old.ZQuery; 014 import railo.runtime.sql.old.ZStatement; 015 import railo.runtime.sql.old.ZqlParser; 016 017 018 /** 019 * utilities for sql statements 020 */ 021 public final class HSQLUtil { 022 023 private ZqlParser parser; 024 private String sql; 025 private boolean isUnion; 026 027 /**or of the class 028 * construct 029 * @param sql SQl Statement as String 030 */ 031 public HSQLUtil(String sql) { 032 this.sql=SQLPrettyfier.prettyfie(sql,true);//sqlToZQL(sql,true); 033 parser = new ZqlParser(new ByteArrayInputStream(this.sql.getBytes())); 034 } 035 036 /* * 037 * transalte SQL syntax to a ZQL combatible form 038 * @param sql sql to transalte 039 * @param changePlaceHolder 040 * @return translated sql 041 * / 042 private static String sqlToZQL(String sql,boolean changePlaceHolder) { 043 sql=sql.trim(); 044 char c=' ';//,last=' '; 045 int len=sql.length(); 046 boolean insideString=false; 047 StringBuffer sb=new StringBuffer(len); 048 049 050 051 for(int i=0;i<len;i++) { 052 c=sql.charAt(i); 053 if(insideString) { 054 if(c=='\'') { 055 if(i+1>=len || sql.charAt(i+1)!='\'')insideString=false; 056 } 057 } 058 else { 059 if(c=='\'')insideString=true; 060 else if(changePlaceHolder && c=='?') { 061 sb.append("QUESTION_MARK_SIGN"); 062 //last=c; 063 continue; 064 } 065 else if(c=='a'|| c=='A') { 066 if( 067 (i!=0 && isWhiteSpace(sql.charAt(i-1))) 068 && 069 (i+1<len && (sql.charAt(i+1)=='s' || sql.charAt(i+1)=='S')) 070 && 071 (i+2<len && isWhiteSpace(sql.charAt(i+2))) 072 ) { 073 i++; 074 //last=c; 075 continue; 076 } 077 } 078 else if(c=='*') { 079 080 } 081 } 082 //last=c; 083 sb.append(c); 084 } 085 086 if(c!=';')sb.append(';'); 087 088 return sb.toString(); 089 090 }*/ 091 092 /*private static boolean isWhiteSpace(char c) { 093 return (c==' ' || c=='\t' || c=='\b' || c=='\r' || c=='\n'); 094 }*/ 095 096 /** 097 * @return return the sql state inside 098 */ 099 public String getSQL() { 100 return sql; 101 } 102 103 /** 104 * return all invoked tables by a sql statement 105 * @return invoked tables in a ArrayList 106 * @throws ParseException 107 */ 108 public Set<String> getInvokedTables() throws ParseException { 109 110 111 // Read all SQL statements from input 112 ZStatement st; 113 Set<String> tables=new HashSet<String>(); 114 115 while((st = parser.readStatement()) != null) { 116 this.sql=st.toString(); 117 if(st instanceof ZQuery) { // An SQL query: query the DB 118 getInvokedTables((ZQuery)st,tables); 119 } 120 break; 121 } 122 return tables; 123 } 124 125 private void getInvokedTables(ZQuery query, Set<String> tablesNames) { 126 //print.out("qry:"+query.getSet()); 127 Vector tables=query.getFrom(); 128 Enumeration e = tables.elements(); 129 130 // from 131 while(e.hasMoreElements()) { 132 ZFromItem fromItem=(ZFromItem) e.nextElement(); 133 tablesNames.add(fromItem.getFullName()); 134 } 135 // where 136 ZExp where = query.getWhere(); 137 if(where instanceof ZExpression) { 138 parseZExpression((ZExpression) where, tablesNames); 139 } 140 // set 141 ZExpression set = query.getSet(); 142 if(set!=null){ 143 isUnion=true; 144 ZExp op = set.getOperand(0); 145 if(op instanceof ZQuery) getInvokedTables((ZQuery)op, tablesNames); 146 } 147 } 148 149 150 151 public boolean isUnion() { 152 return isUnion; 153 } 154 155 private void parseZExpression(ZExpression expression, Set tablesNames) { 156 Vector operands = expression.getOperands(); 157 Enumeration e = operands.elements(); 158 while(e.hasMoreElements()) { 159 Object el=e.nextElement(); 160 if(el instanceof ZExpression)parseZExpression((ZExpression)el,tablesNames); 161 else if(el instanceof ZQuery)getInvokedTables((ZQuery)el,tablesNames); 162 } 163 } 164 }