Variable-length UDT including nondefault input and output methods
/* Variable Length UDT example type: Record3
** Example of required and explicit method implementations.
**
** The C language structure equivalent of this JUDT is:
**
** typedef struct
** {
** mi_double_precision d;
** mi_chara[4];
** mi_integerb;
** mi_realc;
** mi_datee;
** mi_smallintf;
** mi_booleang[MAXBOOLS];
** } NewFixUDT;
**
** Where the last boolean array can contain up to MAX values
** but only valid values will be written to disk.
*/
// Put this in our test package,
// could be anywhere but needs to match SQL definitons for UDRs.
package informix.testclasses.jlm.udt;
// get the usual suspect classes
import java.sql.*;
// get informix specific interfaces, etal.
import com.informix.jdbc.*;
// These are only needed for the non-default Input/Output
// functions, remove if you use defaults.
import informix.jvp.dbapplet.impl.IfmxTextInStream;
import informix.jvp.dbapplet.impl.IfmxTextOutStream;
/**************** Now here’s our UDT *************/
public class Record3 implements SQLData
{
// to turn debug print lines on and off
private static boolean classDebug = true;
// define storage for Java members of UDT
private double d_double;
private String a_char;
private int b_int;
private float c_float;
private java.sql.Date e_date;
private short f_smint;
// could use a Vector for booleans, but would then need Boolean
// objects ...so I’ve left it as an exercise for the reader...
private static final int MAXBOOLS = 20;
private boolean g_boolvals[] = new boolean[MAXBOOLS];
private int numbools = 0;
// dummy constructor just so we can log instantiation
public Record3()
{
super();
if( classDebug )
System.out.println( "Record3() " + super.toString() + " created" );
}
// dummy finalizer just so we can log our own destruction
protected void finalize()
{
super.finalize();
if( classDebug )
System.out.println( "Record3() " + super.toString() + " deleted" );
}
/*********** REQUIRED SQLData implementation: ***********/
// needed for SQLData interface
private String type;
public String getSQLTypeName()
{
return type;
}
// Called to convert an SQL buffer TYPE to JAVA class.
// note: we need to use SQLInput as the argument type or this
// method signature won’t resolve correctly.
public void readSQL (SQLInput in, String typeName) throws
SQLException
{
if( classDebug )
System.out.println( "Record3.readSQL() entered" );
// save the type name
type = typeName;
// cast the _real_ type of Stream for IFMX extensions.
IfmxUDTSQLInput stream = (IfmxUDTSQLInput) in;
// trap exceptions; don’t really know how many bytes
// are in the input.
try
{
d_double = stream.readDouble();
a_char = stream.readString(4);
b_int = stream.readInt();
c_float = stream.readFloat();
e_date = stream.readDate();
f_smint = stream.readShort();
// Read booleans until we get an exception:
// converting a non-existant boolean will throw cookies.
// but we can use available() to make sure there is more
// to read...
for( int count = 0; (stream.available() > 0) && (count
< MAXBOOLS); ++count )
{
g_boolvals[count] = stream.readBoolean();
++numbools;
}
}
catch (SQLException e)
{
// if we got something besides end of input rethrow,
// otherwise just assume we’re done.
if( e.getErrorCode() != IfxErrMsg.S_BADSQLDATA )
{
if( classDebug )
System.out.println("Record3.readSQL() exception = " +
e.toString());
throw e;
}
}
}
// Called to convert JAVA class to SQL buffer TYPE.
// note: we need to use SQLOutput as the argument type or this
// method signature won’t resolve correctly.
public void writeSQL( SQLOutput out ) throws SQLException
{
if( classDebug )
System.out.println( "Record3.writeSQL() entered" );
// cast up to _real_ type of Stream to use IFMX extensions.
IfmxUDTSQLOutput stream = (IfmxUDTSQLOutput) out;
stream.writeDouble(d_double);
stream.writeString(a_char, 4);
stream.writeInt(b_int);
stream.writeFloat(c_float);
stream.writeDate(e_date);
stream.writeShort(f_smint);
for( int i = 0; i < numbools; i++ )
stream.writeBoolean(g_boolvals[i]);
}
/*********** END SQLData implementation ***********/
/**** NON-DEFAULT implementation of Input and Output functions ****/
/* Remove all this if you only use the Defaults */
The following example illustrates the implementation of
user-defined input and output functions that override the default
I/O methods. If you use the default methods, you do not need to implement
overriding methods like those that follow:
// Called as Input function to convert SQL lvarchar to JAVA class
public static Record3 fromString( String str )
{
if( classDebug )
System.out.println( "Record3.fromString(String) entered" );
// Make a stream of the right kind.
IfmxTextInStream stream = new IfmxTextInStream(str);
// Make a new Java object of the right type.
Record3 record = new Record3();
// Just call readSQL ourselves.
// For a real implementation you would probably copy all the
// readXXX()’s and intersperse delimiting chars as needed...
try
{
readSQL( stream, "Record3" );
}
catch (Exception e)
{
System.err.println(e.getMessage());
}
return record;
}
// Called as Output function; convert JAVA class to SQL lvarchar.
// note: could use toString() directly,
// except that the UDR method must be "static", and
// it needs to take a Record3 as an argument....
public static String makeString(Record3 x)
{
if( classDebug )
System.out.println( "Record3.makeString() entered" );
return x.toString();
}
// Might as well implement the standard toString() as long as
// we’re doing non-defaults. If a different method name is
// used here, Object.toString() will be called when the class
// gets printed out in debug lines....
public String toString()
{
// Need to use a StringBuffer because we can’t pass a
// reference to a String to be initialized.
// We could optimize by guessing at size of buffer, too.
// StringBuffer str = new StringBuffer();
// IfmxTextOutStream stream = new IfmxTextOutStream(str);
// Just call writeSQL.
// For a real implementation you would probably copy all the
// writeXXX()’s and intersperse delimiting chars as needed...
try
{
writeSQL( stream );
}
catch (Exception e)
{
System.err.println(e.getMessage());
// not sure if we need to clear out result string?
str.setLength(0);
}
return str.toString();
}