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 }