1 package org.apache.torque.adapter;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.sql.Connection;
23 import java.sql.SQLException;
24 import java.sql.Timestamp;
25 import java.util.Date;
26
27 import org.apache.torque.TorqueException;
28 import org.apache.torque.util.Query;
29
30 /***
31 * This class is the abstract base for any database adapter
32 * Support for new databases is added by subclassing this
33 * class and implementing its abstract methods, and by
34 * registering the new database adapter and its corresponding
35 * JDBC driver in the service configuration file.
36 *
37 * <p>The Torque database adapters exist to present a uniform
38 * interface to database access across all available databases. Once
39 * the necessary adapters have been written and configured,
40 * transparent swapping of databases is theoretically supported with
41 * <i>zero code changes</i> and minimal configuration file
42 * modifications.
43 *
44 * <p>Torque uses the driver class name to find the right adapter.
45 * A JDBC driver corresponding to your adapter must be added to the properties
46 * file, using the fully-qualified class name of the driver. If no driver is
47 * specified for your database, <code>driver.default</code> is used.
48 *
49 * <pre>
50 * #### MySQL MM Driver
51 * database.default.driver=org.gjt.mm.mysql.Driver
52 * database.default.url=jdbc:mysql://localhost/DATABASENAME
53 * </pre>
54 *
55 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
56 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
57 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
58 * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a>
59 * @version $Id: DB.java 393063 2006-04-10 20:59:16Z tfischer $
60 */
61 public abstract class AbstractDBAdapter implements DB
62 {
63 /***
64 * Empty constructor.
65 */
66 protected AbstractDBAdapter()
67 {
68 }
69
70 /***
71 * This method is used to ignore case.
72 *
73 * @param in The string to transform to upper case.
74 * @return The upper case string.
75 */
76 public abstract String toUpperCase(String in);
77
78 /***
79 * Returns the character used to indicate the beginning and end of
80 * a piece of text used in a SQL statement (generally a single
81 * quote).
82 *
83 * @return The text delimeter.
84 */
85 public char getStringDelimiter()
86 {
87 return '\'';
88 }
89
90 /***
91 * Returns the constant from the {@link
92 * org.apache.torque.adapter.IDMethod} interface denoting which
93 * type of primary key generation method this type of RDBMS uses.
94 *
95 * @return IDMethod constant
96 */
97 public abstract String getIDMethodType();
98
99 /***
100 * Returns SQL used to get the most recently inserted primary key.
101 * Databases which have no support for this return
102 * <code>null</code>.
103 *
104 * @param obj Information used for key generation.
105 * @return The most recently inserted database key.
106 */
107 public abstract String getIDMethodSQL(Object obj);
108
109 /***
110 * Locks the specified table.
111 *
112 * @param con The JDBC connection to use.
113 * @param table The name of the table to lock.
114 * @throws SQLException No Statement could be created or executed.
115 */
116 public abstract void lockTable(Connection con, String table)
117 throws SQLException;
118
119 /***
120 * Unlocks the specified table.
121 *
122 * @param con The JDBC connection to use.
123 * @param table The name of the table to unlock.
124 * @throws SQLException No Statement could be created or executed.
125 */
126 public abstract void unlockTable(Connection con, String table)
127 throws SQLException;
128
129 /***
130 * This method is used to ignore case.
131 *
132 * @param in The string whose case to ignore.
133 * @return The string in a case that can be ignored.
134 */
135 public abstract String ignoreCase(String in);
136
137 /***
138 * This method is used to ignore case in an ORDER BY clause.
139 * Usually it is the same as ignoreCase, but some databases
140 * (Interbase for example) does not use the same SQL in ORDER BY
141 * and other clauses.
142 *
143 * @param in The string whose case to ignore.
144 * @return The string in a case that can be ignored.
145 */
146 public String ignoreCaseInOrderBy(String in)
147 {
148 return ignoreCase(in);
149 }
150
151 /***
152 * This method is used to check whether the database natively
153 * supports limiting the size of the resultset.
154 *
155 * @return True if the database natively supports limiting the
156 * size of the resultset.
157 */
158 public boolean supportsNativeLimit()
159 {
160 return false;
161 }
162
163 /***
164 * This method is used to check whether the database natively
165 * supports returning results starting at an offset position other
166 * than 0.
167 *
168 * @return True if the database natively supports returning
169 * results starting at an offset position other than 0.
170 */
171 public boolean supportsNativeOffset()
172 {
173 return false;
174 }
175
176 /***
177 * This method is used to generate the database specific query
178 * extension to limit the number of record returned.
179 *
180 * @param query The query to modify
181 * @param offset the offset Value
182 * @param limit the limit Value
183 *
184 * @throws TorqueException if any error occurs when building the query
185 */
186 public void generateLimits(Query query, int offset, int limit)
187 throws TorqueException
188 {
189 if (supportsNativeLimit())
190 {
191 query.setLimit(String.valueOf(limit));
192 }
193 }
194
195 /***
196 * This method is for the SqlExpression.quoteAndEscape rules. The rule is,
197 * any string in a SqlExpression with a BACKSLASH will either be changed to
198 * "//" or left as "\". SapDB does not need the escape character.
199 *
200 * @return true if the database needs to escape text in SqlExpressions.
201 */
202
203 public boolean escapeText()
204 {
205 return true;
206 }
207
208 /***
209 * This method is used to check whether the database supports
210 * limiting the size of the resultset.
211 *
212 * @return The limit style for the database.
213 * @deprecated This should not be exposed to the outside
214 */
215 public int getLimitStyle()
216 {
217 return LIMIT_STYLE_NONE;
218 }
219
220 /***
221 * This method is used to format any date string.
222 * Database can use different default date formats.
223 *
224 * @param date the Date to format
225 * @return The proper date formatted String.
226 */
227 public String getDateString(Date date)
228 {
229 Timestamp ts = null;
230 if (date instanceof Timestamp)
231 {
232 ts = (Timestamp) date;
233 }
234 else
235 {
236 ts = new Timestamp(date.getTime());
237 }
238
239 return ("{ts '" + ts + "'}");
240 }
241
242 /***
243 * This method is used to format a boolean string.
244 *
245 * @param b the Boolean to format
246 * @return The proper date formatted String.
247 */
248 public String getBooleanString(Boolean b)
249 {
250 return (Boolean.TRUE.equals(b) ? "1" : "0");
251 }
252
253 /***
254 * Whether ILIKE should be used for case insensitive like clauses.
255 *
256 * As most databases do not use ILIKE, this implementation returns false.
257 * This behaviour may be overwritten in subclasses.
258 *
259 * @return true if ilike should be used for case insensitive likes,
260 * false if ignoreCase should be applied to the compared strings.
261 */
262 public boolean useIlike()
263 {
264 return false;
265 }
266
267 /***
268 * Whether an escape clause in like should be used.
269 * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\';
270 *
271 * As most databases do not need the escape clause, this implementation
272 * always returns <code>false</code>. This behaviour can be overwritten
273 * in subclasses.
274 *
275 * @return whether the escape clause should be appended or not.
276 */
277 public boolean useEscapeClauseForLike()
278 {
279 return false;
280 }
281 }