KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ziclix > python > sql > JDBC20DataHandler


1 /*
2  * Jython Database Specification API 2.0
3  *
4  * $Id: JDBC20DataHandler.java,v 1.5 2005/05/12 02:38:59 fwierzbicki Exp $
5  *
6  * Copyright (c) 2001 brian zimmer <bzimmer@ziclix.com>
7  *
8  */

9 package com.ziclix.python.sql;
10
11 import org.python.core.Py;
12 import org.python.core.PyFile;
13 import org.python.core.PyObject;
14 import org.python.core.PyString;
15
16 import java.io.BufferedInputStream JavaDoc;
17 import java.io.BufferedReader JavaDoc;
18 import java.io.ByteArrayInputStream JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.InputStreamReader JavaDoc;
21 import java.io.Reader JavaDoc;
22 import java.math.BigDecimal JavaDoc;
23 import java.sql.Blob JavaDoc;
24 import java.sql.PreparedStatement JavaDoc;
25 import java.sql.ResultSet JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.sql.Types JavaDoc;
28
29 /**
30  * Support for JDBC 2.x type mappings, including Arrays, CLOBs and BLOBs.
31  *
32  * @author brian zimmer
33  * @author last revised by $Author: fwierzbicki $
34  * @version $Revision: 1.5 $
35  */

36 public class JDBC20DataHandler extends FilterDataHandler {
37
38     /**
39      * Handle JDBC 2.0 datatypes.
40      */

41     public JDBC20DataHandler(DataHandler datahandler) {
42         super(datahandler);
43     }
44
45     /**
46      * Handle CLOBs and BLOBs.
47      *
48      * @param stmt
49      * @param index
50      * @param object
51      * @param type
52      * @throws SQLException
53      */

54     public void setJDBCObject(PreparedStatement JavaDoc stmt, int index, PyObject object, int type) throws SQLException JavaDoc {
55
56         if (DataHandler.checkNull(stmt, index, object, type)) {
57             return;
58         }
59
60         switch (type) {
61
62             case Types.CLOB:
63                 if (object instanceof PyFile) {
64                     object = new PyString(((PyFile) object).read());
65                 }
66
67                 String JavaDoc clob = (String JavaDoc) object.__tojava__(String JavaDoc.class);
68                 int length = clob.length();
69                 InputStream JavaDoc stream = new ByteArrayInputStream JavaDoc(clob.getBytes());
70
71                 stream = new BufferedInputStream JavaDoc(stream);
72
73                 stmt.setBinaryStream(index, stream, length);
74
75                 // Reader reader = new StringReader(clob);
76
// reader = new BufferedReader(reader);
77
// stmt.setCharacterStream(index, reader, length);
78
break;
79
80             case Types.BLOB:
81                 byte[] lob = null;
82                 Object JavaDoc jobject = null;
83
84                 if (object instanceof PyFile) {
85                     jobject = object.__tojava__(InputStream JavaDoc.class);
86                 } else {
87                     jobject = object.__tojava__(Object JavaDoc.class);
88                 }
89
90                 // it really is unfortunate that I need to send the length of the stream
91
if (jobject instanceof InputStream JavaDoc) {
92                     lob = DataHandler.read(new BufferedInputStream JavaDoc((InputStream JavaDoc) jobject));
93                 } else if (jobject instanceof byte[]) {
94                     lob = (byte[]) jobject;
95                 }
96
97                 if (lob != null) {
98                     stmt.setBytes(index, lob);
99
100                     break;
101                 }
102             default :
103                 super.setJDBCObject(stmt, index, object, type);
104                 break;
105         }
106     }
107
108     /**
109      * Get the object from the result set.
110      *
111      * @param set
112      * @param col
113      * @param type
114      * @return a Python object
115      * @throws SQLException
116      */

117     public PyObject getPyObject(ResultSet JavaDoc set, int col, int type) throws SQLException JavaDoc {
118
119         PyObject obj = Py.None;
120
121         switch (type) {
122
123             case Types.NUMERIC:
124             case Types.DECIMAL:
125
126                 // in JDBC 2.0, use of a scale is deprecated
127
try {
128                     BigDecimal JavaDoc bd = set.getBigDecimal(col);
129
130                     obj = (bd == null) ? Py.None : Py.newFloat(bd.doubleValue());
131                 } catch (SQLException JavaDoc e) {
132                     obj = super.getPyObject(set, col, type);
133                 }
134                 break;
135
136             case Types.CLOB:
137
138                 /*
139                  * It seems some drivers (well at least Informix) don't clean up after themselves
140                  * if the Clob is requested. The engine keeps a handle to an open table for each
141                  * row requested and cleans up fully only when the ResultSet or Connection is closed.
142                  * While this generally will never be noticed because the number of CLOBs or BLOBs
143                  * queried will likely be small in the event a large number are queried, it is a huge
144                  * problem. So, handle it as low as possible by managing the stream directly. I've
145                  * decided to leave this in the generic JDBC20 handler because it works for all engines
146                  * I've tested and seems to perform quite well to boot.
147                  */

148                 Reader JavaDoc reader = null;
149
150                 try {
151                     InputStream JavaDoc stream = set.getBinaryStream(col);
152
153                     if (stream == null) {
154                         obj = Py.None;
155                     } else {
156                         reader = new InputStreamReader JavaDoc(stream);
157                         reader = new BufferedReader JavaDoc(reader);
158                         obj = Py.newString(DataHandler.read(reader));
159                     }
160                 } finally {
161                     if (reader != null) {
162                         try {
163                             reader.close();
164                         } catch (Exception JavaDoc e) {
165                         }
166                     }
167                 }
168                 break;
169
170             case Types.BLOB:
171                 Blob JavaDoc blob = set.getBlob(col);
172
173                 if (blob == null) {
174                     obj = Py.None;
175                 } else {
176                     InputStream JavaDoc stream = null;
177
178                     try {
179                         stream = blob.getBinaryStream();
180                         stream = new BufferedInputStream JavaDoc(stream);
181                         obj = Py.java2py(DataHandler.read(stream));
182                     } finally {
183                         if (stream != null) {
184                             try {
185                                 stream.close();
186                             } catch (Exception JavaDoc e) {
187                             }
188                         }
189                     }
190                 }
191                 break;
192
193             case Types.ARRAY:
194                 obj = Py.java2py(set.getArray(col).getArray());
195                 break;
196
197             default :
198                 return super.getPyObject(set, col, type);
199         }
200
201         return (set.wasNull() || (obj == null)) ? Py.None : obj;
202     }
203 }
204
Popular Tags