/*
* Copyright (c) 2004-2016 Tada AB and other contributors, as listed below.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the The BSD 3-Clause License
* which accompanies this distribution, and is available at
* http://opensource.org/licenses/BSD-3-Clause
*
* Contributors:
* Tada AB
* Chapman Flack
*/
package org.postgresql.pljava.example.annotation;
import java.sql.SQLData;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLOutput;
import java.util.logging.Logger;
import org.postgresql.pljava.annotation.Function;
import org.postgresql.pljava.annotation.MappedUDT;
import org.postgresql.pljava.annotation.SQLAction;
import org.postgresql.pljava.annotation.SQLType;
import static org.postgresql.pljava.annotation.Function.Effects.IMMUTABLE;
import static
org.postgresql.pljava.annotation.Function.OnNullInput.RETURNS_NULL;
/**
* Example of a "mirrored UDT": a user-defined type that exposes to Java the
* internal representation of an existing (but not SQL-standard) PostgreSQL
* type. Naturally, the author of this type has to know (from the PostgreSQL
* source) that a {@code Point} is stored as two {@code float8}s, {@code x}
* first and then {@code y}.
*/
@SQLAction(requires={"point mirror type", "point assertHasValues"}, install=
"SELECT javatest.assertHasValues(CAST('(1,2)' AS point), 1, 2)"
)
@MappedUDT(name="point", provides="point mirror type")
public class Point implements SQLData {
private static Logger s_logger = Logger.getAnonymousLogger();
/**
* Return the same 'point' passed in, logging its contents at level INFO.
* @param pt any instance of the type this UDT mirrors
* @return the same instance passed in
*/
@Function(schema="javatest", type="point", requires="point mirror type",
effects=IMMUTABLE, onNullInput=RETURNS_NULL)
public static Point logAndReturn(@SQLType("point") Point pt) {
s_logger.info(pt.getSQLTypeName() + pt);
return pt;
}
/**
* Assert a 'point' has given x and y values, to test that its
* representation in Java corresponds to what PostgreSQL sees.
* @param pt an instance of this UDT
* @param x the x value it should have
* @param y the y value it should have
* @throws SQLException if the values do not match
*/
@Function(schema="javatest",
requires="point mirror type", provides="point assertHasValues",
effects=IMMUTABLE, onNullInput=RETURNS_NULL)
public static void assertHasValues(
@SQLType("point") Point pt,
double x, double y)
throws SQLException
{
if ( pt.m_x != x || pt.m_y != y )
throw new SQLException("assertHasValues fails");
}
private double m_x;
private double m_y;
private String m_typeName;
@Override
public String getSQLTypeName() {
return m_typeName;
}
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
s_logger.info(typeName + " from SQLInput");
m_x = stream.readDouble();
m_y = stream.readDouble();
m_typeName = typeName;
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
s_logger.info(m_typeName + " to SQLOutput");
stream.writeDouble(m_x);
stream.writeDouble(m_y);
}
@Override
public String toString()
{
return String.format("(%g,%g)", m_x, m_y);
}
}