Home | Previous Page | Next Page   Working with Opaque Types > Examples >

Creating an Opaque Type from an Existing Java Class with UDTManager

The following example shows how an application can use the UDTManager and UDTMetaData classes to convert an existing Java class on the client (inaccessible to the database server) to an SQL opaque type in the database server.

Creating an Opaque Type Using Default Support Functions

The following example creates an opaque type named Circle, using an existing Java class and using the default support functions provided in the database server:

*/

import java.sql.*;
import com.informix.jdbc.IfmxUDTSQLInput;
import com.informix.jdbc.IfmxUDTSQLOutput;

public class Circle implements SQLData
{
    private static double PI = 3.14159;

    double x;           // x coordinate
    double y;           // y coordinate
    double radius;

    private String type = "circle";

    public String getSQLTypeName() { return type; }

    public void readSQL(SQLInput stream, String typeName)
        throws SQLException
    {
        // To be able to use the DEFAULT support functions supplied
        // by the server, you must cast the stream to IfmxUDTSQLInput.
        // (Server requirement)

        IfmxUDTSQLInput in = (IfmxUDTSQLInput) stream;
        x = in.readDouble();
        y = in.readDouble();
        radius = in.readDouble();
    }

    public void writeSQL(SQLOutput stream) throws SQLException
    {
        // To be able to use the DEFAULT support functions supplied
        // by the server, have to cast the stream to IfmxUDTSQLOutput.
        // (Server requirement)

        IfmxUDTSQLOutput out = (IfmxUDTSQLOutput) stream;
        out.writeDouble(x);
        out.writeDouble(y);
        out.writeDouble(radius);
    }
 
    public static double area(Circle c)
    {
        return PI * c.radius * c.radius;
    }
       
}
Using the Opaque Type

The following JDBC client application installs the class Circle (which is packaged in Circle .jar) as an opaque type in the system catalog. Applications can then use the opaque type Circle as a data type in SQL statements:

import java.sql.*;
import java.lang.reflect.*;


public class PlayWithCircle
{
    String dbname = "test";
    String url = null;
    Connection conn = null;

    public static void main (String args[])
    {
        new PlayWithCircle(args);
    }

