All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ziclix.python.sql.JDBC20DataHandler Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
/*
 * Jython Database Specification API 2.0
 *
 * $Id: JDBC20DataHandler.java 2467 2005-05-12 02:38:59Z fwierzbicki $
 *
 * Copyright (c) 2001 brian zimmer 
 *
 */
package com.ziclix.python.sql;

import org.python.core.Py;
import org.python.core.PyFile;
import org.python.core.PyObject;
import org.python.core.PyString;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * Support for JDBC 2.x type mappings, including Arrays, CLOBs and BLOBs.
 *
 * @author brian zimmer
 * @author last revised by $Author: fwierzbicki $
 * @version $Revision: 2467 $
 */
public class JDBC20DataHandler extends FilterDataHandler {

    /**
     * Handle JDBC 2.0 datatypes.
     */
    public JDBC20DataHandler(DataHandler datahandler) {
        super(datahandler);
    }

    /**
     * Handle CLOBs and BLOBs.
     *
     * @param stmt
     * @param index
     * @param object
     * @param type
     * @throws SQLException
     */
    public void setJDBCObject(PreparedStatement stmt, int index, PyObject object, int type) throws SQLException {

        if (DataHandler.checkNull(stmt, index, object, type)) {
            return;
        }

        switch (type) {

            case Types.CLOB:
                if (object instanceof PyFile) {
                    object = new PyString(((PyFile) object).read());
                }

                String clob = (String) object.__tojava__(String.class);
                int length = clob.length();
                InputStream stream = new ByteArrayInputStream(clob.getBytes());

                stream = new BufferedInputStream(stream);

                stmt.setBinaryStream(index, stream, length);

                // Reader reader = new StringReader(clob);
                // reader = new BufferedReader(reader);
                // stmt.setCharacterStream(index, reader, length);
                break;

            case Types.BLOB:
                byte[] lob = null;
                Object jobject = null;

                if (object instanceof PyFile) {
                    jobject = object.__tojava__(InputStream.class);
                } else {
                    jobject = object.__tojava__(Object.class);
                }

                // it really is unfortunate that I need to send the length of the stream
                if (jobject instanceof InputStream) {
                    lob = DataHandler.read(new BufferedInputStream((InputStream) jobject));
                } else if (jobject instanceof byte[]) {
                    lob = (byte[]) jobject;
                }

                if (lob != null) {
                    stmt.setBytes(index, lob);

                    break;
                }
            default :
                super.setJDBCObject(stmt, index, object, type);
                break;
        }
    }

    /**
     * Get the object from the result set.
     *
     * @param set
     * @param col
     * @param type
     * @return a Python object
     * @throws SQLException
     */
    public PyObject getPyObject(ResultSet set, int col, int type) throws SQLException {

        PyObject obj = Py.None;

        switch (type) {

            case Types.NUMERIC:
            case Types.DECIMAL:

                // in JDBC 2.0, use of a scale is deprecated
                try {
                    BigDecimal bd = set.getBigDecimal(col);

                    obj = (bd == null) ? Py.None : Py.newFloat(bd.doubleValue());
                } catch (SQLException e) {
                    obj = super.getPyObject(set, col, type);
                }
                break;

            case Types.CLOB:

                /*
                 * It seems some drivers (well at least Informix) don't clean up after themselves
                 * if the Clob is requested.  The engine keeps a handle to an open table for each
                 * row requested and cleans up fully only when the ResultSet or Connection is closed.
                 * While this generally will never be noticed because the number of CLOBs or BLOBs
                 * queried will likely be small in the event a large number are queried, it is a huge
                 * problem.  So, handle it as low as possible by managing the stream directly.  I've
                 * decided to leave this in the generic JDBC20 handler because it works for all engines
                 * I've tested and seems to perform quite well to boot.
                 */
                Reader reader = null;

                try {
                    InputStream stream = set.getBinaryStream(col);

                    if (stream == null) {
                        obj = Py.None;
                    } else {
                        reader = new InputStreamReader(stream);
                        reader = new BufferedReader(reader);
                        obj = Py.newString(DataHandler.read(reader));
                    }
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (Exception e) {
                        }
                    }
                }
                break;

            case Types.BLOB:
                Blob blob = set.getBlob(col);

                if (blob == null) {
                    obj = Py.None;
                } else {
                    InputStream stream = null;

                    try {
                        stream = blob.getBinaryStream();
                        stream = new BufferedInputStream(stream);
                        obj = Py.java2py(DataHandler.read(stream));
                    } finally {
                        if (stream != null) {
                            try {
                                stream.close();
                            } catch (Exception e) {
                            }
                        }
                    }
                }
                break;

            case Types.ARRAY:
                obj = Py.java2py(set.getArray(col).getArray());
                break;

            default :
                return super.getPyObject(set, col, type);
        }

        return (set.wasNull() || (obj == null)) ? Py.None : obj;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy