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