KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > lib > sql > SQLDocument


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: SQLDocument.java,v 1.25 2004/02/11 17:56:36 minchau Exp $
18  */

19
20 package org.apache.xalan.lib.sql;
21
22 import java.util.Vector JavaDoc;
23
24 import org.apache.xalan.extensions.ExpressionContext;
25 import org.apache.xpath.XPathContext;
26
27 import org.apache.xml.dtm.DTMManager;
28 import org.apache.xml.dtm.DTM;
29 import java.sql.Connection JavaDoc;
30 import java.sql.Statement JavaDoc;
31 import java.sql.ResultSet JavaDoc;
32 import java.sql.ResultSetMetaData JavaDoc;
33 import java.sql.SQLException JavaDoc;
34 import java.sql.*;
35 import org.apache.xml.dtm.ref.*;
36
37 /**
38  * The SQL Document is the main controlling class the executesa SQL Query
39  */

40 public class SQLDocument extends DTMDocument
41 {
42
43   /**
44    */

45   private boolean DEBUG = false;
46
47   /**
48    */

49   private static final String JavaDoc S_NAMESPACE = "http://xml.apache.org/xalan/SQLExtension";
50
51
52   /**
53    */

54   private static final String JavaDoc S_SQL = "sql";
55
56   /**
57    */

58   private static final String JavaDoc S_ROW_SET = "row-set";
59
60   /**
61    */

62   private static final String JavaDoc S_METADATA = "metadata";
63
64   /**
65    */

66   private static final String JavaDoc S_COLUMN_HEADER = "column-header";
67
68   /**
69    */

70   private static final String JavaDoc S_ROW = "row";
71
72   /**
73    */

74   private static final String JavaDoc S_COL = "col";
75
76   /**
77    */

78   private static final String JavaDoc S_OUT_PARAMETERS = "out-parameters";
79
80   /**
81    */

82   private static final String JavaDoc S_CATALOGUE_NAME = "catalogue-name";
83   /**
84    */

85   private static final String JavaDoc S_DISPLAY_SIZE = "column-display-size";
86   /**
87    */

88   private static final String JavaDoc S_COLUMN_LABEL = "column-label";
89   /**
90    */

91   private static final String JavaDoc S_COLUMN_NAME = "column-name";
92   /**
93    */

94   private static final String JavaDoc S_COLUMN_TYPE = "column-type";
95   /**
96    */

97   private static final String JavaDoc S_COLUMN_TYPENAME = "column-typename";
98   /**
99    */

100   private static final String JavaDoc S_PRECISION = "precision";
101   /**
102    */

103   private static final String JavaDoc S_SCALE = "scale";
104   /**
105    */

106   private static final String JavaDoc S_SCHEMA_NAME = "schema-name";
107   /**
108    */

109   private static final String JavaDoc S_TABLE_NAME = "table-name";
110   /**
111    */

112   private static final String JavaDoc S_CASESENSITIVE = "case-sensitive";
113   /**
114    */

115   private static final String JavaDoc S_DEFINITELYWRITABLE = "definitely-writable";
116   /**
117    */

118   private static final String JavaDoc S_ISNULLABLE = "nullable";
119   /**
120    */

121   private static final String JavaDoc S_ISSIGNED = "signed";
122   /**
123    */

124   private static final String JavaDoc S_ISWRITEABLE = "writable";
125   /**
126    */

127   private static final String JavaDoc S_ISSEARCHABLE = "searchable";
128
129   /**
130    */

131   private int m_SQL_TypeID = 0;
132   /**
133    */

134   private int m_MetaData_TypeID = 0;
135   /**
136    */

137   private int m_ColumnHeader_TypeID = 0;
138   /**
139    */

140   private int m_RowSet_TypeID = 0;
141   /**
142    */

143   private int m_Row_TypeID = 0;
144   /**
145    */

146   private int m_Col_TypeID = 0;
147   /**
148    */

149   private int m_OutParameter_TypeID = 0;
150
151   /**
152    */

153   private int m_ColAttrib_CATALOGUE_NAME_TypeID = 0;
154   /**
155    */

156   private int m_ColAttrib_DISPLAY_SIZE_TypeID = 0;
157   /**
158    */

159   private int m_ColAttrib_COLUMN_LABEL_TypeID = 0;
160   /**
161    */

162   private int m_ColAttrib_COLUMN_NAME_TypeID = 0;
163   /**
164    */

165   private int m_ColAttrib_COLUMN_TYPE_TypeID = 0;
166   /**
167    */

168   private int m_ColAttrib_COLUMN_TYPENAME_TypeID = 0;
169   /**
170    */

171   private int m_ColAttrib_PRECISION_TypeID = 0;
172   /**
173    */

174   private int m_ColAttrib_SCALE_TypeID = 0;
175   /**
176    */

177   private int m_ColAttrib_SCHEMA_NAME_TypeID = 0;
178   /**
179    */

180   private int m_ColAttrib_TABLE_NAME_TypeID = 0;
181   /**
182    */

183   private int m_ColAttrib_CASESENSITIVE_TypeID = 0;
184   /**
185    */

186   private int m_ColAttrib_DEFINITELYWRITEABLE_TypeID = 0;
187   /**
188    */

189   private int m_ColAttrib_ISNULLABLE_TypeID = 0;
190   /**
191    */

192   private int m_ColAttrib_ISSIGNED_TypeID = 0;
193   /**
194    */

195   private int m_ColAttrib_ISWRITEABLE_TypeID = 0;
196   /**
197    */

198   private int m_ColAttrib_ISSEARCHABLE_TypeID = 0;
199
200   /**
201    * The Statement used to extract the data from the database connection.
202    */

203   private Statement JavaDoc m_Statement = null;
204
205   /**
206    * Expression COntext used to creat this document
207    * may be used to grab variables from the XSL processor
208    */

209   private ExpressionContext m_ExpressionContext = null;
210
211   /**
212    * The Connection Pool where we has derived all of our connections
213    * for this document
214    */

215   private ConnectionPool m_ConnectionPool = null;
216
217   /**
218    * The current ResultSet.
219    */

220   private ResultSet JavaDoc m_ResultSet = null;
221
222   /**
223    * The parameter definitions if this is a callable
224    * statement with output parameters.
225    */

226   private SQLQueryParser m_QueryParser = null;
227
228   /**
229    * As the column header array is built, keep the node index
230    * for each Column.
231    * The primary use of this is to locate the first attribute for
232    * each column in each row as we add records.
233    */

234   private int[] m_ColHeadersIdx;
235
236   /**
237    * An indicator on how many columns are in this query
238    */

239   private int m_ColCount;
240
241   /**
242    * The Index of the MetaData Node. Currently the MetaData Node contains the
243    *
244    */

245   private int m_MetaDataIdx = DTM.NULL;
246
247   /**
248    * The index of the Row Set node. This is the sibling directly after
249    * the last Column Header.
250    */

251   private int m_RowSetIdx = DTM.NULL;
252
253   /**
254    */

255   private int m_SQLIdx = DTM.NULL;
256
257   /**
258    * Demark the first row element where we started adding rows into the
259    * Document.
260    */

261   private int m_FirstRowIdx = DTM.NULL;
262
263   /**
264    * Keep track of the Last row inserted into the DTM from the ResultSet.
265    * This will be used as the index of the parent Row Element when adding
266    * a row.
267    */

268   private int m_LastRowIdx = DTM.NULL;
269
270   /**
271    * Streaming Mode Control, In Streaming mode we reduce the memory
272    * footprint since we only use a single row instance.
273    */

274   private boolean m_StreamingMode = true;
275
276   /**
277    * Multiple Result sets mode (metadata inside rowset).
278    */

279   private boolean m_MultipleResults = false;
280
281   /**
282    * Flag to detect if an error occured during an operation
283    * Defines how errors are handled and how the SQL Connection
284    * is closed.
285    */

286   private boolean m_HasErrors = false;
287
288   /**
289    * Is statement caching enabled.
290    */

291   private boolean m_IsStatementCachingEnabled = false;
292
293   /**
294    * XConnection this document came from.
295    */

296   private XConnection m_XConnection = null;
297
298   /**
299    * @param mgr
300    * @param ident
301    * @param pool
302    * @param con
303    * @param stmt
304    * @param data
305    * @param streamingMode
306    * @throws SQLException
307    */

308   // public cSQLDocument(DTMManager mgr, int ident, Statement stmt,
309
// ResultSet singleResult, Vector paramdefs, boolean streamingMode,
310
// boolean multipleResults, boolean statementCachingEnabled) throws SQLException
311

312   public SQLDocument(DTMManager mgr, int ident)
313   {
314     super(mgr, ident);
315   }
316
317   /**
318    * This static method simplifies the creation of an SQL Document and allows
319    * us to embedd the complexity of creating / handling the dtmIdent inside
320    * the document. This type of method may better placed inside the DTMDocument
321    * code
322    */

323   public static SQLDocument getNewDocument(ExpressionContext exprContext)
324   {
325     DTMManager mgr =
326       ((XPathContext.XPathExpressionContext)exprContext).getDTMManager();
327     DTMManagerDefault mgrDefault = (DTMManagerDefault) mgr;
328
329
330     int dtmIdent = mgrDefault.getFirstFreeDTMID();
331
332     SQLDocument doc =
333       new SQLDocument(mgr, dtmIdent << DTMManager.IDENT_DTM_NODE_BITS);
334
335     // Register the document
336
mgrDefault.addDTM(doc, dtmIdent);
337     doc.setExpressionContext(exprContext);
338
339     return doc;
340   }
341
342   /**
343    * When building the SQL Document, we need to store the Expression
344    * Context that was used to create the document. This will be se to
345    * reference items int he XSLT process such as any variables that were
346    * present.
347    */

348   protected void setExpressionContext(ExpressionContext expr)
349   {
350     m_ExpressionContext = expr;
351   }
352
353   /**
354    * Return the context used to build this document
355    */

356   public ExpressionContext getExpressionContext()
357   {
358     return m_ExpressionContext;
359   }
360
361
362   public void execute(XConnection xconn, SQLQueryParser query)
363     throws SQLException JavaDoc
364   {
365     try
366     {
367       m_StreamingMode = "true".equals(xconn.getFeature("streaming"));
368       m_MultipleResults = "true".equals(xconn.getFeature("multiple-results"));
369       m_IsStatementCachingEnabled = "true".equals(xconn.getFeature("cache-statements"));
370       m_XConnection = xconn;
371       m_QueryParser = query;
372
373       executeSQLStatement();
374
375       createExpandedNameTable();
376
377       // Start the document here
378
m_DocumentIdx = addElement(0, m_Document_TypeID, DTM.NULL, DTM.NULL);
379       m_SQLIdx = addElement(1, m_SQL_TypeID, m_DocumentIdx, DTM.NULL);
380
381
382       if ( ! m_MultipleResults )
383         extractSQLMetaData(m_ResultSet.getMetaData());
384
385       // Only grab the first row, subsequent rows will be
386
// fetched on demand.
387
// We need to do this here so at least on row is set up
388
// to measure when we are actually reading rows.
389
addRowToDTMFromResultSet();
390     }
391     catch(SQLException JavaDoc e)
392     {
393       m_HasErrors = true;
394       throw e;
395     }
396   }
397
398   private void executeSQLStatement() throws SQLException JavaDoc
399   {
400     m_ConnectionPool = m_XConnection.getConnectionPool();
401
402     Connection JavaDoc conn = m_ConnectionPool.getConnection();
403
404     if (! m_QueryParser.hasParameters() )
405     {
406       m_Statement = conn.createStatement();
407       if (! m_Statement.execute(m_QueryParser.getSQLQuery()))
408       {
409         throw new SQLException JavaDoc("Error in Query");
410       }
411     }
412     else if (m_QueryParser.isCallable())
413     {
414       CallableStatement cstmt =
415         conn.prepareCall(m_QueryParser.getSQLQuery());
416       m_QueryParser.registerOutputParameters(cstmt);
417       m_QueryParser.populateStatement(cstmt, m_ExpressionContext);
418       m_Statement = cstmt;
419       if (! cstmt.execute()) throw new SQLException JavaDoc("Error in Callable Statement");
420     }
421     else
422     {
423       PreparedStatement stmt =
424         conn.prepareStatement(m_QueryParser.getSQLQuery());
425       m_QueryParser.populateStatement(stmt, m_ExpressionContext);
426       m_Statement = stmt;
427       if (! stmt.execute()) throw new SQLException JavaDoc("Error in Prepared Statement");
428     }
429
430     m_ResultSet = m_Statement.getResultSet();
431   }
432
433   /**
434    * Extract the Meta Data and build the Column Attribute List.
435    * @param meta
436    * @return
437    */

438   private void extractSQLMetaData( ResultSetMetaData JavaDoc meta )
439   {
440     // Build the Node Tree, just add the Column Header
441
// branch now, the Row & col elements will be added
442
// on request.
443

444     // Add in the row-set Element
445

446     // Add in the MetaData Element
447
m_MetaDataIdx = addElement(1, m_MetaData_TypeID, m_MultipleResults ? m_RowSetIdx : m_SQLIdx, DTM.NULL);
448
449     try
450     {
451       m_ColCount = meta.getColumnCount();
452       m_ColHeadersIdx = new int[m_ColCount];
453     }
454     catch(Exception JavaDoc e)
455     {
456       m_XConnection.setError(e, this, checkWarnings());
457       //error("ERROR Extracting Metadata");
458
}
459
460     // The ColHeaderIdx will be used to keep track of the
461
// Element entries for the individual Column Header.
462
int lastColHeaderIdx = DTM.NULL;
463
464     // JDBC Columms Start at 1
465
int i = 1;
466     for (i=1; i<= m_ColCount; i++)
467     {
468       m_ColHeadersIdx[i-1] =
469         addElement(2,m_ColumnHeader_TypeID, m_MetaDataIdx, lastColHeaderIdx);
470
471       lastColHeaderIdx = m_ColHeadersIdx[i-1];
472       // A bit brute force, but not sure how to clean it up
473

474       try
475       {
476         addAttributeToNode(
477           meta.getColumnName(i),
478           m_ColAttrib_COLUMN_NAME_TypeID, lastColHeaderIdx);
479       }
480       catch(Exception JavaDoc e)
481       {
482         addAttributeToNode(
483           S_ATTRIB_NOT_SUPPORTED,
484           m_ColAttrib_COLUMN_NAME_TypeID, lastColHeaderIdx);
485       }
486
487       try
488       {
489         addAttributeToNode(
490           meta.getColumnLabel(i),
491           m_ColAttrib_COLUMN_LABEL_TypeID, lastColHeaderIdx);
492       }
493       catch(Exception JavaDoc e)
494       {
495         addAttributeToNode(
496           S_ATTRIB_NOT_SUPPORTED,
497           m_ColAttrib_COLUMN_LABEL_TypeID, lastColHeaderIdx);
498       }
499
500       try
501       {
502         addAttributeToNode(
503           meta.getCatalogName(i),
504           m_ColAttrib_CATALOGUE_NAME_TypeID, lastColHeaderIdx);
505       }
506       catch(Exception JavaDoc e)
507       {
508         addAttributeToNode(
509           S_ATTRIB_NOT_SUPPORTED,
510           m_ColAttrib_CATALOGUE_NAME_TypeID, lastColHeaderIdx);
511       }
512
513       try
514       {
515         addAttributeToNode(
516           new Integer JavaDoc(meta.getColumnDisplaySize(i)),
517           m_ColAttrib_DISPLAY_SIZE_TypeID, lastColHeaderIdx);
518       }
519       catch(Exception JavaDoc e)
520       {
521         addAttributeToNode(
522           S_ATTRIB_NOT_SUPPORTED,
523           m_ColAttrib_DISPLAY_SIZE_TypeID, lastColHeaderIdx);
524       }
525
526       try
527       {
528         addAttributeToNode(
529           new Integer JavaDoc(meta.getColumnType(i)),
530           m_ColAttrib_COLUMN_TYPE_TypeID, lastColHeaderIdx);
531       }
532       catch(Exception JavaDoc e)
533       {
534         addAttributeToNode(
535           S_ATTRIB_NOT_SUPPORTED,
536           m_ColAttrib_COLUMN_TYPE_TypeID, lastColHeaderIdx);
537       }
538
539       try
540       {
541         addAttributeToNode(
542           meta.getColumnTypeName(i),
543           m_ColAttrib_COLUMN_TYPENAME_TypeID, lastColHeaderIdx);
544       }
545       catch(Exception JavaDoc e)
546       {
547         addAttributeToNode(
548           S_ATTRIB_NOT_SUPPORTED,
549           m_ColAttrib_COLUMN_TYPENAME_TypeID, lastColHeaderIdx);
550       }
551
552       try
553       {
554         addAttributeToNode(
555           new Integer JavaDoc(meta.getPrecision(i)),
556           m_ColAttrib_PRECISION_TypeID, lastColHeaderIdx);
557       }
558       catch(Exception JavaDoc e)
559       {
560         addAttributeToNode(
561           S_ATTRIB_NOT_SUPPORTED,
562           m_ColAttrib_PRECISION_TypeID, lastColHeaderIdx);
563       }
564       try
565       {
566         addAttributeToNode(
567           new Integer JavaDoc(meta.getScale(i)),
568           m_ColAttrib_SCALE_TypeID, lastColHeaderIdx);
569       }
570       catch(Exception JavaDoc e)
571       {
572         addAttributeToNode(
573           S_ATTRIB_NOT_SUPPORTED,
574           m_ColAttrib_SCALE_TypeID, lastColHeaderIdx);
575       }
576
577       try
578       {
579         addAttributeToNode(
580           meta.getSchemaName(i),
581           m_ColAttrib_SCHEMA_NAME_TypeID, lastColHeaderIdx);
582       }
583       catch(Exception JavaDoc e)
584       {
585         addAttributeToNode(
586           S_ATTRIB_NOT_SUPPORTED,
587           m_ColAttrib_SCHEMA_NAME_TypeID, lastColHeaderIdx);
588       }
589       try
590       {
591         addAttributeToNode(
592           meta.getTableName(i),
593           m_ColAttrib_TABLE_NAME_TypeID, lastColHeaderIdx);
594       }
595       catch(Exception JavaDoc e)
596       {
597         addAttributeToNode(
598           S_ATTRIB_NOT_SUPPORTED,
599           m_ColAttrib_TABLE_NAME_TypeID, lastColHeaderIdx);
600       }
601
602       try
603       {
604         addAttributeToNode(
605           meta.isCaseSensitive(i) ? S_ISTRUE : S_ISFALSE,
606           m_ColAttrib_CASESENSITIVE_TypeID, lastColHeaderIdx);
607       }
608       catch(Exception JavaDoc e)
609       {
610         addAttributeToNode(
611           S_ATTRIB_NOT_SUPPORTED,
612           m_ColAttrib_CASESENSITIVE_TypeID, lastColHeaderIdx);
613       }
614
615       try
616       {
617         addAttributeToNode(
618           meta.isDefinitelyWritable(i) ? S_ISTRUE : S_ISFALSE,
619           m_ColAttrib_DEFINITELYWRITEABLE_TypeID, lastColHeaderIdx);
620       }
621       catch(Exception JavaDoc e)
622       {
623         addAttributeToNode(
624           S_ATTRIB_NOT_SUPPORTED,
625           m_ColAttrib_DEFINITELYWRITEABLE_TypeID, lastColHeaderIdx);
626       }
627
628       try
629       {
630         addAttributeToNode(
631           meta.isNullable(i) != 0 ? S_ISTRUE : S_ISFALSE,
632           m_ColAttrib_ISNULLABLE_TypeID, lastColHeaderIdx);
633       }
634       catch(Exception JavaDoc e)
635       {
636         addAttributeToNode(
637           S_ATTRIB_NOT_SUPPORTED,
638           m_ColAttrib_ISNULLABLE_TypeID, lastColHeaderIdx);
639       }
640
641       try
642       {
643         addAttributeToNode(
644           meta.isSigned(i) ? S_ISTRUE : S_ISFALSE,
645           m_ColAttrib_ISSIGNED_TypeID, lastColHeaderIdx);
646       }
647       catch(Exception JavaDoc e)
648       {
649         addAttributeToNode(
650           S_ATTRIB_NOT_SUPPORTED,
651           m_ColAttrib_ISSIGNED_TypeID, lastColHeaderIdx);
652       }
653
654       try
655       {
656         addAttributeToNode(
657           meta.isWritable(i) == true ? S_ISTRUE : S_ISFALSE,
658           m_ColAttrib_ISWRITEABLE_TypeID, lastColHeaderIdx);
659       }
660       catch(Exception JavaDoc e)
661       {
662         addAttributeToNode(
663           S_ATTRIB_NOT_SUPPORTED,
664           m_ColAttrib_ISWRITEABLE_TypeID, lastColHeaderIdx);
665       }
666
667       try
668       {
669         addAttributeToNode(
670           meta.isSearchable(i) == true ? S_ISTRUE : S_ISFALSE,
671           m_ColAttrib_ISSEARCHABLE_TypeID, lastColHeaderIdx);
672       }
673       catch(Exception JavaDoc e)
674       {
675         addAttributeToNode(
676           S_ATTRIB_NOT_SUPPORTED,
677           m_ColAttrib_ISSEARCHABLE_TypeID, lastColHeaderIdx);
678       }
679     }
680   }
681
682   /**
683    * Populate the Expanded Name Table with the Node that we will use.
684    * Keep a reference of each of the types for access speed.
685    * @return
686    */

687   protected void createExpandedNameTable( )
688   {
689     super.createExpandedNameTable();
690
691     m_SQL_TypeID =
692       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SQL, DTM.ELEMENT_NODE);
693
694     m_MetaData_TypeID =
695       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_METADATA, DTM.ELEMENT_NODE);
696
697     m_ColumnHeader_TypeID =
698       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COLUMN_HEADER, DTM.ELEMENT_NODE);
699     m_RowSet_TypeID =
700       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ROW_SET, DTM.ELEMENT_NODE);
701     m_Row_TypeID =
702       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ROW, DTM.ELEMENT_NODE);
703     m_Col_TypeID =
704       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COL, DTM.ELEMENT_NODE);
705     m_OutParameter_TypeID =
706       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_OUT_PARAMETERS, DTM.ELEMENT_NODE);
707
708     m_ColAttrib_CATALOGUE_NAME_TypeID =
709       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_CATALOGUE_NAME, DTM.ATTRIBUTE_NODE);
710     m_ColAttrib_DISPLAY_SIZE_TypeID =
711       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_DISPLAY_SIZE, DTM.ATTRIBUTE_NODE);
712     m_ColAttrib_COLUMN_LABEL_TypeID =
713       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COLUMN_LABEL, DTM.ATTRIBUTE_NODE);
714     m_ColAttrib_COLUMN_NAME_TypeID =
715       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COLUMN_NAME, DTM.ATTRIBUTE_NODE);
716     m_ColAttrib_COLUMN_TYPE_TypeID =
717       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COLUMN_TYPE, DTM.ATTRIBUTE_NODE);
718     m_ColAttrib_COLUMN_TYPENAME_TypeID =
719       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_COLUMN_TYPENAME, DTM.ATTRIBUTE_NODE);
720     m_ColAttrib_PRECISION_TypeID =
721       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_PRECISION, DTM.ATTRIBUTE_NODE);
722     m_ColAttrib_SCALE_TypeID =
723       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SCALE, DTM.ATTRIBUTE_NODE);
724     m_ColAttrib_SCHEMA_NAME_TypeID =
725       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_SCHEMA_NAME, DTM.ATTRIBUTE_NODE);
726     m_ColAttrib_TABLE_NAME_TypeID =
727       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_TABLE_NAME, DTM.ATTRIBUTE_NODE);
728     m_ColAttrib_CASESENSITIVE_TypeID =
729       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_CASESENSITIVE, DTM.ATTRIBUTE_NODE);
730     m_ColAttrib_DEFINITELYWRITEABLE_TypeID =
731       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_DEFINITELYWRITABLE, DTM.ATTRIBUTE_NODE);
732     m_ColAttrib_ISNULLABLE_TypeID =
733       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ISNULLABLE, DTM.ATTRIBUTE_NODE);
734     m_ColAttrib_ISSIGNED_TypeID =
735       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ISSIGNED, DTM.ATTRIBUTE_NODE);
736     m_ColAttrib_ISWRITEABLE_TypeID =
737       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ISWRITEABLE, DTM.ATTRIBUTE_NODE);
738     m_ColAttrib_ISSEARCHABLE_TypeID =
739       m_expandedNameTable.getExpandedTypeID(S_NAMESPACE, S_ISSEARCHABLE, DTM.ATTRIBUTE_NODE);
740   }
741
742
743   /**
744    * Pull a record from the result set and map it to a DTM based ROW
745    * If we are in Streaming mode, then only create a single row and
746    * keep copying the data into the same row. This will keep the memory
747    * footprint constint independant of the RecordSet Size. If we are not
748    * in Streaming mode then create ROWS for the whole tree.
749    * @return
750    */

