Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/derby/impl/drda/Database.java


1   /*
2   
3      Derby - Class org.apache.derby.impl.drda.Database
4   
5      Copyright 2002, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.impl.drda;
22  
23  import java.sql.Connection;
24  import java.sql.Driver;
25  import java.sql.PreparedStatement;
26  import java.sql.Statement;
27  import java.sql.ResultSet;
28  import java.sql.SQLException;
29  import java.util.Hashtable;
30  import java.util.Enumeration;
31  import java.util.Properties;
32  import org.apache.derby.iapi.reference.Attribute;
33  import org.apache.derby.iapi.tools.i18n.LocalizedResource;
34  import org.apache.derby.impl.jdbc.EmbedConnection;
35  import org.apache.derby.iapi.services.sanity.SanityManager;
36  /**
37    Database stores information about the current database
38    It is used so that a session may have more than one database
39  */
40  class Database
41  {
42  
43    protected String dbName;      // database name 
44    protected String shortDbName;       // database name without attributes
45    String attrString="";               // attribute string
46    protected int securityMechanism;  // Security mechanism
47    protected String userId;      // User Id
48    protected String password;      // password
49    protected String decryptedUserId;  // Decrypted User id
50    protected String decryptedPassword;  // Decrypted password
51    protected boolean rdbAllowUpdates = true; // Database allows updates -default is true    
52    protected int  accessCount;    // Number of times we have tried to
53                      // set up access to this database (only 1 
54                      // allowed)
55    protected byte[] publicKeyIn;    // Security token from app requester
56    protected byte[] publicKeyOut;    // Security token sent to app requester
57    protected byte[] crrtkn;      // Correlation token
58    protected String typDefNam;      // Type definition name
59    protected int byteOrder;      //deduced from typDefNam, save String comparisons
60    protected int ccsidSBC;        // Single byte CCSID
61    protected int ccsidDBC;        // Double byte CCSID
62    protected int ccsidMBC;        // Mixed byte CCSID
63    protected String ccsidSBCEncoding;  // Encoding for single byte code page
64    protected String ccsidDBCEncoding;  // Encoding for double byte code page
65    protected String ccsidMBCEncoding;  // Encoding for mixed byte code page
66    protected boolean RDBUPDRM_sent = false;  //We have sent that an update
67                        // occurred in this transaction
68    protected boolean sendTRGDFTRT = false; // Send package target default value
69  
70    private Connection conn;      // Connection to the database
71    DRDAStatement defaultStatement;    // default statement used 
72                               // for execute imm
73    private DRDAStatement currentStatement; // current statement we are working on
74    Hashtable stmtTable;    // Hash table for storing statements
75  
76    boolean forXA = false;
77  
78    // constructor
79    /**
80     * Database constructor
81     * 
82     * @param dbName  database name
83     */
84    protected Database (String dbName)
85    {
86      if (dbName != null)
87      {
88        int attrOffset = dbName.indexOf(';');
89        if (attrOffset != -1)
90        {
91          this.attrString = dbName.substring(attrOffset,dbName.length());
92          this.shortDbName = dbName.substring(0,attrOffset);
93        }
94        else
95          this.shortDbName = dbName;
96      }
97  
98      this.dbName = dbName;
99      this.stmtTable = new Hashtable();
100     initializeDefaultStatement();
101   }
102 
103 
104   private void initializeDefaultStatement()
105   {
106     this.defaultStatement = new DRDAStatement(this);
107   }
108 
109   /**
110    * Set connection and create the SQL statement for the default statement
111    *
112    * @param conn Connection
113    * @exception SQLException
114    */
115   protected void setConnection(Connection conn)
116     throws SQLException
117   {
118     this.conn = conn;
119     defaultStatement.setStatement(conn);
120   }
121   /**
122    * Get the connection
123    *
124    * @return connection
125    */
126   protected Connection getConnection()
127   {
128     return conn;
129   }
130   /**
131    * Get current DRDA statement 
132    *
133    * @return DRDAStatement
134    * @exception SQLException
135    */
136   protected DRDAStatement getCurrentStatement() 
137   {
138     return currentStatement;
139   }
140   /**
141    * Get default statement for use in EXCIMM
142    *
143    * @return DRDAStatement
144    */
145   protected DRDAStatement getDefaultStatement() 
146   {
147     currentStatement = defaultStatement;
148     return defaultStatement;
149   }
150 
151   /**
152    * Get default statement for use in EXCIMM with specified pkgnamcsn
153    * The pkgnamcsn has the encoded isolation level
154    *
155    * @param pkgnamcsn package/ section # for statement
156    * @return DRDAStatement
157    */
158   protected DRDAStatement getDefaultStatement(String pkgnamcsn) 
159   {
160     currentStatement = defaultStatement;
161     currentStatement.setPkgnamcsn(pkgnamcsn);
162     return currentStatement;
163   }
164 
165   /**
166    * Get prepared statement based on pkgnamcsn
167    *
168    * @param pkgnamcsn - key to access statement
169    * @return prepared statement
170    */
171   protected PreparedStatement getPreparedStatement(String pkgnamcsn) 
172     throws SQLException
173   {
174     currentStatement = getDRDAStatement(pkgnamcsn);
175     if (currentStatement == null)
176       return null;
177     return currentStatement.getPreparedStatement();
178   }
179   
180   /**
181    * Get a new DRDA statement and store it in the stmtTable if stortStmt is true
182    * If possible recycle an existing statement
183    * If we are asking for one with the same name it means it
184    * was already closed.
185    * @param pkgnamcsn  Package name and section
186    * @return DRDAStatement  
187    */
188   protected DRDAStatement newDRDAStatement(String pkgnamcsn)
189   throws SQLException
190   {
191     DRDAStatement stmt = getDRDAStatement(pkgnamcsn);
192     if (stmt != null)
193       stmt.close();
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(String pkgnamcsn) 
210     throws SQLException
211   {
212     // Need to get the short version because resultSets have different
213     // corelation ids.
214     String key = getStmtKey(pkgnamcsn);
215     DRDAStatement newStmt = null;
216 
217     // If our current statement doesn't match,retrieve the statement
218     // and make it current if not null.
219     if (currentStatement == null || 
220       !key.equals(getStmtKey(currentStatement.getPkgnamcsn())));
221       {
222         newStmt  = (DRDAStatement) stmtTable.get(key);        
223       }
224       
225       if (newStmt != null)   // don't blow away currentStatement if we can't find this one
226         currentStatement = newStmt;
227       else
228         return null;
229 
230     // Set the correct result set.
231     currentStatement.setCurrentDrdaResultSet(pkgnamcsn);
232     return currentStatement;
233   }
234 
235   /**
236    * Make a new connection using the database name and set 
237    * the connection in the database
238    * @param p Properties for connection attributes to pass to connect
239    * @return new local connection
240    */
241   protected Connection makeConnection(Properties p) throws SQLException
242   {
243     p.put(Attribute.USERNAME_ATTR, userId);
244                 
245                 // take care of case of SECMEC_USRIDONL
246                 if(password != null) 
247         p.put(Attribute.PASSWORD_ATTR, password);
248     Connection conn = NetworkServerControlImpl.getDriver().connect(Attribute.PROTOCOL
249                + dbName + attrString, p);
250     conn.setAutoCommit(false);
251     setConnection(conn);
252     return conn;
253   }
254 
255   // Create string to pass to DataSource.setConnectionAttributes
256   String appendAttrString(Properties p)
257   {
258     if (p == null)
259       return null;
260     
261     Enumeration pKeys = p.propertyNames();
262     while (pKeys.hasMoreElements()) 
263     {
264       String key = (String) pKeys.nextElement();
265       attrString +=";" + key  +"=" + p.getProperty(key);
266     }
267 
268     return attrString;
269   }
270 
271   /**
272    * Get result set
273    *
274    * @param pkgnamcsn - key to access prepared statement
275    * @return result set
276    */
277   protected ResultSet getResultSet(String pkgnamcsn) throws SQLException
278   {
279     return getDRDAStatement(pkgnamcsn).getResultSet();
280   }
281   /**
282     * Set result set
283    *
284    * @param value
285    */
286   protected void setResultSet(ResultSet value) throws SQLException
287   {
288     currentStatement.setResultSet(value);
289   }
290   /**
291    * Store DRDA prepared statement
292    * @param  stmt  DRDA prepared statement
293    */
294   protected void storeStatement(DRDAStatement stmt) throws SQLException
295   {
296     stmtTable.put(getStmtKey(stmt.getPkgnamcsn()), stmt);
297   }
298 
299   protected void removeStatement(DRDAStatement stmt) throws SQLException
300   {
301     stmtTable.remove(stmt.getPkgnamcsn());
302     stmt.close();
303   }
304   
305   /**
306    * Make statement the current statement
307    * @param stmt
308    *
309    */
310 
311   protected void setCurrentStatement(DRDAStatement stmt)
312   {
313     currentStatement = stmt;
314   }
315 
316    
317   protected void commit() throws SQLException
318   {
319     
320     if (conn != null)
321       conn.commit();
322   }
323 
324   protected void rollback() throws SQLException
325   {
326     
327     if (conn != null)
328       conn.rollback();
329   }
330   /**
331     * Close the connection and clean up the statement table
332     * @throws SQLException on conn.close() error to be handled in DRDAConnThread.
333     */
334   protected void close() throws SQLException
335   {
336 
337     try {
338       if (stmtTable != null)
339       {
340         for (Enumeration e = stmtTable.elements() ; e.hasMoreElements() ;) 
341         {
342           ((DRDAStatement) e.nextElement()).close();
343         }
344       
345       }
346       if (defaultStatement != null)      
347         defaultStatement.close();
348       if ((conn != null) && !conn.isClosed())
349       {
350         if (! forXA)
351         {
352           conn.rollback();
353         }
354         conn.close();          
355       }
356     }
357     finally {
358       conn = null;
359       currentStatement = null;
360       defaultStatement = null;
361       stmtTable=null;
362     }
363   }
364 
365   protected void setDrdaID(String drdaID)
366   {
367     if (conn != null)
368       ((EmbedConnection)conn).setDrdaID(drdaID);
369   }
370 
371   /**
372    *  Set the internal isolation level to use for preparing statements.
373    *  Subsequent prepares will use this isoalation level
374    * @param level internal isolation level 
375    *
376    * @throws SQLException
377    * @see EmbedConnection#setPrepareIsolation
378    * 
379    */
380   protected void setPrepareIsolation(int level) throws SQLException
381   {
382     ((EmbedConnection) conn).setPrepareIsolation(level);
383   }
384 
385   protected int getPrepareIsolation() throws SQLException
386   {
387     return ((EmbedConnection) conn).getPrepareIsolation();
388   }
389 
390   protected String buildRuntimeInfo(String indent, LocalizedResource localLangUtil)
391   {  
392     
393     String s = indent + 
394     localLangUtil.getTextMessage("DRDA_RuntimeInfoDatabase.I") +
395       dbName + "\n" +  
396     localLangUtil.getTextMessage("DRDA_RuntimeInfoUser.I")  +
397       userId +  "\n" +
398     localLangUtil.getTextMessage("DRDA_RuntimeInfoNumStatements.I") +
399       stmtTable.size() + "\n";
400     s += localLangUtil.getTextMessage("DRDA_RuntimeInfoPreparedStatementHeader.I");
401     for (Enumeration e = stmtTable.elements() ; e.hasMoreElements() ;) 
402         {
403           s += ((DRDAStatement) e.nextElement()).toDebugString(indent
404                                      +"\t") +"\n";
405         }
406     return s;
407   }
408 
409 
410   private String getStmtKey(String pkgnamcsn)
411   {
412     if (pkgnamcsn == null)
413       return null;
414     return  pkgnamcsn.substring(0,pkgnamcsn.length() - CodePoint.PKGCNSTKN_LEN);
415   }
416 }
417 
418 
419 
420 
421 
422 
423 
424 
425 
426 
427 
428 
429 
430