From f152ff3665854eda95df9916a022351da219efac Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 12 Apr 2002 12:26:52 +0000 Subject: [PATCH] would parse source files before telling you that you forgot to specify a JDBC driver - make it fail faster. didn't reset its state (7552) wouldn't close input files if an error occured. I've left two XXX comments in the source for people who may know better than me. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272401 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tools/ant/taskdefs/SQLExec.java | 400 ++++++++++-------- 1 file changed, 223 insertions(+), 177 deletions(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java index c0d12c490..feffcba30 100644 --- a/src/main/org/apache/tools/ant/taskdefs/SQLExec.java +++ b/src/main/org/apache/tools/ant/taskdefs/SQLExec.java @@ -100,6 +100,8 @@ import java.sql.ResultSetMetaData; * @author Michael McCallum * @author Tim Stephenson * + * @since Ant 1.2 + * * @ant.task name="sql" category="database" */ public class SQLExec extends Task { @@ -119,6 +121,7 @@ public class SQLExec extends Task { */ private static Hashtable loaderMap = new Hashtable(3); + // XXX - why is this public? public boolean caching = true; private int goodSql = 0; @@ -351,10 +354,12 @@ public class SQLExec extends Task { } /** - * Set the Delimiter type for this sql task. The delimiter type takes - * two values - normal and row. Normal means that any occurence of the delimiter - * terminate the SQL command whereas with row, only a line containing just the - * delimiter is recognized as the end of the command. + * Set the Delimiter type for this sql task. + * + *

The delimiter type takes two values - normal and row. Normal + * means that any occurence of the delimiter terminate the SQL + * command whereas with row, only a line containing just the + * delimiter is recognized as the end of the command.

