bump product version to 4.1.6.2
[LibreOffice.git] / qadevOOo / runner / stats / SQLExecution.java
blobe65ac26d3f12c7d1fea5fbd50cd5699d79a1ff07
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 package stats;
20 import java.sql.Connection;
21 import java.sql.DriverManager;
22 import java.sql.ResultSet;
23 import java.sql.ResultSetMetaData;
24 import java.sql.Statement;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.StringTokenizer;
30 /**
33 public class SQLExecution {
35 protected Connection mConnection = null;
36 protected Statement mStatement = null;
37 protected String mJdbcClass = null;
38 protected String mDbURL = null;
39 protected String mUser = null;
40 protected String mPassword = null;
41 protected boolean m_bConnectionOpen = false;
42 protected boolean m_bDebug = false;
45 /** Creates a new instance of SQLExecution
46 * @param jdbcClass The jdbc class for the connection.
47 * @param dbUrl The url of the database.
48 * @param user The user for connecting the database.
49 * @param password The password of throws user.
51 public SQLExecution(String jdbcClass, String dbUrl, String user, String password) {
52 mJdbcClass = jdbcClass;
53 mUser = user;
54 mPassword = password;
55 mDbURL = dbUrl;
58 /** Creates a new instance of SQLExecution with additional debug output.
59 * @param jdbcClass The jdbc class for the connection.
60 * @param dbUrl The url of the database.
61 * @param user The user for connecting the database.
62 * @param password The password of throws user.
63 * @param debug Write debug information, if true.
65 public SQLExecution(String jdbcClass, String dbUrl, String user, String password, boolean debug) {
66 mJdbcClass = jdbcClass;
67 mUser = user;
68 mPassword = password;
69 mDbURL = dbUrl;
70 m_bDebug = debug;
73 /**
74 * Open a connection to the DataBase
75 * @return True, if no error occurred.
77 public boolean openConnection() {
78 if(m_bConnectionOpen) return true;
79 try {
80 Class.forName(mJdbcClass);
81 } catch (ClassNotFoundException e) {
82 System.err.println("Couldn't find jdbc driver : " + e.getMessage());
83 return false;
86 try {
87 // establish database connection
88 mConnection = DriverManager.getConnection(
89 mDbURL, mUser, mPassword);
90 mStatement = mConnection.createStatement();
92 catch(java.sql.SQLException e) {
93 System.err.println("Couldn't establish a connection: " + e.getMessage());
94 return false;
96 m_bConnectionOpen = true;
97 return true;
101 * Close the connection to the DataBase
102 * @return True, if no error occurred.
104 public boolean closeConnection() {
105 if (!m_bConnectionOpen) return true;
106 try {
107 // close database connection
108 mStatement.close();
109 mConnection.close();
111 catch(java.sql.SQLException e) {
112 System.err.println("Couldn't close the connection: " + e.getMessage());
113 return false;
115 m_bConnectionOpen = false;
116 return true;
120 * Execute an sql command.
121 * @param command The command to execute.
122 * @param sqlInput Input values for the command.
123 * @param sqlOutput The results of the command are put in this HashMap.
124 * @return True, if no error occurred.
126 public boolean executeSQLCommand(String command, HashMap<String,Object> sqlInput, HashMap<String, String[]> sqlOutput)
127 throws IllegalArgumentException {
128 return executeSQLCommand(command, sqlInput, sqlOutput, false);
132 * Execute an sql command.
133 * @param command The command to execute.
134 * @param sqlInput Input values for the command.
135 * @param sqlOutput The results of the command are put in this HashMap.
136 * @param mergeOutputIntoInput The output of the result is put into the
137 * sqlInput HashMap.
138 * @return True, if no error occurred.
140 public boolean executeSQLCommand(String command, HashMap<String,Object> sqlInput, HashMap<String, String[]> sqlOutput, boolean mergeOutputIntoInput)
141 throws IllegalArgumentException {
142 if (sqlOutput == null) {
143 sqlOutput = new HashMap<String, String[]>();
144 // this has to be true, so the user of this method gets a return
145 mergeOutputIntoInput = true;
146 if (sqlInput == null) {
147 System.out.println("sqlInput and sqlOutput are null: cannot return the results of the sql command.");
148 return false;
151 ArrayList<String> sqlCommand = new ArrayList<String>();
152 sqlCommand.add("");
153 boolean update = false;
154 // synchronize all "$varname" occurrences in the command string with
155 // values from input
156 StringTokenizer token = new StringTokenizer(command, " ");
157 while (token.hasMoreTokens()) {
158 String originalKey = token.nextToken();
159 // search for keys, beginning with "$"
160 int index = originalKey.indexOf('$');
161 if (index != -1) {
162 // found key
163 String pre = "";
164 pre = originalKey.substring(0,index);
165 // generate key: remove "$"
166 String key = originalKey.substring(index+1);
167 String post = "";
168 // remove any endings the key might have
169 while (key.endsWith(",") || key.endsWith("\'") ||
170 key.endsWith(";") || key.endsWith(")") ||
171 key.endsWith("\"")) {
172 post = key.substring(key.length()-1) + post;
173 key = key.substring(0, key.length()-1);
175 // look for key in the Hashtable
176 if (sqlInput.containsKey(key)) {
177 // is there a value for the key?
178 Object in = sqlInput.get(key);
179 if (in instanceof String[]) {
180 // value is a String[]
181 String[]vals = (String[])in;
182 if (vals.length != sqlCommand.size() && sqlCommand.size() > 1) {
183 // size of this array and previous array(s) does not match
184 throw new IllegalArgumentException("The key '" + key + "' in command \n'"
185 + command + "'\n has not the same value count as the keys before.");
187 // build up the commands
188 boolean addNewVals = (sqlCommand.size() == 1);
189 for (int i=0; i<vals.length; i++) {
190 String value = checkForQuotationMarks(vals[i]);
191 // add the values
192 if (addNewVals && i!=0) {
193 // all values until now were of type String, not String[], so now new values have to be added.
194 sqlCommand.add(i, sqlCommand.get(0) + " " + pre + value + post);
196 else {
197 // we already have vals.length commands (or are at the first command), so just add.
198 sqlCommand.set(i, sqlCommand.get(i) + " " + pre + value + post);
202 else {
203 // value is a String: no other possibility
204 String value = checkForQuotationMarks((String)sqlInput.get(key));
205 for (int i=0; i<sqlCommand.size(); i++) {
206 sqlCommand.set(i, sqlCommand.get(i) + " " + pre + value + post);
210 else {
211 // no input value found
212 throw new IllegalArgumentException ("The key '" + key + "' in command \n'"
213 + command + "'\n does not exist in the input values.");
216 else {
217 // token is not a key, just add it
218 for (int i=0; i<sqlCommand.size(); i++)
219 sqlCommand.set(i, sqlCommand.get(i) + " " + originalKey);
220 if (originalKey.equalsIgnoreCase("update") ||
221 originalKey.equalsIgnoreCase("delete") ||
222 originalKey.equalsIgnoreCase("insert")) {
223 update = true;
228 for (int i=0;i<sqlCommand.size(); i++) {
229 execute(sqlCommand.get(i), sqlOutput, update);
230 // merge output with input
231 if (!update && mergeOutputIntoInput) {
232 Iterator<String> keys = sqlOutput.keySet().iterator();
233 while(keys.hasNext()) {
234 String key = keys.next();
235 String[]val = sqlOutput.get(key);
236 if (val != null && val.length != 0) {
237 if (val.length == 1)
238 sqlInput.put(key, val[0]);
239 else
240 sqlInput.put(key, val);
245 if (!update && sqlOutput == null)
246 return false;
247 return true;
251 * Execute any SQL command.
252 * @param command The command.
253 * @param update If true, it is a update/alter command instead of an select
254 * command
255 * @param output A HashMap with the result.
257 private void execute(String command, HashMap<String, String[]> output, boolean update) {
258 if (m_bDebug)
259 System.out.println("Debug - SQLExecution - execute Command: " + command);
260 try {
261 if (update) {
262 // make an update
263 mStatement.executeUpdate(command);
265 else {
266 // make a select: collect the result
267 ResultSet sqlResult = mStatement.executeQuery(command);
268 ResultSetMetaData sqlRSMeta = sqlResult.getMetaData();
269 int columnCount = sqlRSMeta.getColumnCount();
270 String[] columnNames = new String[columnCount];
271 int countRows = 0;
272 boolean goThroughRowsTheFirstTime = true;
273 for(int i=1; i<=columnCount; i++) {
274 columnNames[i-1] = sqlRSMeta.getColumnName(i);
275 // initialize output
276 ArrayList<String> v = new ArrayList<String>();
278 sqlResult.beforeFirst();
279 while (sqlResult.next()) {
280 String value = sqlResult.getString(i);
281 v.add(value);
282 // the first time: count rows
283 if (goThroughRowsTheFirstTime)
284 countRows++;
286 // rows are counted
287 if (goThroughRowsTheFirstTime)
288 goThroughRowsTheFirstTime = false;
290 // put result in output HashMap
291 String[]s = new String[countRows];
292 s = v.toArray(s);
293 output.put(columnNames[i-1], s);
294 if (m_bDebug) {
295 if (i == 1) {
296 System.out.print("Debug - SQLExecution - Command returns: ");
297 System.out.print("row: " + columnNames[i-1] + " vals: ");
299 for (int j=0; j<s.length; j++)
300 System.out.print(s[j] + " ");
301 if (i == columnCount - 1)
302 System.out.println();
307 catch (java.sql.SQLException e) {
308 e.printStackTrace();
313 * Replace <"> with <''> in the value Strings, or the command will fail.
314 * @param checkString The String that is checked: a part of the command
315 * @return The String, cleared of all quotation marks.
317 private String checkForQuotationMarks(String checkString) {
318 String returnString = checkString;
319 int quotIndex = 0;
320 while ((quotIndex = returnString.indexOf('\"')) != -1) {
321 String firstHalf = returnString.substring(0, quotIndex);
322 String secondHalf = returnString.substring(quotIndex+1);
323 returnString = firstHalf + "\'\'" + secondHalf;
325 return returnString;