001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.db; 020 021import java.io.ByteArrayInputStream; 022import java.util.Enumeration; 023import java.util.HashSet; 024import java.util.Set; 025import java.util.Vector; 026 027import lucee.runtime.sql.old.ParseException; 028import lucee.runtime.sql.old.ZExp; 029import lucee.runtime.sql.old.ZExpression; 030import lucee.runtime.sql.old.ZFromItem; 031import lucee.runtime.sql.old.ZQuery; 032import lucee.runtime.sql.old.ZStatement; 033import lucee.runtime.sql.old.ZqlParser; 034 035 036/** 037 * utilities for sql statements 038 */ 039public final class HSQLUtil { 040 041 private ZqlParser parser; 042 private String sql; 043 private boolean isUnion; 044 045 /**or of the class 046 * construct 047 * @param sql SQl Statement as String 048 */ 049 public HSQLUtil(String sql) { 050 this.sql=SQLPrettyfier.prettyfie(sql,true);//sqlToZQL(sql,true); 051 parser = new ZqlParser(new ByteArrayInputStream(this.sql.getBytes())); 052 } 053 054 /* * 055 * transalte SQL syntax to a ZQL combatible form 056 * @param sql sql to transalte 057 * @param changePlaceHolder 058 * @return translated sql 059 * / 060 private static String sqlToZQL(String sql,boolean changePlaceHolder) { 061 sql=sql.trim(); 062 char c=' ';//,last=' '; 063 int len=sql.length(); 064 boolean insideString=false; 065 StringBuilder sb=new StringBuilder(len); 066 067 068 069 for(int i=0;i<len;i++) { 070 c=sql.charAt(i); 071 if(insideString) { 072 if(c=='\'') { 073 if(i+1>=len || sql.charAt(i+1)!='\'')insideString=false; 074 } 075 } 076 else { 077 if(c=='\'')insideString=true; 078 else if(changePlaceHolder && c=='?') { 079 sb.append("QUESTION_MARK_SIGN"); 080 //last=c; 081 continue; 082 } 083 else if(c=='a'|| c=='A') { 084 if( 085 (i!=0 && isWhiteSpace(sql.charAt(i-1))) 086 && 087 (i+1<len && (sql.charAt(i+1)=='s' || sql.charAt(i+1)=='S')) 088 && 089 (i+2<len && isWhiteSpace(sql.charAt(i+2))) 090 ) { 091 i++; 092 //last=c; 093 continue; 094 } 095 } 096 else if(c=='*') { 097 098 } 099 } 100 //last=c; 101 sb.append(c); 102 } 103 104 if(c!=';')sb.append(';'); 105 106 return sb.toString(); 107 108 }*/ 109 110 /*private static boolean isWhiteSpace(char c) { 111 return (c==' ' || c=='\t' || c=='\b' || c=='\r' || c=='\n'); 112 }*/ 113 114 /** 115 * @return return the sql state inside 116 */ 117 public String getSQL() { 118 return sql; 119 } 120 121 /** 122 * return all invoked tables by a sql statement 123 * @return invoked tables in a ArrayList 124 * @throws ParseException 125 */ 126 public Set<String> getInvokedTables() throws ParseException { 127 128 129 // Read all SQL statements from input 130 ZStatement st; 131 Set<String> tables=new HashSet<String>(); 132 133 while((st = parser.readStatement()) != null) { 134 this.sql=st.toString(); 135 if(st instanceof ZQuery) { // An SQL query: query the DB 136 getInvokedTables((ZQuery)st,tables); 137 } 138 break; 139 } 140 return tables; 141 } 142 143 private void getInvokedTables(ZQuery query, Set<String> tablesNames) { 144 //print.out("qry:"+query.getSet()); 145 Vector tables=query.getFrom(); 146 Enumeration e = tables.elements(); 147 148 // from 149 while(e.hasMoreElements()) { 150 ZFromItem fromItem=(ZFromItem) e.nextElement(); 151 tablesNames.add(fromItem.getFullName()); 152 } 153 // where 154 ZExp where = query.getWhere(); 155 if(where instanceof ZExpression) { 156 parseZExpression((ZExpression) where, tablesNames); 157 } 158 // set 159 ZExpression set = query.getSet(); 160 if(set!=null){ 161 isUnion=true; 162 ZExp op = set.getOperand(0); 163 if(op instanceof ZQuery) getInvokedTables((ZQuery)op, tablesNames); 164 } 165 } 166 167 168 169 public boolean isUnion() { 170 return isUnion; 171 } 172 173 private void parseZExpression(ZExpression expression, Set tablesNames) { 174 Vector operands = expression.getOperands(); 175 Enumeration e = operands.elements(); 176 while(e.hasMoreElements()) { 177 Object el=e.nextElement(); 178 if(el instanceof ZExpression)parseZExpression((ZExpression)el,tablesNames); 179 else if(el instanceof ZQuery)getInvokedTables((ZQuery)el,tablesNames); 180 } 181 } 182}