751   private boolean addRowToDTMFromResultSet( )
752   {
753     try
754     {
755       // If we have not started the RowSet yet, then add it to the
756
// tree.
757
if (m_FirstRowIdx == DTM.NULL)
758       {
759         m_RowSetIdx =
760           addElement(1, m_RowSet_TypeID, m_SQLIdx, m_MultipleResults ? m_RowSetIdx : m_MetaDataIdx);
761         if ( m_MultipleResults ) extractSQLMetaData(m_ResultSet.getMetaData());
762       }
763
764
765       // Check to see if all the data has been read from the Query.
766
// If we are at the end the signal that event
767
if ( ! m_ResultSet.next())
768       {
769         // In Streaming mode, the current ROW will always point back
770
// to itself until all the data was read. Once the Query is
771
// empty then point the next row to DTM.NULL so that the stream
772
// ends. Only do this if we have statted the loop to begin with.
773

774         if (m_StreamingMode && (m_LastRowIdx != DTM.NULL))
775         {
776           // We are at the end, so let's untie the mark
777
m_nextsib.setElementAt(DTM.NULL, m_LastRowIdx);
778         }
779
780         m_ResultSet.close();
781         if ( m_MultipleResults )
782         {
783           while ( !m_Statement.getMoreResults() && m_Statement.getUpdateCount() >= 0 ) ;
784           m_ResultSet = m_Statement.getResultSet();
785         }
786         else
787           m_ResultSet = null;
788
789         if ( m_ResultSet != null )
790         {
791           m_FirstRowIdx = DTM.NULL;
792           addRowToDTMFromResultSet();
793         }
794         else
795         {
796           Vector JavaDoc parameters = m_QueryParser.getParameters();
797           // Get output parameters.
798
if ( parameters != null )
799           {
800             int outParamIdx = addElement(1, m_OutParameter_TypeID, m_SQLIdx, m_RowSetIdx);
801             int lastColID = DTM.NULL;
802             for ( int indx = 0 ; indx < parameters.size() ; indx++ )
803             {
804               QueryParameter parm = (QueryParameter)parameters.elementAt(indx);
805               if ( parm.isOutput() )
806               {
807                 Object JavaDoc rawobj = ((CallableStatement)m_Statement).getObject(indx + 1);
808                 lastColID = addElementWithData(rawobj, 2, m_Col_TypeID, outParamIdx, lastColID);
809                 addAttributeToNode(parm.getName(), m_ColAttrib_COLUMN_NAME_TypeID, lastColID);
810                 addAttributeToNode(parm.getName(), m_ColAttrib_COLUMN_LABEL_TypeID, lastColID);
811                 addAttributeToNode(new Integer JavaDoc(parm.getType()), m_ColAttrib_COLUMN_TYPE_TypeID, lastColID);
812                 addAttributeToNode(parm.getTypeName(), m_ColAttrib_COLUMN_TYPENAME_TypeID, lastColID);
813               }
814             }
815           }
816
817           SQLWarning warn = checkWarnings();
818           if ( warn != null ) m_XConnection.setError(null, null, warn);
819         }
820
821         return false;
822       }
823
824       // If this is the first time here, start the new level
825
if (m_FirstRowIdx == DTM.NULL)
826       {
827         m_FirstRowIdx =
828           addElement(2, m_Row_TypeID, m_RowSetIdx, m_MultipleResults ? m_MetaDataIdx : DTM.NULL);
829
830         m_LastRowIdx = m_FirstRowIdx;
831
832         if (m_StreamingMode)
833         {
834           // Let's tie the rows together until the end.
835
m_nextsib.setElementAt(m_LastRowIdx, m_LastRowIdx);
836         }
837
838       }
839       else
840       {
841         //
842
// If we are in Streaming mode, then only use a single row instance
843
if (! m_StreamingMode)
844         {
845           m_LastRowIdx = addElement(2, m_Row_TypeID, m_RowSetIdx, m_LastRowIdx);
846         }
847       }
848
849       // If we are not in streaming mode, this will always be DTM.NULL
850
// If we are in streaming mode, it will only be DTM.NULL the first time
851
int colID = _firstch(m_LastRowIdx);
852
853       // Keep Track of who our parent was when adding new col objects.
854
int pcolID = DTM.NULL;
855
856       // Columns in JDBC Start at 1 and go to the Extent
857
for (int i=1; i<= m_ColCount; i++)
858       {
859         // Just grab the Column Object Type, we will convert it to a string
860
// later.
861
Object JavaDoc o = m_ResultSet.getObject(i);
862
863         // Create a new column object if one does not exist.
864
// In Streaming mode, this mechinism will reuse the column
865
// data the second and subsequent row accesses.
866
if (colID == DTM.NULL)
867         {
868           pcolID = addElementWithData(o,3,m_Col_TypeID, m_LastRowIdx, pcolID);
869           cloneAttributeFromNode(pcolID, m_ColHeadersIdx[i-1]);
870         }
871         else
872         {
873           // We must be in streaming mode, so let's just replace the data
874
// If the firstch was not set then we have a major error
875
int dataIdent = _firstch(colID);
876           if (dataIdent == DTM.NULL)
877           {
878             error("Streaming Mode, Data Error");
879           }
880           else
881           {
882             m_ObjectArray.setAt(dataIdent, o);
883           }
884         } // If
885

886         // In streaming mode, this will be !DTM.NULL
887
// So if the elements were already established then we
888
// should be able to walk them in order.
889
if (colID != DTM.NULL)
890         {
891           colID = _nextsib(colID);
892         }
893
894       } // For Col Loop
895
}
896     catch(Exception JavaDoc e)
897     {
898       if (DEBUG)
899       {
900         System.out.println(
901           "SQL Error Fetching next row [" + e.getLocalizedMessage() + "]");
902       }
903
904       m_XConnection.setError(e, this, checkWarnings());
905       m_HasErrors = true;
906     }
907
908     // Only do a single row...
909
return true;
910   }
911
912
913   /**
914    * Used by the XConnection to determine if the Document should
915    * handle the document differently.
916    */

