KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > db > sapdb > SapDBDatabaseImpl


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: SapDBDatabaseImpl.java,v 1.5 2007/01/07 06:15:04 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.sapdb;
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.Map JavaDoc;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32
33 import org.opensubsystems.core.data.BasicDataObject;
34 import org.opensubsystems.core.data.ModifiableDataObject;
35 import org.opensubsystems.core.error.OSSDatabaseAccessException;
36 import org.opensubsystems.core.error.OSSException;
37 import org.opensubsystems.core.persist.db.DatabaseConnectionFactoryImpl;
38 import org.opensubsystems.core.persist.db.DatabaseImpl;
39 import org.opensubsystems.core.persist.db.DatabaseTransactionFactoryImpl;
40 import org.opensubsystems.core.util.DatabaseUtils;
41 import org.opensubsystems.core.util.Log;
42
43 import com.sap.dbtech.powertoys.DBM;
44 import com.sap.dbtech.powertoys.DBMException;
45 import com.sap.dbtech.rte.comm.RTEException;
46
47 /**
48  * Management layer for SAP DB database (www.sapdb.org)
49  *
50  * @version $Id: SapDBDatabaseImpl.java,v 1.5 2007/01/07 06:15:04 bastafidli Exp $
51  * @author Miro Halas
52  * @code.reviewer Miro Halas
53  * @code.reviewed 1.1 2005/08/20 21:17:02 bastafidli
54  */

55 public class SapDBDatabaseImpl extends DatabaseImpl
56 {
57    // Cached values ////////////////////////////////////////////////////////////
58

59    /**
60     * Logger for this class
61     */

62    private static Logger JavaDoc s_logger = Log.getInstance(SapDBDatabaseImpl.class);
63
64    // Constructors /////////////////////////////////////////////////////////////
65

66    /**
67     * Default constructor for empty database.
68     *
69     * @throws OSSException - problem connecting to database
70     */

71    public SapDBDatabaseImpl(
72    ) throws OSSException
73    {
74       super();
75    }
76    
77    // Database administration //////////////////////////////////////////////////
78

79    /**
80     * {@inheritDoc}
81     */

82    protected void createUser(
83       Connection JavaDoc cntAdminDBConnection
84    ) throws OSSException
85    {
86       // Now create the user
87
PreparedStatement JavaDoc pstmQuery = null;
88       try
89       {
90          // SapDB doesn't support creation of users using ?, we must immidiately
91
// specify name and password
92
/*
93          pstmQuery = cntAdminDBConnection.prepareStatement("create user ? password ?");
94          pstmQuery.setString(1, m_dcfConnectionFactory.getDatabaseUser());
95          pstmQuery.setString(2, m_dcfConnectionFactory.getDatabasePassword());
96          */

97          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
98          
99          buffer.append("CREATE user ");
100          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser());
101          buffer.append(" PASSWORD ");
102          buffer.append(DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword());
103          buffer.append(" RESOURCE NOT EXCLUSIVE");
104
105          pstmQuery = cntAdminDBConnection.prepareStatement(buffer.toString());
106          if (pstmQuery.execute())
107          {
108             // Close any results
109
pstmQuery.getMoreResults(Statement.CLOSE_ALL_RESULTS);
110          }
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          s_logger.log(Level.FINER, "Database user "
120                              + DatabaseConnectionFactoryImpl.getInstance().getDatabaseUser()
121                              + " with password "
122                              + DatabaseConnectionFactoryImpl.getInstance().getDatabasePassword()
123                              + " created.");
124       }
125       catch (SQLException JavaDoc sqleExc)
126       {
127          try
128          {
129             // At this point we don't know if this is just a single operation
130
// and we need to commit or if it is a part of bigger transaction
131
// and the commit is not desired until all operations proceed.
132
// Therefore let the DatabaseTransactionFactory resolve it
133
DatabaseTransactionFactoryImpl.getInstance().rollbackTransaction(
134                cntAdminDBConnection);
135          }
136          catch (SQLException JavaDoc sqleExc2)
137          {
138             // Ignore this
139
s_logger.log(Level.WARNING,
140                                 "Failed to rollback changes for creation of user.",
141                                 sqleExc2);
142          }
143          s_logger.log(Level.SEVERE,
144                              "Unable to create default database user.",
145                              sqleExc);
146          throw new OSSDatabaseAccessException("Unable to create default database user.",
147                                               sqleExc);
148       }
149       finally
150       {
151          DatabaseUtils.closeStatement(pstmQuery);
152       }
153    }
154     
155    /**
156     * {@inheritDoc}
157     */

