KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > db > hsqldb > HsqlDBDatabaseImpl


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: HsqlDBDatabaseImpl.java,v 1.7 2007/01/07 06:15:15 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.hsqldb;
23
24 import java.sql.Connection JavaDoc;
25 import java.sql.PreparedStatement JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.sql.Statement JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.logging.Level JavaDoc;
30 import java.util.logging.Logger JavaDoc;
31
32 import org.opensubsystems.core.data.BasicDataObject;
33 import org.opensubsystems.core.data.ModifiableDataObject;
34 import org.opensubsystems.core.error.OSSDatabaseAccessException;
35 import org.opensubsystems.core.error.OSSException;
36 import org.opensubsystems.core.persist.db.DatabaseConnectionFactoryImpl;
37 import org.opensubsystems.core.persist.db.DatabaseImpl;
38 import org.opensubsystems.core.persist.db.DatabaseTransactionFactoryImpl;
39 import org.opensubsystems.core.util.DatabaseUtils;
40 import org.opensubsystems.core.util.Log;
41
42 /**
43  * Management layer for HSQLDB database (hsqldb.sourceforge.net)
44  *
45  * @version $Id: HsqlDBDatabaseImpl.java,v 1.7 2007/01/07 06:15:15 bastafidli Exp $
46  * @author Miro Halas
47  * @code.reviewer Miro Halas
48  * @code.reviewed 1.3 2006/04/05 05:02:43 bastafidli
49  */

50 public class HsqlDBDatabaseImpl extends DatabaseImpl
51 {
52    // Cached values ////////////////////////////////////////////////////////////
53

54    /**
55     * Logger for this class
56     */

57    private static Logger JavaDoc s_logger = Log.getInstance(HsqlDBDatabaseImpl.class);
58
59    // Constructors /////////////////////////////////////////////////////////////
60

61    /**
62     * Default constructor for empty database.
63     *
64     * @throws OSSException - problem creating the database
65     */

66    public HsqlDBDatabaseImpl(
67    ) throws OSSException
68    {
69       super();
70    }
71    
72    /**
73     * {@inheritDoc}
74     */

75    public void stop(
76    ) throws OSSException
77    {
78       // HSQLDB 1.7 had bug which prevented to restart the database if it was
79
// stopped. This should be fixed and now version 1.8 requires explicit
80
// shutdown rather than closing the database when the last connection
81
// is closed so lets issue explicit shutdown
82
if (m_bDatabaseStarted)
83       {
84          Connection JavaDoc cntAdminDBConnection = null;
85          boolean bStopped = false;
86    
87          try
88          {
89             // Try to shutdown the database
90
// HSQLDB requires us to connect as administrator
91
cntAdminDBConnection = getAdminConnection(true);
92    
93             if (cntAdminDBConnection == null)
94             {
95                s_logger.log(Level.WARNING,
96                             "Unable to connect to database as admin to stop it.");
97             }
98             else
99             {
100                Statement JavaDoc stmQuery = null;
101                try
102                {
103                   stmQuery = cntAdminDBConnection.createStatement();
104                   if (stmQuery.execute("shutdown"))
105                   {
106                      // We should close all statements, but the database was already closed
107
// stQuery.getMoreResults(Statement.CLOSE_ALL_RESULTS);
108
}
109                   bStopped = true;
110                   s_logger.log(Level.FINER, "Database is stopped.");
111                }
112                catch (SQLException JavaDoc sqleExc)
113                {
114                   s_logger.log(Level.WARNING, "Unable to stop the database.", sqleExc);
115                }
116                finally
117                {
118                   if ((!bStopped) && (stmQuery != null))
119                   {
120                      // If the database is stopped, no need to close the statement
121
try
122                      {
123                         stmQuery.close();
124                      }
125                      catch (SQLException JavaDoc sqleExc)
126                      {
127                         s_logger.log(Level.WARNING,
128                                      "Closing of statement has failed.",
129                                      sqleExc);
130                      }
131                   }
132                }
133             }
134          }
135          finally
136          {
137             try
138             {
139                if (cntAdminDBConnection != null)
140                {
141                   // We still need to return the connection since the factory
142
// keeps track of them
143
DatabaseConnectionFactoryImpl.getInstance().returnConnection(
144                            cntAdminDBConnection);
145                }
146             }
147             finally
148             {
149                super.stop();
150             }
151          }
152       }
153    }
154     
155    /**
156     * {@inheritDoc}
157     */

158    protected void createUser(
159       Connection JavaDoc cntAdminDBConnection
160    ) throws OSSException
161    {
162       // Now create the user
163
PreparedStatement JavaDoc pstmQuery = null;
164       try
165       {
166          // HSQLDB doesn't support creation of users using ?, we must immidiately
167
// specify name and password
168
// HSQLDB requires user to have administrator priviledges to create tables
169
/*
170          pstmQuery = cntAdminDBConnection.prepareStatement(
171                         "create user ? password ? admin");
172          pstmQuery.setString(1,
173             DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
174          pstmQuery.setString(2,
175             DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword());
176          */

177
178          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
179          
180          buffer.append("CREATE user ");
181          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
182          buffer.append(" PASSWORD ");
183          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword());
184          // We have to make the user ADMIN otherwise it is not possible
185
// to create tables, since following exception will be thrown
186
// Caused by: java.sql.SQLException: Access is denied in statement [create table]
187
// and hsqldb doesn't provide grant to create tables
188
buffer.append(" ADMIN ");
189          pstmQuery = cntAdminDBConnection.prepareStatement(buffer.toString());
190
191          if (pstmQuery.execute())
192          {
193             // Close any results
194
pstmQuery.getMoreResults(Statement.CLOSE_ALL_RESULTS);
195          }
196          
197          // At this point we don't know if this is just a single operation
198
// and we need to commit or if it is a part of bigger transaction
199
// and the commit is not desired until all operations proceed.
200
// Therefore let the DatabaseTransactionFactory resolve it
201
DatabaseTransactionFactoryImpl.getInstance().commitTransaction(
202                                                  cntAdminDBConnection);
203          
204          s_logger.log(Level.FINER, "Database user "
205             + DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser()
206             + " with password "
207             + DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword()
208             + " created.");
209       }
210       catch (SQLException JavaDoc sqleExc)
211       {
212          try
213          {
214             // At this point we don't know if this is just a single operation
215
// and we need to commit or if it is a part of bigger transaction
216
// and the commit is not desired until all operations proceed.
217
// Therefore let the DatabaseTransactionFactory resolve it
218
DatabaseTransactionFactoryImpl.getInstance().rollbackTransaction(
219                cntAdminDBConnection);
220          }
221          catch (SQLException JavaDoc sqleExc2)
222          {
223             // Ignore this
224
s_logger.log(Level.WARNING,
225                                 "Failed to rollback changes for creation of user.",
226                                 sqleExc2);
227          }
228          s_logger.log(Level.SEVERE,
229                              "Unable to create default database user.",
230                              sqleExc);
231          throw new OSSDatabaseAccessException("Unable to create default database user.",
232                                               sqleExc);
233       }
234       finally
235       {
236          DatabaseUtils.closeStatement(pstmQuery);
237       }
238    }
239
240    /**
241     * {@inheritDoc}
242     */

