001: /*
002: * SetCommand.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.sql.commands;
013:
014: import java.sql.SQLException;
015:
016: import workbench.db.WbConnection;
017: import workbench.resource.ResourceMgr;
018: import workbench.sql.SqlCommand;
019: import workbench.sql.StatementRunnerResult;
020: import workbench.sql.formatter.SQLLexer;
021: import workbench.sql.formatter.SQLToken;
022: import workbench.util.SqlUtil;
023: import workbench.util.StringUtil;
024:
025: /**
026: * This class implements a wrapper for the SET command
027: *
028: * Oracle's SET command is only valid from within SQL*Plus.
029: * By supplying an implementation for the Workbench, we can ignore the errors
030: * reported by the JDBC interface, so that SQL scripts intended for SQL*Plus
031: * can also be run from within the workbench
032: *
033: * For other DBMS this enables the support for controlling autocommit
034: * through a SQL command. All parameters except serveroutput and autocommit
035: * are passed on to the server.
036: *
037: * @author support@sql-workbench.net
038: */
039: public class SetCommand extends SqlCommand {
040: public static final String VERB = "SET";
041:
042: public SetCommand() {
043: }
044:
045: public StatementRunnerResult execute(String aSql)
046: throws SQLException {
047: StatementRunnerResult result = null; //
048:
049: try {
050: String command = null;
051: String param = null;
052: try {
053: SQLLexer l = new SQLLexer(aSql);
054: SQLToken t = l.getNextToken(false, false); // ignore the verb
055: t = l.getNextToken(false, false);
056: if (t != null)
057: command = t.getContents();
058: t = l.getNextToken(false, false);
059: if (t != null)
060: param = t.getContents();
061: } catch (Exception e) {
062: e.printStackTrace();
063: }
064: boolean execSql = true;
065:
066: if (command != null) {
067: // those SET commands that have a SQL Workbench equivalent
068: // will be "executed" by calling the approriate functions
069: // we don't need to send the SQL to the server in this case
070: // everything else is sent to the server
071: if (command.equalsIgnoreCase("autocommit")) {
072: result = this .setAutocommit(currentConnection,
073: param);
074: execSql = false;
075: } else if (currentConnection.getMetadata().isOracle()) {
076: if (command.equalsIgnoreCase("serveroutput")) {
077: result = this .setServeroutput(
078: currentConnection, param);
079: execSql = false;
080: } else if (command.equalsIgnoreCase("feedback")) {
081: result = this .setFeedback(param);
082: execSql = false;
083: }
084: }
085: }
086:
087: if (execSql) {
088: result = new StatementRunnerResult();
089: this .currentStatement = currentConnection
090: .createStatement();
091: // Using a generic execute ensures that servers that
092: // can process more than one statement with a single SQL
093: // are treated correctly. E.g. when sending a SET and a SELECT
094: // as one statement for SQL Server
095: boolean hasResult = this .currentStatement.execute(aSql);
096: result.setSuccess();
097: processMoreResults(aSql, result, hasResult);
098: }
099: } catch (Exception e) {
100: result = new StatementRunnerResult();
101: result.clear();
102: if (currentConnection.getMetadata().isOracle()) {
103: // for oracle we'll simply ignore the error as the SET command
104: // is a SQL*Plus command
105: result.setSuccess();
106: result.setWarning(true);
107: result.addMessage(ResourceMgr
108: .getString("MsgSetErrorIgnored")
109: + ": " + e.getMessage());
110: } else {
111: // for other DBMS this is an error
112: result.setFailure();
113: result.addMessage(e.getMessage());
114: }
115: } finally {
116: SqlUtil.closeStatement(this .currentStatement);
117: this .done();
118: }
119:
120: return result;
121: }
122:
123: private StatementRunnerResult setServeroutput(
124: WbConnection aConnection, String param) {
125: StatementRunnerResult result = new StatementRunnerResult();
126: result.setSuccess();
127:
128: if ("off".equalsIgnoreCase(param)) {
129: aConnection.getMetadata().disableOutput();
130: result.addMessage(ResourceMgr
131: .getString("MsgDbmsOutputDisabled"));
132: } else if ("on".equalsIgnoreCase(param)) {
133: aConnection.getMetadata().enableOutput();
134: result.addMessage(ResourceMgr
135: .getString("MsgDbmsOutputEnabled"));
136: } else {
137: result.setFailure();
138: result.addMessage(ResourceMgr
139: .getString("ErrServeroutputWrongParameter"));
140: }
141: return result;
142: }
143:
144: private StatementRunnerResult setAutocommit(
145: WbConnection aConnection, String param) {
146: StatementRunnerResult result = new StatementRunnerResult();
147:
148: if (StringUtil.isEmptyString(param)) {
149: result.setFailure();
150: result.addMessage(ResourceMgr
151: .getString("ErrAutocommitWrongParameter"));
152: return result;
153: }
154:
155: try {
156: if ("off".equalsIgnoreCase(param)
157: || "false".equalsIgnoreCase(param)) {
158: aConnection.setAutoCommit(false);
159: result.addMessage(ResourceMgr
160: .getString("MsgAutocommitDisabled"));
161: result.setSuccess();
162: } else if ("on".equalsIgnoreCase(param)
163: || "true".equalsIgnoreCase(param)) {
164: aConnection.setAutoCommit(true);
165: result.addMessage(ResourceMgr
166: .getString("MsgAutocommitEnabled"));
167: result.setSuccess();
168: } else {
169: result.addMessage(ResourceMgr
170: .getString("ErrAutocommitWrongParameter"));
171: result.setFailure();
172: }
173: } catch (SQLException e) {
174: result.setFailure();
175: result.addMessage(e.getMessage());
176: }
177: return result;
178: }
179:
180: private StatementRunnerResult setFeedback(String param) {
181: StatementRunnerResult result = new StatementRunnerResult();
182: if (StringUtil.isEmptyString(param)) {
183: result.setFailure();
184: result.addMessage(ResourceMgr
185: .getString("ErrFeedbackWrongParameter"));
186: return result;
187: }
188:
189: if ("off".equalsIgnoreCase(param)
190: || "false".equalsIgnoreCase(param)) {
191: this .runner.setVerboseLogging(false);
192: result.addMessage(ResourceMgr
193: .getString("MsgFeedbackDisabled"));
194: result.setSuccess();
195: } else if ("on".equalsIgnoreCase(param)
196: || "true".equalsIgnoreCase(param)) {
197: this .runner.setVerboseLogging(true);
198: result.addMessage(ResourceMgr
199: .getString("MsgFeedbackEnabled"));
200: result.setSuccess();
201: } else {
202: result.addMessage(ResourceMgr
203: .getString("ErrFeedbackWrongParameter"));
204: result.setFailure();
205: }
206:
207: return result;
208: }
209:
210: public String getVerb() {
211: return VERB;
212: }
213:
214: }
|