158    public void startDatabaseServer(
159    ) throws OSSException
160    {
161       String JavaDoc result = null;
162       
163        try
164       {
165          String JavaDoc strURL;
166
167          strURL = DatabaseConnectionFactoryImpl.getInstance().getDatabaseURL();
168          DBM dbSession = DBM.dbDBM(getDatabaseHost(strURL), getDatabaseName(strURL));
169          // logon to dbm server
170
dbSession.cmd("user_logon " +
171                        DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminUser() +
172                        "," +
173                        DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminPassword());
174          // send server command for starting the database
175
result = dbSession.cmd("db_state");
176          // test if the server is on-line
177
if (!(result.indexOf("ONLINE") > 0))
178          {
179             // set server to the on-line state
180
result = dbSession.cmd("db_warm");
181             s_logger.log(Level.FINEST, "Starting SAP DB server");
182          }
183          dbSession.release();
184       }
185       catch (DBMException eDBMex)
186       {
187          throw new OSSDatabaseAccessException("Unable to connect to the SAP DB server",
188                                              eDBMex);
189       }
190       catch (RTEException eRTEex)
191       {
192          throw new OSSDatabaseAccessException("Unable to connect to the SAP DB server",
193                                              eRTEex);
194       }
195    }
196
197    /**
198     * {@inheritDoc}
199     */

200    public void createDatabaseInstance(
201    ) throws OSSException
202    {
203       // TODO: Feature: Find out how to create db and set up parameters
204
// commented for now (not finished)
205
// this will be used for programmatically creating of the new db instance
206
/*
207       String result = null;
208       
209        try
210       {
211          Properties pt = new Properties();
212          pt.setProperty("host", DatabaseConnectionFactoryImpl.getInstance().getDatabaseHost());
213          pt.setProperty("dbname", DatabaseConnectionFactoryImpl.getInstance().getDatabaseName());
214          pt.setProperty("dbroot", "c:\\data\\db_test");
215          String dbuser = DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminUser();
216          String dbpasswd = DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminPassword();
217
218          DBM session = new DBM(pt);
219          DBM.dbrootDBM(DatabaseConnectionFactoryImpl.getInstance().getDatabaseHost(),
220           "c:\\data");
221          result = session.cmd ("db_create");
222          DBM.dbDBM();
223          
224          // changing of parameter attribute
225          result = session.cmd("param_directput MAXUSERTASKS 20");
226          // or using session
227          result = session.cmd ("db_warm");
228          result = session.cmd ("db_state");
229          System.out.println("------------ > RESULT1 " + result);
230          result = session.cmd ("param_startsession");
231          System.out.println("------------ > RESULT2 " + result);
232          result = session.cmd ("param_put MAXUSERTASKS 5");
233          System.out.println("------------ > RESULT4 " + result);
234          result = session.cmd ("param_checkall");
235          System.out.println("------------ > RESULT5 " + result);
236          result = session.cmd ("param_commitsession");
237
238          // create a DBM object
239          // DBM session = DBM.dbBM(DatabaseConnectionFactoryImpl.getInstance().getDatabaseHost(),
240          // "TEST_DB");
241          // DBM session = DBM.dbrootDBM(
242          // DatabaseConnectionFactoryImpl.getInstance().getDatabaseHost(),
243          // "c:\\data\TESTDB");
244          // DatabaseConnectionFactoryImpl.getInstance().getDatabaseName());
245          // result = session.cmd ("db_create");
246          // logon to dbm server
247          // session.cmd ("user_logon " +
248          // DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminUser() +
249          // "," +
250          // DatabaseConnectionFactoryImpl.getInstance().getDatabaseAdminPassword());
251
252          System.out.println("------------ > RESULT " + result);
253          Log.getLogger().log(Level.FINEST, "Creating database instance");
254          session.release();
255       }
256       catch (Exception eExc)
257       {
258          System.out.println("------------ > RESULT " + result);
259          System.out.println("------------ > ERROR within the cretaing method " + eExc);
260       }
261       */

262    }
263
264    /**
265     * {@inheritDoc}
266     */

267    public int getDatabaseType()
268    {
269       return DatabaseImpl.SAPDB_DATABASE_TYPE;
270    }
271
272    /**
273     * {@inheritDoc}
274     */

275    public String JavaDoc getDatabaseTypeIdentifier()
276    {
277       return DatabaseImpl.SAPDB_DATABASE_TYPE_IDENTIFIER;
278    }
279
280    // Helper methods ///////////////////////////////////////////////////////////
281

282    /**
283     * Returns the database host name.
284     *
285     * @param strDatabaseURL - The database URL the host name to be parsed from
286     * @return String - database host name
287     */

