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 476490 2006-11-18 11:38:04Z tfischer $
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 + offset > 0)
170 {
171 query.setRowcount(String.valueOf(limit + offset));
172 }
173 else if (limit + offset == 0)
174 {
175
176 query.getWhereClause().add(SqlExpression.build("1", new Integer(0), Criteria.EQUAL));
177 }
178 }
179
180 /***
181 * This method overrides the JDBC escapes used to format dates
182 * using a <code>DateFormat</code>. As of version 11, the Sybase
183 * JDBC driver does not implement JDBC 3.0 escapes.
184 *
185 * @param date the date to format
186 * @return The properly formatted date String.
187 */
188 public String getDateString(Date date)
189 {
190 char delim = getStringDelimiter();
191 return (delim + new SimpleDateFormat(DATE_FORMAT).format(date) + delim);
192 }
193
194 /***
195 * Determines whether backslashes (\) should be escaped in explicit SQL
196 * strings. If true is returned, a BACKSLASH will be changed to "//".
197 * If false is returned, a BACKSLASH will be left as "\".
198 *
199 * Sybase (and MSSQL) doesn't define a default escape character,
200 * so false is returned.
201 *
202 * @return false
203 * @see org.apache.torque.adapter.DB#escapeText()
204 */
205 public boolean escapeText()
206 {
207 return false;
208 }
209
210 /***
211 * Whether an escape clause in like should be used.
212 * Example : select * from AUTHOR where AUTHOR.NAME like '\_%' ESCAPE '\';
213 *
214 * Sybase needs this, so this implementation always returns
215 * <code>true</code>.
216 *
217 * @return whether the escape clause should be appended or not.
218 */
219 public boolean useEscapeClauseForLike()
220 {
221 return true;
222 }
223 }