*/ public void setDelimiterType(DelimiterType delimiterType) { this.delimiterType = delimiterType.getValue(); @@ -384,7 +389,7 @@ public class SQLExec extends Task { /** * Shall we append to an existing file? * - * @since 1.36, Ant 1.5 + * @since Ant 1.5 */ public void setAppend(boolean append) { this.append = append; @@ -415,214 +420,245 @@ public class SQLExec extends Task { * Load the sql file and then execute it */ public void execute() throws BuildException { + Vector savedTransaction = (Vector) transactions.clone(); + String savedSqlCommand = sqlCommand; + sqlCommand = sqlCommand.trim(); - if (srcFile == null && sqlCommand.length()==0 && filesets.isEmpty()) { - if (transactions.size() == 0) { - throw new BuildException("Source file or fileset, transactions or sql statement must be set!", location); + try { + if (srcFile == null && sqlCommand.length()==0 + && filesets.isEmpty()) { + if (transactions.size() == 0) { + throw new BuildException("Source file or fileset, " + + "transactions or sql statement " + + "must be set!", location); + } + } + if (driver == null) { + throw new BuildException("Driver attribute must be set!", + location); } - } else { + if (userId == null) { + throw new BuildException("User Id attribute must be set!", + location); + } + if (password == null) { + throw new BuildException("Password attribute must be set!", + location); + } + if (url == null) { + throw new BuildException("Url attribute must be set!", + location); + } + if (srcFile != null && !srcFile.exists()) { + throw new BuildException("Source file does not exist!", + location); + } + Driver driverInstance = null; + try { + Class dc; + if (classpath != null) { + // check first that it is not already loaded otherwise + // consecutive runs seems to end into an OutOfMemoryError + // or it fails when there is a native library to load + // several times. + // this is far from being perfect but should work + // in most cases. + synchronized (loaderMap){ + if (caching){ + loader = (AntClassLoader)loaderMap.get(driver); + } + if (loader == null){ + log( "Loading " + driver + + " using AntClassLoader with classpath " + + classpath, + Project.MSG_VERBOSE ); + loader = new AntClassLoader(project, classpath); + if (caching){ + loaderMap.put(driver, loader); + } + } else { + log("Loading " + driver + + " using a cached AntClassLoader.", + Project.MSG_VERBOSE); + } + } + dc = loader.loadClass(driver); + } + else { + log("Loading " + driver + " using system loader.", + Project.MSG_VERBOSE); + dc = Class.forName(driver); + } + driverInstance = (Driver) dc.newInstance(); + }catch(ClassNotFoundException e){ + throw new BuildException("Class Not Found: JDBC driver " + + driver + " could not be loaded", + location); + }catch(IllegalAccessException e){ + throw new BuildException("Illegal Access: JDBC driver " + + driver + " could not be loaded", + location); + }catch(InstantiationException e) { + throw new BuildException("Instantiation Exception: JDBC driver " + + driver + " could not be loaded", + location); + } + // deal with the filesets for (int i=0; i= 0) { - sql += "\n"; - } - - if (delimiterType.equals(DelimiterType.NORMAL) && sql.endsWith(delimiter) || - delimiterType.equals(DelimiterType.ROW) && line.equals(delimiter)) { - log("SQL: " + sql, Project.MSG_VERBOSE); - execSQL(sql.substring(0, sql.length() - delimiter.length()), out); - sql = ""; + while ((line=in.readLine()) != null){ + line = line.trim(); + line = project.replaceProperties(line); + if (line.startsWith("//")) { + continue; + } + if (line.startsWith("--")) { + continue; + } + StringTokenizer st = new StringTokenizer(line); + if (st.hasMoreTokens()) { + String token = st.nextToken(); + if ("REM".equalsIgnoreCase(token)) { + continue; } } - - // Catch any statements not followed by ; - if(!sql.equals("")){ - execSQL(sql, out); + + sql += " " + line; + sql = sql.trim(); + + // SQL defines "--" as a comment to EOL + // and in Oracle it may contain a hint + // so we cannot just remove it, instead we must end it + if (line.indexOf("--") >= 0) { + sql += "\n"; + } + + if ((delimiterType.equals(DelimiterType.NORMAL) + && sql.endsWith(delimiter)) + || + (delimiterType.equals(DelimiterType.ROW) + && line.equals(delimiter))) { + log("SQL: " + sql, Project.MSG_VERBOSE); + execSQL(sql.substring(0, sql.length() - delimiter.length()), + out); + sql = ""; } - }catch(SQLException e){ - throw e; } - + + // Catch any statements not followed by ; + if(!sql.equals("")){ + execSQL(sql, out); + } } /** @@ -647,13 +683,16 @@ public class SQLExec extends Task { } if (version != null) { - String theVersion = dmd.getDatabaseProductVersion().toLowerCase(); + // XXX maybe better toLowerCase(Locale.US) + String theVersion = + dmd.getDatabaseProductVersion().toLowerCase(); log("Version = " + theVersion, Project.MSG_VERBOSE); if (theVersion == null || !(theVersion.startsWith(version) || theVersion.indexOf(" " + version) >= 0)) { - log("Not the required version: \""+ version +"\"", Project.MSG_VERBOSE); + log("Not the required version: \"" + + version +"\"", Project.MSG_VERBOSE); return false; } } @@ -673,7 +712,7 @@ public class SQLExec extends Task { protected void execSQL(String sql, PrintStream out) throws SQLException { // Check and ignore empty statements if ("".equals(sql.trim())) { - return; + return; } try { @@ -699,7 +738,7 @@ public class SQLExec extends Task { catch (SQLException e) { log("Failed to execute: " + sql, Project.MSG_ERR); if (!onError.equals("continue")) { - throw e; + throw e; } log(e.toString(), Project.MSG_ERR); } @@ -779,7 +818,8 @@ public class SQLExec extends Task { this.tSqlCommand += sql; } - private void runTransaction(PrintStream out) throws IOException, SQLException { + private void runTransaction(PrintStream out) + throws IOException, SQLException { if (tSqlCommand.length() != 0) { log("Executing commands", Project.MSG_INFO); runStatements(new StringReader(tSqlCommand), out); @@ -788,10 +828,16 @@ public class SQLExec extends Task { if (tSrcFile != null) { log("Executing file: " + tSrcFile.getAbsolutePath(), Project.MSG_INFO); - Reader reader = (encoding == null) ? new FileReader(tSrcFile) - : new InputStreamReader(new FileInputStream(tSrcFile), encoding); - runStatements(reader, out); - reader.close(); + Reader reader = + (encoding == null) ? new FileReader(tSrcFile) + : new InputStreamReader( + new FileInputStream(tSrcFile), + encoding); + try { + runStatements(reader, out); + } finally { + reader.close(); + } } } }