917   public boolean hasErrors()
918   {
919     return m_HasErrors;
920   }
921
922   /**
923    * Close down any resources used by this document. If an SQL Error occure
924    * while the document was being accessed, the SQL Connection used to create
925    * this document will be released to the Connection Pool on error. This allows
926    * the COnnection Pool to give special attention to any connection that may
927    * be in a errored state.
928    *
929    */

930   public void close( )
931   {
932     try
933     {
934       SQLWarning warn = checkWarnings();
935       if ( warn != null ) m_XConnection.setError(null, null, warn);
936     }
937     catch(Exception JavaDoc e) {}
938
939     try
940     {
941       if (null != m_ResultSet)
942       {
943         m_ResultSet.close();
944         m_ResultSet = null;
945       }
946     }
947     catch(Exception JavaDoc e) {}
948
949
950     Connection JavaDoc conn = null;
951
952     try
953     {
954       if (null != m_Statement)
955       {
956         conn = m_Statement.getConnection();
957         m_Statement.close();
958         m_Statement = null;
959       }
960     }
961     catch(Exception JavaDoc e) {}
962
963     try
964     {
965       if (conn != null)
966       {
967         if (m_HasErrors) m_ConnectionPool.releaseConnectionOnError(conn);
968         else m_ConnectionPool.releaseConnection(conn);
969       }
970     }
971     catch(Exception JavaDoc e) {}
972
973     getManager().release(this, true);
974   }
975
976   /**
977    * @return
978    */

