001: /*
002: * (c) Copyright 2007 by Volker Bergmann. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, is permitted under the terms of the
006: * GNU General Public License.
007: *
008: * For redistributing this software or a derivative work under a license other
009: * than the GPL-compatible Free Software License as defined by the Free
010: * Software Foundation or approved by OSI, you must first obtain a commercial
011: * license to this software product from Volker Bergmann.
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
014: * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
015: * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
016: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
017: * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
018: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
019: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
020: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
021: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
022: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
023: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGE.
025: */
026:
027: package org.databene.platform.db;
028:
029: import org.databene.task.AbstractTask;
030: import org.databene.task.TaskException;
031: import org.databene.commons.IOUtil;
032: import org.databene.commons.ReaderLineIterator;
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
036: import java.io.BufferedReader;
037: import java.io.IOException;
038: import java.sql.Connection;
039: import java.sql.Statement;
040: import java.sql.SQLException;
041:
042: /**
043: * Runs a SQL script against the specified database.<br/>
044: * <br/>
045: * Created: 23.08.2007 06:38:43
046: * @author Volker Bergmann
047: */
048: public class RunSqlScriptTask extends AbstractTask {
049:
050: private static final Log logger = LogFactory
051: .getLog(RunSqlScriptTask.class);
052: private static final Log sqlLogger = LogFactory
053: .getLog("org.databene.benerator.SQL");
054:
055: private String uri;
056: private DBSystem db;
057: private boolean haltOnError;
058: private boolean ignoreComments;
059:
060: // constructors ----------------------------------------------------------------------------------------------------
061:
062: public RunSqlScriptTask() {
063: this (null, null);
064: }
065:
066: public RunSqlScriptTask(String uri, DBSystem db) {
067: this .uri = uri;
068: this .db = db;
069: this .haltOnError = true;
070: this .ignoreComments = false;
071: }
072:
073: // properties ------------------------------------------------------------------------------------------------------
074:
075: public String getUri() {
076: return uri;
077: }
078:
079: public void setUri(String uri) {
080: this .uri = uri;
081: }
082:
083: public DBSystem getDb() {
084: return db;
085: }
086:
087: public void setDb(DBSystem db) {
088: this .db = db;
089: }
090:
091: public boolean isHaltOnError() {
092: return haltOnError;
093: }
094:
095: public void setHaltOnError(boolean haltOnError) {
096: this .haltOnError = haltOnError;
097: }
098:
099: /**
100: * @return the ignoringComments
101: */
102: public boolean isIgnoreComments() {
103: return ignoreComments;
104: }
105:
106: /**
107: * @param ignoreComments the ignoringComments to set
108: */
109: public void setIgnoreComments(boolean ignoreComments) {
110: this .ignoreComments = ignoreComments;
111: }
112:
113: // Task implementation ---------------------------------------------------------------------------
114:
115: public void run() {
116: Connection connection = null;
117: Exception exception = null;
118: try {
119: connection = db.createConnection();
120: BufferedReader reader = IOUtil.getReaderForURI(uri);
121: ReaderLineIterator iterator = new ReaderLineIterator(reader);
122: StringBuilder cmd = new StringBuilder();
123: while (iterator.hasNext()) {
124: String line = iterator.next();
125: if (line.startsWith("--"))
126: continue;
127: if (cmd.length() > 0)
128: cmd.append('\r');
129: cmd.append(line.trim());
130: if (line.endsWith(";"))
131: execute(connection, cmd);
132: }
133: iterator.close();
134: } catch (IOException e) {
135: exception = e;
136: if (haltOnError)
137: throw new TaskException(e);
138: else
139: logger.error(e.getMessage());
140: } finally {
141: if (connection != null) {
142: try {
143: if (exception != null && haltOnError)
144: connection.rollback();
145: else
146: connection.commit();
147: } catch (SQLException e) {
148: exception = e;
149: }
150: DBUtil.close(connection);
151: }
152: }
153: if (exception != null)
154: throw new RuntimeException(exception);
155: }
156:
157: // java.lang.Object overrides --------------------------------------------------------------------------------------
158:
159: public String toString() {
160: return getClass().getSimpleName() + '[' + uri + "->"
161: + db.getId() + ']';
162: }
163:
164: // private helpers -------------------------------------------------------------------------------------------------
165:
166: private void execute(Connection connection, StringBuilder cmd) {
167: // delete the trailing ';'
168: cmd.delete(cmd.length() - 1, cmd.length());
169: try {
170: executeUpdate(cmd.toString(), connection);
171: } catch (SQLException e) {
172: if (haltOnError)
173: throw new TaskException(e);
174: else
175: logger.error(e.getMessage() + ":\n" + cmd);
176: } finally {
177: cmd.delete(0, cmd.length());
178: }
179: }
180:
181: private int executeUpdate(String sql, Connection connection)
182: throws SQLException {
183: if (ignoreComments
184: && sql.trim().toUpperCase().startsWith("COMMENT"))
185: return 0;
186: if (sqlLogger.isDebugEnabled())
187: sqlLogger.debug(sql);
188: int result = 0;
189: Statement statement = null;
190: try {
191: statement = connection.createStatement();
192: result = statement.executeUpdate(sql);
193: } finally {
194: if (statement != null)
195: statement.close();
196: }
197: return result;
198: }
199:
200: }
|