KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > drda > Database


1 /*
2
3    Derby - Class org.apache.derby.impl.drda.Database
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    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, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.drda;
23
24 import java.sql.Connection JavaDoc;
25 import java.sql.Driver JavaDoc;
26 import java.sql.PreparedStatement JavaDoc;
27 import java.sql.Statement JavaDoc;
28 import java.sql.ResultSet JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.Properties JavaDoc;
33
34 import org.apache.derby.iapi.jdbc.EngineConnection;
35 import org.apache.derby.iapi.reference.Attribute;
36 import org.apache.derby.iapi.tools.i18n.LocalizedResource;
37 import org.apache.derby.iapi.services.sanity.SanityManager;
38
39 /**
40     Database stores information about the current database
41     It is used so that a session may have more than one database
42 */

43 class Database
44 {
45
46     protected String JavaDoc dbName; // database name
47
protected String JavaDoc shortDbName; // database name without attributes
48
String JavaDoc attrString=""; // attribute string
49
protected int securityMechanism; // Security mechanism
50
protected String JavaDoc userId; // User Id
51
protected String JavaDoc password; // password
52
protected String JavaDoc decryptedUserId; // Decrypted User id
53
protected String JavaDoc decryptedPassword; // Decrypted password
54
protected byte[] passwordSubstitute;// password substitute - SECMEC_USRSSBPWD
55
protected boolean rdbAllowUpdates = true; // Database allows updates -default is true
56
protected int accessCount; // Number of times we have tried to
57
// set up access to this database (only 1
58
// allowed)
59
protected byte[] secTokenIn; // Security token from app requester
60
protected byte[] secTokenOut; // Security token sent to app requester
61
protected byte[] crrtkn; // Correlation token
62
protected String JavaDoc typDefNam; // Type definition name
63
protected int byteOrder; //deduced from typDefNam, save String comparisons
64
protected int ccsidSBC; // Single byte CCSID
65
protected int ccsidDBC; // Double byte CCSID
66
protected int ccsidMBC; // Mixed byte CCSID
67
protected String JavaDoc ccsidSBCEncoding; // Encoding for single byte code page
68
protected String JavaDoc ccsidDBCEncoding; // Encoding for double byte code page
69
protected String JavaDoc ccsidMBCEncoding; // Encoding for mixed byte code page
70
protected boolean RDBUPDRM_sent = false; //We have sent that an update
71
// occurred in this transaction
72
protected boolean sendTRGDFTRT = false; // Send package target default value
73

74     /**
75      * Connection to the database in the embedded engine.
76      */

77     private EngineConnection conn;
78     DRDAStatement defaultStatement; // default statement used
79
// for execute imm
80
private DRDAStatement currentStatement; // current statement we are working on
81
private Hashtable JavaDoc stmtTable; // Hash table for storing statements
82

83     boolean forXA = false;
84
85     // constructor
86
/**
87      * Database constructor
88      *
89      * @param dbName database name
90      */

91     Database (String JavaDoc dbName)
92     {
93         if (dbName != null)
94         {
95             int attrOffset = dbName.indexOf(';');
96             if (attrOffset != -1)
97             {
98                 this.attrString = dbName.substring(attrOffset,dbName.length());
99                 this.shortDbName = dbName.substring(0,attrOffset);
100             }
101             else
102                 this.shortDbName = dbName;
103         }
104
105         this.dbName = dbName;
106         this.stmtTable = new Hashtable JavaDoc();
107         initializeDefaultStatement();
108     }
109
110
111     private void initializeDefaultStatement()
112     {
113         this.defaultStatement = new DRDAStatement(this);
114     }
115
116     /**
117      * Set connection and create the SQL statement for the default statement
118      *
119      * @param conn Connection
120      * @exception SQLException
121      */

122     final void setConnection(EngineConnection conn)
123         throws SQLException JavaDoc
124     {
125         this.conn = conn;
126         if(conn != null)
127             defaultStatement.setStatement(conn);
128     }
129     /**
130      * Get the connection
131      *
132      * @return connection
133      */

134     final EngineConnection getConnection()
135     {
136         return conn;
137     }
138     /**
139      * Get current DRDA statement
140      *
141      * @return DRDAStatement
142      * @exception SQLException
143      */

144     protected DRDAStatement getCurrentStatement()
145     {
146         return currentStatement;
147     }
148     /**
149      * Get default statement for use in EXCIMM
150      *
151      * @return DRDAStatement
152      */

153     protected DRDAStatement getDefaultStatement()
154     {
155         currentStatement = defaultStatement;
156         return defaultStatement;
157     }
158
159     /**
160      * Get default statement for use in EXCIMM with specified pkgnamcsn
161      * The pkgnamcsn has the encoded isolation level
162      *
163      * @param pkgnamcsn package/ section # for statement
164      * @return DRDAStatement
165      */

166     protected DRDAStatement getDefaultStatement(Pkgnamcsn pkgnamcsn)
167     {
168         currentStatement = defaultStatement;
169         currentStatement.setPkgnamcsn(pkgnamcsn);
170         return currentStatement;
171     }
172
173     /**
174      * Get a new DRDA statement and store it in the stmtTable if stortStmt is
175      * true. If possible recycle an existing statement. When the server gets a
176      * new statement with a previously used pkgnamcsn, it means that
177      * client-side statement associated with this pkgnamcsn has been closed. In
178      * this case, server can re-use the DRDAStatement by doing the following:
179      * 1) Retrieve the old DRDAStatement associated with this pkgnamcsn and
180      * close it.
181      * 2) Reset the DRDAStatement state for re-use.
182      *
183      * @param pkgnamcsn Package name and section
184      * @return DRDAStatement
185      */

186     protected DRDAStatement newDRDAStatement(Pkgnamcsn pkgnamcsn)
187     throws SQLException JavaDoc
188     {
189         DRDAStatement stmt = getDRDAStatement(pkgnamcsn);
190         if (stmt != null) {
191             stmt.close();
192             stmt.reset();
193         }
194         else
195         {
196             stmt = new DRDAStatement(this);
197             stmt.setPkgnamcsn(pkgnamcsn);
198             storeStatement(stmt);
199         }
200         return stmt;
201     }
202
203     /**
204      * Get DRDA statement based on pkgnamcsn
205      *
206      * @param pkgnamcsn - key to access statement
207      * @return DRDAStatement
208      */

209     protected DRDAStatement getDRDAStatement(Pkgnamcsn pkgnamcsn) {
210         DRDAStatement newStmt =
211             (DRDAStatement) stmtTable.get(pkgnamcsn.getStatementKey());
212         if (newStmt != null) {
213             currentStatement = newStmt;
214             currentStatement.setCurrentDrdaResultSet(pkgnamcsn);
215         }
216         return newStmt;
217     }
218
219     /**
220      * Make a new connection using the database name and set
221      * the connection in the database
222      * @param p Properties for connection attributes to pass to connect
223      */

224     void makeConnection(Properties JavaDoc p) throws SQLException JavaDoc
225     {
226         p.put(Attribute.USERNAME_ATTR, userId);
227                 
228         // take care of case of SECMEC_USRIDONL
229
if (password != null)
230             p.put(Attribute.PASSWORD_ATTR, password);
231                 
232         // Contract between network server and embedded engine
233
// is that any connection returned implements EngineConnection.
234
EngineConnection conn = (EngineConnection)
235             NetworkServerControlImpl.getDriver().connect(Attribute.PROTOCOL
236                              + shortDbName + attrString, p);
237         if (conn != null) {
238             conn.setAutoCommit(false);
239         }
240         setConnection(conn);
241     }
242
243     /**
244      * This makes a dummy connection to the database in order to
245      * boot and/or create this last one. If database cannot
246      * be found or authentication does not succeed, this will throw
247      * a SQLException which we catch and do nothing. We don't pass a
248      * userid and password here as we don't need to for the purpose
249      * of this method - main goal is to cause the database to be
250      * booted via a dummy connection.
251      */

252     void makeDummyConnection()
253     {
254         try {
255             // Contract between network server and embedded engine
256
// is that any connection returned implements EngineConnection.
257
EngineConnection conn = (EngineConnection)
258                 NetworkServerControlImpl.getDriver().connect(Attribute.PROTOCOL
259                     + shortDbName + attrString, new Properties JavaDoc());
260
261             // If we succeeded in getting a connection, well just close it
262
if (conn != null) {
263                 conn.close();
264             }
265         } catch (SQLException JavaDoc se) {} // Simply do nothing
266
}
267     
268     // Create string to pass to DataSource.setConnectionAttributes
269
String JavaDoc appendAttrString(Properties JavaDoc p)
270     {
271         if (p == null)
272             return null;
273         
274         Enumeration JavaDoc pKeys = p.propertyNames();
275         while (pKeys.hasMoreElements())
276         {
277             String JavaDoc key = (String JavaDoc) pKeys.nextElement();
278             attrString +=";" + key + "=" + p.getProperty(key);
279         }
280
281         return attrString;
282     }
283
284     /**
285      * Store DRDA prepared statement
286      * @param stmt DRDA prepared statement
287      */

288     protected void storeStatement(DRDAStatement stmt) throws SQLException JavaDoc
289     {
290         stmtTable.put(stmt.getPkgnamcsn().getStatementKey(), stmt);
291     }
292
293     protected void removeStatement(DRDAStatement stmt) throws SQLException JavaDoc
294     {
295         stmtTable.remove(stmt.getPkgnamcsn().getStatementKey());
296         stmt.close();
297     }
298     
299     /**
300      * Make statement the current statement
301      * @param stmt
302      *
303      */

304
305     protected void setCurrentStatement(DRDAStatement stmt)
306     {
307         currentStatement = stmt;
308     }
309
310    
311     protected void commit() throws SQLException JavaDoc
312     {
313         
314         if (conn != null)
315             conn.commit();
316     }
317
318     protected void rollback() throws SQLException JavaDoc
319     {
320         
321         if (conn != null)
322             conn.rollback();
323     }
324     /**
325       * Close the connection and clean up the statement table
326       * @throws SQLException on conn.close() error to be handled in DRDAConnThread.
327       */

328     protected void close() throws SQLException JavaDoc
329     {
330
331         try {
332             if (stmtTable != null)
333             {
334                 for (Enumeration JavaDoc e = stmtTable.elements() ; e.hasMoreElements() ;)
335                 {
336                     ((DRDAStatement) e.nextElement()).close();
337                 }
338             
339             }
340             if (defaultStatement != null)
341                 defaultStatement.close();
342             if ((conn != null) && !conn.isClosed())
343             {
344                 if (! forXA)
345                 {
346                     conn.rollback();
347                 }
348                 conn.close();
349             }
350         }
351         finally {
352             conn = null;
353             currentStatement = null;
354             defaultStatement = null;
355             stmtTable=null;
356         }
357     }
358
359     final void setDrdaID(String JavaDoc drdaID)
360     {
361         if (conn != null)
362             conn.setDrdaID(drdaID);
363     }
364
365     /**
366      * Set the internal isolation level to use for preparing statements.
367      * Subsequent prepares will use this isoalation level
368      * @param level internal isolation level
369      *
370      * @throws SQLException
371      * @see EngineConnection#setPrepareIsolation
372      *
373      */

374     final void setPrepareIsolation(int level) throws SQLException JavaDoc
375     {
376         conn.setPrepareIsolation(level);
377     }
378
379     final int getPrepareIsolation() throws SQLException JavaDoc
380     {
381         return conn.getPrepareIsolation();
382     }
383
384     protected String JavaDoc buildRuntimeInfo(String JavaDoc indent, LocalizedResource localLangUtil)
385     {
386       
387         String JavaDoc s = indent +
388         localLangUtil.getTextMessage("DRDA_RuntimeInfoDatabase.I") +
389             dbName + "\n" +
390         localLangUtil.getTextMessage("DRDA_RuntimeInfoUser.I") +
391             userId + "\n" +
392         localLangUtil.getTextMessage("DRDA_RuntimeInfoNumStatements.I") +
393             stmtTable.size() + "\n";
394         s += localLangUtil.getTextMessage("DRDA_RuntimeInfoPreparedStatementHeader.I");
395         for (Enumeration JavaDoc e = stmtTable.elements() ; e.hasMoreElements() ;)
396                 {
397                     s += ((DRDAStatement) e.nextElement()).toDebugString(indent
398                                                                          +"\t") +"\n";
399                 }
400         return s;
401     }
402
403     /**
404      * This method resets the state of this Database object so that it can
405      * be re-used.
406      * Note: currently this method resets the variables related to security
407      * mechanisms that have been investigated as needing a reset.
408      * TODO: Investigate what all variables in this class need to be
409      * reset when this database object is re-used on a connection pooling or
410      * transaction pooling. see DRDAConnThread.parseACCSEC (CodePoint.RDBNAM)
411      * where database object is re-used on a connection reset.
412      */

413     public void reset()
414     {
415         // Reset variables for connection re-use. Currently only takes care
416
// of reset the variables that affect EUSRIDPWD and USRSSBPWD
417
// security mechanisms. (DERBY-1080)
418
decryptedUserId = null;
419         decryptedPassword = null;
420         passwordSubstitute = null;
421         secTokenIn = null;
422         secTokenOut = null;
423         userId = null;
424         password = null;
425         securityMechanism = 0;
426     }
427 }
428
Popular Tags