288    protected String JavaDoc getDatabaseHost(
289       String JavaDoc strDatabaseURL
290    )
291    {
292       // database host name is possible to get from the database URL
293
// Complete syntax: jdbc:sapdb:[//host/]dbname[?name=value[&name=value]*]
294
String JavaDoc strDatabaseHost = "localhost";
295       int sIndex = 0;
296       int eIndex = 0;
297
298       // get starting index of the possible host name
299
sIndex = strDatabaseURL.indexOf("//");
300       
301       if (sIndex > 0)
302       {
303          // if the host name clause was found, get the substring
304
eIndex = strDatabaseURL.indexOf("/", sIndex + 2);
305          strDatabaseHost = strDatabaseURL.substring(sIndex + 2, eIndex);
306       }
307
308       return strDatabaseHost;
309    }
310
311    /**
312      * Returns the database name.
313      *
314      * @param strDatabaseURL - The database URL the name to be parsed from
315      * @return String - database name
316      */

317     protected String JavaDoc getDatabaseName(
318        String JavaDoc strDatabaseURL
319     )
320     {
321        // database name is possible to get from the database URL
322
// Complete syntax: jdbc:sapdb:[//host/]dbname[?name=value[&name=value]*]
323
String JavaDoc strDatabaseName = null;
324        int sIndex = 0;
325        int eIndex = 0;
326
327        // get starting index of the possible host name
328
sIndex = strDatabaseURL.indexOf("//");
329       
330        if (sIndex > 0)
331        {
332           // if the host name clause was found, get the substring
333
sIndex = strDatabaseURL.indexOf("/", sIndex + "//".length());
334        }
335        else
336        {
337           // if the host name clause is not included in URL string
338
sIndex = strDatabaseURL.indexOf(":", "sapdb:".length());
339        }
340        eIndex = strDatabaseURL.indexOf("?", sIndex + "?".length());
341        strDatabaseName = strDatabaseURL.substring(
342                                         sIndex + 1,
343                                         eIndex > 0 ? eIndex : strDatabaseURL.length()
344                                                  );
345        return strDatabaseName;
346     }
347
348    /**
349     * {@inheritDoc}
350     */

351    public void stop(
352    ) throws OSSException
353    {
354       s_logger.entering(this.getClass().getName(), "stop");
355
356       // TODO: Feature: Implement this so we can safely stop the database when
357
// the application is finished.
358
super.stop();
359
360       s_logger.entering(this.getClass().getName(), "stop");
361    }
362
363    /**
364     * {@inheritDoc}
365     */

366    public boolean preferCountToLast(
367    )
368    {
369       // For SapDB it is generally faster to execute count(*) than to do last()
370
// since it seems that it creates copy of the result set, which takes some
371
// time
372
return true;
373    }
374
375    /**
376     * {@inheritDoc}
377     */

378    public String JavaDoc getCurrentTimestampFunctionCall()
379    {
380       // SapDB requries () for this call
381
return "now()";
382    }
383
384    /**
385     * {@inheritDoc}
386     */

387    public String JavaDoc getSQLCountFunctionCall()
388    {
389       // For SapDB for best performance use COUNT(*)
390
// It is better than count(1) or count(id)
391
return "count(*)";
392    }
393
394    /**
395     * {@inheritDoc}
396     */

397    public Object JavaDoc[] getSQLAnalyzeFunctionCall(
398       Map JavaDoc mapTableNames
399    )
400    {
401       // There is no command to analyze tables or update statistics for Sap DB
402
// since Sap DB apparently does this automatically.
403
// Return null and this command will be not executed.
404
return null;
405    }
406
407    /**
408     * {@inheritDoc}
409     */

410    public boolean isCallableStatement(
411       String JavaDoc strQuery
412    )
413    {
414       return strQuery.indexOf("call ") != -1;
415    }
416
417    /**
418     * {@inheritDoc}
419     */

420    public void insertAndFetchGeneratedValues(
421       Connection JavaDoc dbConnection,
422       PreparedStatement JavaDoc insertStatement,
423       boolean bIsInDomain,
424       String JavaDoc strTableName,
425       int iIndex,
426       BasicDataObject data
427    ) throws SQLException JavaDoc,
428             OSSException
429    {
430       SapDBDataUtils.insertAndFetchGeneratedValues((CallableStatement JavaDoc)insertStatement,
431                                                    iIndex, data);
432    }
433
434    /**
435     * {@inheritDoc}
436     */

437    public void updatedAndFetchGeneratedValues(
438       String JavaDoc strDataName,
439       Connection JavaDoc dbConnection,
440       PreparedStatement JavaDoc updateStatement,
441       boolean bIsInDomain,
442       String JavaDoc strTableName,
443       int iIndex,
444       ModifiableDataObject data
445    ) throws SQLException JavaDoc,
446             OSSException
447    {
448       SapDBDataUtils.updateAndFetchGeneratedValues((CallableStatement JavaDoc)updateStatement,
449                                                    iIndex, data);
450    }
451 }
452
Popular Tags