1 /*
2 *
3 * The DbUnit Database Testing Framework
4 * Copyright (C)2002-2004, DbUnit.org
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 package org.dbunit.database;
23
24 import java.sql.Connection;
25 import java.sql.SQLException;
26
27 import org.dbunit.DatabaseUnitException;
28 import org.dbunit.util.SQLHelper;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33 * This class adapts a JDBC <code>Connection</code> to a
34 * {@link IDatabaseConnection}.
35 *
36 * @author Manuel Laflamme
37 * @version $Revision$
38 * @since Feb 21, 2002
39 */
40 public class DatabaseConnection extends AbstractDatabaseConnection
41 implements IDatabaseConnection
42 {
43
44 /**
45 * Logger for this class
46 */
47 private static final Logger logger = LoggerFactory.getLogger(DatabaseConnection.class);
48
49 private final Connection _connection;
50 private final String _schema;
51
52 /**
53 * Creates a new <code>DatabaseConnection</code>.
54 *
55 * @param connection the adapted JDBC connection
56 * @throws DatabaseUnitException
57 */
58 public DatabaseConnection(Connection connection) throws DatabaseUnitException
59 {
60 this( connection, null );
61 }
62
63 /**
64 * Creates a new <code>DatabaseConnection</code> using a specific schema.
65 *
66 * @param connection the adapted JDBC connection
67 * @param schema the database schema. Note that the schema name is case sensitive. This
68 * is necessary because schemas with the same name but different case can coexist on one
69 * database. <br>
70 * Here an example that creates two users/schemas for oracle where only the case is different:<br>
71 * <code>
72 * create user dbunittest identified by dbunittest;
73 * create user "dbunittest" identified by "dbunittest";
74 * </code>
75 * The first one creates the "default" user where everything is interpreted by oracle in uppercase.
76 * The second one is completely lowercase because of the quotes.
77 * @throws DatabaseUnitException
78 */
79 public DatabaseConnection(Connection connection, String schema) throws DatabaseUnitException
80 {
81 this(connection, schema, false);
82 }
83
84 /**
85 * Creates a new <code>DatabaseConnection</code> using a specific schema.
86 *
87 * @param connection the adapted JDBC connection
88 * @param schema the database schema. Note that the schema name is case sensitive. This
89 * is necessary because schemas with the same name but different case can coexist on one
90 * database. <br>
91 * Here an example that creates two users/schemas for oracle where only the case is different:<br>
92 * <code>
93 * create user dbunittest identified by dbunittest;
94 * create user "dbunittest" identified by "dbunittest";
95 * </code>
96 * The first one creates the "default" user where everything is interpreted by oracle in uppercase.
97 * The second one is completely lowercase because of the quotes.
98 * @param validate If <code>true</code> an exception is thrown when the given schema
99 * does not exist according to the DatabaseMetaData. If <code>false</code> the validation
100 * will only print a warning if the schema was not found.
101 * @since 2.3.0
102 * @throws DatabaseUnitException If the <code>validate</code> parameter is <code>true</code> and the
103 * validation of the given connection/schema was not successful (added with 2.3.0). This can happen if the given
104 * schema does not exist or if the jdbc driver does not implement the metaData.getSchemas() method properly.
105 */
106 public DatabaseConnection(Connection connection, String schema, boolean validate) throws DatabaseUnitException
107 {
108 if(connection == null)
109 {
110 throw new NullPointerException("The parameter 'connection' must not be null");
111 }
112 _connection = connection;
113
114 if(schema != null)
115 {
116 _schema = SQLHelper.correctCase(schema, connection);
117 SQLHelper.logInfoIfValueChanged(schema, _schema, "Corrected schema name:", DatabaseConnection.class);
118 }
119 else
120 {
121 _schema = null;
122 }
123
124 printConnectionInfo();
125 validateSchema(validate);
126 }
127
128 ////////////////////////////////////////////////////////////////////////////
129 // IDatabaseConnection interface
130
131 public Connection getConnection() throws SQLException
132 {
133 return _connection;
134 }
135
136 public String getSchema()
137 {
138 return _schema;
139 }
140
141 public void close() throws SQLException
142 {
143 logger.debug("close() - start");
144 _connection.close();
145 }
146
147
148 /**
149 * Prints debugging information about the current JDBC connection
150 */
151 private void printConnectionInfo()
152 {
153 if(logger.isDebugEnabled())
154 {
155 try {
156 logger.debug("Database connection info: " + SQLHelper.getDatabaseInfo(_connection.getMetaData()));
157 }
158 catch (SQLException e) {
159 logger.warn("Exception while trying to retrieve database info from connection", e);
160 }
161 }
162 }
163
164 /**
165 * Validates if the database schema exists for this connection.
166 * @param validateStrict If <code>true</code> an exception is thrown when the given schema
167 * does not exist according to the DatabaseMetaData. If <code>false</code> the validation
168 * will only print a warning if the schema was not found.
169 * @throws DatabaseUnitException
170 */
171 private void validateSchema(boolean validateStrict) throws DatabaseUnitException
172 {
173 logger.debug("validateSchema(validateStrict={}) - start", validateStrict);
174
175 if(this._schema == null)
176 {
177 logger.debug("Schema is null. Nothing to validate.");
178 return;
179 }
180
181 try
182 {
183 boolean schemaExists = SQLHelper.schemaExists(this._connection, this._schema);
184 if(!schemaExists)
185 {
186 // Under certain circumstances the cause might be that the JDBC driver
187 // implementation of 'DatabaseMetaData.getSchemas()' is not correct
188 // (known issue of MySQL driver).
189 String msg = "The given schema '" + this._schema + "' does not exist.";
190 // If strict validation is wished throw an exception
191 if(validateStrict)
192 throw new DatabaseUnitException(msg);
193 else
194 logger.warn(msg);
195 }
196 }
197 catch(SQLException e)
198 {
199 throw new DatabaseUnitException("Exception while checking the schema for validity", e);
200 }
201 }
202
203 public String toString()
204 {
205 final StringBuilder sb = new StringBuilder();
206 sb.append(getClass().getName()).append("[");
207 sb.append("schema=").append(_schema);
208 sb.append(", connection=").append(_connection);
209 sb.append(", super=").append(super.toString());
210 sb.append("]");
211 return sb.toString();
212 }
213 }