979   protected boolean nextNode( )
980   {
981     if (DEBUG) System.out.println("nextNode()");
982     try
983     {
984       return false;
985 // return m_ResultSet.isAfterLast();
986
}
987     catch(Exception JavaDoc e)
988     {
989       return false;
990     }
991   }
992
993   /**
994    * @param identity
995    * @return
996    */

997   protected int _nextsib( int identity )
998   {
999     // If we are asking for the next row and we have not
1000
// been there yet then let's see if we can get another
1001
// row from the ResultSet.
1002
//
1003

1004  if ( m_ResultSet != null )
1005  {
1006      int id = _exptype(identity);
1007      if (
1008        ( id == m_Row_TypeID) &&
1009        (identity >= m_LastRowIdx) )
1010      {
1011        if (DEBUG) System.out.println("reading from the ResultSet");
1012        addRowToDTMFromResultSet();
1013      }
1014      else if ( m_MultipleResults && identity == m_RowSetIdx )
1015      {
1016        if (DEBUG) System.out.println("reading for next ResultSet");
1017      int startIdx = m_RowSetIdx;
1018      while ( startIdx == m_RowSetIdx && m_ResultSet != null )
1019            addRowToDTMFromResultSet();
1020      }
1021  }
1022
1023    return super._nextsib(identity);
1024  }
1025
1026  public void documentRegistration()
1027  {
1028    if (DEBUG) System.out.println("Document Registration");
1029  }
1030
1031  public void documentRelease()
1032  {
1033    if (DEBUG) System.out.println("Document Release");
1034  }
1035
1036  public SQLWarning checkWarnings()
1037  {
1038    SQLWarning warn = null;
1039    if ( m_Statement != null )
1040    {
1041      try
1042      {
1043        warn = m_Statement.getWarnings();
1044        m_Statement.clearWarnings();
1045      }
1046      catch (SQLException JavaDoc se) {}
1047    }
1048    return(warn);
1049  }
1050}
1051
Popular Tags