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.Statement;
25 import java.text.SimpleDateFormat;
26 import java.util.Date;
27
28 import org.apache.torque.TorqueException;
29 import org.apache.torque.util.Criteria;
30 import org.apache.torque.util.Query;
31 import org.apache.torque.util.SqlExpression;
32
33 /***
34 * This is used to connect to a Sybase database using Sybase's
35 * JConnect JDBC driver.
36 *
37 * <B>NOTE:</B><I>Currently JConnect does not implement the required
38 * methods for ResultSetMetaData, and therefore the village API's may
39 * not function. For connection pooling, everything works.</I>
40 *
41 * @author <a href="mailto:ekkerbj@netscape.net">Jeff Brekke</a>
42 * @version $Id: DBSybase.java 586553 2007-10-19 17:33:53Z gmonroe $
43 */
44 public class DBSybase extends AbstractDBAdapter
45 {
46 /***
47 * Serial version
48 */
49 private static final long serialVersionUID = 4782996646843056810L;
50
51 /*** date format */
52 private static final String DATE_FORMAT = "yyyyMMdd HH:mm:ss";
53
54 /***
55 * Empty constructor.
56 */
57 protected DBSybase()
58 {
59 }
60
61 /***
62 * This method is used to ignore case.
63 *
64 * @param in The string to transform to upper case.
65 * @return The upper case string.
66 */
67 public String toUpperCase(String in)
68 {
69 return new StringBuffer("UPPER(").append(in).append(")").toString();
70 }
71
72 /***
73 * This method is used to ignore case.
74 *
75 * @param in The string whose case to ignore.
76 * @return The string in a case that can be ignored.
77 */
78 public String ignoreCase(String in)
79 {
80 return new StringBuffer("UPPER(").append(in).append(")").toString();
81 }
82
83 /***
84 * @see org.apache.torque.adapter.DB#getIDMethodType()
85 */
86 public String getIDMethodType()
87 {
88 return AUTO_INCREMENT;
89 }
90
91 /***
92 * Returns the last value from an identity column (available on a
93 * per-session basis from the global variable
94 * <code>@@identity</code>).
95 *
96 * @see org.apache.torque.adapter.DB#getIDMethodSQL(Object obj)
97 */
98 public String getIDMethodSQL(Object unused)
99 {
100 return "select @@identity";
101 }
102
103 /***
104 * Locks the specified table.
105 *
106 * @param con The JDBC connection to use.
107 * @param table The name of the table to lock.
108 * @throws SQLException No Statement could be created or executed.
109 */
110 public void lockTable(Connection con, String table) throws SQLException
111 {
112 Statement statement = con.createStatement();
113
114 StringBuffer stmt = new StringBuffer();
115 stmt.append("SELECT next_id FROM ")
116 .append(table)
117 .append(" FOR UPDATE");
118
119 statement.executeQuery(stmt.toString());
120 }
121
122 /***
123 * Unlocks the specified table.
124 *
125 * @param con The JDBC connection to use.
126 * @param table The name of the table to unlock.
127 * @throws SQLException No Statement could be created or executed.
128 */
129 public void unlockTable(Connection con, String table) throws SQLException
130 {
131
132
133 con.commit();
134 }
135
136 /***
137 * This method is used to chek whether the database supports
138 * limiting the size of the resultset.
139 *
140 * @return LIMIT_STYLE_SYBASE.
141 * @deprecated This should not be exposed to the outside
142 */
143 public int getLimitStyle()
144 {
145 return DB.LIMIT_STYLE_SYBASE;
146 }
147
148 /***
149 * Return true for Sybase
150 * @see org.apache.torque.adapter.AbstractDBAdapter#supportsNativeLimit()
151 */
152 public boolean supportsNativeLimit()
153 {
154 return true;
155 }
156
157 /***
158 * Modify a query to add limit and offset values for Sybase.
159 *
160 * @param query The query to modify
161 * @param offset the offset Value
162 * @param limit the limit Value
163 *
164 * @throws TorqueException if any error occurs when building the query
165 */
166 public void generateLimits(Query query, int offset, int limit)
167 throws TorqueException
168 {
169 if ( limit < 0 && offset >= 0 )
170 {
171 return;
172 }
173 if (limit + offset > 0)
174 {
175 query.setRowcount(String.valueOf(limit + offset));
176 }
177 else if (limit + offset == 0)
178 {
179
180 query.getWhereClause().add(SqlExpression.build("1", new Integer(0), Criteria.EQUAL));
181 }
182 }
183
184 /***
185 * This method overrides the JDBC escapes used to format dates
186 * using a <code>DateFormat</code>. As of version 11, the Sybase
187 * JDBC driver does not implement JDBC 3.0 escapes.
188 *
189 * @param date the date to format
190 * @return The properly formatted date String.
191 */
192 public String getDateString(Date date)
193 {
194 char delim = getStringDelimiter();
195 return (delim + new SimpleDateFormat(DATE_FORMAT).format(date) + delim);
196 }
197
198 /***
199 * Determines whether backslashes (\) should be escaped in explicit SQL
200 * strings. If true is returned, a BACKSLASH will be changed to "//".
201 * If false is returned, a BACKSLASH will be left as "\".
202 *
203 * Sybase (and MSSQL) doesn't define a default escape character,
204 * so false is returned.
205 *
206 * @return false
207 * @see org.apache.torque.adapter.DB#escapeText()
208 */
209 public boolean escapeText()
210 {
211 return false;
212 }
213
214 /***
215 * Whether an escape clause in like should be used.
216 * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\';
217 *
218 * Sybase needs this, so this implementation always returns
219 * <code>true</code>.
220 *
221 * @return whether the escape clause should be appended or not.
222 */
223 public boolean useEscapeClauseForLike()
224 {
225 return true;
226 }
227 }