bodewig 02/04/12 05:26:52
Modified: src/main/org/apache/tools/ant/taskdefs SQLExec.java
Log:
<sql> would parse source files before telling you that you forgot to
specify a JDBC driver - make it fail faster.
<sql> didn't reset its state (7552)
<sql> 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.
Revision Changes Path
1.37 +223 -177
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
Index: SQLExec.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/SQLExec.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- SQLExec.java 5 Apr 2002 09:28:54 -0000 1.36
+++ SQLExec.java 12 Apr 2002 12:26:52 -0000 1.37
@@ -100,6 +100,8 @@
* @author <A href="mailto:[EMAIL PROTECTED]">Michael McCallum</A>
* @author <A href="mailto:[EMAIL PROTECTED]">Tim Stephenson</A>
*
+ * @since Ant 1.2
+ *
* @ant.task name="sql" category="database"
*/
public class SQLExec extends Task {
@@ -119,6 +121,7 @@
*/
private static Hashtable loaderMap = new Hashtable(3);
+ // XXX - why is this public?
public boolean caching = true;
private int goodSql = 0;
@@ -351,10 +354,12 @@
}
/**
- * 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.
+ *
+ * <p>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.</p>
*/
public void setDelimiterType(DelimiterType delimiterType) {
this.delimiterType = delimiterType.getValue();
@@ -384,7 +389,7 @@
/**
* 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 @@
* 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);
+ }
+ 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);
}
- } else {
+ 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<filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(project);
File srcDir = fs.getDir(project);
-
+
String[] srcFiles = ds.getIncludedFiles();
-
+
// Make a transaction for each file
for ( int j=0 ; j<srcFiles.length ; j++ ) {
Transaction t = createTransaction();
t.setSrc(new File(srcDir, srcFiles[j]));
}
}
-
+
// Make a transaction group for the outer command
Transaction t = createTransaction();
t.setSrc(srcFile);
t.addText(sqlCommand);
- }
- if (driver == null) {
- throw new BuildException("Driver attribute must be set!",
location);
- }
- 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);
- }
+ try{
+ log("connecting to " + url, Project.MSG_VERBOSE );
+ Properties info = new Properties();
+ info.put("user", userId);
+ info.put("password", password);
+ conn = driverInstance.connect(url, info);
+
+ if (conn == null) {
+ // Driver doesn't understand the URL
+ throw new SQLException("No suitable Driver for "+url);
+ }
+
+ if (!isValidRdbms(conn)) {
+ return;
}
- 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);
- }
-
- try{
- log("connecting to " + url, Project.MSG_VERBOSE );
- Properties info = new Properties();
- info.put("user", userId);
- info.put("password", password);
- conn = driverInstance.connect(url, info);
-
- if (conn == null) {
- // Driver doesn't understand the URL
- throw new SQLException("No suitable Driver for "+url);
- }
-
- if (!isValidRdbms(conn)) {
- return;
- }
- conn.setAutoCommit(autocommit);
+ conn.setAutoCommit(autocommit);
- statement = conn.createStatement();
+ statement = conn.createStatement();
- PrintStream out = System.out;
- try {
- if (output != null) {
- log("Opening PrintStream to output file " + output,
Project.MSG_VERBOSE);
- out = new PrintStream(new BufferedOutputStream(new
FileOutputStream(output.getAbsolutePath(), append)));
- }
-
- // Process all transactions
- for (Enumeration e = transactions.elements();
- e.hasMoreElements();) {
+ PrintStream out = System.out;
+ try {
+ if (output != null) {
+ log("Opening PrintStream to output file " + output,
+ Project.MSG_VERBOSE);
+ out = new PrintStream(
+ new BufferedOutputStream(
+ new FileOutputStream(output
+
.getAbsolutePath(),
+ append)));
+ }
+
+ // Process all transactions
+ for (Enumeration e = transactions.elements();
+ e.hasMoreElements();) {
- ((Transaction) e.nextElement()).runTransaction(out);
- if (!autocommit) {
- log("Commiting transaction", Project.MSG_VERBOSE);
- conn.commit();
+ ((Transaction) e.nextElement()).runTransaction(out);
+ if (!autocommit) {
+ log("Commiting transaction",
Project.MSG_VERBOSE);
+ conn.commit();
+ }
}
}
- }
- finally {
- if (out != null && out != System.out) {
- out.close();
+ finally {
+ if (out != null && out != System.out) {
+ out.close();
+ }
}
+ } catch(IOException e){
+ if (!autocommit && conn != null && onError.equals("abort")) {
+ try {
+ conn.rollback();
+ } catch (SQLException ex) {}
+ }
+ throw new BuildException(e, location);
+ } catch(SQLException e){
+ if (!autocommit && conn != null && onError.equals("abort")) {
+ try {
+ conn.rollback();
+ } catch (SQLException ex) {}
+ }
+ throw new BuildException(e, location);
}
- } catch(IOException e){
- if (!autocommit && conn != null && onError.equals("abort")) {
- try {
- conn.rollback();
- } catch (SQLException ex) {}
- }
- throw new BuildException(e, location);
- } catch(SQLException e){
- if (!autocommit && conn != null && onError.equals("abort")) {
+ finally {
try {
- conn.rollback();
- } catch (SQLException ex) {}
- }
- throw new BuildException(e, location);
- }
- finally {
- try {
- if (statement != null) {
- statement.close();
- }
- if (conn != null) {
- conn.close();
+ if (statement != null) {
+ statement.close();
+ }
+ if (conn != null) {
+ conn.close();
+ }
}
+ catch (SQLException e) {}
}
- catch (SQLException e) {}
+
+ log(goodSql + " of " + totalSql +
+ " SQL statements executed successfully");
+ } finally {
+ transactions = savedTransaction;
+ sqlCommand = savedSqlCommand;
}
-
- log(goodSql + " of " + totalSql +
- " SQL statements executed successfully");
}
- protected void runStatements(Reader reader, PrintStream out) throws
SQLException, IOException {
+ protected void runStatements(Reader reader, PrintStream out)
+ throws SQLException, IOException {
String sql = "";
String line = "";
BufferedReader in = new BufferedReader(reader);
- try{
- 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;
- }
- }
-
- 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 = "";
+ 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 @@
}
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 @@
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 @@
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 @@
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 @@
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();
+ }
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>