243    public void startDatabaseServer(
244    ) throws OSSException
245    {
246       // Implementation of this method is not neccessary because HSQLDB database
247
// starts (or schema is created) when the administrator is connected to
248
}
249
250    /**
251     * {@inheritDoc}
252     */

253    public void createDatabaseInstance(
254    ) throws OSSException
255    {
256       // Implementation of this method is not neccessary because HSQLDB database
257
// is created when the administrator is connected to
258
}
259
260    /**
261     * {@inheritDoc}
262     */

263    public int getDatabaseType()
264    {
265       return DatabaseImpl.HSQLDB_DATABASE_TYPE;
266    }
267
268    /**
269     * {@inheritDoc}
270     */

271    public String JavaDoc getDatabaseTypeIdentifier()
272    {
273       return DatabaseImpl.HSQLDB_DATABASE_TYPE_IDENTIFIER;
274    }
275
276    /**
277     * {@inheritDoc}
278     */

279    public String JavaDoc getCurrentTimestampFunctionCall()
280    {
281       // HSQLDB doesn't allow () for this call
282
return "now";
283    }
284
285    /**
286     * {@inheritDoc}
287     */

288    public String JavaDoc getSQLCountFunctionCall()
289    {
290       // For HSQLDB is best for performance use COUNT(*)
291
return "count(*)";
292    }
293
294    /**
295     * {@inheritDoc}
296     */

297    public Object JavaDoc[] getSQLAnalyzeFunctionCall(
298       Map JavaDoc mapTableNames
299    )
300    {
301       // For HsqlDB is not necessary to update statistics because this DB is not
302
// appropriate for processing huge amount of records
303
return null;
304    }
305
306    /**
307     * {@inheritDoc}
308     */

309    public int getTransactionIsolation(
310       int iTransactionIsolation
311    )
312    {
313       // TODO: Bug: HSQLDB 1.7.1: Doesn't support setTransactionIsolation call
314
// so change this to -1 to do not set any (XAPool requires it)
315
return -1;
316    }
317
318    /**
319     * {@inheritDoc}
320     */

321    public boolean isCallableStatement(
322       String JavaDoc strQuery
323    )
324    {
325       // HSQLDB doesn't support stored procedures
326
return false;
327    }
328
329    /**
330     * {@inheritDoc}
331     */

332    public void insertAndFetchGeneratedValues(
333       Connection JavaDoc dbConnection,
334       PreparedStatement JavaDoc insertStatement,
335       boolean bIsInDomain,
336       String JavaDoc strTableName,
337       int iIndex,
338       BasicDataObject data
339    ) throws SQLException JavaDoc,
340             OSSException
341    {
342       HsqlDBDataUtils.insertAndFetchGeneratedValues(dbConnection,
343                            insertStatement, bIsInDomain, strTableName, data);
344    }
345
346    /**
347     * {@inheritDoc}
348     */

349    public void updatedAndFetchGeneratedValues(
350       String JavaDoc strDataName,
351       Connection JavaDoc dbConnection,
352       PreparedStatement JavaDoc updateStatement,
353       boolean bIsInDomain,
354       String JavaDoc strTableName,
355       int iIndex,
356       ModifiableDataObject data
357    ) throws SQLException JavaDoc,
358             OSSException
359    {
360       HsqlDBDataUtils.updatedAndFetchGeneratedValues(strDataName, dbConnection,
361                          updateStatement, bIsInDomain, strTableName, data);
362    }
363 }
364
Popular Tags