KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > jdbc > JdbcConnection


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package scriptella.jdbc;
17
18 import scriptella.configuration.ConfigurationException;
19 import scriptella.spi.AbstractConnection;
20 import scriptella.spi.ConnectionParameters;
21 import scriptella.spi.DialectIdentifier;
22 import scriptella.spi.ParametersCallback;
23 import scriptella.spi.QueryCallback;
24 import scriptella.spi.Resource;
25 import scriptella.util.StringUtils;
26
27 import java.sql.Connection JavaDoc;
28 import java.sql.DatabaseMetaData JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.IdentityHashMap JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34
35 /**
36  * Represents a JDBC connection.
37  *
38  * @author Fyodor Kupolov
39  * @version 1.0
40  */

41 public class JdbcConnection extends AbstractConnection {
42     public static final String JavaDoc STATEMENT_CACHE_KEY = "statement.cache";
43     public static final String JavaDoc STATEMENT_SEPARATOR_KEY = "statement.separator";
44     public static final String JavaDoc STATEMENT_SEPARATOR_SINGLELINE_KEY = "statement.separator.singleline";
45     public static final String JavaDoc KEEPFORMAT_KEY = "keepformat";
46     public static final String JavaDoc TRANSACTION_ISOLATION_KEY = "transaction.isolation";
47     public static final String JavaDoc TRANSACTION_ISOLATION_READ_UNCOMMITTED = "READ_UNCOMMITTED";
48     public static final String JavaDoc TRANSACTION_ISOLATION_READ_COMMITTED = "READ_COMMITTED";
49     public static final String JavaDoc TRANSACTION_ISOLATION_REPEATABLE_READ = "REPEATABLE_READ";
50     public static final String JavaDoc TRANSACTION_ISOLATION_SERIALIZABLE = "SERIALIZABLE";
51     private Connection con;
52     private static final Logger JavaDoc LOG = Logger.getLogger(JdbcConnection.class.getName());
53     private boolean transactable;
54     private ParametersParser parametersParser;
55     int statementCacheSize;
56     protected String JavaDoc separator = ";";
57     protected boolean separatorSingleLine;
58     protected boolean keepformat;
59     private Integer JavaDoc txIsolation;
60     private final Map JavaDoc<Resource, SqlExecutor> resourcesMap = new IdentityHashMap JavaDoc<Resource, SqlExecutor>();
61
62     public JdbcConnection(Connection con, ConnectionParameters parameters) {
63         super(parameters);
64         if (con == null) {
65             throw new IllegalArgumentException JavaDoc("Connection cannot be null");
66         }
67         this.con = con;
68         init(parameters);
69         if (txIsolation != null) {
70             try {
71                 con.setTransactionIsolation(txIsolation);
72             } catch (SQLException JavaDoc e) {
73                 throw new JdbcException("Unable to set transaction isolation level for " + toString(), e);
74             }
75         }
76
77         try {
78             //Several drivers return -1 which is illegal, but means no TX
79
transactable = con.getTransactionIsolation() > Connection.TRANSACTION_NONE;
80         } catch (SQLException JavaDoc e) {
81             LOG.log(Level.WARNING, "Unable to determine transaction isolation level for connection " + toString(), e);
82         }
83         if (transactable) { //only effective for transactable connections
84
try {
85                 con.setAutoCommit(false);
86             } catch (Exception JavaDoc e) {
87                 throw new JdbcException("Unable to set autocommit=false for " + toString(), e);
88             }
89         }
90     }
91
92     /**
93      * Called in constructor
94      */

95     protected void init(ConnectionParameters parameters) {
96
97         statementCacheSize = parameters.getIntegerProperty(STATEMENT_CACHE_KEY, 64);
98         String JavaDoc separatorStr = parameters.getStringProperty(STATEMENT_SEPARATOR_KEY);
99         if (!StringUtils.isEmpty(separatorStr)) {
100             separator = separatorStr.trim();
101         }
102         separatorSingleLine = parameters.getBooleanProperty(STATEMENT_SEPARATOR_SINGLELINE_KEY, false);
103         keepformat = parameters.getBooleanProperty(KEEPFORMAT_KEY, false);
104         String JavaDoc isolationStr = parameters.getStringProperty(TRANSACTION_ISOLATION_KEY);
105         if (isolationStr != null) {
106             isolationStr = isolationStr.trim();
107             if (TRANSACTION_ISOLATION_READ_COMMITTED.equalsIgnoreCase(isolationStr)) {
108                 txIsolation = Connection.TRANSACTION_READ_COMMITTED;
109             } else if (TRANSACTION_ISOLATION_READ_UNCOMMITTED.equalsIgnoreCase(isolationStr)) {
110                 txIsolation = Connection.TRANSACTION_READ_UNCOMMITTED;
111             } else if (TRANSACTION_ISOLATION_REPEATABLE_READ.equalsIgnoreCase(isolationStr)) {
112                 txIsolation = Connection.TRANSACTION_REPEATABLE_READ;
113             } else if (TRANSACTION_ISOLATION_SERIALIZABLE.equalsIgnoreCase(isolationStr)) {
114                 txIsolation = Connection.TRANSACTION_SERIALIZABLE;
115             } else if (StringUtils.isDecimalInt(isolationStr)) {
116                 txIsolation = parameters.getIntegerProperty(TRANSACTION_ISOLATION_KEY);
117             } else {
118                 throw new ConfigurationException(
119                         "Invalid " + TRANSACTION_ISOLATION_KEY + " connection property value: " + isolationStr +
120                                 ". Valid values are: " + TRANSACTION_ISOLATION_READ_COMMITTED + ", " +
121                                 TRANSACTION_ISOLATION_READ_UNCOMMITTED + ", " + TRANSACTION_ISOLATION_REPEATABLE_READ +
122                                 ", " + TRANSACTION_ISOLATION_SERIALIZABLE +
123                                 " or a numeric value according to java.sql.Connection transaction isolation constants");
124             }
125
126         }
127         parametersParser = new ParametersParser(parameters.getContext());
128         initDialectIdentifier();
129     }
130
131     StatementCounter getStatementCounter() {
132         return counter;
133     }
134
135     /**
136      * Initializes dialect identifier for connection.
137      * If driver doesn't support DatabaseMetaData or other problem occurs,
138      * {@link DialectIdentifier#NULL_DIALECT} is used.
139      * <p>May be overriden by subclasses.
140      */

141     protected void initDialectIdentifier() {
142         try {
143             final DatabaseMetaData JavaDoc metaData = con.getMetaData();
144             if (metaData != null) { //Several drivers violate spec and return null
145
setDialectIdentifier(new DialectIdentifier(metaData.getDatabaseProductName(),
146                         metaData.getDatabaseProductVersion()));
147             }
148         } catch (Exception JavaDoc e) {
149             setDialectIdentifier(DialectIdentifier.NULL_DIALECT);
150             LOG.log(Level.WARNING, "Failed to obtain meta data for connection. No dialect checking for " + con, e);
151         }
152     }
153
154     public void executeScript(Resource scriptContent, ParametersCallback parametersCallback) {
155         SqlExecutor s = resourcesMap.get(scriptContent);
156         if (s == null) {
157             resourcesMap.put(scriptContent, s = new SqlExecutor(scriptContent, this));
158         }
159         s.execute(parametersCallback);
160     }
161
162     public void executeQuery(Resource queryContent, ParametersCallback parametersCallback, QueryCallback queryCallback) {
163         SqlExecutor q = resourcesMap.get(queryContent);
164         if (q == null) {
165             resourcesMap.put(queryContent, q = new SqlExecutor(queryContent, this));
166         }
167         q.execute(parametersCallback, queryCallback);
168         if (q.getUpdateCount() < 0) {
169             throw new JdbcException("SQL query cannot make updates");
170         }
171     }
172
173     ParametersParser getParametersParser() {
174         return parametersParser;
175     }
176
177     public void commit() {
178         if (con == null) {
179             throw new IllegalStateException JavaDoc("Attempt to commit a transaction on a closed connection");
180         }
181         if (!transactable) {
182             LOG.log(Level.INFO, "Connection " + toString() + " doesn't support transactions. Commit ignored.");
183         } else {
184             try {
185                 con.commit();
186             } catch (Exception JavaDoc e) {
187                 throw new JdbcException("Unable to commit transaction", e);
188             }
189         }
190     }
191
192     public void rollback() {
193         if (con == null) {
194             throw new IllegalStateException JavaDoc("Attempt to roll back a transaction on a closed connection");
195         }
196         if (!transactable) {
197             LOG.log(Level.INFO, "Connection " + toString() + " doesn't support transactions. Rollback ignored.");
198         } else {
199             try {
200                 con.rollback();
201             } catch (Exception JavaDoc e) {
202                 throw new JdbcException("Unable to roll back transaction", e);
203             }
204         }
205     }
206
207     public void close() {
208         if (con != null) {
209             //Closing resources
210
for (SqlExecutor element : resourcesMap.values()) {
211                 element.close();
212             }
213             resourcesMap.clear();
214             try {
215                 con.close();
216                 con = null;
217             } catch (SQLException JavaDoc e) {
218                 throw new JdbcException("Unable to close a connection", e);
219             }
220
221         }
222     }
223
224     public Connection getNativeConnection() {
225         return con;
226     }
227
228     public String JavaDoc toString() {
229         return "JdbcConnection{" + (con == null ? "" : con.getClass().getName()) + '}';
230     }
231
232 }
233
Popular Tags