KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > db > sybase > SybaseDatabaseImpl


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: SybaseDatabaseImpl.java,v 1.19 2007/01/07 06:14:45 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.persist.db.sybase;
23
24 import java.sql.CallableStatement JavaDoc;
25 import java.sql.Connection JavaDoc;
26 import java.sql.PreparedStatement JavaDoc;
27 import java.sql.SQLException JavaDoc;
28 import java.sql.Statement JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.logging.Level JavaDoc;
32 import java.util.logging.Logger JavaDoc;
33
34 import org.opensubsystems.core.data.BasicDataObject;
35 import org.opensubsystems.core.data.ModifiableDataObject;
36 import org.opensubsystems.core.error.OSSDatabaseAccessException;
37 import org.opensubsystems.core.error.OSSException;
38 import org.opensubsystems.core.persist.db.DatabaseConnectionFactoryImpl;
39 import org.opensubsystems.core.persist.db.DatabaseImpl;
40 import org.opensubsystems.core.persist.db.DatabaseTransactionFactoryImpl;
41 import org.opensubsystems.core.util.DatabaseUtils;
42 import org.opensubsystems.core.util.Log;
43
44 /**
45  * Management layer for Sybase database (www.sybase.com)
46  *
47  * @version $Id: SybaseDatabaseImpl.java,v 1.19 2007/01/07 06:14:45 bastafidli Exp $
48  * @author Julo Legeny
49  * @code.reviewer Miro Halas
50  * @code.reviewed 1.14 2006/04/05 05:03:09 bastafidli
51  */

52 public class SybaseDatabaseImpl extends DatabaseImpl
53 {
54    // Cached values ////////////////////////////////////////////////////////////
55

56    /**
57     * Logger for this class
58     */

59    private static Logger JavaDoc s_logger = Log.getInstance(SybaseDatabaseImpl.class);
60
61    // Constructors /////////////////////////////////////////////////////////////
62

63    /**
64     * Default constructor for empty database.
65     *
66     * @throws OSSException - problem connecting to database
67     */

68    public SybaseDatabaseImpl(
69    ) throws OSSException
70    {
71       super();
72    }
73    
74    // Database administration //////////////////////////////////////////////////
75

76    /**
77     * {@inheritDoc}
78     */

79    protected void createUser(
80       Connection JavaDoc cntAdminDBConnection
81    ) throws OSSException
82    {
83       // Now create the user
84
PreparedStatement JavaDoc pstmQuery = null;
85       try
86       {
87          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
88          String JavaDoc strDatabaseURL = DatabaseConnectionFactoryImpl.getInstance().getDatabaseURL();
89          String JavaDoc strDatabaseName = strDatabaseURL.substring(
90                                      strDatabaseURL.lastIndexOf("/") + 1, strDatabaseURL.length());
91          
92          buffer.append("USE ");
93          buffer.append(strDatabaseName);
94          buffer.append(" EXEC sp_addlogin '");
95          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
96          buffer.append("', '");
97          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword());
98          buffer.append("', @defdb='");
99          buffer.append(strDatabaseName);
100          buffer.append("', @deflanguage='us_english', @auth_mech = 'ASE'");
101          buffer.append(" EXEC sp_locklogin '");
102          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
103          buffer.append("', 'unlock'");
104          buffer.append(" EXEC sp_adduser '");
105          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
106          buffer.append("', '");
107          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
108          buffer.append("', 'public'");
109          buffer.append(" GRANT ALL to ");
110          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
111
112          // At this point we don't know if this is just a single operation
113
// and we need to commit or if it is a part of bigger transaction
114
// and the commit is not desired until all operations proceed.
115
// Therefore let the DatabaseTransactionFactory resolve it
116
DatabaseTransactionFactoryImpl.getInstance().commitTransaction(
117                                                  cntAdminDBConnection);
118          
119          // We have to use here autocommit = true, because there is problem to
120
// execute some stored procedure while in transaction
121
boolean bOriginalAutoCommit = cntAdminDBConnection.getAutoCommit();
122          
123          try
124          {
125             if (!bOriginalAutoCommit)
126             {
127                cntAdminDBConnection.setAutoCommit(true);
128             }
129    
130             pstmQuery = cntAdminDBConnection.prepareStatement(buffer.toString());
131    
132             if (pstmQuery.execute())
133             {
134                // Close any results
135
pstmQuery.getMoreResults(Statement.CLOSE_ALL_RESULTS);
136             }
137          }
138          finally
139          {
140             if (!bOriginalAutoCommit)
141             {
142                cntAdminDBConnection.setAutoCommit(bOriginalAutoCommit);
143             }
144          }
145          
146          s_logger.log(Level.FINER, "Database user "
147                       + DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser()
148                       + " with password "
149                       + DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword()
150                       + " created.");
151       }
152       catch (SQLException JavaDoc sqleExc)
153       {
154          try
155          {
156             // At this point we don't know if this is just a single operation
157
// and we need to commit or if it is a part of bigger transaction
158
// and the commit is not desired until all operations proceed.
159
// Therefore let the DatabaseTransactionFactory resolve it
160
DatabaseTransactionFactoryImpl.getInstance().rollbackTransaction(
161                cntAdminDBConnection);
162          }
163          catch (SQLException JavaDoc sqleExc2)
164          {
165             // Ignore this
166
s_logger.log(Level.WARNING,
167                          "Failed to rollback changes for creation of user.",
168                          sqleExc2);
169          }
170          s_logger.log(Level.SEVERE,
171                       "Unable to create default database user.",
172                       sqleExc);
173          throw new OSSDatabaseAccessException("Unable to create default database user.",
174                                               sqleExc);
175       }
176       finally
177       {
178          DatabaseUtils.closeStatement(pstmQuery);
179       }
180    }
181
182    /**
183     * {@inheritDoc}
184     */

