View Javadoc

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  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         // Tables in Sybase are unlocked when a commit is issued.  The
132         // user may have issued a commit but do it here to be sure.
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 ) // Offset only test
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             // This is necessary to create the empty result set that Torque expects
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 }