001: /*
002: * Jython Database Specification API 2.0
003: *
004: * $Id: PostgresqlDataHandler.java 2469 2005-05-16 06:43:33Z otmarhumbel $
005: *
006: * Copyright (c) 2001 brian zimmer <bzimmer@ziclix.com>
007: *
008: */
009: package com.ziclix.python.sql.handler;
010:
011: import com.ziclix.python.sql.DataHandler;
012: import org.python.core.Py;
013: import org.python.core.PyFile;
014: import org.python.core.PyObject;
015:
016: import java.math.BigDecimal;
017: import java.sql.PreparedStatement;
018: import java.sql.ResultSet;
019: import java.sql.SQLException;
020: import java.sql.Types;
021:
022: /**
023: * Postgresql specific data handling.
024: *
025: * @author brian zimmer
026: * @author last revised by $Author: otmarhumbel $
027: * @version $Revision: 2469 $
028: */
029: public class PostgresqlDataHandler extends RowIdHandler {
030:
031: /**
032: * Decorator for handling Postgresql specific issues.
033: *
034: * @param datahandler the delegate DataHandler
035: */
036: public PostgresqlDataHandler(DataHandler datahandler) {
037: super (datahandler);
038: }
039:
040: protected String getRowIdMethodName() {
041: return "getLastOID";
042: }
043:
044: /**
045: * Override to handle Postgresql related issues.
046: *
047: * @param set the result set
048: * @param col the column number
049: * @param type the SQL type
050: * @return the mapped Python object
051: * @throws SQLException thrown for a sql exception
052: */
053: public PyObject getPyObject(ResultSet set, int col, int type)
054: throws SQLException {
055:
056: PyObject obj = Py.None;
057:
058: switch (type) {
059:
060: case Types.NUMERIC:
061: case Types.DECIMAL:
062:
063: // in JDBC 2.0, use of a scale is deprecated
064: // The big fix here is a problem with numeric types. It seems the ResultSet
065: // tries to fix a JBuilder bug (as commented in the source) by including a
066: // scale of 0. Well this blows up BigDecimal if the number is, say, 4.22.
067: // It appears the workaround is to call the deprecated method with a scale of
068: // -1 which forces the return of the BD without setting the scale.
069: BigDecimal bd = set.getBigDecimal(col, -1);
070:
071: obj = (bd == null) ? Py.None : Py
072: .newFloat(bd.doubleValue());
073: break;
074:
075: case Types.OTHER:
076:
077: // it seems pg doesn't like to handle OTHER types as anything but strings
078: // but we'll try first anyways just to see what happens
079: try {
080: obj = super .getPyObject(set, col, type);
081: } catch (SQLException e) {
082: obj = super .getPyObject(set, col, Types.VARCHAR);
083: }
084: break;
085:
086: default:
087: obj = super .getPyObject(set, col, type);
088: }
089:
090: return (set.wasNull() || (obj == null)) ? Py.None : obj;
091: }
092:
093: /**
094: * Provide fixes for Postgresql driver.
095: *
096: * @param stmt
097: * @param index
098: * @param object
099: * @param type
100: * @throws SQLException
101: */
102: public void setJDBCObject(PreparedStatement stmt, int index,
103: PyObject object, int type) throws SQLException {
104:
105: if (DataHandler.checkNull(stmt, index, object, type)) {
106: return;
107: }
108:
109: switch (type) {
110:
111: case Types.LONGVARCHAR:
112:
113: String varchar;
114: // Postgresql driver can't handle the setCharacterStream() method so use setObject() instead
115: if (object instanceof PyFile) {
116: varchar = ((PyFile) object).read();
117: } else {
118: varchar = (String) object.__tojava__(String.class);
119: }
120:
121: stmt.setObject(index, varchar, type);
122: break;
123:
124: default:
125: super.setJDBCObject(stmt, index, object, type);
126: }
127: }
128: }
|