185    public void startDatabaseServer() throws OSSException
186    {
187       // TODO: Feature: Implement starting database server
188
}
189
190    /**
191     * {@inheritDoc}
192     */

193    public void createDatabaseInstance() throws OSSException
194    {
195       // TODO: Feature: Implement creating database instance
196
}
197
198    /**
199     * {@inheritDoc}
200     */

201    public void stop(
202    ) throws OSSException
203    {
204       s_logger.entering(this.getClass().getName(), "stop");
205
206       // TODO: Feature: Implement this so we can safely stop the database when
207
// the application is finished.
208
super.stop();
209
210       s_logger.entering(this.getClass().getName(), "stop");
211    }
212
213    /**
214     * {@inheritDoc}
215     */

216    public int getDatabaseType()
217    {
218       return DatabaseImpl.SYBASE_DATABASE_TYPE;
219    }
220
221    /**
222     * {@inheritDoc}
223     */

224    public String JavaDoc getDatabaseTypeIdentifier()
225    {
226       return DatabaseImpl.SYBASE_DATABASE_TYPE_IDENTIFIER;
227    }
228
229    /**
230     * {@inheritDoc}
231     */

232    public String JavaDoc getCurrentTimestampFunctionCall()
233    {
234       return "GETDATE()";
235    }
236
237    /**
238     * {@inheritDoc}
239     */

240    public String JavaDoc getSQLCountFunctionCall()
241    {
242       // For Sybase is best for performance to use COUNT(*)
243
return "count(*)";
244    }
245
246    /**
247     * {@inheritDoc}
248     */

249    public Object JavaDoc[] getSQLAnalyzeFunctionCall(
250       Map JavaDoc mapTableNames
251    )
252    {
253       // Sybase ASE uses UPDATE STATISTICS <table_name> to update indexes and
254
// increase performance.
255

256       String JavaDoc[] arrReturn = new String JavaDoc[mapTableNames.size()];
257       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
258       Iterator JavaDoc itItem;
259       int iIndex = 0;
260
261       itItem = mapTableNames.values().iterator();
262       while (itItem.hasNext())
263       {
264          // construct analyze query for each table from the array
265
buffer.append("update statistics ");
266          buffer.append((String JavaDoc)itItem.next());
267          // add constructed query to the output array
268
arrReturn[iIndex++] = buffer.toString();
269          // delete buffer for next usage
270
buffer.delete(0, buffer.length());
271       }
272
273       return new Object JavaDoc[] {arrReturn, Boolean.TRUE};
274    }
275
276    /**
277     * {@inheritDoc}
278     */

279    public boolean preferCountToLast(
280    )
281    {
282       // For Sybase ASE it is generally faster to execute count(*) than to do last()
283
// since it seems that it creates copy of the result set, which takes some
284
// time
285
return true;
286    }
287
288    /**
289     * {@inheritDoc}
290     */

291    public boolean hasSelectListRangeSupport(
292    )
293    {
294       // Sybase ASE supports rows limitation by using clause SET rownum and then
295
// select into the temporary table and retrieve limited data
296
return true;
297    }
298
299    /**
300     * {@inheritDoc}
301     */

302    public boolean isCallableStatement(
303       String JavaDoc strQuery
304    )
305    {
306       return strQuery.indexOf("{call ") != -1;
307    }
308
309    /**
310     * {@inheritDoc}
311     */

312    public void insertAndFetchGeneratedValues(
313       Connection JavaDoc dbConnection,
314       PreparedStatement JavaDoc insertStatement,
315       boolean bIsInDomain,
316       String JavaDoc strTableName,
317       int iIndex,
318       BasicDataObject data
319    ) throws SQLException JavaDoc,
320             OSSException
321    {
322       SybaseDataUtils.insertAndFetchGeneratedValues((CallableStatement JavaDoc)insertStatement,
323                                                     iIndex, data);
324    }
325
326    /**
327     * {@inheritDoc}
328     */

329    public void updatedAndFetchGeneratedValues(
330       String JavaDoc strDataName,
331       Connection JavaDoc dbConnection,
332       PreparedStatement JavaDoc updateStatement,
333       boolean bIsInDomain,
334       String JavaDoc strTableName,
335       int iIndex,
336       ModifiableDataObject data
337    ) throws SQLException JavaDoc,
338             OSSException
339    {
340       SybaseDataUtils.updateAndFetchGeneratedValues((CallableStatement JavaDoc)updateStatement,
341                                                     iIndex, data);
342    }
343 }
344
Popular Tags