Coverage Report - org.apache.torque.task.TorqueSQLExec
 
Classes in this File Line Coverage Branch Coverage Complexity
TorqueSQLExec
0%
0/269
0%
0/126
3.97
TorqueSQLExec$DelimiterType
0%
0/2
N/A
3.97
TorqueSQLExec$OnError
0%
0/2
N/A
3.97
TorqueSQLExec$Transaction
0%
0/16
0%
0/6
3.97
 
 1  
 package org.apache.torque.task;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.BufferedOutputStream;
 23  
 import java.io.BufferedReader;
 24  
 import java.io.File;
 25  
 import java.io.FileInputStream;
 26  
 import java.io.FileOutputStream;
 27  
 import java.io.FileReader;
 28  
 import java.io.IOException;
 29  
 import java.io.InputStreamReader;
 30  
 import java.io.PrintStream;
 31  
 import java.io.Reader;
 32  
 import java.io.StringReader;
 33  
 import java.sql.Connection;
 34  
 import java.sql.DatabaseMetaData;
 35  
 import java.sql.Driver;
 36  
 import java.sql.ResultSet;
 37  
 import java.sql.ResultSetMetaData;
 38  
 import java.sql.SQLException;
 39  
 import java.sql.SQLWarning;
 40  
 import java.sql.Statement;
 41  
 import java.util.ArrayList;
 42  
 import java.util.HashMap;
 43  
 import java.util.Iterator;
 44  
 import java.util.List;
 45  
 import java.util.Map;
 46  
 import java.util.Properties;
 47  
 
 48  
 import org.apache.commons.lang.StringUtils;
 49  
 import org.apache.tools.ant.AntClassLoader;
 50  
 import org.apache.tools.ant.BuildException;
 51  
 import org.apache.tools.ant.Project;
 52  
 import org.apache.tools.ant.PropertyHelper;
 53  
 import org.apache.tools.ant.Task;
 54  
 import org.apache.tools.ant.types.EnumeratedAttribute;
 55  
 import org.apache.tools.ant.types.Path;
 56  
 import org.apache.tools.ant.types.Reference;
 57  
 
 58  
 /**
 59  
  * This task uses an SQL -> Database map in the form of a properties file to insert each SQL file listed into its
 60  
  * designated database.
 61  
  * 
 62  
  * @author <a href="mailto:jeff@custommonkey.org">Jeff Martin</a>
 63  
  * @author <a href="mailto:gholam@xtra.co.nz">Michael McCallum</A>
 64  
  * @author <a href="mailto:tim.stephenson@sybase.com">Tim Stephenson</A>
 65  
  * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</A>
 66  
  * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
 67  
  * @version $Id: TorqueSQLExec.java,v 1.1 2007-10-21 07:57:26 abyrne Exp $
 68  
  */
 69  0
 public class TorqueSQLExec extends Task {
 70  0
         private int goodSql = 0;
 71  0
         private int totalSql = 0;
 72  
         private Path classpath;
 73  
         private AntClassLoader loader;
 74  
 
 75  
         /**
 76  
      *
 77  
      */
 78  0
         public static class DelimiterType extends EnumeratedAttribute {
 79  
                 public static final String NORMAL = "normal";
 80  
                 public static final String ROW = "row";
 81  
 
 82  
                 public String[] getValues() {
 83  0
                         return new String[] { NORMAL, ROW };
 84  
                 }
 85  
         }
 86  
 
 87  
         /** Database connection */
 88  0
         private Connection conn = null;
 89  
 
 90  
         /** Autocommit flag. Default value is false */
 91  0
         private boolean autocommit = false;
 92  
 
 93  
         /** SQL statement */
 94  0
         private Statement statement = null;
 95  
 
 96  
         /** DB driver. */
 97  0
         private String driver = null;
 98  
 
 99  
         /** DB url. */
 100  0
         private String url = null;
 101  
 
 102  
         /** User name. */
 103  0
         private String userId = null;
 104  
 
 105  
         /** Password */
 106  0
         private String password = null;
 107  
 
 108  
         /** SQL Statement delimiter */
 109  0
         private String delimiter = ";";
 110  
 
 111  
         /**
 112  
          * The delimiter type indicating whether the delimiter will only be recognized on a line by itself
 113  
          */
 114  0
         private String delimiterType = DelimiterType.NORMAL;
 115  
 
 116  
         /** Print SQL results. */
 117  0
         private boolean print = false;
 118  
 
 119  
         /** Print header columns. */
 120  0
         private boolean showheaders = true;
 121  
 
 122  
         /** Results Output file. */
 123  0
         private File output = null;
 124  
 
 125  
         /** RDBMS Product needed for this SQL. */
 126  0
         private String rdbms = null;
 127  
 
 128  
         /** RDBMS Version needed for this SQL. */
 129  0
         private String version = null;
 130  
 
 131  
         /** Action to perform if an error is found */
 132  0
         private String onError = "abort";
 133  
 
 134  
         /** Encoding to use when reading SQL statements from a file */
 135  0
         private String encoding = null;
 136  
 
 137  
         /** Src directory for the files listed in the sqldbmap. */
 138  
         private String srcDir;
 139  
 
 140  
         /** Properties file that maps an individual SQL file to a database. */
 141  
         private File sqldbmap;
 142  
 
 143  
         /**
 144  
          * Set the sqldbmap properties file.
 145  
          * 
 146  
          * @param sqldbmap
 147  
          *            filename for the sqldbmap
 148  
          */
 149  
         public void setSqlDbMap(String sqldbmap) {
 150  0
                 this.sqldbmap = getProject().resolveFile(sqldbmap);
 151  0
         }
 152  
 
 153  
         /**
 154  
          * Get the sqldbmap properties file.
 155  
          * 
 156  
          * @return filename for the sqldbmap
 157  
          */
 158  
         public File getSqlDbMap() {
 159  0
                 return sqldbmap;
 160  
         }
 161  
 
 162  
         /**
 163  
          * Set the src directory for the sql files listed in the sqldbmap file.
 164  
          * 
 165  
          * @param srcDir
 166  
          *            sql source directory
 167  
          */
 168  
         public void setSrcDir(String srcDir) {
 169  0
                 this.srcDir = getProject().resolveFile(srcDir).toString();
 170  0
         }
 171  
 
 172  
         /**
 173  
          * Get the src directory for the sql files listed in the sqldbmap file.
 174  
          * 
 175  
          * @return sql source directory
 176  
          */
 177  
         public String getSrcDir() {
 178  0
                 return srcDir;
 179  
         }
 180  
 
 181  
         /**
 182  
          * Set the classpath for loading the driver.
 183  
          * 
 184  
          * @param classpath
 185  
          *            the classpath
 186  
          */
 187  
         public void setClasspath(Path classpath) {
 188  0
                 if (this.classpath == null) {
 189  0
                         this.classpath = classpath;
 190  
                 } else {
 191  0
                         this.classpath.append(classpath);
 192  
                 }
 193  0
         }
 194  
 
 195  
         /**
 196  
          * Create the classpath for loading the driver.
 197  
          * 
 198  
          * @return the classpath
 199  
          */
 200  
         public Path createClasspath() {
 201  0
                 if (this.classpath == null) {
 202  0
                         this.classpath = new Path(getProject());
 203  
                 }
 204  0
                 return this.classpath.createPath();
 205  
         }
 206  
 
 207  
         /**
 208  
          * Set the classpath for loading the driver using the classpath reference.
 209  
          * 
 210  
          * @param r
 211  
          *            reference to the classpath
 212  
          */
 213  
         public void setClasspathRef(Reference r) {
 214  0
                 createClasspath().setRefid(r);
 215  0
         }
 216  
 
 217  
         /**
 218  
          * Set the sql command to execute
 219  
          * 
 220  
          * @param sql
 221  
          *            sql command to execute
 222  
          * @deprecated This method has no effect and will be removed in a future version.
 223  
          */
 224  
         public void addText(String sql) {
 225  0
         }
 226  
 
 227  
         /**
 228  
          * Set the JDBC driver to be used.
 229  
          * 
 230  
          * @param driver
 231  
          *            driver class name
 232  
          */
 233  
         public void setDriver(String driver) {
 234  0
                 this.driver = driver;
 235  0
         }
 236  
 
 237  
         /**
 238  
          * Set the DB connection url.
 239  
          * 
 240  
          * @param url
 241  
          *            connection url
 242  
          */
 243  
         public void setUrl(String url) {
 244  0
                 this.url = url;
 245  0
         }
 246  
 
 247  
         /**
 248  
          * Set the user name for the DB connection.
 249  
          * 
 250  
          * @param userId
 251  
          *            database user
 252  
          */
 253  
         public void setUserid(String userId) {
 254  0
                 this.userId = userId;
 255  0
         }
 256  
 
 257  
         /**
 258  
          * Set the file encoding to use on the sql files read in
 259  
          * 
 260  
          * @param encoding
 261  
          *            the encoding to use on the files
 262  
          */
 263  
         public void setEncoding(String encoding) {
 264  0
                 this.encoding = encoding;
 265  0
         }
 266  
 
 267  
         /**
 268  
          * Set the password for the DB connection.
 269  
          * 
 270  
          * @param password
 271  
          *            database password
 272  
          */
 273  
         public void setPassword(String password) {
 274  0
                 this.password = password;
 275  0
         }
 276  
 
 277  
         /**
 278  
          * Set the autocommit flag for the DB connection.
 279  
          * 
 280  
          * @param autocommit
 281  
          *            the autocommit flag
 282  
          */
 283  
         public void setAutocommit(boolean autocommit) {
 284  0
                 this.autocommit = autocommit;
 285  0
         }
 286  
 
 287  
         /**
 288  
          * Set the statement delimiter.
 289  
          * 
 290  
          * <p>
 291  
          * For example, set this to "go" and delimitertype to "ROW" for Sybase ASE or MS SQL Server.
 292  
          * </p>
 293  
          * 
 294  
          * @param delimiter
 295  
          */
 296  
         public void setDelimiter(String delimiter) {
 297  0
                 this.delimiter = delimiter;
 298  0
         }
 299  
 
 300  
         /**
 301  
          * Set the Delimiter type for this sql task. The delimiter type takes two values - normal and row. Normal means that
 302  
          * any occurence of the delimiter terminate the SQL command whereas with row, only a line containing just the
 303  
          * delimiter is recognized as the end of the command.
 304  
          * 
 305  
          * @param delimiterType
 306  
          */
 307  
         public void setDelimiterType(DelimiterType delimiterType) {
 308  0
                 this.delimiterType = delimiterType.getValue();
 309  0
         }
 310  
 
 311  
         /**
 312  
          * Set the print flag.
 313  
          * 
 314  
          * @param print
 315  
          */
 316  
         public void setPrint(boolean print) {
 317  0
                 this.print = print;
 318  0
         }
 319  
 
 320  
         /**
 321  
          * Set the showheaders flag.
 322  
          * 
 323  
          * @param showheaders
 324  
          */
 325  
         public void setShowheaders(boolean showheaders) {
 326  0
                 this.showheaders = showheaders;
 327  0
         }
 328  
 
 329  
         /**
 330  
          * Set the output file.
 331  
          * 
 332  
          * @param output
 333  
          */
 334  
         public void setOutput(File output) {
 335  0
                 this.output = output;
 336  0
         }
 337  
 
 338  
         /**
 339  
          * Set the rdbms required
 340  
          * 
 341  
          * @param vendor
 342  
          */
 343  
         public void setRdbms(String vendor) {
 344  0
                 this.rdbms = vendor.toLowerCase();
 345  0
         }
 346  
 
 347  
         /**
 348  
          * Set the version required
 349  
          * 
 350  
          * @param version
 351  
          */
 352  
         public void setVersion(String version) {
 353  0
                 this.version = version.toLowerCase();
 354  0
         }
 355  
 
 356  
         /**
 357  
          * Set the action to perform onerror
 358  
          * 
 359  
          * @param action
 360  
          */
 361  
         public void setOnerror(OnError action) {
 362  0
                 this.onError = action.getValue();
 363  0
         }
 364  
 
 365  
         /**
 366  
          * Load the sql file and then execute it
 367  
          * 
 368  
          * @throws BuildException
 369  
          */
 370  
         @SuppressWarnings("unchecked")
 371  
         public void execute() throws BuildException {
 372  0
                 if (sqldbmap == null || getSqlDbMap().exists() == false) {
 373  0
                         throw new BuildException("You haven't provided an sqldbmap, or " + "the one you specified doesn't exist: " + sqldbmap);
 374  
                 }
 375  
 
 376  0
                 if (driver == null) {
 377  0
                         throw new BuildException("Driver attribute must be set!", getLocation());
 378  
                 }
 379  0
                 if (userId == null) {
 380  0
                         throw new BuildException("User Id attribute must be set!", getLocation());
 381  
                 }
 382  0
                 if (password == null) {
 383  0
                         throw new BuildException("Password attribute must be set!", getLocation());
 384  
                 }
 385  0
                 if (url == null) {
 386  0
                         throw new BuildException("Url attribute must be set!", getLocation());
 387  
                 }
 388  
 
 389  0
                 Properties map = new Properties();
 390  
 
 391  
                 try {
 392  0
                         FileInputStream fis = new FileInputStream(getSqlDbMap());
 393  0
                         map.load(fis);
 394  0
                         fis.close();
 395  0
                 } catch (IOException ioe) {
 396  0
                         throw new BuildException("Cannot open and process the sqldbmap!");
 397  0
                 }
 398  
 
 399  0
                 Map<Object, Object> databases = new HashMap<Object, Object>();
 400  
 
 401  0
                 Iterator<?> eachFileName = map.keySet().iterator();
 402  0
                 while (eachFileName.hasNext()) {
 403  0
                         String sqlfile = (String) eachFileName.next();
 404  0
                         String database = map.getProperty(sqlfile);
 405  
 
 406  0
                         List<Object> files = (List<Object>) databases.get(database);
 407  
 
 408  0
                         if (files == null) {
 409  0
                                 files = new ArrayList<Object>();
 410  0
                                 databases.put(database, files);
 411  
                         }
 412  
 
 413  
                         // We want to make sure that the base schemas
 414  
                         // are inserted first.
 415  0
                         if (sqlfile.indexOf("schema.sql") != -1) {
 416  0
                                 files.add(0, sqlfile);
 417  
                         } else {
 418  0
                                 files.add(sqlfile);
 419  
                         }
 420  0
                 }
 421  
 
 422  0
                 Iterator<?> eachDatabase = databases.keySet().iterator();
 423  0
                 while (eachDatabase.hasNext()) {
 424  0
                         String db = (String) eachDatabase.next();
 425  0
                         List<Object> transactions = new ArrayList<Object>();
 426  0
                         eachFileName = ((List<?>) databases.get(db)).iterator();
 427  0
                         while (eachFileName.hasNext()) {
 428  0
                                 String fileName = (String) eachFileName.next();
 429  0
                                 File file = new File(srcDir, fileName);
 430  
 
 431  0
                                 if (file.exists()) {
 432  0
                                         Transaction transaction = new Transaction();
 433  0
                                         transaction.setSrc(file);
 434  0
                                         transactions.add(transaction);
 435  0
                                 } else {
 436  0
                                         System.out.println("File '" + file.getAbsolutePath() + "' in sqldbmap does not exist, so skipping it.");
 437  
                                 }
 438  0
                         }
 439  
 
 440  0
                         insertDatabaseSqlFiles(url, db, transactions);
 441  0
                 }
 442  0
         }
 443  
 
 444  
         /**
 445  
          * Take the base url, the target database and insert a set of SQL files into the target database.
 446  
          * 
 447  
          * @param url
 448  
          * @param database
 449  
          * @param transactions
 450  
          */
 451  
         private void insertDatabaseSqlFiles(String url, String database, List<?> transactions) {
 452  0
                 url = StringUtils.replace(url, "@DB@", database);
 453  0
                 System.out.println("Our new url -> " + url);
 454  
 
 455  0
                 Driver driverInstance = null;
 456  
                 try {
 457  
                         Class<?> dc;
 458  0
                         if (classpath != null) {
 459  0
                                 log("Loading " + driver + " using AntClassLoader with classpath " + classpath, Project.MSG_VERBOSE);
 460  
 
 461  0
                                 loader = new AntClassLoader(getProject(), classpath);
 462  0
                                 dc = loader.loadClass(driver);
 463  
                         } else {
 464  0
                                 log("Loading " + driver + " using system loader.", Project.MSG_VERBOSE);
 465  0
                                 dc = Class.forName(driver);
 466  
                         }
 467  0
                         driverInstance = (Driver) dc.newInstance();
 468  0
                 } catch (ClassNotFoundException e) {
 469  0
                         throw new BuildException("Class Not Found: JDBC driver " + driver + " could not be loaded", getLocation());
 470  0
                 } catch (IllegalAccessException e) {
 471  0
                         throw new BuildException("Illegal Access: JDBC driver " + driver + " could not be loaded", getLocation());
 472  0
                 } catch (InstantiationException e) {
 473  0
                         throw new BuildException("Instantiation Exception: JDBC driver " + driver + " could not be loaded", getLocation());
 474  0
                 }
 475  
 
 476  
                 try {
 477  0
                         log("connecting to " + url, Project.MSG_VERBOSE);
 478  0
                         Properties info = new Properties();
 479  0
                         info.put("user", userId);
 480  0
                         info.put("password", password);
 481  0
                         conn = driverInstance.connect(url, info);
 482  
 
 483  0
                         if (conn == null) {
 484  
                                 // Driver doesn't understand the URL
 485  0
                                 throw new SQLException("No suitable Driver for " + url);
 486  
                         }
 487  
 
 488  0
                         if (!isValidRdbms(conn)) {
 489  
                                 return;
 490  
                         }
 491  
 
 492  0
                         conn.setAutoCommit(autocommit);
 493  0
                         statement = conn.createStatement();
 494  0
                         PrintStream out = System.out;
 495  
                         try {
 496  0
                                 if (output != null) {
 497  0
                                         log("Opening PrintStream to output file " + output, Project.MSG_VERBOSE);
 498  0
                                         out = new PrintStream(new BufferedOutputStream(new FileOutputStream(output)));
 499  
                                 }
 500  
 
 501  
                                 // Process all transactions
 502  0
                                 for (Iterator<?> it = transactions.iterator(); it.hasNext();) {
 503  0
                                         Transaction transaction = (Transaction) it.next();
 504  0
                                         transaction.runTransaction(out);
 505  0
                                         if (!autocommit) {
 506  0
                                                 log("Commiting transaction", Project.MSG_VERBOSE);
 507  0
                                                 conn.commit();
 508  
                                         }
 509  0
                                 }
 510  
                         } finally {
 511  0
                                 if (out != null && out != System.out) {
 512  0
                                         out.close();
 513  
                                 }
 514  
                         }
 515  0
                 } catch (IOException e) {
 516  0
                         if (!autocommit && conn != null && onError.equals("abort")) {
 517  
                                 try {
 518  0
                                         conn.rollback();
 519  0
                                 } catch (SQLException ex) {
 520  
                                         // do nothing.
 521  0
                                 }
 522  
                         }
 523  0
                         throw new BuildException(e, getLocation());
 524  0
                 } catch (SQLException e) {
 525  0
                         if (!autocommit && conn != null && onError.equals("abort")) {
 526  
                                 try {
 527  0
                                         conn.rollback();
 528  0
                                 } catch (SQLException ex) {
 529  
                                         // do nothing.
 530  0
                                 }
 531  
                         }
 532  0
                         throw new BuildException(e, getLocation());
 533  
                 } finally {
 534  0
                         try {
 535  0
                                 if (statement != null) {
 536  0
                                         statement.close();
 537  
                                 }
 538  0
                                 if (conn != null) {
 539  0
                                         conn.close();
 540  
                                 }
 541  0
                         } catch (SQLException e) {
 542  0
                         }
 543  0
                 }
 544  
 
 545  0
                 System.out.println(goodSql + " of " + totalSql + " SQL statements executed successfully");
 546  0
         }
 547  
 
 548  
         /**
 549  
          * Read the statements from the .sql file and execute them. Lines starting with '//', '--' or 'REM ' are ignored.
 550  
          * 
 551  
          * @param reader
 552  
          * @param out
 553  
          * @throws SQLException
 554  
          * @throws IOException
 555  
          */
 556  
         protected void runStatements(Reader reader, PrintStream out) throws SQLException, IOException {
 557  0
                 String sql = "";
 558  0
                 String line = "";
 559  
 
 560  0
                 BufferedReader in = new BufferedReader(reader);
 561  0
                 PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
 562  
 
 563  
                 try {
 564  0
                         while ((line = in.readLine()) != null) {
 565  0
                                 line = line.trim();
 566  0
                                 line = ph.replaceProperties("", line, getProject().getProperties());
 567  0
                                 if (line.startsWith("//") || line.startsWith("--")) {
 568  0
                                         continue;
 569  
                                 }
 570  0
                                 if (line.length() > 4 && line.substring(0, 4).equalsIgnoreCase("REM ")) {
 571  0
                                         continue;
 572  
                                 }
 573  
 
 574  0
                                 sql += " " + line;
 575  0
                                 sql = sql.trim();
 576  
 
 577  
                                 // SQL defines "--" as a comment to EOL
 578  
                                 // and in Oracle it may contain a hint
 579  
                                 // so we cannot just remove it, instead we must end it
 580  0
                                 if (line.indexOf("--") >= 0) {
 581  0
                                         sql += "\n";
 582  
                                 }
 583  
 
 584  0
                                 if (delimiterType.equals(DelimiterType.NORMAL) && sql.endsWith(delimiter) || delimiterType.equals(DelimiterType.ROW) && line.equals(delimiter)) {
 585  0
                                         log("SQL: " + sql, Project.MSG_VERBOSE);
 586  0
                                         execSQL(sql.substring(0, sql.length() - delimiter.length()), out);
 587  0
                                         sql = "";
 588  
                                 }
 589  
                         }
 590  
 
 591  
                         // Catch any statements not followed by ;
 592  0
                         if (!sql.equals("")) {
 593  0
                                 execSQL(sql, out);
 594  
                         }
 595  0
                 } catch (SQLException e) {
 596  0
                         throw e;
 597  0
                 }
 598  0
         }
 599  
 
 600  
         /**
 601  
          * Verify if connected to the correct RDBMS
 602  
          * 
 603  
          * @param conn
 604  
          */
 605  
         protected boolean isValidRdbms(Connection conn) {
 606  0
                 if (rdbms == null && version == null) {
 607  0
                         return true;
 608  
                 }
 609  
 
 610  
                 try {
 611  0
                         DatabaseMetaData dmd = conn.getMetaData();
 612  
 
 613  0
                         if (rdbms != null) {
 614  0
                                 String theVendor = dmd.getDatabaseProductName().toLowerCase();
 615  
 
 616  0
                                 log("RDBMS = " + theVendor, Project.MSG_VERBOSE);
 617  0
                                 if (theVendor == null || theVendor.indexOf(rdbms) < 0) {
 618  0
                                         log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE);
 619  0
                                         return false;
 620  
                                 }
 621  
                         }
 622  
 
 623  0
                         if (version != null) {
 624  0
                                 String theVersion = dmd.getDatabaseProductVersion().toLowerCase();
 625  
 
 626  0
                                 log("Version = " + theVersion, Project.MSG_VERBOSE);
 627  0
                                 if (theVersion == null || !(theVersion.startsWith(version) || theVersion.indexOf(" " + version) >= 0)) {
 628  0
                                         log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE);
 629  0
                                         return false;
 630  
                                 }
 631  
                         }
 632  0
                 } catch (SQLException e) {
 633  
                         // Could not get the required information
 634  0
                         log("Failed to obtain required RDBMS information", Project.MSG_ERR);
 635  0
                         return false;
 636  0
                 }
 637  
 
 638  0
                 return true;
 639  
         }
 640  
 
 641  
         /**
 642  
          * Exec the sql statement.
 643  
          * 
 644  
          * @param sql
 645  
          * @param out
 646  
          * @throws SQLException
 647  
          */
 648  
         protected void execSQL(String sql, PrintStream out) throws SQLException {
 649  
                 // Check and ignore empty statements
 650  0
                 if ("".equals(sql.trim())) {
 651  0
                         return;
 652  
                 }
 653  
 
 654  
                 try {
 655  0
                         totalSql++;
 656  0
                         if (!statement.execute(sql)) {
 657  0
                                 log(statement.getUpdateCount() + " rows affected", Project.MSG_VERBOSE);
 658  
                         } else {
 659  0
                                 if (print) {
 660  0
                                         printResults(out);
 661  
                                 }
 662  
                         }
 663  
 
 664  0
                         SQLWarning warning = conn.getWarnings();
 665  0
                         while (warning != null) {
 666  0
                                 log(warning + " sql warning", Project.MSG_VERBOSE);
 667  0
                                 warning = warning.getNextWarning();
 668  
                         }
 669  0
                         conn.clearWarnings();
 670  0
                         goodSql++;
 671  0
                 } catch (SQLException e) {
 672  0
                         System.out.println("Failed to execute: " + sql);
 673  0
                         if (!onError.equals("continue")) {
 674  0
                                 throw e;
 675  
                         }
 676  0
                         log(e.toString(), Project.MSG_ERR);
 677  0
                 }
 678  0
         }
 679  
 
 680  
         /**
 681  
          * print any results in the statement.
 682  
          * 
 683  
          * @param out
 684  
          * @throws SQLException
 685  
          */
 686  
         protected void printResults(PrintStream out) throws java.sql.SQLException {
 687  0
                 ResultSet rs = null;
 688  
                 do {
 689  0
                         rs = statement.getResultSet();
 690  0
                         if (rs != null) {
 691  0
                                 log("Processing new result set.", Project.MSG_VERBOSE);
 692  0
                                 ResultSetMetaData md = rs.getMetaData();
 693  0
                                 int columnCount = md.getColumnCount();
 694  0
                                 StringBuffer line = new StringBuffer();
 695  0
                                 if (showheaders) {
 696  0
                                         for (int col = 1; col < columnCount; col++) {
 697  0
                                                 line.append(md.getColumnName(col));
 698  0
                                                 line.append(",");
 699  
                                         }
 700  0
                                         line.append(md.getColumnName(columnCount));
 701  0
                                         out.println(line);
 702  0
                                         line.setLength(0);
 703  
                                 }
 704  0
                                 while (rs.next()) {
 705  0
                                         boolean first = true;
 706  0
                                         for (int col = 1; col <= columnCount; col++) {
 707  0
                                                 String columnValue = rs.getString(col);
 708  0
                                                 if (columnValue != null) {
 709  0
                                                         columnValue = columnValue.trim();
 710  
                                                 }
 711  
 
 712  0
                                                 if (first) {
 713  0
                                                         first = false;
 714  
                                                 } else {
 715  0
                                                         line.append(",");
 716  
                                                 }
 717  0
                                                 line.append(columnValue);
 718  
                                         }
 719  0
                                         out.println(line);
 720  0
                                         line.setLength(0);
 721  0
                                 }
 722  
                         }
 723  0
                 } while (statement.getMoreResults());
 724  0
                 out.println();
 725  0
         }
 726  
 
 727  
         /**
 728  
          * Enumerated attribute with the values "continue", "stop" and "abort" for the onerror attribute.
 729  
          */
 730  0
         public static class OnError extends EnumeratedAttribute {
 731  
                 public static final String CONTINUE = "continue";
 732  
 
 733  
                 public static final String STOP = "stop";
 734  
 
 735  
                 public static final String ABORT = "abort";
 736  
 
 737  
                 public String[] getValues() {
 738  0
                         return new String[] { CONTINUE, STOP, ABORT };
 739  
                 }
 740  
         }
 741  
 
 742  
         /**
 743  
          * Contains the definition of a new transaction element. Transactions allow several files or blocks of statements to
 744  
          * be executed using the same JDBC connection and commit operation in between.
 745  
          */
 746  0
         public class Transaction {
 747  0
                 private File tSrcFile = null;
 748  0
                 private String tSqlCommand = "";
 749  
 
 750  
                 public void setSrc(File src) {
 751  0
                         this.tSrcFile = src;
 752  0
                 }
 753  
 
 754  
                 public void addText(String sql) {
 755  0
                         this.tSqlCommand += sql;
 756  0
                 }
 757  
 
 758  
                 private void runTransaction(PrintStream out) throws IOException, SQLException {
 759  0
                         if (tSqlCommand.length() != 0) {
 760  0
                                 log("Executing commands", Project.MSG_INFO);
 761  0
                                 runStatements(new StringReader(tSqlCommand), out);
 762  
                         }
 763  
 
 764  0
                         if (tSrcFile != null) {
 765  0
                                 System.out.println("Executing file: " + tSrcFile.getAbsolutePath());
 766  0
                                 Reader reader = (encoding == null) ? new FileReader(tSrcFile) : new InputStreamReader(new FileInputStream(tSrcFile), encoding);
 767  0
                                 runStatements(reader, out);
 768  0
                                 reader.close();
 769  
                         }
 770  0
                 }
 771  
         }
 772  
 }