View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2002-2003 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: SchemaBrowser.java,v 1.5 2003/08/07 13:33:11 tanderson Exp $ 44 */ 45 46 package org.exolab.jms.tools.db; 47 48 import java.sql.Connection; 49 import java.sql.DatabaseMetaData; 50 import java.sql.PreparedStatement; 51 import java.sql.ResultSet; 52 import java.sql.ResultSetMetaData; 53 import java.sql.SQLException; 54 55 import org.apache.commons.logging.Log; 56 import org.apache.commons.logging.LogFactory; 57 58 import org.exolab.jms.persistence.PersistenceException; 59 import org.exolab.jms.persistence.SQLHelper; 60 61 62 /*** 63 * This class provides methods for examining a database schema 64 * 65 * @version $Revision: 1.5 $ $Date: 2003/08/07 13:33:11 $ 66 * @author <a href="mailto:tima@intalio.com">Tim Anderson</a> 67 */ 68 public class SchemaBrowser { 69 70 /*** 71 * The connection to the database 72 */ 73 private Connection _connection = null; 74 75 /*** 76 * The set of data types supported by the RDBMS 77 */ 78 private TypeSet _types = null; 79 80 /*** 81 * The type mapper, used to convert between the type requested by 82 * the schema, and those supported by the RDBMS 83 */ 84 private TypeMapper _mapper = null; 85 86 /*** 87 * The logger 88 */ 89 private static final Log _log = LogFactory.getLog(SchemaBrowser.class); 90 91 92 /*** 93 * Construct a new <code>SchemaBrowser</code> 94 * 95 * @param connection the JDBC connection 96 * @throws PersistenceException if database meta-data can't be obtained 97 */ 98 public SchemaBrowser(Connection connection) throws PersistenceException { 99 _connection = connection; 100 101 // get the types supported by the database 102 _types = new TypeSet(_connection); 103 _mapper = new TypeMapper(_types); 104 } 105 106 /*** 107 * Returns the schema for the specified table 108 * 109 * @param name the table name 110 * @return the schema for the table identified by <code>name</code> 111 * @throws PersistenceException if the named table doesn't exist, or the 112 * schema cannot be obtained 113 */ 114 public Table getTable(String name) throws PersistenceException { 115 Table result = new Table(); 116 117 result.setName(name); 118 119 // determine the column types. Another approach would be to use 120 // DatabaseMetaData.getColumns() - except that not all JDBC drivers 121 // seem to support this (e.g, Sybase) 122 PreparedStatement select = null; 123 try { 124 select = _connection.prepareStatement( 125 "select * from " + name + " where 1 = 0"); 126 ResultSet set = select.executeQuery(); 127 ResultSetMetaData metaData = set.getMetaData(); 128 129 for (int i = 1; i <= metaData.getColumnCount(); ++i) { 130 String columnName = metaData.getColumnName(i); 131 int dataType = metaData.getColumnType(i); 132 long precision = metaData.getPrecision(i); 133 int nullable = metaData.isNullable(i); 134 String typeName = metaData.getColumnTypeName(i); 135 Type type = _mapper.getType(dataType, precision); 136 if (type == null) { 137 // this will only occur if the JDBC driver is buggy, as the 138 // database meta data is inconsistent with the column meta 139 // data 140 // Try and get the nearest precision equivalent 141 type = _types.getNearestType(dataType, precision); 142 if (type == null) { 143 // getColumns() refers to type not included in 144 // database meta data 145 throw new InvalidTypeException( 146 "JDBC driver error. Type=" + dataType 147 + ", precision=" + precision + "(SQL type=" 148 + typeName + ") isn't supported by " 149 + "Connection.getMetaData().getTypeInfo(), but is " 150 + "referred to by " 151 + "Connection.getMetaData().getColumns()"); 152 } 153 } 154 155 Attribute attribute = new Attribute(); 156 attribute.setName(columnName); 157 attribute.setType(type.getSymbolicType()); 158 if (nullable == DatabaseMetaData.columnNoNulls) { 159 attribute.setNot_null(true); 160 } else { 161 attribute.setNot_null(false); 162 } 163 result.addAttribute(attribute); 164 } 165 } catch (SQLException exception) { 166 throw new PersistenceException( 167 "Failed to determine the schema of table=" + name, 168 exception); 169 } finally { 170 SQLHelper.close(select); 171 } 172 return result; 173 } 174 175 /*** 176 * Returns the {@link Type} for an {@link Attribute} 177 * 178 * @param attribute the attribute 179 * @return the type 180 * @throws PersistenceException if {@link Attribute#getType} is invalid, or 181 * the RDBMS doesn't support the type 182 */ 183 public Type getType(Attribute attribute) throws PersistenceException { 184 Type result = null; 185 Type type = Type.getType(attribute.getType()); 186 Type map = _mapper.getType(type.getType(), type.getPrecision()); 187 if (map == null) { 188 throw new PersistenceException( 189 "Database does not support type=" + attribute.getType()); 190 } 191 192 if (type.getType() != map.getType()) { 193 result = map; 194 } else { 195 boolean parameters = type.getParameters(); 196 long precision = type.getPrecision(); 197 if (precision <= map.getPrecision()) { 198 if (precision == -1) { 199 precision = map.getPrecision(); 200 parameters = map.getParameters(); 201 } 202 result = new Type(map.getType(), map.getName(), 203 precision, parameters); 204 } else { 205 throw new PersistenceException( 206 attribute.getName() + type + " exceeds precision for " 207 + map + " precision=" + map.getPrecision()); 208 } 209 } 210 return result; 211 } 212 213 /*** 214 * Returns true if a table exists 215 * 216 * @param table the name of the table 217 */ 218 public boolean getTableExists(String table) throws PersistenceException { 219 boolean result = false; 220 221 String name = table; 222 ResultSet set = null; 223 try { 224 DatabaseMetaData metaData = _connection.getMetaData(); 225 if (metaData.storesUpperCaseIdentifiers()) { 226 name = name.toUpperCase(); 227 } 228 229 set = metaData.getTables(_connection.getCatalog(), null, 230 name, null); 231 if (set.next()) { 232 result = true; 233 } 234 } catch (SQLException exception) { 235 throw new PersistenceException("Failed to determine if table=" 236 + table + " exists", exception); 237 } finally { 238 SQLHelper.close(set); 239 } 240 return result; 241 } 242 243 } //-- SchemaBrowser

This page was automatically generated by Maven