Some more additions to contrib for JDBC
This commit is contained in:
parent
d09fc12044
commit
11cb9acb68
@ -0,0 +1,4 @@
|
||||
Tue Jan 23 10:19:00 GMT 2001 peter@retep.org.uk
|
||||
- Finished the XML Export classes
|
||||
- First of the test data suite now in CVS.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
build file to build the donated retep tools packages
|
||||
|
||||
$Id: build.xml,v 1.1 2001/01/18 14:50:14 peter Exp $
|
||||
$Id: build.xml,v 1.2 2001/01/23 10:22:18 peter Exp $
|
||||
|
||||
-->
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
<!-- Builds the various jar files -->
|
||||
<target name="jar" depends="xml">
|
||||
<jar jarfile="${jars}/retepTools.jar" basedir="${dest}">
|
||||
<include name="${package}/xml/parser/**" if="xml" />
|
||||
<include name="${package}/xml/**" if="xml" />
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
|
16
contrib/retep/data/cds.dtd
Normal file
16
contrib/retep/data/cds.dtd
Normal file
@ -0,0 +1,16 @@
|
||||
<!ELEMENT album (track*)+>
|
||||
<!ATTLIST album
|
||||
title CDATA #IMPLIED
|
||||
aid CDATA #IMPLIED
|
||||
>
|
||||
<!ELEMENT catalogue (group)>
|
||||
<!ELEMENT group (album*)>
|
||||
<!ATTLIST group
|
||||
name CDATA #IMPLIED
|
||||
>
|
||||
<!ELEMENT track (#PCDATA)>
|
||||
<!ATTLIST track
|
||||
tid CDATA #IMPLIED
|
||||
id CDATA #IMPLIED
|
||||
>
|
||||
|
2691
contrib/retep/data/cds.xml
Normal file
2691
contrib/retep/data/cds.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
<property category="sys" name="CompanyLabel" value="Company:" />
|
||||
<property category="sys" name="Copyright" value="Copyright (c) 2001" />
|
||||
<property category="sys" name="CopyrightLabel" value="Copyright:" />
|
||||
<property category="sys" name="DefaultPackage" value="org.postgresql.core" />
|
||||
<property category="sys" name="DefaultPackage" value="uk.org.retep.xml.jdbc" />
|
||||
<property category="sys" name="Description" value="" />
|
||||
<property category="sys" name="DescriptionLabel" value="Description:" />
|
||||
<property category="sys" name="DocPath" value="doc" />
|
||||
@ -25,7 +25,7 @@
|
||||
<property category="sys" name="InstanceVisibility" value="0" />
|
||||
<property category="sys" name="JDK" value="java 1.3.0-C" />
|
||||
<property category="sys" name="LastTag" value="0" />
|
||||
<property category="sys" name="Libraries" value="JAXP" />
|
||||
<property category="sys" name="Libraries" value="JAXP;Oracle JDBC" />
|
||||
<property category="sys" name="MakeStable" value="0" />
|
||||
<property category="sys" name="OutPath" value="build" />
|
||||
<property category="sys" name="SourcePath" value="." />
|
||||
@ -34,6 +34,8 @@
|
||||
<property category="sys" name="Version" value="1.0" />
|
||||
<property category="sys" name="VersionLabel" value="@version" />
|
||||
<property category="sys" name="WorkingDirectory" value="." />
|
||||
<node type="Folder" name="core" />
|
||||
<node type="Package" name="uk.org.retep.xml.core" />
|
||||
<node type="Package" name="uk.org.retep.xml.jdbc" />
|
||||
<node type="Package" name="uk.org.retep.xml.parser" />
|
||||
<file path="build.xml" />
|
||||
|
334
contrib/retep/uk/org/retep/xml/core/XMLFactory.java
Normal file
334
contrib/retep/uk/org/retep/xml/core/XMLFactory.java
Normal file
@ -0,0 +1,334 @@
|
||||
package uk.org.retep.xml.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* An XMLFactory is used to render XML Tags, accounting for nesting etc
|
||||
*/
|
||||
public class XMLFactory
|
||||
{
|
||||
/**
|
||||
* The lest level (ie, how many tags down the tree we are)
|
||||
*/
|
||||
protected int level;
|
||||
|
||||
/**
|
||||
* The size of our tag name cache
|
||||
*/
|
||||
protected int maxlevel;
|
||||
|
||||
/**
|
||||
* Our tag name cache
|
||||
*/
|
||||
protected String[] names;
|
||||
|
||||
/**
|
||||
* Used to keep track of how formatting is done
|
||||
*/
|
||||
protected boolean hascontent;
|
||||
protected boolean[] contbuf;
|
||||
|
||||
/**
|
||||
* Scratch used by nest()
|
||||
*/
|
||||
private char[] nestbuf;
|
||||
|
||||
/**
|
||||
* The destination Writer
|
||||
*/
|
||||
protected Writer out;
|
||||
|
||||
/**
|
||||
* True if we are still within a tag
|
||||
*/
|
||||
protected boolean inTag;
|
||||
|
||||
/**
|
||||
* True if we have just created a tag so parameters are valid
|
||||
*/
|
||||
protected boolean inArg;
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory with no output Writer
|
||||
*/
|
||||
public XMLFactory()
|
||||
{
|
||||
this(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory with no output Writer
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m)
|
||||
{
|
||||
// Initialise the names cache
|
||||
level=0;
|
||||
maxlevel=m;
|
||||
names=new String[maxlevel];
|
||||
contbuf=new boolean[maxlevel];
|
||||
|
||||
// This is used by nest()
|
||||
nestbuf=new char[maxlevel];
|
||||
for(int i=0;i<maxlevel;i++)
|
||||
nestbuf[i]=' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
*/
|
||||
public XMLFactory(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
this();
|
||||
setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param encoding The XML encoding
|
||||
*/
|
||||
public XMLFactory(Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this();
|
||||
setWriter(out,encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m,Writer out)
|
||||
throws IOException
|
||||
{
|
||||
this(m);
|
||||
setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XMLFactory
|
||||
* @param out Writer to send the output to
|
||||
* @param encoding The XML encoding
|
||||
* @param m Expected number of leaves in the XML Tree
|
||||
*/
|
||||
public XMLFactory(int m,Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this(m);
|
||||
setWriter(out,encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send the output to. This call will also send the
|
||||
* XML header.
|
||||
*
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void setWriter(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
setWriter(out,"ISO-8859-1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send the output to. This call will also send the
|
||||
* XML header using the supplied encoding. It is up to the user code to
|
||||
* implement this encoding.
|
||||
*
|
||||
* @param out Writer to send output to
|
||||
* @param encoding Encoding of the XML Output
|
||||
*/
|
||||
public void setWriter(Writer out,String encoding)
|
||||
throws IOException
|
||||
{
|
||||
this.out=out;
|
||||
out.write("<?xml version=\"1.0\" encoding=\"");
|
||||
out.write(encoding);
|
||||
out.write("\" ?>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Writer the XML is being sent out on.
|
||||
*/
|
||||
public Writer getWriter() {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* This starts a tag
|
||||
* @param name The tag name
|
||||
*/
|
||||
public void startTag(String name)
|
||||
throws IOException
|
||||
{
|
||||
if(inTag && inArg) {
|
||||
// Handles two startTag() calls in succession.
|
||||
out.write(">");
|
||||
}
|
||||
|
||||
nest(level);
|
||||
out.write('<');
|
||||
out.write(name);
|
||||
inTag=true;
|
||||
inArg=true;
|
||||
|
||||
// cache the current tag name
|
||||
names[level]=name;
|
||||
|
||||
// cache the current hascontent value & reset
|
||||
contbuf[level]=hascontent;
|
||||
hascontent=false;
|
||||
|
||||
// increase the level and the cache's as necessary
|
||||
level++;
|
||||
if(level>maxlevel) {
|
||||
maxlevel=maxlevel+10;
|
||||
|
||||
String n[]=new String[maxlevel];
|
||||
System.arraycopy(names,0,n,0,level);
|
||||
names=n;
|
||||
|
||||
boolean b[] = new boolean[maxlevel];
|
||||
System.arraycopy(contbuf,0,b,0,level);
|
||||
contbuf=b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This ends a tag
|
||||
*/
|
||||
public void endTag()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(level<1)
|
||||
throw new XMLFactoryException("endTag called above root node");
|
||||
|
||||
level--;
|
||||
|
||||
if(inArg) {
|
||||
// We are still within the opening tag
|
||||
out.write(" />");
|
||||
} else {
|
||||
// We must have written some content or child tags
|
||||
|
||||
// hascontent is true if addContent() was called. If it was never called
|
||||
// to get here some child tags must have been written, so we call nest()
|
||||
// so that the close tag is on it's own line, and everything looks neat
|
||||
// and tidy.
|
||||
if(!hascontent)
|
||||
nest(level);
|
||||
|
||||
out.write("</");
|
||||
out.write(names[level]);
|
||||
out.write('>');
|
||||
}
|
||||
|
||||
inArg=false; // The parent tag must be told it now has content
|
||||
inTag= level>0; // Are we still in a tag?
|
||||
hascontent=contbuf[level]; // retrieve this level's hascontent value
|
||||
}
|
||||
|
||||
/**
|
||||
* This completes the document releasing any open resources.
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
while(level>0)
|
||||
endTag();
|
||||
out.write('\n');
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes an attribute to the current tag. If the value is null, then no action is taken.
|
||||
* @param name Name of the parameter
|
||||
* @param value Value of the parameter
|
||||
* @throw XMLFactoryException if out of context
|
||||
*/
|
||||
public void addAttribute(String name,Object value)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(value==null)
|
||||
return;
|
||||
|
||||
if(inArg) {
|
||||
out.write(' ');
|
||||
out.write(name);
|
||||
out.write("=\"");
|
||||
out.write(encode(value.toString()));
|
||||
out.write("\"");
|
||||
} else
|
||||
throw new XMLFactoryException("Cannot add attribute outside of a tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* This writes some content to the current tag. Once this has been called,
|
||||
* you cannot add any more attributes to the current tag. Note, if c is null,
|
||||
* no action is taken.
|
||||
* @param c content to add.
|
||||
*/
|
||||
public void addContent(Object c)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(c==null)
|
||||
return;
|
||||
|
||||
if(inTag) {
|
||||
if(inArg) {
|
||||
// close the open tag
|
||||
out.write('>');
|
||||
inArg=false;
|
||||
}
|
||||
out.write(c.toString());
|
||||
|
||||
// This is used by endTag()
|
||||
hascontent=true;
|
||||
} else
|
||||
throw new XMLFactoryException("Cannot add content outside of a tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds a comment to the XML file. This is normally used at the start of
|
||||
* any XML output.
|
||||
* @parm c Comment to include
|
||||
*/
|
||||
public void addComment(Object c)
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
if(inTag)
|
||||
throw new XMLFactoryException("Cannot add comments within a tag");
|
||||
|
||||
out.write("\n<!-- ");
|
||||
out.write(c.toString());
|
||||
out.write(" -->");
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents the output according to the level
|
||||
* @param level The indent level to generate
|
||||
*/
|
||||
protected void nest(int level)
|
||||
throws IOException
|
||||
{
|
||||
out.write('\n');
|
||||
while(level>nestbuf.length) {
|
||||
out.write(nestbuf,0,nestbuf.length);
|
||||
level-=nestbuf.length;
|
||||
}
|
||||
out.write(nestbuf,0,level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the string so that any XML tag chars are translated
|
||||
*/
|
||||
protected String encode(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
19
contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java
Normal file
19
contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java
Normal file
@ -0,0 +1,19 @@
|
||||
package uk.org.retep.xml.core;
|
||||
|
||||
/**
|
||||
* Title:
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2001
|
||||
* Company:
|
||||
* @author
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class XMLFactoryException extends Exception
|
||||
{
|
||||
|
||||
public XMLFactoryException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
237
contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java
Normal file
237
contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java
Normal file
@ -0,0 +1,237 @@
|
||||
package uk.org.retep.xml.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
public class XMLDatabase
|
||||
{
|
||||
/**
|
||||
* The XMLFactory being used by this instance
|
||||
*/
|
||||
protected XMLFactory factory;
|
||||
|
||||
/**
|
||||
* Constructor. setXMLFactory() must be called if this method is used.
|
||||
*/
|
||||
public XMLDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param fac XMLFactory to use
|
||||
*/
|
||||
public XMLDatabase(XMLFactory fac)
|
||||
{
|
||||
this();
|
||||
setXMLFactory(fac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory to use.
|
||||
* @param factory XMLFactory to use
|
||||
*/
|
||||
public void setXMLFactory(XMLFactory factory)
|
||||
{
|
||||
this.factory=factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the XMLFactory being used.
|
||||
*/
|
||||
public XMLFactory getXMLFactory()
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all output to the Writer.
|
||||
* @throw IOException from Writer
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
factory.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param con Connection to database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(Connection con,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
writeTable(con.getMetaData(),table);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param db DatabaseMetaData for the database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(DatabaseMetaData db,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
writeTable(db,null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the schema of a table.
|
||||
* @param db DatabaseMetaData for the database
|
||||
* @param table Table name
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void writeTable(DatabaseMetaData db,String cat,String schem,String table)
|
||||
throws IOException,SQLException,XMLFactoryException
|
||||
{
|
||||
ResultSet trs;
|
||||
|
||||
factory.startTag("TABLE");
|
||||
factory.addAttribute("NAME",table);
|
||||
// fetch the remarks for this table (if any)
|
||||
trs = db.getTables(null,null,table,null);
|
||||
if(trs!=null) {
|
||||
if(trs.next()) {
|
||||
String rem = trs.getString(5);
|
||||
if(rem!=null)
|
||||
factory.addContent(rem);
|
||||
}
|
||||
trs.close();
|
||||
}
|
||||
|
||||
trs = db.getColumns(null,null,table,"%");
|
||||
if(trs!=null) {
|
||||
while(trs.next()) {
|
||||
factory.startTag("COLUMN");
|
||||
factory.addAttribute("NAME",trs.getString(4));
|
||||
factory.addAttribute("TYPE",trs.getString(6));
|
||||
factory.addAttribute("COLUMN_SIZE",trs.getString(7));
|
||||
factory.addAttribute("DECIMAL_DIGITS",trs.getString(9));
|
||||
factory.addAttribute("NUM_PREC_RADIX",trs.getString(10));
|
||||
factory.addAttribute("NULLABLE",trs.getString(11));
|
||||
factory.addAttribute("COLUMN_DEF",trs.getString(13));
|
||||
factory.addAttribute("CHAR_OCTET_LENGTH",trs.getString(16));
|
||||
factory.addAttribute("ORDINAL_POSITION",trs.getString(17));
|
||||
factory.addAttribute("IS_NULLABLE",trs.getString(18));
|
||||
factory.addAttribute("TABLE_CAT",trs.getString(1));
|
||||
factory.addAttribute("TABLE_SCHEM",trs.getString(2));
|
||||
String rem = trs.getString(12);
|
||||
if(rem!=null)
|
||||
factory.addContent(rem);
|
||||
factory.endTag();
|
||||
}
|
||||
trs.close();
|
||||
}
|
||||
|
||||
factory.endTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db Connection to database
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(Connection db,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db.getMetaData(),null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db,null,null,table);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(Connection db)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db.getMetaData(),null,null,"%");
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
writeDatabase(db,null,null,"%");
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates the schema of an entire database.
|
||||
* @param db DatabaseMetaData of database
|
||||
* @param cat Catalog (may be null)
|
||||
* @param schem Schema (may be null)
|
||||
* @param table Table pattern
|
||||
* @throw IOException from Writer
|
||||
* @throw SQLException from JDBC
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
* @see java.sql.DatabaseMetaData.getTables()
|
||||
*/
|
||||
public void writeDatabase(DatabaseMetaData db,String cat,String schem,String table)
|
||||
throws IOException, SQLException, XMLFactoryException
|
||||
{
|
||||
ResultSet rs = db.getTables(cat,schem,table,null);
|
||||
if(rs!=null) {
|
||||
factory.startTag("DATABASE");
|
||||
factory.addAttribute("PRODUCT",db.getDatabaseProductName());
|
||||
factory.addAttribute("VERSION",db.getDatabaseProductVersion());
|
||||
|
||||
while(rs.next()) {
|
||||
writeTable(db,rs.getString(1),rs.getString(2),rs.getString(3));
|
||||
}
|
||||
|
||||
factory.endTag();
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
505
contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java
Normal file
505
contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java
Normal file
@ -0,0 +1,505 @@
|
||||
package uk.org.retep.xml.jdbc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import uk.org.retep.xml.core.XMLFactory;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
|
||||
/**
|
||||
* This class takes a java.sql.ResultSet object and generates an XML stream
|
||||
* based on it's contents.
|
||||
*
|
||||
* $Id: XMLResultSet.java,v 1.1 2001/01/23 10:22:20 peter Exp $
|
||||
*/
|
||||
public class XMLResultSet
|
||||
{
|
||||
/**
|
||||
* The current ResultSet to process
|
||||
*/
|
||||
protected ResultSet rs;
|
||||
|
||||
/**
|
||||
* The XMLFactory being used by this instance
|
||||
*/
|
||||
protected XMLFactory factory;
|
||||
|
||||
/**
|
||||
* The default properties used when none are supplied by the user
|
||||
*/
|
||||
protected static Properties defaults;
|
||||
|
||||
/**
|
||||
* The default property name for defining the tag name used to define a
|
||||
* ResultSet
|
||||
*/
|
||||
public static String RESULTSET_NAME = "resultset.name";
|
||||
|
||||
/**
|
||||
* The default tag name for a resultset
|
||||
*/
|
||||
public static String DEFAULT_RESULTSET_NAME = "RESULTSET";
|
||||
|
||||
/**
|
||||
* The default property name for defining the tag name used to define a row
|
||||
*/
|
||||
public static String ROW_NAME = "row.name";
|
||||
|
||||
/**
|
||||
* The default tag name for a row
|
||||
*/
|
||||
public static String DEFAULT_ROW_NAME = "RECORD";
|
||||
|
||||
/**
|
||||
* The default tag name for a resultset
|
||||
*/
|
||||
public static String COLNAME = ".name";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* enclosed within a pair of tags, ie: <id>1234</id>
|
||||
*/
|
||||
public static String CONTENT = "content";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* an attribute in the columns tag. ie: <id value="1234" />
|
||||
*/
|
||||
public static String ATTRIBUTE = "attribute";
|
||||
|
||||
/**
|
||||
* This is the default attribute name used when the ATTRIBUTE option is set.
|
||||
*/
|
||||
public static String DEFAULT_ATTRIBUTE = "VALUE";
|
||||
|
||||
/**
|
||||
* The value of the property (named as its related column) used to define
|
||||
* how the column is generated. This indicates that the columns data is
|
||||
* an attribute in the parent's tag. ie: <row id="1234" />
|
||||
*/
|
||||
public static String ROW_ATTRIBUTE = "row";
|
||||
|
||||
/**
|
||||
* This property name marks the begining row number within the ResultSet to
|
||||
* start processing.
|
||||
*/
|
||||
public static String FIRST_ROW = "row.first";
|
||||
|
||||
/**
|
||||
* This property name marks the last row number within the ResultSet to
|
||||
* end processing.
|
||||
*/
|
||||
public static String LAST_ROW = "row.last";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public XMLResultSet()
|
||||
{
|
||||
factory = new XMLFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public XMLResultSet(ResultSet rs)
|
||||
{
|
||||
this();
|
||||
setResultSet(rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ResultSet to use
|
||||
* @param rs ResultSet
|
||||
*/
|
||||
public void setResultSet(ResultSet rs)
|
||||
{
|
||||
this.rs=rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current ResultSet
|
||||
*
|
||||
*/
|
||||
public ResultSet getResultSet()
|
||||
{
|
||||
return rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Writer to send all output to
|
||||
* @param out Writer
|
||||
* @throws IOException from XMLFactory
|
||||
* @see XMLFactory.setWriter
|
||||
*/
|
||||
public void setWriter(Writer out)
|
||||
throws IOException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Writer output is going to
|
||||
*/
|
||||
public Writer getWriter()
|
||||
{
|
||||
return factory.getWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return XMLFactory being used
|
||||
*/
|
||||
public XMLFactory getXMLFactory()
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all output to the Writer
|
||||
* @throw IOException from Writer
|
||||
* @throw XMLFactoryException from XMLFactory
|
||||
*/
|
||||
public void close()
|
||||
throws IOException, XMLFactoryException
|
||||
{
|
||||
factory.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default properties used by translate() and buildDTD()
|
||||
* @return Properties default property settings
|
||||
*/
|
||||
public static Properties getDefaultProperties()
|
||||
{
|
||||
if(defaults==null) {
|
||||
defaults=new Properties();
|
||||
defaults.setProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
defaults.setProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the supplied
|
||||
* Writer.
|
||||
* @param rs ResultSet to convert
|
||||
* @param p Properties for the conversion
|
||||
* @param out Writer to send output to (replaces existing one)
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Properties p,Writer out)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
translate(rs,p);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the supplied
|
||||
* Writer using a default tag struct
|
||||
* @param rs ResultSet to convert
|
||||
* @param out Writer to send output to (replaces existing one)
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Writer out)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
factory.setWriter(out);
|
||||
translate(rs,(Properties)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the current
|
||||
* output stream using a default tag structure.
|
||||
* @param rs ResultSet to convert
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
translate(rs,(Properties)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates an XML version of a ResultSet sending it to the current
|
||||
* output stream.
|
||||
* @param rs ResultSet to convert
|
||||
* @param p Properties for the conversion
|
||||
* @throws XMLFactoryException from XMLFactory
|
||||
* @throws IOException from Writer
|
||||
* @throws SQLException from ResultSet
|
||||
*/
|
||||
public void translate(ResultSet rs,Properties p)
|
||||
throws XMLFactoryException, IOException, SQLException
|
||||
{
|
||||
// if we don't pass any properties, create an empty one and cache it if
|
||||
// further calls do the same
|
||||
if(p==null) {
|
||||
p=getDefaultProperties();
|
||||
}
|
||||
|
||||
// Fetch some common values
|
||||
String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int numcols = rsmd.getColumnCount();
|
||||
|
||||
String colname[] = new String[numcols]; // field name cache
|
||||
int coltype[] = new int[numcols]; // true to use attribute false content
|
||||
String colattr[] = new String[numcols]; // Attribute name
|
||||
|
||||
// These deal with when an attribute is to go into the row's tag parameters
|
||||
int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's
|
||||
int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields
|
||||
boolean haveParent= numParents>0; // true only if we need to us these
|
||||
|
||||
// This allows some limiting of the output result
|
||||
int firstRow = Integer.parseInt(p.getProperty(FIRST_ROW,"0"));
|
||||
int lastRow = Integer.parseInt(p.getProperty(LAST_ROW,"0"));
|
||||
int curRow=0;
|
||||
|
||||
// Start the result set's tag
|
||||
factory.startTag(setName);
|
||||
|
||||
while(rs.next()) {
|
||||
if(firstRow<=curRow && (lastRow==0 || curRow<lastRow)) {
|
||||
factory.startTag(rowName);
|
||||
|
||||
if(haveParent) {
|
||||
// Add any ROW_ATTRIBUTE entries
|
||||
for(int i=0;i<numParents;i++)
|
||||
factory.addAttribute(colname[i],rs.getString(i+1));
|
||||
}
|
||||
|
||||
// Process any CONTENT & ATTRIBUTE entries.
|
||||
// This skips if all the entries are ROW_ATTRIBUTE's
|
||||
if(numParents < numcols) {
|
||||
for(int i=1;i<=numcols;i++) {
|
||||
// Now do we write the value as an argument or as PCDATA?
|
||||
switch(coltype[i-1]) {
|
||||
case 1:
|
||||
factory.startTag(colname[i-1]);
|
||||
factory.addAttribute(colattr[i-1],rs.getString(i));
|
||||
factory.endTag();
|
||||
break;
|
||||
|
||||
case 0:
|
||||
factory.startTag(colname[i-1]);
|
||||
factory.addContent(rs.getString(i));
|
||||
factory.endTag();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown type. This should only be called for ROW_ATTRIBUTE which
|
||||
// is handled before this loop.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End the row
|
||||
factory.endTag();
|
||||
}
|
||||
curRow++;
|
||||
|
||||
} // check for firstRow <= curRow <= lastRow
|
||||
|
||||
// Close the result set's tag
|
||||
factory.endTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
*/
|
||||
public void buildDTD(ResultSet rs)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,null,getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Writer out)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,null,out);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current writer
|
||||
* @param rs ResultSet
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Properties p)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
buildDTD(rs,p,getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a ResultSet and writes it's DTD to the current a.
|
||||
*
|
||||
* <p>ToDo:<ol>
|
||||
* <li>Add ability to have NULLABLE columns appear as optional (ie instead of
|
||||
* x, have x? (DTD for Optional). Can't use + or * as that indicates more than
|
||||
* 1 instance).
|
||||
* </ol>
|
||||
*
|
||||
* @param rs ResultSet
|
||||
* @param p Properties defining tag types (as translate)
|
||||
* @param out Writer to send output to
|
||||
*/
|
||||
public void buildDTD(ResultSet rs,Properties p,Writer out)
|
||||
throws IOException, SQLException
|
||||
{
|
||||
// if we don't pass any properties, create an empty one and cache it if
|
||||
// further calls do the same
|
||||
if(p==null) {
|
||||
p=getDefaultProperties();
|
||||
}
|
||||
|
||||
// Fetch some common values
|
||||
String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME);
|
||||
String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME);
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int numcols = rsmd.getColumnCount();
|
||||
|
||||
String colname[] = new String[numcols]; // field name cache
|
||||
int coltype[] = new int[numcols]; // true to use attribute false content
|
||||
String colattr[] = new String[numcols]; // Attribute name
|
||||
|
||||
// These deal with when an attribute is to go into the row's tag parameters
|
||||
int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's
|
||||
int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields
|
||||
boolean haveParent= numParents>0; // true only if we need to us these
|
||||
|
||||
// Now the dtd defining the ResultSet
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(setName);
|
||||
out.write(" (");
|
||||
out.write(rowName);
|
||||
out.write("*)>\n");
|
||||
|
||||
// Now the dtd defining each row
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(rowName);
|
||||
out.write(" (");
|
||||
boolean s=false;
|
||||
for(int i=0;i<numcols;i++) {
|
||||
if(coltype[i]!=2) { // not ROW_ATTRIBUTE
|
||||
if(s)
|
||||
out.write(",");
|
||||
out.write(colname[i]);
|
||||
s=true;
|
||||
}
|
||||
}
|
||||
out.write(")>\n");
|
||||
|
||||
// Now handle any ROW_ATTRIBUTE's
|
||||
if(haveParent) {
|
||||
out.write("<!ATTLIST ");
|
||||
out.write(rowName);
|
||||
for(int i=0;i<numParents;i++) {
|
||||
out.write("\n ");
|
||||
out.write(colname[parentFields[i]]);
|
||||
out.write(" CDATA #IMPLIED");
|
||||
}
|
||||
out.write("\n>\n");
|
||||
}
|
||||
|
||||
// Now add any CONTENT & ATTRIBUTE fields
|
||||
for(int i=0;i<numcols;i++) {
|
||||
if(coltype[i]!=2) {
|
||||
out.write("<!ELEMENT ");
|
||||
out.write(colname[i]);
|
||||
|
||||
// CONTENT
|
||||
if(coltype[i]==0) {
|
||||
out.write(" (#PCDATA)");
|
||||
} else {
|
||||
out.write(" EMPTY");
|
||||
}
|
||||
|
||||
out.write(">\n");
|
||||
|
||||
// ATTRIBUTE
|
||||
if(coltype[i]==1) {
|
||||
out.write("<!ATTLIST ");
|
||||
out.write(colname[i]);
|
||||
out.write("\n ");
|
||||
out.write(colattr[i]);
|
||||
out.write(" CDATA #IMPLIED\n>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method used by the core translate and buildDTD methods.
|
||||
* @param numcols Number of columns in ResultSet
|
||||
* @param colname Array of column names
|
||||
* @param colattr Array of column attribute names
|
||||
* @param coltype Array of column types
|
||||
* @param rsmd ResultSetMetaData for ResultSet
|
||||
* @param p Properties being used
|
||||
* @return array containing field numbers which should appear as attributes
|
||||
* within the rows tag.
|
||||
* @throws SQLException from JDBC
|
||||
*/
|
||||
private int[] getRowAttributes(int numcols,
|
||||
String colname[],String colattr[],
|
||||
int coltype[],
|
||||
ResultSetMetaData rsmd,Properties p)
|
||||
throws SQLException
|
||||
{
|
||||
int pf[] = null;
|
||||
int nf = 0;
|
||||
|
||||
// Now we put a columns value as an attribute if the property
|
||||
// fieldname=attribute (ie myname=attribute)
|
||||
// and if the fieldname.name property exists, use it as the attribute name
|
||||
for(int i=0;i<numcols;i++) {
|
||||
colname[i] = rsmd.getColumnName(i+1);
|
||||
colattr[i] = p.getProperty(colname[i]+COLNAME,DEFAULT_ATTRIBUTE);
|
||||
if(p.getProperty(colname[i],CONTENT).equals(ROW_ATTRIBUTE)) {
|
||||
// Ok, ROW_ATTRIBUTE's need to be cached, so add them in here
|
||||
coltype[i]=2;
|
||||
if(pf==null) {
|
||||
pf = new int[numcols]; // Max possible number of entries
|
||||
}
|
||||
pf[nf++] = i;
|
||||
} else {
|
||||
// Normal CONTENT or ATTRIBUTE entry
|
||||
coltype[i] = p.getProperty(colname[i],CONTENT).equals(ATTRIBUTE) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Form an array exactly nf elements long
|
||||
if(nf>0) {
|
||||
int r[] = new int[nf];
|
||||
System.arraycopy(pf,0,r,0,nf);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return null if no tags are to appear as attributes to the row's tag
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ import java.io.CharArrayWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
191
contrib/retep/uk/org/retep/xml/test/XMLExport.java
Normal file
191
contrib/retep/uk/org/retep/xml/test/XMLExport.java
Normal file
@ -0,0 +1,191 @@
|
||||
package uk.org.retep.xml.test;
|
||||
|
||||
import java.lang.Exception;
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.Properties;
|
||||
import uk.org.retep.xml.core.XMLFactoryException;
|
||||
import uk.org.retep.xml.jdbc.XMLDatabase;
|
||||
import uk.org.retep.xml.jdbc.XMLResultSet;
|
||||
|
||||
/**
|
||||
* This "test" class is a fully functional tool in its own right. It utilises
|
||||
* the xml classes to query and export to XML, or to dump database structures
|
||||
* into XML.
|
||||
*/
|
||||
|
||||
public class XMLExport
|
||||
{
|
||||
/**
|
||||
* The current Database Connection
|
||||
*/
|
||||
protected Connection conn;
|
||||
protected Statement stat;
|
||||
protected String drvr,url,table;
|
||||
|
||||
protected XMLResultSet xrs;
|
||||
protected XMLDatabase xdb;
|
||||
protected Properties prop;
|
||||
protected boolean outXML;
|
||||
protected boolean outDTD;
|
||||
protected boolean outTAB;
|
||||
protected int maxRows=0;
|
||||
|
||||
public XMLExport(String[] args)
|
||||
throws IOException,SQLException,XMLFactoryException,ClassNotFoundException
|
||||
{
|
||||
xrs = new XMLResultSet();
|
||||
xrs.setWriter(new OutputStreamWriter(System.out));
|
||||
//Properties p = new Properties(xrs.getDefaultProperties());
|
||||
prop = (Properties) xrs.getDefaultProperties().clone();
|
||||
|
||||
xdb = new XMLDatabase(xrs.getXMLFactory());
|
||||
|
||||
for(int i=0;i<args.length;i++) {
|
||||
String arg=args[i];
|
||||
if(arg.startsWith("-D")) {
|
||||
// Load JDBC Driver
|
||||
drvr=arg.substring(2);
|
||||
Class.forName(drvr);
|
||||
System.out.println("Now using JDBC Driver: "+drvr);
|
||||
} else if(arg.startsWith("-J")) {
|
||||
// Open a JDBC Connection (closing the existing one, if any)
|
||||
close();
|
||||
url = arg.substring(2);
|
||||
conn = DriverManager.getConnection(url);
|
||||
System.out.println("Opened "+url);
|
||||
stat=null;
|
||||
} else if(arg.startsWith("-M")) {
|
||||
// Set the maximum number of rows to process (0=no limit)
|
||||
maxRows=Integer.parseInt(arg.substring(2));
|
||||
if(maxRows<0)
|
||||
maxRows=0;
|
||||
prop.setProperty(XMLResultSet.FIRST_ROW,"0");
|
||||
prop.setProperty(XMLResultSet.LAST_ROW,Integer.toString(maxRows));
|
||||
} else if(arg.startsWith("-O")) {
|
||||
// Set the output file for XML & DTD
|
||||
xrs.setWriter(new FileWriter(arg.substring(2)));
|
||||
System.out.println("XML/DTD Output now going to "+arg.substring(2));
|
||||
} else if(arg.startsWith("-P")) {
|
||||
// Set a parameter for XML & DTD
|
||||
int p = arg.indexOf('=');
|
||||
prop.setProperty(arg.substring(2,p),arg.substring(p+1));
|
||||
} else if(arg.startsWith("-S")) {
|
||||
// -Stable generate schema of just table
|
||||
// -S generate schema of entire database
|
||||
if(arg.length()>2) {
|
||||
String table=arg.substring(2);
|
||||
System.out.println("Generating XML Schema of table "+table);
|
||||
xdb.writeTable(conn,table);
|
||||
xdb.close();
|
||||
} else {
|
||||
System.out.println("Generating XML Schema of database");
|
||||
xdb.writeDatabase(conn);
|
||||
xdb.close();
|
||||
}
|
||||
} else if(arg.equals("-V")) {
|
||||
// Select table output
|
||||
outXML=outDTD=false;
|
||||
} else if(arg.equals("-X")) {
|
||||
// Select XML output
|
||||
outXML=true;
|
||||
outDTD=outTAB=false;
|
||||
} else if(arg.equals("-Y")) {
|
||||
// Select DTD output
|
||||
outXML=outTAB=false;
|
||||
outDTD=true;
|
||||
} else if(arg.startsWith("-")) {
|
||||
System.err.println("Unknown argument: "+arg);
|
||||
System.exit(1);
|
||||
} else {
|
||||
// Ok, anything not starting with "-" are queries
|
||||
if(stat==null)
|
||||
stat=conn.createStatement();
|
||||
|
||||
System.out.println("Executing "+arg);
|
||||
ResultSet rs = stat.executeQuery(arg);
|
||||
if(rs!=null) {
|
||||
if(outXML) {
|
||||
xrs.translate(rs,prop);
|
||||
xrs.close();
|
||||
} else if(outDTD) {
|
||||
// Output the DTD
|
||||
xrs.buildDTD(rs,prop);
|
||||
xrs.close();
|
||||
} else {
|
||||
// Normal resultset output
|
||||
int rc=0;
|
||||
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int nc = rsmd.getColumnCount();
|
||||
boolean us=false;
|
||||
for(int c=0;c<nc;c++) {
|
||||
if(us)
|
||||
System.out.print("\t");
|
||||
System.out.print(rsmd.getColumnName(c+1));
|
||||
us=true;
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
while(rs.next() && (maxRows==0 || rc<maxRows)) {
|
||||
us=false;
|
||||
for(int c=0;c<nc;c++) {
|
||||
if(us)
|
||||
System.out.print("\t");
|
||||
System.out.print(rs.getString(c+1));
|
||||
us=true;
|
||||
}
|
||||
System.out.println();
|
||||
rc++;
|
||||
}
|
||||
|
||||
System.out.println("Returned "+rc+" rows.");
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
public void close() throws SQLException
|
||||
{
|
||||
if(conn!=null) {
|
||||
conn.close();
|
||||
System.out.println("Closed "+url);
|
||||
conn=null;
|
||||
stat=null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if(args.length==0) {
|
||||
System.out.println("Useage: java uk.org.retep.xml.test.XMLExport [args ...]\nwhere args are:\n"+
|
||||
"-Dclass.name JDBC Driver Class\n"+
|
||||
"-Jurl JDBC URL\n"+
|
||||
"-Mmax Maximum number of rows to process\n"+
|
||||
"-Ofilename Send all XML or DTD output to file\n"+
|
||||
"-Pkey=value Property passed on to XMLResultSet\n"+
|
||||
"-S[table] Write XML description of table. Whole DB if table left out.\n"+
|
||||
"-V Default: Write result to System.out\n"+
|
||||
"-X Write result in XML to System.out\n"+
|
||||
"-Y Write DTD describing result to System.out\n"+
|
||||
"\nAny other argument not starting with - is treated as an SQL Query\n"+
|
||||
"\nFor example:\n"+
|
||||
"To dump the table structure of a database into db.xml, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -Odb.xml -S\n"+
|
||||
"To dump the structure of a single table PRODUCTS and write into products.xml, use\n $ clear;java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver-Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -Oproducts.xml -SPRODUCT\n"+
|
||||
"To query a table and write the results into standard out as XML, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -M5 -PSKU=row -PIMAGE=attribute -X \"select sku,image,template from product\"\n"+
|
||||
"To query a table and write a DTD describing the ResultSet, use\n $ java uk.org.retep.xml.test.XMLExport -Doracle.jdbc.driver.OracleDriver -Jjdbc:oracle:thin:dbname/username@localhost:1521:ISORCL -M5 -PSKU=row -PIMAGE=attribute -Y \"select sku,image,template from product\"\n"
|
||||
);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
XMLExport XMLExport1 = new XMLExport(args);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user