1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir package stats; 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir import java.sql.Connection; 30*cdf0e10cSrcweir import java.sql.DriverManager; 31*cdf0e10cSrcweir import java.sql.ResultSet; 32*cdf0e10cSrcweir import java.sql.ResultSetMetaData; 33*cdf0e10cSrcweir import java.sql.Statement; 34*cdf0e10cSrcweir import java.util.Enumeration; 35*cdf0e10cSrcweir import java.util.Hashtable; 36*cdf0e10cSrcweir import java.util.StringTokenizer; 37*cdf0e10cSrcweir import java.util.Vector; 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir /** 40*cdf0e10cSrcweir * 41*cdf0e10cSrcweir */ 42*cdf0e10cSrcweir public class SQLExecution { 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir protected Connection mConnection = null; 45*cdf0e10cSrcweir protected Statement mStatement = null; 46*cdf0e10cSrcweir protected String mJdbcClass = null; 47*cdf0e10cSrcweir protected String mDbURL = null; 48*cdf0e10cSrcweir protected String mUser = null; 49*cdf0e10cSrcweir protected String mPassword = null; 50*cdf0e10cSrcweir protected boolean m_bConnectionOpen = false; 51*cdf0e10cSrcweir protected boolean m_bDebug = false; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir /** Creates a new instance of SQLExecution 55*cdf0e10cSrcweir * @param jdbcClass The jdbc class for the connection. 56*cdf0e10cSrcweir * @param dbUrl The url of the database. 57*cdf0e10cSrcweir * @param user The user for connecting the database. 58*cdf0e10cSrcweir * @param password The password of throws user. 59*cdf0e10cSrcweir */ 60*cdf0e10cSrcweir public SQLExecution(String jdbcClass, String dbUrl, String user, String password) { 61*cdf0e10cSrcweir mJdbcClass = jdbcClass; 62*cdf0e10cSrcweir mUser = user; 63*cdf0e10cSrcweir mPassword = password; 64*cdf0e10cSrcweir mDbURL = dbUrl; 65*cdf0e10cSrcweir } 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir /** Creates a new instance of SQLExecution with additional debug output. 68*cdf0e10cSrcweir * @param jdbcClass The jdbc class for the connection. 69*cdf0e10cSrcweir * @param dbUrl The url of the database. 70*cdf0e10cSrcweir * @param user The user for connecting the database. 71*cdf0e10cSrcweir * @param password The password of throws user. 72*cdf0e10cSrcweir * @param debug Write debug information, if true. 73*cdf0e10cSrcweir */ 74*cdf0e10cSrcweir public SQLExecution(String jdbcClass, String dbUrl, String user, String password, boolean debug) { 75*cdf0e10cSrcweir mJdbcClass = jdbcClass; 76*cdf0e10cSrcweir mUser = user; 77*cdf0e10cSrcweir mPassword = password; 78*cdf0e10cSrcweir mDbURL = dbUrl; 79*cdf0e10cSrcweir m_bDebug = debug; 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir /** 83*cdf0e10cSrcweir * Open a connection to the DataBase 84*cdf0e10cSrcweir * @return True, if no error occured. 85*cdf0e10cSrcweir */ 86*cdf0e10cSrcweir public boolean openConnection() { 87*cdf0e10cSrcweir if(m_bConnectionOpen) return true; 88*cdf0e10cSrcweir try { 89*cdf0e10cSrcweir Class.forName(mJdbcClass); 90*cdf0e10cSrcweir } catch (ClassNotFoundException e) { 91*cdf0e10cSrcweir System.err.println("Couldn't find jdbc driver : " + e.getMessage()); 92*cdf0e10cSrcweir return false; 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir try { 96*cdf0e10cSrcweir // establish database connection 97*cdf0e10cSrcweir mConnection = DriverManager.getConnection( 98*cdf0e10cSrcweir mDbURL, mUser, mPassword); 99*cdf0e10cSrcweir mStatement = mConnection.createStatement(); 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir catch(java.sql.SQLException e) { 102*cdf0e10cSrcweir System.err.println("Couldn't establish a connection: " + e.getMessage()); 103*cdf0e10cSrcweir return false; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir m_bConnectionOpen = true; 106*cdf0e10cSrcweir return true; 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir /** 110*cdf0e10cSrcweir * Close the connection to the DataBase 111*cdf0e10cSrcweir * @return True, if no error occured. 112*cdf0e10cSrcweir */ 113*cdf0e10cSrcweir public boolean closeConnection() { 114*cdf0e10cSrcweir if (!m_bConnectionOpen) return true; 115*cdf0e10cSrcweir try { 116*cdf0e10cSrcweir // close database connection 117*cdf0e10cSrcweir mStatement.close(); 118*cdf0e10cSrcweir mConnection.close(); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir catch(java.sql.SQLException e) { 121*cdf0e10cSrcweir System.err.println("Couldn't close the connection: " + e.getMessage()); 122*cdf0e10cSrcweir return false; 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir m_bConnectionOpen = false; 125*cdf0e10cSrcweir return true; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir /** 129*cdf0e10cSrcweir * Execute an sql command. 130*cdf0e10cSrcweir * @param command The command to execute. 131*cdf0e10cSrcweir * @param sqlInput Input values for the command. 132*cdf0e10cSrcweir * @param sqlOutput The results of the command are put in this Hashtable. 133*cdf0e10cSrcweir * @return True, if no error occured. 134*cdf0e10cSrcweir */ 135*cdf0e10cSrcweir public boolean executeSQLCommand(String command, Hashtable sqlInput, Hashtable sqlOutput) 136*cdf0e10cSrcweir throws IllegalArgumentException { 137*cdf0e10cSrcweir return executeSQLCommand(command, sqlInput, sqlOutput, false); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir /** 141*cdf0e10cSrcweir * Execute an sql command. 142*cdf0e10cSrcweir * @param command The command to execute. 143*cdf0e10cSrcweir * @param sqlInput Input values for the command. 144*cdf0e10cSrcweir * @param sqlOutput The results of the command are put in this Hashtable. 145*cdf0e10cSrcweir * @param mergeOutputIntoInput The output of the result is put into the 146*cdf0e10cSrcweir * sqlInput Hashtable. 147*cdf0e10cSrcweir * @return True, if no error occured. 148*cdf0e10cSrcweir */ 149*cdf0e10cSrcweir public boolean executeSQLCommand(String command, Hashtable sqlInput, Hashtable sqlOutput, boolean mergeOutputIntoInput) 150*cdf0e10cSrcweir throws IllegalArgumentException { 151*cdf0e10cSrcweir if (sqlOutput == null) { 152*cdf0e10cSrcweir sqlOutput = new Hashtable(); 153*cdf0e10cSrcweir // this has to be true, so the user of this method gets a return 154*cdf0e10cSrcweir mergeOutputIntoInput = true; 155*cdf0e10cSrcweir if (sqlInput == null) { 156*cdf0e10cSrcweir System.out.println("sqlInput and sqlOutput are null: cannot return the results of the sql command."); 157*cdf0e10cSrcweir return false; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir Vector sqlCommand = new Vector(); 161*cdf0e10cSrcweir sqlCommand.add(""); 162*cdf0e10cSrcweir boolean update = false; 163*cdf0e10cSrcweir // synchronize all "$varname" occurences in the command string with 164*cdf0e10cSrcweir // values from input 165*cdf0e10cSrcweir StringTokenizer token = new StringTokenizer(command, " "); 166*cdf0e10cSrcweir while (token.hasMoreTokens()) { 167*cdf0e10cSrcweir String originalKey = token.nextToken(); 168*cdf0e10cSrcweir // search for keys, beginning with "$" 169*cdf0e10cSrcweir int index = originalKey.indexOf('$'); 170*cdf0e10cSrcweir if (index != -1) { 171*cdf0e10cSrcweir // found key 172*cdf0e10cSrcweir String pre = ""; 173*cdf0e10cSrcweir pre = originalKey.substring(0,index); 174*cdf0e10cSrcweir // generate key: remove "$" 175*cdf0e10cSrcweir String key = originalKey.substring(index+1); 176*cdf0e10cSrcweir String post = ""; 177*cdf0e10cSrcweir // remove any endings the key might have 178*cdf0e10cSrcweir while (key.endsWith(",") || key.endsWith("\'") || 179*cdf0e10cSrcweir key.endsWith(";") || key.endsWith(")") || 180*cdf0e10cSrcweir key.endsWith("\"")) { 181*cdf0e10cSrcweir post = key.substring(key.length()-1) + post; 182*cdf0e10cSrcweir key = key.substring(0, key.length()-1); 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir // look for key in the Hashtable 185*cdf0e10cSrcweir if (sqlInput.containsKey(key)) { 186*cdf0e10cSrcweir // is there a value for the key? 187*cdf0e10cSrcweir Object in = sqlInput.get(key); 188*cdf0e10cSrcweir if (in instanceof String[]) { 189*cdf0e10cSrcweir // value is a String[] 190*cdf0e10cSrcweir String[]vals = (String[])in; 191*cdf0e10cSrcweir if (vals.length != sqlCommand.size() && sqlCommand.size() > 1) { 192*cdf0e10cSrcweir // size of this array and previous array(s) does not match 193*cdf0e10cSrcweir throw new IllegalArgumentException("The key '" + key + "' in command \n'" 194*cdf0e10cSrcweir + command + "'\n has not the same value count as the keys before."); 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir // build up the commands 197*cdf0e10cSrcweir boolean addNewVals = (sqlCommand.size() == 1); 198*cdf0e10cSrcweir for (int i=0; i<vals.length; i++) { 199*cdf0e10cSrcweir String value = checkForQuotationMarks(vals[i]); 200*cdf0e10cSrcweir // add the values 201*cdf0e10cSrcweir if (addNewVals && i!=0) { 202*cdf0e10cSrcweir // all values until now were of type String, not String[], so now new values have to be added. 203*cdf0e10cSrcweir sqlCommand.add(i, (String)sqlCommand.get(0) + " " + pre + value + post); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir else { 206*cdf0e10cSrcweir // we already have vals.length commands (or are at the first command), so just add. 207*cdf0e10cSrcweir sqlCommand.set(i, (String)sqlCommand.get(i) + " " + pre + value + post); 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir else { 212*cdf0e10cSrcweir // value is a String: no other possibility 213*cdf0e10cSrcweir String value = checkForQuotationMarks((String)sqlInput.get(key)); 214*cdf0e10cSrcweir for (int i=0; i<sqlCommand.size(); i++) { 215*cdf0e10cSrcweir sqlCommand.set(i, (String)sqlCommand.get(i) + " " + pre + value + post); 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir else { 220*cdf0e10cSrcweir // no input value found 221*cdf0e10cSrcweir throw new IllegalArgumentException ("The key '" + key + "' in command \n'" 222*cdf0e10cSrcweir + command + "'\n does not exist in the input values."); 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir else { 226*cdf0e10cSrcweir // token is not a key, just add it 227*cdf0e10cSrcweir for (int i=0; i<sqlCommand.size(); i++) 228*cdf0e10cSrcweir sqlCommand.set(i, (String)sqlCommand.get(i) + " " + originalKey); 229*cdf0e10cSrcweir if (originalKey.equalsIgnoreCase("update") || 230*cdf0e10cSrcweir originalKey.equalsIgnoreCase("delete") || 231*cdf0e10cSrcweir originalKey.equalsIgnoreCase("insert")) { 232*cdf0e10cSrcweir update = true; 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir for (int i=0;i<sqlCommand.size(); i++) { 238*cdf0e10cSrcweir execute((String)sqlCommand.get(i), sqlOutput, update); 239*cdf0e10cSrcweir // merge output with input 240*cdf0e10cSrcweir if (!update && mergeOutputIntoInput) { 241*cdf0e10cSrcweir Enumeration keys = sqlOutput.keys(); 242*cdf0e10cSrcweir while(keys.hasMoreElements()) { 243*cdf0e10cSrcweir String key = (String)keys.nextElement(); 244*cdf0e10cSrcweir String[]val = (String[])sqlOutput.get(key); 245*cdf0e10cSrcweir if (val != null && val.length != 0) { 246*cdf0e10cSrcweir if (val.length == 1) 247*cdf0e10cSrcweir sqlInput.put(key, val[0]); 248*cdf0e10cSrcweir else 249*cdf0e10cSrcweir sqlInput.put(key, val); 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir if (!update && sqlOutput == null) 255*cdf0e10cSrcweir return false; 256*cdf0e10cSrcweir return true; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir /** 260*cdf0e10cSrcweir * Execute any SQL command. 261*cdf0e10cSrcweir * @param command The command. 262*cdf0e10cSrcweir * @param update If true, it is a update/alter command instead of an select 263*cdf0e10cSrcweir * command 264*cdf0e10cSrcweir * @return A Hashtable with the result. 265*cdf0e10cSrcweir */ 266*cdf0e10cSrcweir private void execute(String command, Hashtable output, boolean update) { 267*cdf0e10cSrcweir if (m_bDebug) 268*cdf0e10cSrcweir System.out.println("Debug - SQLExecution - execute Command: " + command); 269*cdf0e10cSrcweir try { 270*cdf0e10cSrcweir if (update) { 271*cdf0e10cSrcweir // make an update 272*cdf0e10cSrcweir mStatement.executeUpdate(command); 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir else { 275*cdf0e10cSrcweir // make a select: collect the result 276*cdf0e10cSrcweir ResultSet sqlResult = mStatement.executeQuery(command); 277*cdf0e10cSrcweir ResultSetMetaData sqlRSMeta = sqlResult.getMetaData(); 278*cdf0e10cSrcweir int columnCount = sqlRSMeta.getColumnCount(); 279*cdf0e10cSrcweir String[] columnNames = new String[columnCount]; 280*cdf0e10cSrcweir int countRows = 0; 281*cdf0e10cSrcweir boolean goThroughRowsTheFirstTime = true; 282*cdf0e10cSrcweir for(int i=1; i<=columnCount; i++) { 283*cdf0e10cSrcweir columnNames[i-1] = sqlRSMeta.getColumnName(i); 284*cdf0e10cSrcweir // initialize output 285*cdf0e10cSrcweir Vector v = new Vector(); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir sqlResult.beforeFirst(); 288*cdf0e10cSrcweir while (sqlResult.next()) { 289*cdf0e10cSrcweir String value = sqlResult.getString(i); 290*cdf0e10cSrcweir v.add(value); 291*cdf0e10cSrcweir // the first time: count rows 292*cdf0e10cSrcweir if (goThroughRowsTheFirstTime) 293*cdf0e10cSrcweir countRows++; 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir // rows are counted 296*cdf0e10cSrcweir if (goThroughRowsTheFirstTime) 297*cdf0e10cSrcweir goThroughRowsTheFirstTime = false; 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir // put result in output Hashtable 300*cdf0e10cSrcweir String[]s = new String[countRows]; 301*cdf0e10cSrcweir s = (String[])v.toArray(s); 302*cdf0e10cSrcweir output.put(columnNames[i-1], s); 303*cdf0e10cSrcweir if (m_bDebug) { 304*cdf0e10cSrcweir if (i == 1) { 305*cdf0e10cSrcweir System.out.print("Debug - SQLExecution - Command returns: "); 306*cdf0e10cSrcweir System.out.print("row: " + columnNames[i-1] + " vals: "); 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir for (int j=0; j<s.length; j++) 309*cdf0e10cSrcweir System.out.print(s[j] + " "); 310*cdf0e10cSrcweir if (i == columnCount - 1) 311*cdf0e10cSrcweir System.out.println(); 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir catch (java.sql.SQLException e) { 317*cdf0e10cSrcweir e.printStackTrace(); 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir /** 322*cdf0e10cSrcweir * Replace <"> with <''> in the value Strings, or the command will fail. 323*cdf0e10cSrcweir * @param checkString The String that is checked: a part of the command 324*cdf0e10cSrcweir * @return The String, cleared of all quotation marks. 325*cdf0e10cSrcweir */ 326*cdf0e10cSrcweir private String checkForQuotationMarks(String checkString) { 327*cdf0e10cSrcweir String returnString = checkString; 328*cdf0e10cSrcweir int quotIndex = 0; 329*cdf0e10cSrcweir while ((quotIndex = returnString.indexOf('\"')) != -1) { 330*cdf0e10cSrcweir String firstHalf = returnString.substring(0, quotIndex); 331*cdf0e10cSrcweir String secondHalf = returnString.substring(quotIndex+1); 332*cdf0e10cSrcweir returnString = firstHalf + "\'\'" + secondHalf; 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir return returnString; 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir } 338