Class PassXML
- java.lang.Object
-
- org.postgresql.pljava.example.annotation.PassXML
-
- All Implemented Interfaces:
SQLData
@SQLAction(provides="postgresql_xml",install="SELECT CASE (SELECT 1 FROM pg_type WHERE typname = \'xml\') WHEN 1 THEN set_config(\'pljava.implementors\', \'postgresql_xml,\' || current_setting(\'pljava.implementors\'), true) END") @SQLAction(implementor="postgresql_xml",requires="echoXMLParameter",install="WITH s(how) AS (SELECT generate_series(1, 7)), t(x) AS ( SELECT table_to_xml(\'pg_catalog.pg_operator\', true, false, \'\') ), r(howin, howout, isdoc) AS ( SELECT i.how, o.how, javatest.echoxmlparameter(x, i.how, o.how) IS DOCUMENT FROM t, s AS i, s AS o WHERE NOT (i.how = 6 and o.how = 7) ) SELECT CASE WHEN every(isdoc) THEN javatest.logmessage(\'INFO\', \'SQLXML echos succeeded\') ELSE javatest.logmessage(\'WARNING\', \'SQLXML echos had problems\') END FROM r") @SQLAction(implementor="postgresql_xml",requires="proxiedXMLEcho",install="WITH s(how) AS (SELECT unnest(\'{1,2,4,5,6,7}\'::int[])), t(x) AS ( SELECT table_to_xml(\'pg_catalog.pg_operator\', true, false, \'\') ), r(how, isdoc) AS ( SELECT\thow,\tjavatest.proxiedxmlecho(x, how) IS DOCUMENT FROM\tt, s )SELECT CASE WHEN every(isdoc) THEN javatest.logmessage(\'INFO\', \'proxied SQLXML echos succeeded\') ELSE javatest.logmessage(\'WARNING\', \'proxied SQLXML echos had problems\') END FROM r") @SQLAction(implementor="postgresql_xml",requires="lowLevelXMLEcho",install={"SELECT preparexmlschema(\'schematest\', $$<xs:schema xmlns:xs=\'http://www.w3.org/2001/XMLSchema\' targetNamespace=\'urn:testme\' elementFormDefault=\'qualified\'> <xs:element name=\'row\'> <xs:complexType> <xs:sequence> <xs:element name=\'textcol\' type=\'xs:string\' nillable=\'true\'/> <xs:element name=\'intcol\' type=\'xs:integer\' nillable=\'true\'/> </xs:sequence> </xs:complexType> </xs:element></xs:schema>$$, \'http://www.w3.org/2001/XMLSchema\', 5)","WITH s(how) AS (SELECT unnest(\'{4,5,7}\'::int[])), r(isdoc) AS ( SELECT javatest.lowlevelxmlecho( query_to_xml( \'SELECT \'\'hi\'\' AS textcol, 1 AS intcol\', true, true, \'urn:testme\' ), how, params) IS DOCUMENT FROM s, (SELECT \'schematest\' AS schema) AS params )SELECT CASE WHEN every(isdoc) THEN javatest.logmessage(\'INFO\', \'XML Schema tests succeeded\') ELSE javatest.logmessage(\'WARNING\', \'XML Schema tests had problems\') END FROM r"}) @SQLAction(implementor="postgresql_xml",requires={"prepareXMLTransform","transformXML"},install={"REVOKE EXECUTE ON FUNCTION javatest.prepareXMLTransformWithJava (pg_catalog.varchar, pg_catalog.xml, integer, boolean, boolean, pg_catalog.RECORD) FROM PUBLIC","SELECT javatest.prepareXMLTransform(\'distinctElementNames\',\'<xsl:transform version=\'\'1.0\'\' xmlns:xsl=\'\'http://www.w3.org/1999/XSL/Transform\'\' xmlns:exsl=\'\'http://exslt.org/common\'\' xmlns:set=\'\'http://exslt.org/sets\'\' extension-element-prefixes=\'\'exsl set\'\'> <xsl:output method=\'\'xml\'\' indent=\'\'no\'\'/> <xsl:template match=\'\'/\'\'> <xsl:variable name=\'\'enames\'\'> <xsl:for-each select=\'\'//*\'\'> <ename><xsl:value-of select=\'\'local-name()\'\'/></ename> </xsl:for-each> </xsl:variable> <xsl:for-each select=\'\'set:distinct(exsl:node-set($enames)/ename)\'\'> <xsl:sort select=\'\'string()\'\'/> <den><xsl:value-of select=\'\'.\'\'/></den> </xsl:for-each> </xsl:template></xsl:transform>\', how => 5, enableExtensionFunctions => true)","SELECT javatest.prepareXMLTransformWithJava(\'getPLJavaVersion\',\'<xsl:transform version=\'\'1.0\'\' xmlns:xsl=\'\'http://www.w3.org/1999/XSL/Transform\'\' xmlns:java=\'\'http://xml.apache.org/xalan/java\'\' exclude-result-prefixes=\'\'java\'\'> <xsl:template match=\'\'/\'\'> <xsl:value-of select=\'\'java:java.lang.System.getProperty( \"org.postgresql.pljava.version\")\'\' /> </xsl:template></xsl:transform>\', enableExtensionFunctions => true)","SELECT CASE WHEN javatest.transformXML(\'distinctElementNames\', \'<a><c/><e/><b/><b/><d/></a>\', 5, 5)::text = \'<den>a</den><den>b</den><den>c</den><den>d</den><den>e</den>\' THEN javatest.logmessage(\'INFO\', \'XSLT 1.0 test succeeded\') ELSE javatest.logmessage(\'WARNING\', \'XSLT 1.0 test failed\') END","SELECT CASE WHEN javatest.transformXML(\'getPLJavaVersion\', \'\')::text OPERATOR(pg_catalog.=) extversion THEN javatest.logmessage(\'INFO\', \'XSLT 1.0 with Java succeeded\') ELSE javatest.logmessage(\'WARNING\', \'XSLT 1.0 with Java failed\') END FROM pg_catalog.pg_extension WHERE extname = \'pljava\'"}) @SQLAction(implementor="postgresql_xml",provides="xml_java_ge_22",requires="javaSpecificationGE",install="SELECT CASE WHEN javatest.javaSpecificationGE(\'22\') THEN set_config(\'pljava.implementors\', \'xml_java_ge_22,\' || current_setting(\'pljava.implementors\'), true) END") @SQLAction(implementor="xml_java_ge_22",requires="lowLevelXMLEcho",install="WITH s(how) AS (SELECT unnest(\'{5,6,7}\'::int[])), r(isdoc) AS ( SELECT javatest.lowlevelxmlecho( \'<!DOCTYPE a []><a/>\'::xml, how, params) IS DOCUMENT FROM s, (SELECT null::void AS ignoreDTD) AS params )SELECT CASE WHEN every(isdoc) THEN javatest.logmessage(\'INFO\', \'jdk.xml.dtd.support=ignore OK\') ELSE javatest.logmessage(\'WARNING\', \'jdk.xml.dtd.support=ignore NG\') END FROM r") @MappedUDT(schema="javatest", name="onexml", structure="c1 xml", implementor="postgresql_xml", comment="A composite type mapped by the PassXML example class") public class PassXML extends Object implements SQLData
Class illustrating use ofSQLXML
to operate on XML data.This class also serves as the mapping class for a composite type
javatest.onexml
, the better to verify thatSQLData
input/output works too. That's why it has to implement SQLData.Everything mentioning the type XML here needs a conditional implementor tag in case of being loaded into a PostgreSQL instance built without that type.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
PassXML.SQLXMLMock
Class that will mock anSQLXML
instance, returning only binary or character stream data from a byte array or string supplied at construction.static class
PassXML.SQLXMLProxy
Class that will proxy methods to anotherSQLXML
class.
-
Method Summary
Modifier and Type Method Description static void
allowFragment(DOMResult r)
Configure aDOMResult
to acceptCONTENT
(a/k/a document fragment), not only the more restrictiveDOCUMENT
.static <T extends org.postgresql.pljava.Adjusting.XML.Parsing<? super T>>
TapplyAdjustments(ResultSet adjust, T axp)
Apply adjustments (supplied as a row type with a named column for each desired adjustment and its value) to an instance ofAdjusting.XML.Parsing
.static SQLXML
bounceXMLParameter(SQLXML sx)
"Echo" an XML parameter not by creating a new writableSQLXML
object at all, but simply returning the passed-in readable one untouched.static SQLXML
bounceXMLParameter_(SQLXML sx)
Just likebounceXMLParameter(java.sql.SQLXML)
but with parameter and return typed astext
, and so usable on a PostgreSQL instance lacking the XML type.static SQLXML
castTextXML(SQLXML sx)
Just likebounceXMLParameter(java.sql.SQLXML)
but with the parameter typed astext
and the return type left as XML, so functions as a cast.static SQLXML
echoXMLParameter(SQLXML sx, int howin, int howout)
Echo an XML parameter back, exercising seven different ways (howin => 1-7) of reading an SQLXML object, and seven (howout => 1-7) of returning one.static SQLXML
echoXMLParameter_(SQLXML sx, int howin, int howout)
Echo an XML parameter back, but with parameter and return types of PostgreSQLtext
.static SQLXML
ensureClosed(Result r, SQLXML sx, int how)
Ensure the closing of whatever method was used to add content to anSQLXML
object.String
getSQLTypeName()
static SQLXML
inStringoutXML(String in)
static String
inXMLoutString(SQLXML in)
static String
lowLevelXMLEcho(String x)
Low-level XML echo where the Java parameter and return type are String.static SQLXML
lowLevelXMLEcho(SQLXML sx, int how, ResultSet adjust)
Echo the XML parameter back, using lower-level manipulations thanechoXMLParameter
.static SQLXML
lowLevelXMLEcho_(SQLXML sx, int how, ResultSet adjust)
Text-typed variant of lowLevelXMLEcho (does not require XML type).static SQLXML
mockedXMLEcho(byte[] bytes)
Supply a sequence of bytes to be the exact (encoded) content of an XML value, which will be returned; if the encoding is not UTF-8, the value should begin with an XML Decl that names the encoding.static SQLXML
mockedXMLEcho(String chars)
Supply a sequence of characters to be the exact (Unicode) content of an XML value, which will be returned; if the value begins with an XML Decl that names an encoding, the content will be assumed to contain only characters representable in that encoding.static void
prepareXMLSchema(String name, SQLXML source, String lang, int how)
Precompile a schemasource
in schema languagelang
and save it (for the current session) asname
.static void
prepareXMLTransform(String name, SQLXML source, int how, boolean enableExtensionFunctions, boolean builtin, ResultSet adjust)
Precompile an XSL transformsource
and save it (for the current session) asname
.static void
prepareXMLTransformWithJava(String name, SQLXML source, int how, boolean enableExtensionFunctions, boolean builtin, ResultSet adjust)
Precompile an XSL transformsource
and save it (for the current session) asname
, where the transform may call Java methods.static SQLXML
proxiedXMLEcho(SQLXML sx, int how)
Proxy a PL/Java SQLXML source object as if it were of a non-PL/Java implementing class, to confirm that it can still be returned successfully to PostgreSQL.void
readSQL(SQLInput stream, String typeName)
static SQLXML
transformXML(String transformName, SQLXML source, int howin, int howout, ResultSet adjust, Boolean indent, Integer indentWidth)
Transform some XML according to a named transform prepared withprepareXMLTransform
.static void
unclosedSQLXML(int howmany, int how)
Create and leave some number of SQLXML objects unclosed, unused, and unreferenced, as a test of reclamation.void
writeSQL(SQLOutput stream)
static SQLXML
xmlFromComposite()
Test the MappedUDT (in one direction anyway).static boolean
xmlInStmtAndRS(ResultSet out)
Create some XML, pass it to aSELECT ?
prepared statement, retrieve it from the result set, and return it via the out-parameter result set of thisRECORD
-returning function.static SQLXML
xmlTextNode(byte[] stuff, String encoding, int how, boolean inElement)
Test serialization into the PostgreSQL server encoding by returning a text node, optionally wrapped in an element, containing the supplied stuff.
-
-
-
Method Detail
-
inXMLoutString
@Function(schema="javatest", implementor="postgresql_xml") public static String inXMLoutString(SQLXML in) throws SQLException
- Throws:
SQLException
-
inStringoutXML
@Function(schema="javatest", implementor="postgresql_xml") public static SQLXML inStringoutXML(String in) throws SQLException
- Throws:
SQLException
-
echoXMLParameter
@Function(schema="javatest", implementor="postgresql_xml", provides="echoXMLParameter") public static SQLXML echoXMLParameter(SQLXML sx, int howin, int howout) throws SQLException
Echo an XML parameter back, exercising seven different ways (howin => 1-7) of reading an SQLXML object, and seven (howout => 1-7) of returning one.If howin => 0, the XML parameter is simply saved in a static. It can be read in a subsequent call with sx => null, but only in the same transaction.
The "echoing" is done (in the
echoXML
method below) using aTransformer
, that is, the "TrAX" Transformation API for XML supplied in Java. It illustrates how an identityTransformer
can be used to get the XML content from the source to the result for any of the APIs selectable by howin and howout.It also illustrates something else. When using StAX (6 for howin or howout) and XML of the
CONTENT
flavor (multiple top-level elements, characters outside the top element, etc.), it is easy to construct examples that fail. The fault is not really with the StAX API, nor with TrAX proper, but with the small handful of bridge classes that were added to the JRE with StAX's first appearance, to make it interoperate with TrAX. It is not that those classes completely overlook theCONTENT
case: they make some efforts to handle it. Just not the right ones, and given the Java developers' usual reluctance to change such longstanding behavior, that's probably not getting fixed.Moral: StAX is a nice API, have no fear to use it directly in freshly-developed code, but: when using TrAX, make every effort to supply a
Transformer
withSource
andResult
objects of any kind other than StAX.- Throws:
SQLException
-
echoXMLParameter_
@Function(schema="javatest", name="echoXMLParameter", type="text") public static SQLXML echoXMLParameter_(@SQLType("text") SQLXML sx, int howin, int howout) throws SQLException
Echo an XML parameter back, but with parameter and return types of PostgreSQLtext
.The other version of this method needs a conditional implementor tag because it cannot be declared in a PostgreSQL instance that was built without
libxml
support and the PostgreSQLXML
type. But this version can, simply by mapping theSQLXML
parameter and return types to the SQLtext
type. The Java code is no different.Note that it's possible for both declarations to coexist in PostgreSQL (because as far as it is concerned, their signatures are different), but these two Java methods cannot have the same name (because they differ only in annotations, not in the declared Java types). So, this one needs a slightly tweaked name, and a
name
attribute in the annotation so PostgreSQL sees the right name.- Throws:
SQLException
-
bounceXMLParameter
@Function(schema="javatest", implementor="postgresql_xml") public static SQLXML bounceXMLParameter(SQLXML sx) throws SQLException
"Echo" an XML parameter not by creating a new writableSQLXML
object at all, but simply returning the passed-in readable one untouched.- Throws:
SQLException
-
bounceXMLParameter_
@Function(schema="javatest", type="text", name="bounceXMLParameter") public static SQLXML bounceXMLParameter_(@SQLType("text") SQLXML sx) throws SQLException
Just likebounceXMLParameter(java.sql.SQLXML)
but with parameter and return typed astext
, and so usable on a PostgreSQL instance lacking the XML type.- Throws:
SQLException
-
castTextXML
@Function(schema="javatest", implementor="postgresql_xml") public static SQLXML castTextXML(@SQLType("text") SQLXML sx) throws SQLException
Just likebounceXMLParameter(java.sql.SQLXML)
but with the parameter typed astext
and the return type left as XML, so functions as a cast.Slower than the other cases, because it must verify that the input really is XML before blindly calling it a PostgreSQL XML type. But the speed compares respectably to PostgreSQL's own CAST(text AS xml), at least for larger values; I am seeing Java pull ahead right around 32kB of XML data and beat PG by a factor of 2 or better at sizes of 1 or 2 MB. Unsurprisingly, PG has the clear advantage when values are very short.
- Throws:
SQLException
-
prepareXMLTransform
@Function(schema="javatest", implementor="postgresql_xml", provides="prepareXMLTransform") public static void prepareXMLTransform(String name, SQLXML source, @SQLType(defaultValue="0") int how, @SQLType(defaultValue="false") boolean enableExtensionFunctions, @SQLType(defaultValue="true") boolean builtin, @SQLType(defaultValue={}) ResultSet adjust) throws SQLException
Precompile an XSL transformsource
and save it (for the current session) asname
.Each value of
how
, 1-7, selects a different way of presenting theSQLXML
object to the XSL processor.Passing
true
forenableExtensionFunctions
allows the transform to use extensions that the Java XSLT implementation supports, such as functions from EXSLT. Those are disabled by default.Passing
false
forbuiltin
will allow aTransformerFactory
other than Java's built-in one to be found using the usual search order and the context class loader (normally the PL/Java class path for the schema where this function is declared). The default oftrue
ensures that the built-in Java XSLT 1.0 implementation is used. A transformer implementation other than Xalan may not recognize the feature controlled byenableExtensionFunctions
, so failure to configure that feature will be logged as a warning ifbuiltin
isfalse
, instead of thrown as an exception.Out of the box, Java's transformers only support XSLT 1.0. See the S9 example for more capabilities (at the cost of downloading the Saxon jar).
- Throws:
SQLException
-
prepareXMLTransformWithJava
@Function(schema="javatest", implementor="postgresql_xml", provides="prepareXMLTransform") public static void prepareXMLTransformWithJava(String name, SQLXML source, @SQLType(defaultValue="0") int how, @SQLType(defaultValue="false") boolean enableExtensionFunctions, @SQLType(defaultValue="true") boolean builtin, @SQLType(defaultValue={}) ResultSet adjust) throws SQLException
Precompile an XSL transformsource
and save it (for the current session) asname
, where the transform may call Java methods.Otherwise identical to
prepareXMLTransform
, this version sets theTransformerFactory
'sextensionClassLoader
(to the context class loader, normally the PL/Java class path for the schema where this function is declared), so the transform will be able to use xalan's Java call syntax to call any public Java methods that would be accessible to this class. (That can make a big difference in usefulness for the otherwise rather limited XSLT 1.0.)As with
enableExtensionFunctions
, failure by the transformer implementation to recognize or allow theextensionClassLoader
property will be logged as a warning ifbuiltin
isfalse
, rather than thrown as an exception.This example function will be installed with
EXECUTE
permission revoked fromPUBLIC
, as it essentially confers the ability to create arbitrary new Java functions, so should only be granted to roles you would be willing to grantUSAGE ON LANGUAGE java
.Because this function only prepares the transform, and
transformXML
applies it, there is some division of labor in determining what limits apply to its behavior. The use of this method instead ofprepareXMLTransform
determines whether the transform is allowed to see external Java methods at all; it will be the policy permissions granted totransformXML
that control what those methods can do when the transform is applied. For now, that method is defined in the trusted/sandboxedjava
language, so this function could reasonably be granted to any role withUSAGE
onjava
. If, by contrast,transformXML
were declared in the 'untrusted'javaU
, it would be prudent to allow only superusers access to this function, just as only they canCREATE FUNCTION
in an untrusted language.- Throws:
SQLException
-
transformXML
@Function(schema="javatest", implementor="postgresql_xml", provides="transformXML") public static SQLXML transformXML(String transformName, SQLXML source, @SQLType(defaultValue="0") int howin, @SQLType(defaultValue="0") int howout, @SQLType(defaultValue={}) ResultSet adjust, @SQLType(optional=true) Boolean indent, @SQLType(optional=true) Integer indentWidth) throws SQLException
Transform some XML according to a named transform prepared withprepareXMLTransform
.Pass null for
transformName
to get a plain identity transform (not such an interesting thing to do, unless you also specify indenting).- Throws:
SQLException
-
prepareXMLSchema
@Function(schema="javatest", implementor="postgresql_xml") public static void prepareXMLSchema(String name, SQLXML source, String lang, int how) throws SQLException
Precompile a schemasource
in schema languagelang
and save it (for the current session) asname
.Each value of
how
, 1-7, selects a different way of presenting theSQLXML
object to the schema parser.The
lang
parameter is a URI that identifies a known schema language. The only language a Java runtime is required to support is W3C XML Schema 1.0, with URIhttp://www.w3.org/2001/XMLSchema
.- Throws:
SQLException
-
lowLevelXMLEcho
@Function(schema="javatest", implementor="postgresql_xml", provides="lowLevelXMLEcho") public static SQLXML lowLevelXMLEcho(SQLXML sx, int how, @SQLType(defaultValue={}) ResultSet adjust) throws SQLException
Echo the XML parameter back, using lower-level manipulations thanechoXMLParameter
.This illustrates how the simple use of
t.transform(src,rlt)
inechoSQLXML
substitutes for a lot of fiddly case-by-case code, but when coding for a specific case, all the generality oftransform
may not be needed. It can be interesting to compare memory use when XML values are large.This method has been revised to demonstrate, even for low-level manipulations, how much fiddliness can now be avoided through use of the
Adjusting.XML.SourceResult
class, and how to make adjustments to parsing restrictions by passing the optional row-typed parameter adjust, which defaults to an empty row. For example, passingadjust => (select a from (true as allowdtd, true as expandentityreferences) as a)
would allow a document that contains an internal DTD subset and uses entities defined there.The older, pre-
SourceResult
code for doing low-level XML echo has been moved to theoldSchoolLowLevelEcho
method below. It can still be exercised by calling this method, explicitly passingadjust => NULL
.- Throws:
SQLException
-
applyAdjustments
public static <T extends org.postgresql.pljava.Adjusting.XML.Parsing<? super T>> T applyAdjustments(ResultSet adjust, T axp) throws SQLException
Apply adjustments (supplied as a row type with a named column for each desired adjustment and its value) to an instance ofAdjusting.XML.Parsing
.Column names in the adjust row are case-insensitive versions of the method names in
Adjusting.XML.Parsing
, and the value of each column should be of the appropriate type (if the method has a parameter).- Parameters:
adjust
- A row type as described above, possibly of no columns if no adjustments are wantedaxp
- An instance of Adjusting.XML.Parsing- Returns:
- axp, after applying any adjustments
- Throws:
SQLException
-
proxiedXMLEcho
@Function(schema="javatest", implementor="postgresql_xml", provides="proxiedXMLEcho") public static SQLXML proxiedXMLEcho(SQLXML sx, int how) throws SQLException
Proxy a PL/Java SQLXML source object as if it were of a non-PL/Java implementing class, to confirm that it can still be returned successfully to PostgreSQL.- Parameters:
sx
- readableSQLXML
object to proxyhow
- 1,2,4,5,6,7 determines what subclass ofSource
will be returned bygetSource
.- Throws:
SQLException
-
mockedXMLEcho
@Function(schema="javatest", implementor="postgresql_xml", provides="mockedXMLEchoB") public static SQLXML mockedXMLEcho(byte[] bytes) throws SQLException
Supply a sequence of bytes to be the exact (encoded) content of an XML value, which will be returned; if the encoding is not UTF-8, the value should begin with an XML Decl that names the encoding.Constructs an
SQLXML
instance that will return the supplied content as aStreamSource
wrapping anInputStream
, or viagetBinaryStream
, but fail if asked for any other form.- Throws:
SQLException
-
mockedXMLEcho
@Function(schema="javatest", implementor="postgresql_xml", provides="mockedXMLEchoC") public static SQLXML mockedXMLEcho(String chars) throws SQLException
Supply a sequence of characters to be the exact (Unicode) content of an XML value, which will be returned; if the value begins with an XML Decl that names an encoding, the content will be assumed to contain only characters representable in that encoding.Constructs an
SQLXML
instance that will return the supplied content as aStreamSource
wrapping aReader
, or viagetCharacterStream
, but fail if asked for any other form.- Throws:
SQLException
-
lowLevelXMLEcho_
@Function(schema="javatest", name="lowLevelXMLEcho", type="text") public static SQLXML lowLevelXMLEcho_(@SQLType("text") SQLXML sx, int how, @SQLType(defaultValue={}) ResultSet adjust) throws SQLException
Text-typed variant of lowLevelXMLEcho (does not require XML type).- Throws:
SQLException
-
lowLevelXMLEcho
@Function(schema="javatest", implementor="postgresql_xml", type="xml") public static String lowLevelXMLEcho(@SQLType("xml") String x) throws SQLException
Low-level XML echo where the Java parameter and return type are String.- Throws:
SQLException
-
xmlInStmtAndRS
@Function(schema="javatest", type="RECORD") public static boolean xmlInStmtAndRS(ResultSet out) throws SQLException
Create some XML, pass it to aSELECT ?
prepared statement, retrieve it from the result set, and return it via the out-parameter result set of thisRECORD
-returning function.- Throws:
SQLException
-
xmlTextNode
@Function(schema="javatest", implementor="postgresql_xml") public static SQLXML xmlTextNode(byte[] stuff, String encoding, int how, boolean inElement) throws Exception
Test serialization into the PostgreSQL server encoding by returning a text node, optionally wrapped in an element, containing the supplied stuff.The stuff is supplied as a
bytea
and a named encoding, so it is easy to supply stuff that isn't in the server encoding and see what the serializer does with it.As of this writing, if the stuff, decoded according to encoding, contains characters that are not representable in the server encoding, the serializers supplied in the JRE will:
- SAX, DOM: replace the character with a numeric character reference if
the node is wrapped in an element, but not outside of an element; there,
PL/Java ensures an
UnmappableCharacterException
is thrown, as the serializer would otherwise silently lose information by replacing the character with a?
. - StAX: replace the character with a numeric character reference whether
wrapped in an element or not (outside of an element, this officially
violates the letter of the XML spec, but does not lose information, and
is closer to the spirit of SQL/XML with its
XML(CONTENT)
type).
- Parameters:
stuff
- Content to be used in the text nodeencoding
- Name of an encoding; stuff will be decoded to Unicode according to this encoding, and then serialized into the server encoding, where possible.how
- Integer specifying which XML API to test, like every other how in this class; here the only valid choices are 5 (SAX), 6 (StAX), or 7 (DOM).inElement
- True if the text node should be wrapped in an element.- Returns:
- The resulting XML content.
- Throws:
Exception
- SAX, DOM: replace the character with a numeric character reference if
the node is wrapped in an element, but not outside of an element; there,
PL/Java ensures an
-
unclosedSQLXML
@Function(schema="javatest") public static void unclosedSQLXML(int howmany, int how) throws SQLException
Create and leave some number of SQLXML objects unclosed, unused, and unreferenced, as a test of reclamation.- Parameters:
howmany
- Number of SQLXML instances to create.how
- If nonzero, the flavor of writing to request on the object before abandoning it; if zero, it is left in its initial, writable state.- Throws:
SQLException
-
ensureClosed
public static SQLXML ensureClosed(Result r, SQLXML sx, int how) throws SQLException
Ensure the closing of whatever method was used to add content to anSQLXML
object.Before a
SQLXML
object that has been written to can be used by PostgreSQL (returned as a function result, plugged in as a prepared statement parameter or into aResultSet
, etc.), the method used for writing it must be "closed" to ensure the writing is complete.If it is set with
setString
, nothing more is needed;setString
obviously sets the whole value at once. AnyOutputStream
orWriter
obtained fromsetBinaryStream
orsetCharacterStream
, or fromsetResult
(StreamResult.class)
, has to be explicitly closed (aTransformer
does not close itsResult
when the transformation is complete!). Those are cases 1, 2, and 4 here.Cases 5 (
SAXResult
) and 6 (StAXResult
) need no special attention; though theTransformer
does not close them, the ones returned by thisSQLXML
implementation are set up to close themselves when theendDocument
event is written.Case 3 (test of
setString
is handled specially here. As this class allows testing of all techniques for writing theSQLXML
object, and most of those involve aResult
, case 3 is handled by also constructing aResult
over aStringWriter
and having the content written into that; this method then extracts the content from theStringWriter
and passes it tosetString
. For cases 1 and 2, likewise, the stream obtained withgetBinaryStream
orgetCharacterStream
has been wrapped in aResult
for generality in this example.A typical application will not need the generality seen here; it will usually know which technique it is using to write the
SQLXML
object, and only needs to know how to close that if it needs closing.- Parameters:
r
- TheResult
onto which writing was done.sx
- TheSQLXML
object being written.how
- The integer used in this example class to select which method of writing theSQLXML
object was to be tested.- Returns:
- The
SQLXML
objectsx
, because why not? - Throws:
SQLException
-
allowFragment
public static void allowFragment(DOMResult r) throws SQLException
Configure aDOMResult
to acceptCONTENT
(a/k/a document fragment), not only the more restrictiveDOCUMENT
.The other forms of
Result
that can be requested will happily acceptXML(CONTENT)
and not justXML(DOCUMENT)
. TheDOMResult
is pickier, however: if you first callsetNode
with aDocumentFragment
, it will accept either form, but if you leave the node unset when passing theDOMResult
to a transformer, the transformer will default to putting aDocument
node there, and then it will not accept a fragment.If you need to handle fragments, this method illustrates how to pre-load the
DOMResult
with an emptyDocumentFragment
. Note that if you use some XML processing package that supplies its own classes implementing DOM nodes, you may need to use aDocumentFragment
instance obtained from that package.- Throws:
SQLException
-
xmlFromComposite
@Function(schema="javatest", implementor="postgresql_xml") public static SQLXML xmlFromComposite() throws SQLException
Test the MappedUDT (in one direction anyway).Creates a
PassXML
object, the Java class that maps thejavatest.onexml
composite type, which has one member, of XML type. Stores aSQLXML
value in that field of thePassXML
object, and passes that to an SQL query that expects and returnsjavatest.onexml
. Retrieves the XML from the value field of thePassXML
object created to map the result of the query.- Returns:
- The original XML value, if all goes well.
- Throws:
SQLException
-
getSQLTypeName
public String getSQLTypeName()
- Specified by:
getSQLTypeName
in interfaceSQLData
-
readSQL
public void readSQL(SQLInput stream, String typeName) throws SQLException
- Specified by:
readSQL
in interfaceSQLData
- Throws:
SQLException
-
writeSQL
public void writeSQL(SQLOutput stream) throws SQLException
- Specified by:
writeSQL
in interfaceSQLData
- Throws:
SQLException
-
-