    PlayWithCircle(String args[])
    {
        System.out.println("----------------");
        System.out.println("- Start - Demo 1");
        System.out.println("----------------");

        // -----------
        // Getting URL
        // -----------
        if (args.length == 0)
            {
            System.out.println("\n***ERROR: connection URL must be provided " +
                               "in order to run the demo!");
            return;
            }
        url = args[0];

        // --------------
        // Loading driver
        // --------------
        try
            {
            System.out.print("Loading JDBC driver...");
            Class.forName("com.informix.jdbc.IfxDriver");
            System.out.println("ok");
            }
        catch (java.lang.ClassNotFoundException e)
            {
            System.out.println("\n***ERROR: " + e.getMessage());
            e.printStackTrace();
            return;
            }
 
        // ------------------
        // Getting connection
        // ------------------
        try
            {
            System.out.print("Getting connection...");
            conn = DriverManager.getConnection(url);
            System.out.println("ok");
            }
        catch (SQLException e)
            {
            System.out.println("URL = '" + url + "'");
            System.out.println("\n***ERROR: " + e.getMessage());
            e.printStackTrace();
            return;
            }
        System.out.println();

        // -------------------
        // Setup UDT meta data
        // -------------------
        Method areamethod = null;
        try
            {
            Class c = Class.forName("Circle");
            areamethod = c.getMethod("area", new Class[] {c});
            }
        catch (ClassNotFoundException e)
            {
            System.out.println("Cannot get Class: " + e.toString());
            return;
            }
        catch (NoSuchMethodException e)
            {
            System.out.println("Cannot get Method: " + e.toString());
            return;
            }
 
        UDTMetaData mdata = null;
        try
            {
            System.out.print("Setting mdata...");
            mdata = new UDTMetaData();
            mdata.setSQLName("circle");
            mdata.setLength(24);
            mdata.setAlignment(UDTMetaData.EIGHT_BYTE);
            mdata.setUDR(areamethod, "area");
            mdata.setJarFileSQLName("circle_jar");
            System.out.println("ok");
            }
        catch (SQLException e)
            {
            System.out.println("\n***ERROR: " + e.getMessage());
            return;
            }
 
        // -------------------------------
        // Install the UDT in the database
        // -------------------------------
        UDTManager udtmgr = null;
        try
            {
            udtmgr = new UDTManager(conn);
 
            System.out.println("\ncreateJar()");
            String jarfilename = udtmgr.createJar(mdata,
                new String[] {"Circle.class"}); // jarfilename = circle.jar
            System.out.println("   jarfilename = " + jarfilename);
 
            System.out.println("\nsetJarTmpPath()");
            udtmgr.setJarTmpPath("/tmp");
 
            System.out.print("\ncreateUDT()...");
            udtmgr.createUDT(mdata,
            "/vobs/jdbc/demo/tools/udtudrmgr/" + jarfilename, "Circle", 0);
            System.out.println("ok");
            }
        catch (SQLException e)
            {
            System.out.println("\n***ERROR: " + e.getMessage());
            return;
            }
        System.out.println();

        // ---------------
        // Now use the UDT
        // ---------------
        try
        {
            String s = "drop table tab";
            System.out.print(s + "...");
            Statement stmt = conn.createStatement();
            int count = stmt.executeUpdate(s);
            stmt.close();
            System.out.println("ok");
        }
        catch ( SQLException e)
        {
            // -206 The specified table (%s) is not in the database.
            if (e.getErrorCode() != -206)
                {
                System.out.println("\n***ERROR: " + e.getMessage());
                return;
                }
            System.out.println("ok");
        }
 
        executeUpdate("create table tab (c circle)");
 
        // test DEFAULT Input function
        executeUpdate("insert into tab values ('10 10 10')");
 
        // test DEFAULT Output function
        try
            {
            String s = "select c::lvarchar from tab";
            System.out.println(s);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(s);
            if (rs.next())
                {
                String c = rs.getString(1);
                System.out.println("   circle = '" + c + "'");
                }
            rs.close();
            stmt.close();
            }
        catch (SQLException e)
            {
            System.out.println("***ERROR: " + e.getMessage());
            }
        System.out.println();
 
        // test DEFAULT Send function
        try
            {
            // setup type map before using getObject() for UDT data.
            java.util.Map customtypemap = conn.getTypeMap();
            System.out.println("getTypeMap...ok");
            if (customtypemap == null)
                {
                System.out.println("***ERROR: map is null!");
                return;
                }
            customtypemap.put("circle", Class.forName("Circle"));
            System.out.println("put...ok");
 
            String s = "select c from tab";
            System.out.println(s);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(s);
            if (rs.next())
                {
                Circle c = (Circle)rs.getObject(1, customtypemap);
                System.out.println("   c.x = " + c.x);
                System.out.println("   c.y = " + c.y);
                System.out.println("   c.radius = " + c.radius);
                }
            rs.close();
            stmt.close();
            }
        catch (SQLException e)
            {
            System.out.println("***ERROR: " + e.getMessage());
            }
        catch (ClassNotFoundException e)
            {
            System.out.println("***ERROR: " + e.getMessage());
            }
        System.out.println();
 
        // test user's non-support UDR
        try
            {
            String s = "select area(c) from tab";
            System.out.println(s);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(s);
            if (rs.next())
                {
                double a = rs.getDouble(1);
                System.out.println("   area = " + a);
                }
            rs.close();
            stmt.close();
            }
        catch (SQLException e)
            {
            System.out.println("***ERROR: " + e.getMessage());
            }
        System.out.println();
 
        executeUpdate("drop table tab");
 
        // ------------------
        // Closing connection
        // ------------------
        try
            {
            System.out.print("Closing connection...");
            conn.close();
            System.out.println("ok");
            }
        catch (SQLException e)
            {
            System.out.println("\n***ERROR: " + e.getMessage());
            }
}

Creating an Opaque Type Using Support Functions You Supply

In this example, the Java class Circle2 on the client is mapped to an SQL opaque type named circle2. The circle2 opaque type uses support functions provided by the programmer.

import java.sql.*;
import java.text.*;
import com.informix.jdbc.IfmxUDTSQLInput;
import com.informix.jdbc.IfmxUDTSQLOutput;

public class Circle2 implements SQLData
{
    private static double PI = 3.14159;

    double x;           // x coordinate
    double y;           // y coordinate
    double radius;

    private String type = "circle2";

    public String getSQLTypeName() { return type; }

