1 package org.apache.torque.adapter; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.sql.Connection; 23 import java.sql.SQLException; 24 25 import org.apache.torque.TorqueException; 26 import org.apache.torque.sql.Query; 27 28 /** 29 * This class is the abstract base for any database adapter 30 * Support for new databases is added by subclassing this 31 * class and implementing its abstract methods, and by 32 * registering the new database adapter and its corresponding 33 * JDBC driver in the service configuration file. 34 * 35 * <p>The Torque database adapters exist to present a uniform 36 * interface to database access across all available databases. Once 37 * the necessary adapters have been written and configured, 38 * transparent swapping of databases is theoretically supported with 39 * <i>zero code changes</i> and minimal configuration file 40 * modifications. 41 * 42 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 43 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a> 44 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 45 * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a> 46 * @author <a href="mailto:greg.monroe@dukece.com">Greg Monroe</a> 47 * @version $Id: AbstractAdapter.java 1373827 2012-08-16 13:34:35Z tfischer $ 48 */ 49 public abstract class AbstractAdapter implements Adapter 50 { 51 /** Serial version UID. */ 52 private static final long serialVersionUID = 1L; 53 54 /** 55 * Empty constructor. 56 */ 57 protected AbstractAdapter() 58 { 59 // empty 60 } 61 62 /** 63 * Wraps the input string in a database function to change it to upper case. 64 * 65 * @param in The string to transform to upper case, may be a literal string, 66 * a prepared statement replacement placeholder(*) or any other 67 * database expression. 68 * 69 * @return The wrapped input string, so that the database evaluates the 70 * returned expression to the upper case of the input. 71 */ 72 public abstract String toUpperCase(String in); 73 74 /** 75 * Returns the character used to indicate the beginning and end of 76 * a piece of text used in a SQL statement (generally a single 77 * quote). 78 * 79 * @return The text delimiter. 80 */ 81 public char getStringDelimiter() 82 { 83 return '\''; 84 } 85 86 /** 87 * Returns the constant from the {@link 88 * org.apache.torque.adapter.IDMethod} interface denoting which 89 * type of primary key generation method this type of RDBMS uses. 90 * 91 * @return IDMethod constant 92 */ 93 public abstract IDMethod getIDMethodType(); 94 95 /** 96 * Returns SQL used to get the most recently inserted primary key. 97 * Databases which have no support for this return 98 * <code>null</code>. 99 * 100 * @param obj Information used for key generation. 101 * @return The most recently inserted database key. 102 */ 103 public abstract String getIDMethodSQL(Object obj); 104 105 /** 106 * Locks the specified table. 107 * 108 * @param con The JDBC connection to use. 109 * @param table The name of the table to lock. 110 * 111 * @throws SQLException No Statement could be created or executed. 112 */ 113 public abstract void lockTable(Connection con, String table) 114 throws SQLException; 115 116 /** 117 * Unlocks the specified table. 118 * 119 * @param con The JDBC connection to use. 120 * @param table The name of the table to unlock. 121 * 122 * @throws SQLException No Statement could be created or executed. 123 */ 124 public abstract void unlockTable(Connection con, String table) 125 throws SQLException; 126 127 /** 128 * Wraps the input string in a database function to change it to 129 * a case-insensitive representation. 130 * 131 * @param in The string to transform to a case-insensitive representation, 132 * may be a literal string, a prepared statement replacement 133 * placeholder(*) or any other database expression. 134 * 135 * @return The wrapped input string, so that the database evaluates the 136 * returned expression to a case-insensitive representation 137 * of the input. 138 */ 139 public abstract String ignoreCase(String in); 140 141 /** 142 * This method is used to ignore case in an ORDER BY clause. 143 * Usually it is the same as ignoreCase, but some databases 144 * (hsqldb for example) do not use the same SQL in ORDER BY 145 * and other clauses. 146 * 147 * @param in The string whose case to ignore. 148 * 149 * @return The string in a case that can be ignored. 150 */ 151 public String ignoreCaseInOrderBy(String in) 152 { 153 return ignoreCase(in); 154 } 155 156 /** 157 * Returns whether the database can natively limit the size of the ResultSet 158 * of a query. 159 * 160 * @return true if the database natively supports limiting the 161 * size of the resultset. 162 */ 163 public boolean supportsNativeLimit() 164 { 165 return false; 166 } 167 168 /** 169 * Returns whether the database natively supports returning results 170 * starting at an offset position other than 0. 171 * 172 * @return true if the database natively supports returning 173 * results starting at an offset position other than 0. 174 */ 175 public boolean supportsNativeOffset() 176 { 177 return false; 178 } 179 180 /** 181 * This method is used to generate the database specific query 182 * extension to limit the number of record returned. 183 * 184 * @param query The query to modify 185 * @param offset the offset Value 186 * @param limit the limit Value 187 * 188 * @throws TorqueException if any error occurs when building the query 189 */ 190 public void generateLimits(Query query, long offset, int limit) 191 throws TorqueException 192 { 193 if (supportsNativeLimit()) 194 { 195 query.setLimit(String.valueOf(limit)); 196 } 197 } 198 199 /** 200 * This method is for the SqlExpression.quoteAndEscape rules. The rule is, 201 * any string in a SqlExpression with a BACKSLASH will either be changed to 202 * "\\" or left as "\". 203 * 204 * @return true if the database needs to escape text in SqlExpressions. 205 */ 206 207 public boolean escapeText() 208 { 209 return true; 210 } 211 212 /** 213 * Whether ILIKE should be used for case insensitive like clauses. 214 * 215 * As most databases do not use ILIKE, this implementation returns false. 216 * This behaviour may be overwritten in subclasses. 217 * 218 * @return true if ilike should be used for case insensitive likes, 219 * false if ignoreCase should be applied to the compared strings. 220 */ 221 public boolean useIlike() 222 { 223 return false; 224 } 225 226 /** 227 * Whether an escape clause in like should be used. 228 * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\'; 229 * 230 * As most databases do not need the escape clause, this implementation 231 * always returns <code>false</code>. This behaviour can be overwritten 232 * in subclasses. 233 * 234 * @return whether the escape clause should be appended or not. 235 */ 236 public boolean useEscapeClauseForLike() 237 { 238 return false; 239 } 240 241 /** 242 * Creates a Torque exception from a database-specific exception. 243 * This implementation alsways returns a plain Torque exception. 244 * 245 * @param e the database-specific exception to create the exception from 246 * 247 * @return the corresponding Torque exception, possibly a subclass. 248 */ 249 public TorqueException toTorqueException(SQLException e) 250 { 251 return new TorqueException(e); 252 } 253 254 }