    public void readSQL(SQLInput stream, String typeName)
        throws SQLException
    {
/* commented out - because the first release of the UDT/UDR Manager feature
 *                 does not support mixing user-supplied support functions
 *                 with server DEFAULT support functions.
 * However, once the mix is supported, this code needs to be used to
 * replace the existing code.
 *
        // To be able to use the DEFAULT support functions (other than
        // Input/Output) supplied by the server, you must cast the stream
        // to IfmxUDTSQLInput.

        IfmxUDTSQLInput in = (IfmxUDTSQLInput) stream;
        x = in.readDouble();
        y = in.readDouble();
        radius = in.readDouble();
 */

        x = stream.readDouble();
        y = stream.readDouble();
        radius = stream.readDouble();
    }
       
    public void writeSQL(SQLOutput stream) throws SQLException
    {
/* commented out - because the 1st release of UDT/UDR Manager feature
 *                 doesn't support the mixing of user support functions
 *                 with server DEFAULT support functions.
 * However, once the mix is supported, this code needs to be used to
 * replace the existing code.
 *
        // To be able to use the DEFAULT support functions (other than
        // Input/Output) supplied by the server, you must cast the stream
        // to IfmxUDTSQLOutput.
 
        IfmxUDTSQLOutput out = (IfmxUDTSQLOutput) stream;
        out.writeDouble(x);
        out.writeDouble(y);
        out.writeDouble(radius);
 */
 
        stream.writeDouble(x);
        stream.writeDouble(y);
        stream.writeDouble(radius);
    }

    /**
     * Input function - return the object from the String representation -
     * 'x y radius'.
     */
    public static Circle2 fromString(String text)
    {
        Number a = null;
        Number b = null;
        Number r = null;
 
        try
            {
            ParsePosition ps = new ParsePosition(0);
            a = NumberFormat.getInstance().parse(text, ps);
            ps.setIndex(ps.getIndex() + 1);
            b = NumberFormat.getInstance().parse(text, ps);
            ps.setIndex(ps.getIndex() + 1);
            r = NumberFormat.getInstance().parse(text, ps);
            }
        catch (Exception e)
            {
            System.out.println("In exception : " + e.getMessage());
            }
 
        Circle2 c = new Circle2();
        c.x = a.doubleValue();
        c.y = b.doubleValue();
        c.radius = r.doubleValue();
 
        return c;
    }
       
    /**
     * Output function - return the string of the form 'x y radius'.
     */
    public static String makeString(Circle2 c)
    {
        StringBuffer sbuff = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.INTEGER_FIELD);
        NumberFormat.getInstance().format(c.x, sbuff, fp);
        sbuff.append(" ");
        NumberFormat.getInstance().format(c.y, sbuff, fp);
        sbuff.append(" ");
        NumberFormat.getInstance().format(c.radius, sbuff, fp);
 
        return sbuff.toString();
    }
       
    /**
     * user function - get the area of a circle.
     */
    public static double area(Circle2 c)
    {
        return PI * c.radius * c.radius;
    }
       
}
Using the Opaque Type

The following JDBC client application installs the class Circle2 (which is packaged in Circle2.jar) as an opaque type in the system catalog. Applications can then use the opaque type Circle2 as a data type in SQL statements:

import java.sql.*;
import java.lang.reflect.*;


public class PlayWithCircle2
{
    String dbname = "test";
    String url = null;
    Connection conn = null;

    public static void main (String args[])
    {
        new PlayWithCircle2(args);
    }

    PlayWithCircle2(String args[])
    {

        // -----------
        // Getting URL
        // -----------
        if (args.length == 0)
            {
            System.out.println("\n***ERROR: connection URL must be provided " +
                               "in order to run the demo!");
            return;
            }

        url = args[0];

        // --------------
        // Loading driver
        // --------------
        try
            {
            System.out.print("Loading JDBC driver...");
            Class.forName("com.informix.jdbc.IfxDriver");
            }
        catch (java.lang.ClassNotFoundException e)
            {
            System.out.println("\n***ERROR: " + e.getMessage());
            e.printStackTrace();
            return;
            }


        try
            {
            conn = DriverManager.getConnection(url);
            }
        catch (SQLException e)
            {
            System.out.println("URL = '" + url + "'");
            System.out.println("\n***ERROR: " + e.getMessage());
            e.printStackTrace();
            return;
            }
        System.out.println();
Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]